1: <?php
2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14:
15: class Ansel_Search_Tag
16: {
17: 18: 19: 20: 21: 22:
23: protected $_tags = array();
24:
25: 26: 27: 28: 29:
30: protected $_totalCount = null;
31:
32: 33: 34: 35: 36:
37: protected $_owner = '';
38:
39: 40: 41: 42: 43:
44: protected $_dirty = false;
45:
46: 47: 48: 49: 50:
51: protected $_results = array();
52:
53: 54: 55: 56: 57:
58: protected $_tagger;
59:
60: 61: 62: 63: 64: 65: 66: 67: 68: 69:
70: public function __construct(Ansel_Tagger $tagger, $tags = null, $owner = null)
71: {
72: $this->_tagger = $tagger;
73: if (!empty($tags)) {
74: $this->_tags = $this->_tagger->getTagIds($tags);
75: } else {
76: $this->_tags = $GLOBALS['session']->get('ansel', 'tags_search', Horde_Session::TYPE_ARRAY);
77: }
78:
79: $this->_owner = $owner;
80:
81: }
82:
83: 84: 85: 86:
87: public function save()
88: {
89: $GLOBALS['session']->set('ansel', 'tags_search', $this->_tags);
90: $this->_dirty = false;
91: }
92:
93: 94: 95: 96: 97:
98: public function getSlice($page, $perpage)
99: {
100: global $conf, $registry;
101:
102:
103: $this->runSearch();
104: $totals = $this->count();
105:
106:
107: $gstart = $page * $perpage;
108: $gresults = array_slice($this->_results['galleries'], $gstart, $perpage);
109:
110:
111: $galleries = array();
112: foreach ($gresults as $gallery) {
113: try {
114: $galleries[] = $GLOBALS['injector']->getInstance('Ansel_Storage')->getGallery($gallery);
115: } catch (Exception $e) {
116: Horde::logMessage('Gallery Not Found: ' . $gallery, 'ERR');
117: }
118: }
119:
120:
121: $istart = max(0, $page * $perpage - $totals['galleries']);
122: $count = $perpage - count($galleries);
123: if ($count > 0) {
124: $iresults = array_slice($this->_results['images'], $istart, $count);
125: try {
126: $images = count($iresults) ? array_values($GLOBALS['injector']->getInstance('Ansel_Storage')->getImages(array('ids' => $iresults))) : array();
127: } catch (Horde_Exception_NotFound $e) {
128: throw new Ansel_Exception($e);
129: }
130: if (($conf['comments']['allow'] == 'all' || ($conf['comments']['allow'] == 'authenticated' && $GLOBALS['registry']->getAuth())) &&
131: $registry->hasMethod('forums/numMessagesBatch')) {
132:
133: $ids = array_keys($images);
134: try {
135: $ccounts = $GLOBALS['registry']->forums->numMessagesBatch($ids, 'ansel');
136: foreach ($images as $image) {
137: $image->commentCount = (!empty($ccounts[$image->id]) ? $ccounts[$image->id] : 0);
138: }
139: } catch (Horde_Exception $e) {}
140: }
141: } else {
142: $images = array();
143: }
144:
145: return array_merge($galleries, $images);
146: }
147:
148: 149: 150: 151: 152: 153: 154:
155: public function addTag($tag)
156: {
157: $tag_id = (int)current($this->_tagger->getTagIds($tag));
158: if (array_search($tag_id, $this->_tags) === false) {
159: $this->_tags[$tag] = $tag_id;
160: $this->_dirty = true;
161: }
162: }
163:
164: 165: 166: 167: 168: 169: 170:
171: public function removeTag($tag)
172: {
173: if (!empty($this->_tags[$tag])) {
174: unset($this->_tags[$tag]);
175: $this->_dirty = true;
176: }
177: }
178:
179: 180: 181: 182: 183:
184: public function getTags()
185: {
186: return $this->_tags;
187: }
188:
189: 190: 191: 192: 193: 194: 195:
196: public function getTagTrail()
197: {
198: global $registry;
199:
200: $html = '<ul class="tag-list">';
201:
202:
203: $count = 0;
204: foreach ($this->_tags as $tagname => $tagid) {
205: $remove_url = Horde::url('view.php', true)->add(
206: array('view' => 'Results',
207: 'tag' => $tagname,
208: 'actionID' => 'remove'));
209: if (!empty($this->_owner)) {
210: $remove_url->add('owner', $this->_owner);
211: }
212: $delete_label = sprintf(_("Remove %s from search"), htmlspecialchars($tagname));
213: $html .= '<li>' . htmlspecialchars($tagname) . $remove_url->link(array('title' => $delete_label)) . Horde::img('delete-small.png', $delete_label) . '</a></li>';
214: }
215:
216: return $html . '</ul>';
217: }
218:
219: 220: 221: 222: 223:
224: public function tagCount()
225: {
226: return count($this->_tags);
227: }
228:
229: 230: 231: 232: 233:
234: public function count()
235: {
236: if (!is_array($this->_tags) || !count($this->_tags)) {
237: return 0;
238: }
239:
240: $count = array('galleries' => count($this->_results['galleries']), 'images' => count($this->_results['images']));
241: $this->_totalCount = $count;
242:
243: return $count;
244: }
245:
246: 247: 248: 249: 250:
251: public function getRelatedTags()
252: {
253: $tags = $this->_tagger->browseTags($this->getTags(), $this->_owner);
254: $search = new Ansel_Search_Tag($this->_tagger, null, $this->_owner);
255: $results = array();
256: foreach ($tags as $id => $tag) {
257: $search->addTag($tag);
258: $search->runSearch();
259: $count = $search->count();
260: if ($count['images'] + $count['galleries'] > 0) {
261: $results[$id] = array('tag_name' => $tag, 'total' => $count['images'] + $count['galleries']);
262: }
263: $search->removeTag($tag);
264: }
265:
266:
267: uasort($results, array($this, '_sortTagInfo'));
268: return $results;
269: }
270:
271: 272: 273: 274:
275: public function runSearch()
276: {
277: if (!empty($this->_owner)) {
278: $filter = array('user' => $this->_owner);
279: } else {
280: $filter = array();
281: }
282: if (empty($this->_results) || $this->_dirty) {
283: $this->_results = $this->_tagger
284: ->search($this->_tags, $filter);
285: }
286: }
287:
288: 289: 290:
291: static public function clearSearch()
292: {
293: $GLOBALS['session']->remove('ansel', 'tags_search');
294: }
295:
296: 297: 298: 299:
300: private function _sortTagInfo($a, $b)
301: {
302: return $a['total'] < $b['total'];
303: }
304:
305: }
306: