1: <?php
2:
3: 4: 5: 6:
7:
8:
9:
10:
11:
12: define('EXACT_TAG_MATCH', getOption('exact_tag_match'));
13: define('SEARCH_DURATION', 3000);
14: define('SEARCH_CACHE_DURATION', getOption('search_cache_duration'));
15:
16: class SearchEngine {
17:
18: var $fieldList = NULL;
19: var $page = 1;
20: var $images = NULL;
21: var $albums = NULL;
22: var $articles = NULL;
23: var $pages = NULL;
24: var $pattern;
25: var $tagPattern;
26: private $exact = false;
27: protected $dynalbumname = NULL;
28: protected $album = NULL;
29: protected $words;
30: protected $dates;
31: protected $whichdates = 'date';
32: protected $search_no_albums = false;
33: protected $search_no_images = false;
34: protected $search_no_pages = false;
35: protected $search_no_news = false;
36: protected $search_unpublished = false;
37: protected $search_structure;
38: protected $iteration = 0;
39: protected $processed_search = NULL;
40: protected $album_list = NULL;
41: protected $category_list = NULL;
42: protected $searches = NULL;
43: protected $extraparams = array();
44:
45: var $loaded = false;
46: var $table = 'albums';
47: var $transient = true;
48:
49: 50: 51: 52: 53: 54:
55: function __construct($dynamic_album = false) {
56: global $_zp_exifvars, $_zp_gallery;
57: switch ((int) getOption('exact_tag_match')) {
58: case 0:
59:
60: $this->tagPattern = array('type' => 'like', 'open' => '%', 'close' => '%');
61: break;
62: case 1:
63:
64: $this->tagPattern = array('type' => '=', 'open' => '', 'close' => '');
65: break;
66: case 2:
67:
68: $this->tagPattern = array('type' => 'regexp', 'open' => '[[:<:]]', 'close' => '[[:>:]]');
69: break;
70: }
71:
72: switch ((int) getOption('exact_string_match')) {
73: case 0:
74:
75: $this->pattern = array('type' => 'like', 'open' => '%', 'close' => '%');
76: break;
77: case 1:
78:
79: $this->pattern = array('type' => 'regexp', 'open' => '[[:<:]]', 'close' => '');
80: break;
81: case 2:
82:
83: $this->pattern = array('type' => 'regexp', 'open' => '[[:<:]]', 'close' => '[[:>:]]');
84: break;
85: }
86:
87: $this->extraparams['albumssorttype'] = getOption('search_album_sort_type');
88: $this->extraparams['albumssortdirection'] = getOption('search_album_sort_direction') ? 'DESC' : '';
89: $this->extraparams['imagessorttype'] = getOption('search_image_sort_type');
90: $this->extraparams['imagessortdirection'] = getOption('search_image_sort_direction') ? 'DESC' : '';
91: $this->extraparams['newssorttype'] = 'date';
92: $this->extraparams['newssortdirection'] = 'DESC';
93: $this->extraparams['pagesssorttype'] = 'title';
94: $this->extraparams['pagessortdirection'] = '';
95:
96:
97: $this->search_structure['title'] = gettext('Title');
98: $this->search_structure['desc'] = gettext('Description');
99: $this->search_structure['tags'] = gettext('Tags');
100: $this->search_structure['tags_exact'] = '';
101: $this->search_structure['filename'] = gettext('File/Folder name');
102: $this->search_structure['date'] = gettext('Date');
103: $this->search_structure['custom_data'] = gettext('Custom data');
104: $this->search_structure['location'] = gettext('Location/Place');
105: $this->search_structure['city'] = gettext('City');
106: $this->search_structure['state'] = gettext('State');
107: $this->search_structure['country'] = gettext('Country');
108: $this->search_structure['copyright'] = gettext('Copyright');
109: $this->search_structure['owner'] = gettext('Owner');
110: $this->search_structure['credit'] = gettext('Credit');
111: if (extensionEnabled('zenpage') && !$dynamic_album) {
112:
113: $this->search_structure['content'] = gettext('Content');
114: $this->search_structure['extracontent'] = gettext('ExtraContent');
115: $this->search_structure['author'] = gettext('Author');
116: $this->search_structure['lastchangeauthor'] = gettext('Last Editor');
117: $this->search_structure['titlelink'] = gettext('TitleLink');
118: $this->search_structure['news_categories'] = gettext('Categories');
119: }
120:
121: foreach ($_zp_exifvars as $field => $row) {
122: if ($row[4] && $row[5]) {
123: $this->search_structure[strtolower($field)] = $row[2];
124: }
125: }
126: $this->search_structure = zp_apply_filter('searchable_fields', $this->search_structure);
127: if (isset($_REQUEST['words'])) {
128: $this->words = zpFunctions::removeTrailingSlash(strtr(sanitize($_REQUEST['words'], 4), array('__23__' => '#', '__25__' => '%', '__26__' => '&', '__2F__' => '/')));
129: } else {
130: $this->words = NULL;
131: if (isset($_REQUEST['date'])) {
132: $this->dates = zpFunctions::removeTrailingSlash(sanitize($_REQUEST['date'], 3));
133: if (isset($_REQUEST['whichdate'])) {
134: $this->whichdates = sanitize($_REQUEST['whichdate']);
135: }
136: } else {
137: $this->dates = NULL;
138: }
139: }
140: $this->fieldList = $this->parseQueryFields();
141: if (isset($_REQUEST['inalbums'])) {
142: $list = trim(sanitize($_REQUEST['inalbums'], 3));
143: if (strlen($list) > 0) {
144: switch ($list) {
145: case "0":
146: $this->search_no_albums = true;
147: setOption('search_no_albums', 1, false);
148: break;
149: case "1":
150: $this->search_no_albums = false;
151: setOption('search_no_albums', 0, false);
152: break;
153: default:
154: $this->album_list = explode(',', $list);
155: break;
156: }
157: }
158: }
159: if (isset($_REQUEST['inimages'])) {
160: $list = trim(sanitize($_REQUEST['inimages'], 3));
161: if (strlen($list) > 0) {
162: switch ($list) {
163: case "0":
164: $this->search_no_images = true;
165: setOption('search_no_images', 1, false);
166: break;
167: case "1":
168: $this->search_no_images = false;
169: setOption('search_no_images', 0, false);
170: break;
171: }
172: }
173: }
174: if (isset($_REQUEST['inpages'])) {
175: $list = trim(sanitize($_REQUEST['inpages'], 3));
176: if (strlen($list) > 0) {
177: switch ($list) {
178: case "0":
179: $this->search_no_pages = true;
180: setOption('search_no_pages', 1, false);
181: break;
182: }
183: }
184: }
185: if (isset($_REQUEST['innews'])) {
186: $list = trim(sanitize($_REQUEST['innews'], 3));
187: if (strlen($list) > 0) {
188: switch ($list) {
189: case "0":
190: $this->search_no_news = true;
191: setOption('search_no_news', 1, false);
192: break;
193: case "1":
194: break;
195: default:
196: $this->category_list = explode(',', $list);
197: break;
198: }
199: }
200: }
201: $this->images = NULL;
202: $this->albums = NULL;
203: $this->searches = array('images' => NULL, 'albums' => NULL, 'pages' => NULL, 'news' => NULL);
204: zp_apply_filter('search_instantiate', $this);
205: }
206:
207: 208: 209: 210:
211: function getID() {
212: return 0;
213: }
214:
215: 216: 217: 218: 219:
220: function getSearchFieldList() {
221: $list = array();
222: foreach ($this->search_structure as $key => $display) {
223: if ($display) {
224: $list[$display] = $key;
225: }
226: }
227: return $list;
228: }
229:
230: 231: 232: 233: 234:
235: function allowedSearchFields() {
236: $setlist = array();
237: $fields = strtolower(getOption('search_fields'));
238: if (is_numeric($fields)) {
239: $setlist = $this->numericFields($fields);
240: } else {
241: $list = explode(',', $fields);
242: foreach ($this->search_structure as $key => $display) {
243: if (in_array($key, $list)) {
244: $setlist[$display] = $key;
245: }
246: }
247: }
248: return $setlist;
249: }
250:
251: 252: 253: 254: 255: 256:
257: protected function numericFields($fields) {
258: if ($fields == 0)
259: $fields = 0x0fff;
260: if ($fields & 0x01)
261: $list[$this->search_structure['title']] = 'title';
262: if ($fields & 0x02)
263: $list[$this->search_structure['desc']] = 'desc';
264: if ($fields & 0x04)
265: $list[$this->search_structure['tags']] = 'tags';
266: if ($fields & 0x08)
267: $list[$this->search_structure['filename']] = 'filename';
268: return $list;
269: }
270:
271: 272: 273: 274: 275: 276: 277:
278: function getSearchParams($long = true) {
279: global $_zp_page;
280: $r = '';
281: $w = urlencode(trim($this->codifySearchString()));
282: if (!empty($w)) {
283: $r .= '&words=' . $w;
284: }
285: $d = trim($this->dates);
286: if (!empty($d)) {
287: $r .= '&date=' . $d;
288: $d = trim($this->whichdates);
289: if ($d != 'date') {
290: $r.= '&whichdates=' . $d;
291: }
292: }
293: $r .= $this->getSearchFieldsText($this->fieldList);
294: if ($long) {
295: $a = $this->dynalbumname;
296: if ($a) {
297: $r .= '&albumname=' . $a;
298: }
299: if (empty($this->album_list)) {
300: if ($this->search_no_albums) {
301: $r .= '&inalbums=0';
302: }
303: } else {
304: $r .= '&inalbums=' . implode(',', $this->album_list);
305: }
306: if ($this->search_no_images) {
307: $r .= '&inimages=0';
308: }
309: if ($this->search_no_pages) {
310: $r .= '&inpages=0';
311: }
312: if (empty($this->categories)) {
313: if ($this->search_no_news) {
314: $r .= '&innews=0';
315: }
316: } else {
317: $r .= '&innews=' . implode(',', $this->categories);
318: }
319: if ($_zp_page > 1) {
320: $this->page = $_zp_page;
321: $r .= '&page=' . $_zp_page;
322: }
323: }
324: foreach ($this->extraparams as $p => $v) {
325: $r .= '&' . $p . '=' . $v;
326: }
327: return $r;
328: }
329:
330: 331: 332: 333: 334:
335: function getSearchExtra() {
336: return $this->extraparams;
337: }
338:
339: 340: 341: 342: 343:
344: function setSearchExtra($extra) {
345: $this->extraparams = $extra;
346: }
347:
348: 349: 350: 351: 352: 353: 354:
355: function setSortDirection($val, $what = 'images') {
356: if ($val) {
357: $this->extraparams[$what . 'sortdirection'] = 'DESC';
358: } else {
359: $this->extraparams[$what . 'sortdirection'] = 'ASC';
360: }
361: }
362:
363: 364: 365: 366: 367: 368:
369: function setSortType($sorttype, $what = 'images') {
370: $this->extraparams[$what . 'sorttype'] = $sorttype;
371: }
372:
373: 374: 375: 376: 377: 378: 379:
380: function getSearchFieldsText($fields, $param = '&searchfields=') {
381: $default = $this->allowedSearchFields();
382: $diff = array_diff($default, $fields);
383: if (count($diff) > 0) {
384: foreach ($fields as $field) {
385: $param .= $field . ',';
386: }
387: return substr($param, 0, -1);
388: }
389: return '';
390: }
391:
392: 393: 394: 395: 396: 397:
398: function setSearchParams($paramstr) {
399: $params = explode('&', $paramstr);
400: foreach ($params as $param) {
401: $e = strpos($param, '=');
402: $p = substr($param, 0, $e);
403: $v = substr($param, $e + 1);
404: switch ($p) {
405: case 'words':
406: $this->words = urldecode($v);
407: break;
408: case 'date':
409: $this->dates = $v;
410: break;
411: case 'whichdates':
412: $this->whichdates = $v;
413: break;
414: case 'searchfields':
415: if (is_numeric($v)) {
416: $this->fieldList = $this->numericFields($v);
417: } else {
418: $this->fieldList = array();
419: $list = explode(',', strtolower($v));
420: foreach ($this->search_structure as $key => $row) {
421: if (in_array(strtolower($key), $list)) {
422: $this->fieldList[] = $key;
423: }
424: }
425: }
426: break;
427: case 'page':
428: $this->page = $v;
429: break;
430: case 'albumname':
431: $alb = newAlbum($v, true, true);
432: if ($alb->loaded) {
433: $this->album = $alb;
434: $this->dynalbumname = $v;
435: $this->setSortType($this->album->getSortType('album'), 'albums');
436: $this->setSortDirection($this->album->getSortDirection('album'), 'albums');
437: $this->setSortType($this->album->getSortType(), 'images');
438: $this->setSortDirection($this->album->getSortDirection('image'), 'images');
439: }
440: break;
441: case 'inimages':
442: if (strlen($v) > 0) {
443: switch ($v) {
444: case "0":
445: $this->search_no_images = true;
446: setOption('search_no_images', 1, false);
447: break;
448: case "1":
449: $this->search_no_images = false;
450: setOption('search_no_images', 0, false);
451: break;
452: }
453: }
454: break;
455: case 'inalbums':
456: if (strlen($v) > 0) {
457: switch ($v) {
458: case "0":
459: $this->search_no_albums = true;
460: setOption('search_no_albums', 1, false);
461: break;
462: case "1":
463: $this->search_no_albums = false;
464: setOption('search_no_albums', 0, false);
465: break;
466: default:
467: $this->album_list = explode(',', $v);
468: break;
469: }
470: }
471: break;
472: case 'unpublished':
473: $this->search_unpublished = (bool) $v;
474: break;
475: default:
476: $this->extraparams[$p] = $v;
477: break;
478: }
479: }
480: if (!empty($this->words)) {
481: $this->dates = '';
482: }
483: }
484:
485:
486: function setSearchUnpublished() {
487: $this->search_unpublished = true;
488: }
489:
490: 491: 492: 493: 494:
495: function getSearchWords() {
496: return $this->words;
497: }
498:
499: 500: 501: 502: 503:
504: function getSearchDate() {
505: return $this->dates;
506: }
507:
508: 509: 510: 511: 512: 513: 514: 515:
516: function getSearchFields($array = false) {
517: if ($array)
518: return $this->fieldList;
519: return implode(',', $this->fieldList);
520: }
521:
522: 523: 524: 525: 526: 527: 528: 529: 530:
531: function getSearchString() {
532: if ($this->processed_search) {
533: return $this->processed_search;
534: }
535: $searchstring = trim($this->words);
536: $space_is = getOption('search_space_is');
537: $opChars = array('&' => 1, '|' => 1, '!' => 1, ',' => 1, '(' => 2);
538: if ($space_is) {
539: $opChars[' '] = 1;
540: }
541: $c1 = ' ';
542: $result = array();
543: $target = "";
544: $i = 0;
545: do {
546: $c = substr($searchstring, $i, 1);
547: $op = '';
548: switch ($c) {
549: case "'":
550: case '"':
551: case '`':
552: $j = strpos(str_replace('\\' . $c, '__', $searchstring), $c, $i + 1);
553: if ($j !== false) {
554: $target .= stripcslashes(substr($searchstring, $i + 1, $j - $i - 1));
555: $i = $j;
556: } else {
557: $target .= $c;
558: }
559: $c1 = $c;
560: break;
561: case ' ':
562: $j = $i + 1;
563: while ($j < strlen($searchstring) && $searchstring{$j} == ' ') {
564: $j++;
565: }
566: switch ($space_is) {
567: case 'OR':
568: case 'AND':
569: if ($j < strlen($searchstring)) {
570: $c3 = $searchstring{$j};
571: if (array_key_exists($c3, $opChars) && $opChars[$c3] == 1) {
572: $nextop = $c3 != '!';
573: } else if (substr($searchstring . ' ', $j, 4) == 'AND ') {
574: $nextop = true;
575: } else if (substr($searchstring . ' ', $j, 3) == 'OR ') {
576: $nextop = true;
577: } else {
578: $nextop = false;
579: }
580: }
581: if (!$nextop) {
582: if (!empty($target)) {
583: $r = trim($target);
584: if (!empty($r)) {
585: $last = $result[] = $r;
586: $target = '';
587: }
588: }
589: if ($space_is == 'AND') {
590: $c1 = '&';
591: } else {
592: $c1 = '|';
593: }
594: $target = '';
595: $last = $result[] = $c1;
596: }
597: break;
598: default:
599: $c1 = $c;
600: $target .= str_pad('', $j - $i);
601: break;
602: }
603: $i = $j - 1;
604: break;
605: case ',':
606: if (!empty($target)) {
607: $r = trim($target);
608: if (!empty($r)) {
609: switch ($r) {
610: case 'AND':
611: $r = '&';
612: break;
613: case 'OR':
614: $r = '|';
615: break;
616: case 'NOT':
617: $r = '!';
618: break;
619: }
620: $last = $result[] = $r;
621: $target = '';
622: }
623: }
624: $c2 = substr($searchstring, $i + 1, 1);
625: switch ($c2) {
626: case 'A':
627: if (substr($searchstring . ' ', $i + 1, 4) == 'AND ')
628: $c2 = '&';
629: break;
630: case 'O':
631: if (substr($searchstring . ' ', $i + 1, 3) == 'OR ')
632: $c2 = '|';
633: break;
634: case 'N':
635: if (substr($searchstring . ' ', $i + 1, 4) == 'NOT ')
636: $c2 = '!';
637: break;
638: }
639: if (!((isset($opChars[$c2]) && $opChars[$c2] == 1) || (isset($opChars[$last]) && $opChars[$last] == 1))) {
640: $last = $result[] = '|';
641: $c1 = $c;
642: }
643: break;
644: case '!':
645: case '&':
646: case '|':
647: case '(':
648: case ')':
649: if (!empty($target)) {
650: $r = trim($target);
651: if (!empty($r)) {
652: $last = $result[] = $r;
653: $target = '';
654: }
655: }
656: $c1 = $c;
657: $target = '';
658: $last = $result[] = $c;
659: $j = $i + 1;
660: break;
661: case 'A':
662: if (substr($searchstring . ' ', $i, 4) == 'AND ') {
663: $op = '&';
664: $skip = 3;
665: }
666: case 'O':
667: if (substr($searchstring . ' ', $i, 3) == 'OR ') {
668: $op = '|';
669: $skip = 2;
670: }
671: case 'N':
672: if (substr($searchstring . ' ', $i, 4) == 'NOT ') {
673: $op = '!';
674: $skip = 3;
675: }
676: if ($op) {
677: if (!empty($target)) {
678: $r = trim($target);
679: if (!empty($r)) {
680: $last = $result[] = $r;
681: $target = '';
682: }
683: }
684: $c1 = $op;
685: $target = '';
686: $last = $result[] = $op;
687: $j = $i + $skip;
688: while ($j < strlen($searchstring) && substr($searchstring, $j, 1) == ' ') {
689: $j++;
690: }
691: $i = $j - 1;
692: } else {
693: $c1 = $c;
694: $target .= $c;
695: }
696: break;
697:
698: default:
699: $c1 = $c;
700: $target .= $c;
701: break;
702: }
703: } while ($i++ < strlen($searchstring));
704: if (!empty($target)) {
705: $last = $result[] = trim($target);
706: }
707: $lasttoken = '';
708: foreach ($result as $key => $token) {
709: if ($token == '|' && $lasttoken == '|') {
710: unset($result[$key]);
711: }
712: $lasttoken = $token;
713: }
714: if (array_key_exists($lasttoken, $opChars) && $opChars[$lasttoken] == 1) {
715: array_pop($result);
716: }
717:
718: $this->processed_search = zp_apply_filter('search_criteria', $result);
719: return $this->processed_search;
720: }
721:
722: 723: 724: 725: 726: 727: 728: 729:
730: function codifySearchString() {
731: $searchstring = $this->getSearchString();
732: $sanitizedwords = '';
733: if (is_array($searchstring)) {
734: foreach ($searchstring as $singlesearchstring) {
735: switch ($singlesearchstring) {
736: case '&':
737: $sanitizedwords .= " AND ";
738: break;
739: case '|':
740: $sanitizedwords .= " OR ";
741: break;
742: case '!':
743: $sanitizedwords .= " NOT ";
744: break;
745: case '(':
746: case ')':
747: $sanitizedwords .= $singlesearchstring;
748: break;
749: default:
750: $sanitizedwords .= search_quote(sanitize($singlesearchstring, 3));
751: break;
752: }
753: }
754: }
755:
756: $sanitizedwords = trim(str_replace(array(' ', ' ',), ' ', $sanitizedwords));
757: $sanitizedwords = trim(str_replace('( ', '(', $sanitizedwords));
758: $sanitizedwords = trim(str_replace(' )', ')', $sanitizedwords));
759: return $sanitizedwords;
760: }
761:
762: 763: 764: 765: 766:
767: function getNumAlbums() {
768: if (is_null($this->albums)) {
769: $this->getAlbums(0, NULL, NULL, false);
770: }
771: return count($this->albums);
772: }
773:
774: 775: 776: 777: 778:
779: function parseQueryFields() {
780: $fields = array();
781: if (isset($_REQUEST['searchfields'])) {
782: $fs = sanitize($_REQUEST['searchfields']);
783: if (is_numeric($fs)) {
784: $fields = array_flip($this->numericFields($fs));
785: } else {
786: $fields = explode(',', $fs);
787: }
788: } else {
789: foreach ($_REQUEST as $key => $value) {
790: if (strpos($key, 'SEARCH_') !== false) {
791: $fields[substr($key, 7)] = $value;
792: }
793: }
794: }
795: return $fields;
796: }
797:
798: 799: 800: 801:
802: protected function subsetNewsCategories() {
803: global $_zp_zenpage;
804: if (!is_array($this->category_list))
805: return false;
806: $cat = '';
807: $list = $_zp_zenpage->getAllCategories();
808: if (!empty($list)) {
809: foreach ($list as $category) {
810: if (in_array($category['title'], $this->category_list)) {
811: $catobj = new ZenpageCategory($category['titlelink']);
812: $cat .= ' `cat_id`=' . $catobj->getID() . ' OR';
813: $subcats = $catobj->getSubCategories();
814: if ($subcats) {
815: foreach ($subcats as $subcat) {
816: $catobj = new ZenpageCategory($subcat);
817: $cat .= ' `cat_id`=' . $catobj->getID() . ' OR';
818: }
819: }
820: }
821: }
822: if ($cat) {
823: $cat = ' WHERE ' . substr($cat, 0, -3);
824: }
825: }
826: $sql = 'SELECT DISTINCT `news_id` FROM ' . prefix('news2cat') . $cat;
827: $result = query($sql);
828: $list = array();
829: if ($result) {
830: while ($row = db_fetch_assoc($result)) {
831: $list[] = $row['news_id'];
832: }
833: db_free_result($result);
834: }
835: return $list;
836: }
837:
838: 839: 840: 841: 842:
843: protected static function compressedIDList($idlist) {
844: $idlist = array_unique($idlist);
845: asort($idlist);
846: return '`id` IN (' . implode(',', $idlist) . ')';
847: }
848:
849: 850: 851: 852: 853: 854: 855: 856:
857: protected function sortKey($sorttype, $sortdirection, $defaulttype, $table) {
858: if (is_null($sorttype)) {
859: if (array_key_exists($table . 'sorttype', $this->extraparams)) {
860: $sorttype = $this->extraparams[$table . 'sorttype'];
861: } else if (array_key_exists('sorttype', $this->extraparams)) {
862: $sorttype = $this->extraparams['sorttype'];
863: }
864: }
865: $sorttype = lookupSortKey($sorttype, $defaulttype, $table);
866: if (is_null($sortdirection)) {
867: if (array_key_exists($table . 'sortdirection', $this->extraparams)) {
868: $sortdirection = $this->extraparams[$table . 'sortdirection'];
869: } else if (array_key_exists('sortdirection', $this->extraparams)) {
870: $sortdirection = $this->extraparams['sortdirection'];
871: }
872: }
873: return array($sorttype, $sortdirection);
874: }
875:
876: 877: 878: 879: 880: 881: 882: 883: 884: 885:
886: function searchDate($searchstring, $searchdate, $tbl, $sorttype, $sortdirection, $whichdate = 'date') {
887: global $_zp_current_album, $_zp_gallery;
888: $sql = 'SELECT DISTINCT `id`, `show`,`title`';
889: switch ($tbl) {
890: case 'pages':
891: case 'news':
892: $sql .= ',`titlelink` ';
893: break;
894: case 'albums':
895: $sql .= ",`desc`,`folder` ";
896: break;
897: default:
898: $sql .= ",`desc`,`albumid`,`filename`,`location`,`city`,`state`,`country` ";
899: break;
900: }
901: $sql .= "FROM " . prefix($tbl) . " WHERE ";
902: if (!zp_loggedin()) {
903: $sql .= "`show` = 1 AND (";
904: }
905:
906: if (!empty($searchdate)) {
907: if ($searchdate == "0000-00") {
908: $sql .= "`$whichdate`=\"0000-00-00 00:00:00\"";
909: } else {
910: $datesize = sizeof(explode('-', $searchdate));
911:
912: if ($datesize == 3) {
913: $d1 = $searchdate . " 00:00:00";
914: $d2 = $searchdate . " 23:59:59";
915: $sql .= "`$whichdate` >= \"$d1\" AND `$whichdate` < \"$d2\"";
916: }
917:
918: else if ($datesize == 2) {
919: $d1 = $searchdate . "-01 00:00:00";
920: $d = strtotime($d1);
921: $d = strtotime('+ 1 month', $d);
922: $d2 = substr(date('Y-m-d H:m:s', $d), 0, 7) . "-01 00:00:00";
923: $sql .= "`$whichdate` >= \"$d1\" AND `$whichdate` < \"$d2\"";
924: } else {
925: $sql .= "`$whichdate`<\"0000-00-00 00:00:00\"";
926: }
927: }
928: }
929: if (!zp_loggedin()) {
930: $sql .= ")";
931: }
932:
933: switch ($tbl) {
934: case 'news':
935: if (empty($sorttype)) {
936: $key = '`date` DESC';
937: } else {
938: $key = trim($sorttype . ' ' . $sortdirection);
939: }
940: break;
941: case 'pages':
942: $key = '`sort_order`';
943: break;
944: case 'albums':
945: if (is_null($sorttype)) {
946: if (empty($this->album)) {
947: list($key, $sortdirection) = $this->sortKey($_zp_gallery->getSortType(), $sortdirection, 'title', 'albums');
948: if ($key != '`sort_order`') {
949: if ($_zp_gallery->getSortDirection()) {
950: $key .= " DESC";
951: }
952: }
953: } else {
954: $key = $this->album->getAlbumSortKey();
955: if ($key != '`sort_order`' && $key != 'RAND()') {
956: if ($this->album->getSortDirection('album')) {
957: $key .= " DESC";
958: }
959: }
960: }
961: } else {
962: list($key, $sortdirection) = $this->sortKey($sorttype, $sortdirection, 'title', 'albums');
963: $key = trim($key . ' ' . $sortdirection);
964: }
965: break;
966: default:
967: $hidealbums = getNotViewableAlbums();
968: if (!is_null($hidealbums)) {
969: foreach ($hidealbums as $id) {
970: $sql .= ' AND `albumid`!=' . $id;
971: }
972: }
973: if (is_null($sorttype)) {
974: if (empty($this->album)) {
975: list($key, $sortdirection) = $this->sortKey(IMAGE_SORT_TYPE, $sortdirection, 'title', 'images');
976: if ($key != '`sort_order`') {
977: if (IMAGE_SORT_DIRECTION) {
978: $key .= " DESC";
979: }
980: }
981: } else {
982: $key = $thie->album->getImageSortKey();
983: if ($key != '`sort_order`' && $key != 'RAND()') {
984: if ($this->album->getSortDirection('image')) {
985: $key .= " DESC";
986: }
987: }
988: }
989: } else {
990: list($key, $sortdirection) = $this->sortKey($sorttype, $sortdirection, 'title', 'images');
991: $key = trim($key . ' ' . $sortdirection);
992: }
993: break;
994: }
995: $sql .= " ORDER BY " . $key;
996: return $sql;
997: }
998:
999: 1000: 1001: 1002: 1003: 1004: 1005: 1006: 1007: 1008:
1009: protected function searchFieldsAndTags($searchstring, $tbl, $sorttype, $sortdirection) {
1010: global $_zp_gallery;
1011: $weights = $idlist = array();
1012: $sql = $allIDs = NULL;
1013: $tagPattern = $this->tagPattern;
1014:
1015: $tag_objects = array();
1016: $fields = $this->fieldList;
1017: if (count($fields) == 0) {
1018: $fields = $this->allowedSearchFields();
1019: }
1020: foreach ($fields as $key => $field) {
1021: switch ($field) {
1022: case 'news_categories':
1023: if ($tbl != 'news') {
1024: break;
1025: }
1026: unset($fields[$key]);
1027: query('SET @serachfield="news_categories"');
1028: $tagsql = 'SELECT @serachfield AS field, t.`title` AS name, o.`news_id` AS `objectid` FROM ' . prefix('news_categories') . ' AS t, ' . prefix('news2cat') . ' AS o WHERE t.`id`=o.`cat_id` AND (';
1029: foreach ($searchstring as $singlesearchstring) {
1030: switch ($singlesearchstring) {
1031: case '&':
1032: case '!':
1033: case '|':
1034: case '(':
1035: case ')':
1036: break;
1037: case '*':
1038: $targetfound = true;
1039: $tagsql .= "COALESCE(title, '') != '' OR ";
1040: break;
1041: default:
1042: $targetfound = true;
1043: $tagsql .= '`title` = ' . db_quote($singlesearchstring) . ' OR ';
1044: }
1045: }
1046: $tagsql = substr($tagsql, 0, strlen($tagsql) - 4) . ') ORDER BY t.`id`';
1047: $objects = query_full_array($tagsql, false);
1048: if (is_array($objects)) {
1049: $tag_objects = $objects;
1050: }
1051: break;
1052: case 'tags_exact':
1053: $tagPattern = array('type' => '=', 'open' => '', 'close' => '');
1054: case 'tags':
1055: unset($fields[$key]);
1056: query('SET @serachfield="tags"');
1057: $tagsql = 'SELECT @serachfield AS field, t.`name`, o.`objectid` FROM ' . prefix('tags') . ' AS t, ' . prefix('obj_to_tag') . ' AS o WHERE t.`id`=o.`tagid` AND o.`type`="' . $tbl . '" AND (';
1058: foreach ($searchstring as $singlesearchstring) {
1059: switch ($singlesearchstring) {
1060: case '&':
1061: case '!':
1062: case '|':
1063: case '(':
1064: case ')':
1065: break;
1066: case '*':
1067: query('SET @emptyfield="*"');
1068: $tagsql = str_replace('t.`name`', '@emptyfield as name', $tagsql);
1069: $tagsql .= "t.`name` IS NOT NULL OR ";
1070: break;
1071: default:
1072: $targetfound = true;
1073: if ($tagPattern['type'] == 'like') {
1074: $target = db_LIKE_escape($singlesearchstring);
1075: } else {
1076: $target = $singlesearchstring;
1077: }
1078: $tagsql .= 't.`name` ' . strtoupper($tagPattern['type']) . ' ' . db_quote($tagPattern['open'] . $target . $tagPattern['close']) . ' OR ';
1079: }
1080: }
1081: $tagsql = substr($tagsql, 0, strlen($tagsql) - 4) . ') ORDER BY t.`id`';
1082: $objects = query_full_array($tagsql, false);
1083: if (is_array($objects)) {
1084: $tag_objects = array_merge($tag_objects, $objects);
1085: }
1086: break;
1087: default:
1088: break;
1089: }
1090: }
1091:
1092:
1093:
1094: $field_objects = array();
1095: if (count($fields) > 0) {
1096: $columns = array();
1097: $dbfields = db_list_fields($tbl);
1098: if (is_array($dbfields)) {
1099: foreach ($dbfields as $row) {
1100: $columns[] = strtolower($row['Field']);
1101: }
1102: }
1103: foreach ($searchstring as $singlesearchstring) {
1104: switch ($singlesearchstring) {
1105: case '!':
1106: case '&':
1107: case '|':
1108: case '(':
1109: case ')':
1110: break;
1111: default:
1112: $targetfound = true;
1113: query('SET @serachtarget=' . db_quote($singlesearchstring));
1114: foreach ($fields as $fieldname) {
1115: if ($tbl == 'albums' && strtolower($fieldname) == 'filename') {
1116: $fieldname = 'folder';
1117: } else {
1118: $fieldname = strtolower($fieldname);
1119: }
1120: if ($fieldname && in_array($fieldname, $columns)) {
1121: query('SET @serachfield=' . db_quote($fieldname));
1122: switch ($singlesearchstring) {
1123: case '*':
1124: $sql = 'SELECT @serachtarget AS name, @serachfield AS field, `id` AS `objectid` FROM ' . prefix($tbl) . ' WHERE (' . "COALESCE(`$fieldname`, '') != ''" . ') ORDER BY `id`';
1125: break;
1126: default:
1127: if ($this->pattern['type'] == 'like') {
1128: $target = db_LIKE_escape($singlesearchstring);
1129: } else {
1130: $target = $singlesearchstring;
1131: }
1132: $fieldsql = ' `' . $fieldname . '` ' . strtoupper($this->pattern['type']) . ' ' . db_quote($this->pattern['open'] . $target . $this->pattern['close']);
1133: $sql = 'SELECT @serachtarget AS name, @serachfield AS field, `id` AS `objectid` FROM ' . prefix($tbl) . ' WHERE (' . $fieldsql . ') ORDER BY `id`';
1134: }
1135: $objects = query_full_array($sql, false);
1136: if (is_array($objects)) {
1137: $field_objects = array_merge($field_objects, $objects);
1138: }
1139: }
1140: }
1141: }
1142: }
1143: }
1144:
1145:
1146: $exact = $tagPattern['type'] == '=';
1147: $objects = array_merge($tag_objects, $field_objects);
1148: if (count($objects) != 0) {
1149: $tagid = '';
1150: $taglist = array();
1151:
1152: foreach ($objects as $object) {
1153: $tagid = strtolower($object['name']);
1154: if (!isset($taglist[$tagid]) || !is_array($taglist[$tagid])) {
1155: $taglist[$tagid] = array();
1156: }
1157: $taglist[$tagid][] = $object['objectid'];
1158: }
1159: $op = '';
1160: $idstack = array();
1161: $opstack = array();
1162: while (count($searchstring) > 0) {
1163: $singlesearchstring = array_shift($searchstring);
1164: switch ($singlesearchstring) {
1165: case '&':
1166: case '!':
1167: case '|':
1168: $op = $op . $singlesearchstring;
1169: break;
1170: case '(':
1171: array_push($idstack, $idlist);
1172: array_push($opstack, $op);
1173: $idlist = array();
1174: $op = '';
1175: break;
1176: case ')':
1177: $objectid = $idlist;
1178: $idlist = array_pop($idstack);
1179: $op = array_pop($opstack);
1180: switch ($op) {
1181: case '&':
1182: if (is_array($objectid)) {
1183: $idlist = array_intersect($idlist, $objectid);
1184: } else {
1185: $idlist = array();
1186: }
1187: break;
1188: case '!':
1189: break;
1190: case '&!':
1191: if (is_array($objectid)) {
1192: $idlist = array_diff($idlist, $objectid);
1193: }
1194: break;
1195: case '';
1196: case '|':
1197: if (is_array($objectid)) {
1198: $idlist = array_merge($idlist, $objectid);
1199: }
1200: break;
1201: }
1202: $op = '';
1203: break;
1204: default:
1205: $lookfor = strtolower($singlesearchstring);
1206: $objectid = NULL;
1207: foreach ($taglist as $key => $objlist) {
1208: if (($exact && $lookfor == $key) || (!$exact && preg_match('|' . preg_quote($lookfor) . '|', $key))) {
1209: if (is_array($objectid)) {
1210: $objectid = array_merge($objectid, $objlist);
1211: } else {
1212: $objectid = $objlist;
1213: }
1214: }
1215: }
1216: switch ($op) {
1217: case '&':
1218: if (is_array($objectid)) {
1219: $idlist = array_intersect($idlist, $objectid);
1220: } else {
1221: $idlist = array();
1222: }
1223: break;
1224: case '!':
1225: if (is_null($allIDs)) {
1226: $allIDs = array();
1227: $result = query("SELECT `id` FROM " . prefix($tbl));
1228: if ($result) {
1229: while ($row = db_fetch_assoc($result)) {
1230: $allIDs[] = $row['id'];
1231: }
1232: db_free_result($result);
1233: }
1234: }
1235: if (is_array($objectid)) {
1236: $idlist = array_merge($idlist, array_diff($allIDs, $objectid));
1237: }
1238: break;
1239: case '&!':
1240: if (is_array($objectid)) {
1241: $idlist = array_diff($idlist, $objectid);
1242: }
1243: break;
1244: case '';
1245: case '|':
1246: if (is_array($objectid)) {
1247: $idlist = array_merge($idlist, $objectid);
1248: }
1249: break;
1250: }
1251: $op = '';
1252: break;
1253: }
1254: }
1255: }
1256:
1257:
1258: if (count($idlist) > 0) {
1259: $weights = array_count_values($idlist);
1260: arsort($weights, SORT_NUMERIC);
1261: $sql = 'SELECT DISTINCT `id`,`show`,';
1262:
1263: switch ($tbl) {
1264: case 'news':
1265: if ($this->search_unpublished || zp_loggedin(MANAGE_ALL_NEWS_RIGHTS)) {
1266: $show = '';
1267: } else {
1268: $show = "`show` = 1 AND ";
1269: }
1270: $sql .= '`titlelink` ';
1271: if (is_array($this->category_list)) {
1272: $news_list = $this->subsetNewsCategories();
1273: $idlist = array_intersect($news_list, $idlist);
1274: if (count($idlist) == 0) {
1275: return array(false, array());
1276: }
1277: }
1278: if (empty($sorttype)) {
1279: $key = '`date` DESC';
1280: } else {
1281: $key = trim($sorttype . $sortdirection);
1282: }
1283: if ($show) {
1284: $show .= '`date`<=' . db_quote(date('Y-m-d H:i:s')) . ' AND ';
1285: }
1286: break;
1287: case 'pages':
1288: if (zp_loggedin(MANAGE_ALL_PAGES_RIGHTS)) {
1289: $show = '';
1290: } else {
1291: $show = "`show` = 1 AND ";
1292: }
1293: $sql .= '`titlelink` ';
1294: if ($show) {
1295: $show .= '`date`<=' . db_quote(date('Y-m-d H:i:s')) . ' AND ';
1296: }
1297: $key = '`sort_order`';
1298: break;
1299: case 'albums':
1300: if ($this->search_unpublished || zp_loggedin()) {
1301: $show = '';
1302: } else {
1303: $show = "`show` = 1 AND ";
1304: }
1305: $sql .= "`folder`, `title` ";
1306: if (is_null($sorttype)) {
1307: if (empty($this->album)) {
1308: list($key, $sortdirection) = $this->sortKey($_zp_gallery->getSortType(), $sortdirection, 'title', 'albums');
1309: if ($_zp_gallery->getSortDirection()) {
1310: $key .= " DESC";
1311: }
1312: } else {
1313: $key = $this->album->getAlbumSortKey();
1314: if ($key != '`sort_order`' && $key != 'RAND()') {
1315: if ($this->album->getSortDirection('album')) {
1316: $key .= " DESC";
1317: }
1318: }
1319: }
1320: } else {
1321: list($key, $sortdirection) = $this->sortKey($sorttype, $sortdirection, 'title', 'albums');
1322: $key = trim($key . ' ' . $sortdirection);
1323: }
1324: break;
1325: default:
1326: if ($this->search_unpublished || zp_loggedin()) {
1327: $show = '';
1328: } else {
1329: $show = "`show` = 1 AND ";
1330: }
1331: $sql .= "`albumid`, `filename`, `title` ";
1332: if (is_null($sorttype)) {
1333: if (empty($this->album)) {
1334: list($key, $sortdirection) = $this->sortKey($sorttype, $sortdirection, 'title', 'images');
1335: if ($sortdirection) {
1336: $key .= " DESC";
1337: }
1338: } else {
1339: $key = $this->album->getImageSortKey();
1340: if ($key != '`sort_order`') {
1341: if ($this->album->getSortDirection('image')) {
1342: $key .= " DESC";
1343: }
1344: }
1345: }
1346: } else {
1347: list($key, $sortdirection) = $this->sortKey($sorttype, $sortdirection, 'title', 'images');
1348: $key = trim($key . ' ' . $sortdirection);
1349: }
1350: break;
1351: }
1352: $sql .= "FROM " . prefix($tbl) . " WHERE " . $show;
1353: $sql .= '(' . self::compressedIDList($idlist) . ')';
1354: $sql .= " ORDER BY " . $key;
1355: return array($sql, $weights);
1356: }
1357: return array(false, array());
1358: }
1359:
1360: 1361: 1362: 1363: 1364: 1365: 1366: 1367:
1368: private function getSearchAlbums($sorttype, $sortdirection, $mine = NULL) {
1369: if (getOption('search_no_albums') || $this->search_no_albums) {
1370: return array();
1371: }
1372: list($sorttype, $sortdirection) = $this->sortKey($sorttype, $sortdirection, 'title', 'albums');
1373: $albums = array();
1374: $searchstring = $this->getSearchString();
1375: if (empty($searchstring)) {
1376: return array();
1377: }
1378: $criteria = $this->getCacheTag('albums', serialize($searchstring), $sorttype . ' ' . $sortdirection . ' '. $mine);
1379: if ($this->albums && $criteria == $this->searches['albums']) {
1380: return $this->albums;
1381: }
1382: $albums = $this->getCachedSearch($criteria);
1383: if (is_null($albums)) {
1384: if (is_null($mine) && zp_loggedin(MANAGE_ALL_ALBUM_RIGHTS)) {
1385: $mine = true;
1386: }
1387: $result = $albums = array();
1388: list ($search_query, $weights) = $this->searchFieldsAndTags($searchstring, 'albums', $sorttype, $sortdirection);
1389: if (!empty($search_query)) {
1390: $search_result = query($search_query);
1391: if ($search_result) {
1392: while ($row = db_fetch_assoc($search_result)) {
1393: $albumname = $row['folder'];
1394: if ($albumname != $this->dynalbumname) {
1395: if (file_exists(ALBUM_FOLDER_SERVERPATH . internalToFilesystem($albumname))) {
1396: $album = newAlbum($albumname);
1397: $uralbum = getUrAlbum($album);
1398: $viewUnpublished = ($this->search_unpublished || zp_loggedin() && $uralbum->albumSubRights() & (MANAGED_OBJECT_RIGHTS_EDIT | MANAGED_OBJECT_RIGHTS_VIEW));
1399: switch (checkPublishDates($row)) {
1400: case 1:
1401: $album->setShow(0);
1402: $album->save();
1403: case 2:
1404: $row['show'] = 0;
1405: }
1406: if ($mine || (is_null($mine) && $album->isMyItem(LIST_RIGHTS)) || (checkAlbumPassword($albumname) && ($row['show'] || $viewUnpublished))) {
1407: if (empty($this->album_list) || in_array($albumname, $this->album_list)) {
1408: $result[] = array('title' => $row['title'], 'name' => $albumname, 'weight' => $weights[$row['id']]);
1409: }
1410: }
1411: }
1412: }
1413: }
1414: db_free_result($search_result);
1415: if (is_null($sorttype)) {
1416: $result = sortMultiArray($result, 'weight', true, true, false, false, array('weight'));
1417: }
1418: if ($sorttype == '`title`') {
1419: $result = sortByMultilingual($result, 'title', $sortdirection);
1420: }
1421: foreach ($result as $album) {
1422: $albums[] = $album['name'];
1423: }
1424: }
1425: }
1426: zp_apply_filter('search_statistics', $searchstring, 'albums', !empty($albums), $this->dynalbumname, $this->iteration++);
1427: $this->cacheSearch($criteria, $albums);
1428: }
1429: $this->albums = $albums;
1430: $this->searches['albums'] = $criteria;
1431:
1432: return $albums;
1433: }
1434:
1435: 1436: 1437: 1438: 1439: 1440: 1441: 1442: 1443: 1444: 1445: 1446:
1447: function getAlbums($page = 0, $sorttype = NULL, $sortdirection = NULL, $care = true, $mine = NULL) {
1448: $this->albums = $this->getSearchAlbums($sorttype, $sortdirection, $mine);
1449: if ($page == 0) {
1450: return $this->albums;
1451: } else {
1452: $albums_per_page = max(1, getOption('albums_per_page'));
1453: return array_slice($this->albums, $albums_per_page * ($page - 1), $albums_per_page);
1454: }
1455: }
1456:
1457: 1458: 1459: 1460: 1461: 1462:
1463: function getAlbumIndex($curalbum) {
1464: $albums = $this->getAlbums(0);
1465: return array_search($curalbum, $albums);
1466: }
1467:
1468: 1469: 1470: 1471: 1472: 1473:
1474: function getNextAlbum($curalbum) {
1475: global $_zp_gallery;
1476: $albums = $this->getAlbums(0);
1477: $inx = array_search($curalbum, $albums) + 1;
1478: if ($inx >= 0 && $inx < count($albums)) {
1479: return newAlbum($albums[$inx]);
1480: }
1481: return null;
1482: }
1483:
1484: 1485: 1486: 1487: 1488: 1489:
1490: function getPrevAlbum($curalbum) {
1491: global $_zp_gallery;
1492: $albums = $this->getAlbums(0);
1493: $inx = array_search($curalbum, $albums) - 1;
1494: if ($inx >= 0 && $inx < count($albums)) {
1495: return newAlbum($albums[$inx]);
1496: }
1497: return null;
1498: }
1499:
1500: 1501: 1502: 1503: 1504:
1505: function getNumImages() {
1506: if (is_null($this->images)) {
1507: $this->getImages(0);
1508: }
1509: return count($this->images);
1510: }
1511:
1512: 1513: 1514: 1515: 1516: 1517: 1518: 1519:
1520: private function getSearchImages($sorttype, $sortdirection, $mine = NULL) {
1521:
1522: if (getOption('search_no_images') || $this->search_no_images) {
1523: return array();
1524: }
1525: list($sorttype, $sortdirection) = $this->sortKey($sorttype, $sortdirection, 'title', 'images');
1526: if (is_null($mine) && zp_loggedin(MANAGE_ALL_ALBUM_RIGHTS)) {
1527: $mine = true;
1528: }
1529: $searchstring = $this->getSearchString();
1530: $searchdate = $this->dates;
1531: if (empty($searchstring) && empty($searchdate)) {
1532: return array();
1533: }
1534:
1535: $criteria = $this->getCacheTag('images', serialize($searchstring) . ' ' . $searchdate, $sorttype . ' ' . $sortdirection . ' '.$mine);
1536: if ($criteria == $this->searches['images']) {
1537: return $this->images;
1538: }
1539: $images = $this->getCachedSearch($criteria);
1540: if (is_null($images)) {
1541: if (empty($searchdate)) {
1542: list ($search_query, $weights) = $this->searchFieldsAndTags($searchstring, 'images', $sorttype, $sortdirection);
1543: } else {
1544: $search_query = $this->searchDate($searchstring, $searchdate, 'images', $sorttype, $sortdirection);
1545: }
1546: if (empty($search_query)) {
1547: $search_result = false;
1548: } else {
1549: $search_result = query($search_query);
1550: }
1551: $albums_seen = $images = array();
1552: if ($search_result) {
1553: while ($row = db_fetch_assoc($search_result)) {
1554: $albumid = $row['albumid'];
1555: if (array_key_exists($albumid, $albums_seen)) {
1556: $albumrow = $albums_seen[$albumid];
1557: } else {
1558: $query = "SELECT folder, `show` FROM " . prefix('albums') . " WHERE id = $albumid";
1559: $row2 = query_single_row($query);
1560: if ($row2) {
1561: $albumname = $row2['folder'];
1562: $allow = false;
1563: $album = newAlbum($albumname);
1564: $uralbum = getUrAlbum($album);
1565: $viewUnpublished = ($this->search_unpublished || zp_loggedin() && $uralbum->albumSubRights() & (MANAGED_OBJECT_RIGHTS_EDIT | MANAGED_OBJECT_RIGHTS_VIEW));
1566: switch (checkPublishDates($row)) {
1567: case 1:
1568: $imageobj = newImage($this, $row['filename']);
1569: $imageobj->setShow(0);
1570: $imageobj->save();
1571: case 2:
1572: $row['show'] = 0;
1573: break;
1574: }
1575: if ($mine || is_null($mine) && ($album->isMyItem(LIST_RIGHTS) || checkAlbumPassword($albumname) && ($album->getShow() || $viewUnpublished))) {
1576: $allow = empty($this->album_list) || in_array($albumname, $this->album_list);
1577: }
1578: $albums_seen[$albumid] = $albumrow = array('allow' => $allow, 'viewUnpublished' => $viewUnpublished, 'folder' => $albumname, 'localpath' => ALBUM_FOLDER_SERVERPATH . internalToFilesystem($albumname) . '/');
1579: } else {
1580: $albums_seen[$albumid] = $albumrow = array('allow' => false, 'viewUnpublished' => false, 'folder' => '', 'localpath' => '');
1581: }
1582: }
1583: if ($albumrow['allow'] && ($row['show'] || $albumrow['viewUnpublished'])) {
1584: if (file_exists($albumrow['localpath'] . internalToFilesystem($row['filename']))) {
1585: $data = array('title' => $row['title'], 'filename' => $row['filename'], 'folder' => $albumrow['folder']);
1586: if (isset($weights)) {
1587: $data['weight'] = $weights[$row['id']];
1588: }
1589: $images[] = $data;
1590: }
1591: }
1592: }
1593: db_free_result($search_result);
1594: if (is_null($sorttype) && isset($weights)) {
1595: $images = sortMultiArray($images, 'weight', true, true, false, false, array('weight'));
1596: }
1597: if ($sorttype == '`title`') {
1598: $images = sortByMultilingual($images, 'title', $sortdirection);
1599: }
1600: }
1601: if (empty($searchdate)) {
1602: zp_apply_filter('search_statistics', $searchstring, 'images', !empty($images), $this->dynalbumname, $this->iteration++);
1603: }
1604: $this->cacheSearch($criteria, $images);
1605: }
1606: $this->searches['images'] = $criteria;
1607: return $images;
1608: }
1609:
1610: 1611: 1612: 1613: 1614: 1615: 1616: 1617: 1618: 1619: 1620: 1621:
1622: function getImages($page = 0, $firstPageCount = 0, $sorttype = NULL, $sortdirection = NULL, $care = true, $mine = NULL) {
1623: $this->images = $this->getSearchImages($sorttype, $sortdirection, $mine);
1624: if ($page == 0) {
1625: return $this->images;
1626: } else {
1627: if (empty($this->images)) {
1628: return array();
1629: }
1630:
1631: if (($page == 1) && ($firstPageCount > 0)) {
1632: $pageStart = 0;
1633: $images_per_page = $firstPageCount;
1634: } else {
1635: if ($firstPageCount > 0) {
1636: $fetchPage = $page - 2;
1637: } else {
1638: $fetchPage = $page - 1;
1639: }
1640: $images_per_page = max(1, getOption('images_per_page'));
1641: $pageStart = $firstPageCount + $images_per_page * $fetchPage;
1642: }
1643: $slice = array_slice($this->images, $pageStart, $images_per_page);
1644: return $slice;
1645: }
1646: }
1647:
1648: 1649: 1650: 1651: 1652: 1653: 1654:
1655: function getImageIndex($album, $filename) {
1656: $images = $this->getImages();
1657: $c = 0;
1658: foreach ($images as $image) {
1659: if (($album == $image['folder']) && ($filename == $image['filename'])) {
1660: return $c;
1661: }
1662: $c++;
1663: }
1664: return false;
1665: }
1666:
1667: 1668: 1669: 1670: 1671: 1672:
1673: function getImage($index) {
1674: global $_zp_gallery;
1675: if (!is_null($this->images)) {
1676: $this->getImages();
1677: }
1678: if ($index >= 0 && $index < $this->getNumImages()) {
1679: $img = $this->images[$index];
1680: return newImage(newAlbum($img['folder']), $img['filename']);
1681: }
1682: return false;
1683: }
1684:
1685: function getDynamicAlbum() {
1686: return $this->album;
1687: }
1688:
1689: 1690: 1691: 1692:
1693: function getAlbumList() {
1694: return $this->album_list;
1695: }
1696:
1697: 1698: 1699: 1700:
1701: function getCategoryList() {
1702: return $this->category_list;
1703: }
1704:
1705: 1706: 1707: 1708: 1709: 1710: 1711: 1712: 1713: 1714: 1715:
1716: function getPages($published = NULL, $toplevel = false, $number = NULL, $sorttype = NULL, $sortdirection = NULL) {
1717: return $this->getSearchPages($sorttype, $sortdirection);
1718: }
1719:
1720: 1721: 1722: 1723: 1724: 1725: 1726: 1727:
1728: private function getSearchPages($sorttype, $sortdirection) {
1729: if (!extensionEnabled('zenpage') || getOption('search_no_pages') || $this->search_no_pages)
1730: return array();
1731: list($sorttype, $sortdirection) = $this->sortKey($sorttype, $sortdirection, 'title', 'pages');
1732: $searchstring = $this->getSearchString();
1733: $searchdate = $this->dates;
1734: if (empty($searchstring) && empty($searchdate)) {
1735: return array();
1736: }
1737: $criteria = $this->getCacheTag('news', serialize($searchstring), $sorttype . ' ' . $sortdirection);
1738: if ($this->pages && $criteria == $this->searches['pages']) {
1739: return $this->pages;
1740: }
1741: if (is_null($this->pages)) {
1742: $pages = $result = array();
1743: if (empty($searchdate)) {
1744: list ($search_query, $weights) = $this->searchFieldsAndTags($searchstring, 'pages', $sorttype, $sortdirection);
1745: if (empty($search_query)) {
1746: $search_result = false;
1747: } else {
1748: $search_result = query($search_query);
1749: }
1750: zp_apply_filter('search_statistics', $searchstring, 'pages', !$search_result, false, $this->iteration++);
1751: } else {
1752: $search_query = $this->searchDate($searchstring, $searchdate, 'pages', NULL, NULL);
1753: $search_result = query($search_query);
1754: }
1755: if ($search_result) {
1756: while ($row = db_fetch_assoc($search_result)) {
1757: $data = array('titlelink' => $row['titlelink']);
1758: if (isset($weights)) {
1759: $data['weight'] = $weights[$row['id']];
1760: }
1761: $result[] = $data;
1762: }
1763: db_free_result($search_result);
1764: }
1765: if (isset($weights)) {
1766: $result = sortMultiArray($result, 'weight', true, true, false, false, array('weight'));
1767: }
1768:
1769:
1770: foreach ($result as $page) {
1771: $pages[] = $page['titlelink'];
1772: }
1773: $this->pages = $pages;
1774: }
1775: $this->searches['pages'] = $criteria;
1776: return $this->pages;
1777: }
1778:
1779: 1780: 1781: 1782: 1783: 1784: 1785: 1786: 1787: 1788: 1789:
1790: function getArticles($articles_per_page = 0, $published = NULL, $ignorepagination = false, $sorttype = NULL, $sortdirection = NULL) {
1791:
1792: $articles = $this->getSearchArticles($sorttype, $sortdirection);
1793: if (empty($articles)) {
1794: return array();
1795: } else {
1796: if ($ignorepagination || !$articles_per_page) {
1797: return $articles;
1798: }
1799: return array_slice($articles, Zenpage::getOffset($articles_per_page), $articles_per_page);
1800: }
1801: }
1802:
1803: 1804: 1805: 1806: 1807: 1808: 1809: 1810:
1811: private function getSearchArticles($sorttype, $sortdirection) {
1812: if (!extensionEnabled('zenpage') || getOption('search_no_news') || $this->search_no_news) {
1813: return array();
1814: }
1815: list($sorttype, $sortdirection) = $this->sortKey($sorttype, $sortdirection, 'title', 'news');
1816: $searchstring = $this->getSearchString();
1817: $searchdate = $this->dates;
1818: if (empty($searchstring) && empty($searchdate)) {
1819: return array();
1820: }
1821: $criteria = $this->getCacheTag('news', serialize($searchstring), $sorttype . ' ' . $sortdirection);
1822: if ($this->articles && $criteria == $this->searches['news']) {
1823: return $this->articles;
1824: }
1825: $result = $this->getCachedSearch($criteria);
1826: if (is_null($result)) {
1827: $result = array();
1828: if (empty($searchdate)) {
1829: list ($search_query, $weights) = $this->searchFieldsAndTags($searchstring, 'news', $sorttype, $sortdirection);
1830: } else {
1831: $search_query = $this->searchDate($searchstring, $searchdate, 'news', $sorttype, $sortdirection, $this->whichdates);
1832: }
1833: if (empty($search_query)) {
1834: $search_result = false;
1835: } else {
1836: $search_result = query($search_query);
1837: }
1838: zp_apply_filter('search_statistics', $searchstring, 'news', !empty($search_result), false, $this->iteration++);
1839: if ($search_result) {
1840: while ($row = db_fetch_assoc($search_result)) {
1841: $data = array('titlelink' => $row['titlelink']);
1842: if (isset($weights)) {
1843: $data['weight'] = $weights[$row['id']];
1844: }
1845: $result[] = $data;
1846: }
1847: db_free_result($search_result);
1848: }
1849: if (isset($weights)) {
1850: $result = sortMultiArray($result, 'weight', true, true, false, false, array('weight'));
1851: }
1852: $this->cacheSearch($criteria, $result);
1853: }
1854: $this->articles = $result;
1855: $this->searches['news'] = $criteria;
1856: return $this->articles;
1857: }
1858:
1859: function clearSearchWords() {
1860: $this->processed_search = '';
1861: $this->words = '';
1862: }
1863:
1864: 1865: 1866: 1867: 1868: 1869: 1870:
1871: protected function getCacheTag($table, $search, $sort) {
1872: $user = 'guest';
1873: $authCookies = Zenphoto_Authority::getAuthCookies();
1874: if (!empty($authCookies)) {
1875: $user = getUserIP();
1876: }
1877: return array('item' => $table, 'fields' => implode(', ', $this->fieldList), 'search' => $search, 'sort' => $sort, 'user' => $user);
1878: }
1879:
1880: 1881: 1882: 1883: 1884: 1885:
1886: private function cacheSearch($criteria, $found) {
1887: if (SEARCH_CACHE_DURATION) {
1888: $criteria = serialize($criteria);
1889: $sql = 'SELECT `id`, `data`, `date` FROM ' . prefix('search_cache') . ' WHERE `criteria` = ' . db_quote($criteria);
1890: $result = query_single_row($sql);
1891: if ($result) {
1892: $sql = 'UPDATE ' . prefix('search_cache') . ' SET `data` = ' . db_quote(serialize($found)) . ', `date` = ' . db_quote(date('Y-m-d H:m:s')) . ' WHERE `id` = ' . $result['id'];
1893: query($sql);
1894: } else {
1895: $sql = 'INSERT INTO ' . prefix('search_cache') . ' (criteria, data, date) VALUES (' . db_quote($criteria) . ', ' . db_quote(serialize($found)) . ', ' . db_quote(date('Y-m-d H:m:s')) . ')';
1896: query($sql);
1897: }
1898: }
1899: }
1900:
1901: 1902: 1903: 1904: 1905:
1906: private function getCachedSearch($criteria) {
1907: if (SEARCH_CACHE_DURATION) {
1908: $sql = 'SELECT `id`, `date`, `data` FROM ' . prefix('search_cache') . ' WHERE `criteria` = ' . db_quote(serialize($criteria));
1909: $result = query_single_row($sql);
1910: if ($result) {
1911: if ((time() - strtotime($result['date'])) > SEARCH_CACHE_DURATION * 60) {
1912: query('DELETE FROM ' . prefix('search_cache') . ' WHERE `id` = ' . $result['id']);
1913: } else {
1914: if ($result = getSerializedArray($result['data'])) {
1915: return $result;
1916: }
1917: }
1918: }
1919: }
1920: return NULL;
1921: }
1922:
1923: 1924: 1925:
1926: static function clearSearchCache() {
1927: $check = query_single_row('SELECT id FROM ' . prefix('search_cache'). ' LIMIT 1');
1928: if($check) {
1929: query('TRUNCATE TABLE ' . prefix('search_cache'));
1930: }
1931: }
1932:
1933: }
1934:
1935:
1936:
1937: 1938: 1939: 1940: 1941: 1942:
1943: function search_quote($word) {
1944: if (is_numeric($word) || preg_match("/[ &|!'\"`,()]/", $word)) {
1945: $word = '"' . str_replace("\\'", "'", addslashes($word)) . '"';
1946: }
1947: return $word;
1948: }
1949:
1950: ?>