1 | <?php |
---|
2 | /** |
---|
3 | * ----------------------------------------------------------------------------- |
---|
4 | * class name : GPCCategorySelector |
---|
5 | * class version : 1.0.1 |
---|
6 | * plugin version : 3.3.3 |
---|
7 | * date : 2010-10-20 |
---|
8 | * ----------------------------------------------------------------------------- |
---|
9 | * author: grum at piwigo.org |
---|
10 | * << May the Little SpaceFrog be with you >> |
---|
11 | * ----------------------------------------------------------------------------- |
---|
12 | * |
---|
13 | * :: HISTORY |
---|
14 | * |
---|
15 | | release | date | |
---|
16 | | 1.0.0 | 2010/10/09 | * create class |
---|
17 | | | | |
---|
18 | | 1.0.1 | 2010/10/20 | * fix bug on the private select methods |
---|
19 | | | | |
---|
20 | | | | |
---|
21 | | | | |
---|
22 | | | | |
---|
23 | | | | |
---|
24 | | | | |
---|
25 | * |
---|
26 | * |
---|
27 | * ----------------------------------------------------------------------------- |
---|
28 | * |
---|
29 | * this class provides methods to easily insert a hierarchical categories |
---|
30 | * selector in the HTML pages |
---|
31 | * |
---|
32 | * ----------------------------------------------------------------------------- |
---|
33 | * |
---|
34 | * Const |
---|
35 | * - GPCCategorySelector::FILTER_ALL |
---|
36 | * - GPCCategorySelector::FILTER_ACCESSIBLE |
---|
37 | * - GPCCategorySelector::FILTER_PUBLIC |
---|
38 | * there is no filter 'private only' or 'not accessible only' because these |
---|
39 | * kind of categories are probably sub categories of 'public' categories |
---|
40 | * |
---|
41 | * |
---|
42 | * Methods |
---|
43 | * - public __construct($options) |
---|
44 | * - public __destruct() |
---|
45 | * - public setFilter($filter) |
---|
46 | * - public getFilter() |
---|
47 | * - public setGalleryRoot($galleryRoot) |
---|
48 | * - public getGalleryRoot() |
---|
49 | * - public getCategoryList() |
---|
50 | * |
---|
51 | * |
---|
52 | * ----------------------------------------------------------------------------- |
---|
53 | * |
---|
54 | */ |
---|
55 | |
---|
56 | |
---|
57 | class GPCCategorySelector |
---|
58 | { |
---|
59 | const FILTER_ALL = 'all'; // no filter, all categories are listed |
---|
60 | const FILTER_ACCESSIBLE = 'accessible'; // only accessible categories are listed (public + private with some access right) |
---|
61 | const FILTER_PUBLIC = 'public'; // only public categories are listed |
---|
62 | |
---|
63 | const USER_MODE_ADMIN = 'admin'; // returns result without user acces right applied (admin can see everything...) |
---|
64 | const USER_MODE_PUBLIC = 'public'; // returns result with user acces right applied |
---|
65 | |
---|
66 | |
---|
67 | private $options=array( |
---|
68 | 'filter' => self::FILTER_ACCESSIBLE, |
---|
69 | 'galleryRoot' => true, |
---|
70 | 'tree' => false, |
---|
71 | 'userMode' => self::USER_MODE_PUBLIC, |
---|
72 | ); |
---|
73 | |
---|
74 | |
---|
75 | /** |
---|
76 | * constructor for the object |
---|
77 | * |
---|
78 | * all options are facultative |
---|
79 | * |
---|
80 | * @param Array $options : an array with the options |
---|
81 | * String 'filter' : can take one the defined FILTER values |
---|
82 | * Bool 'galleryRoot' : if set to true, the category list |
---|
83 | * contain at root, an item with id = 0 |
---|
84 | * and named 'all the gallery' |
---|
85 | * Bool 'tree' : if set to true, the category list |
---|
86 | * is returned as a tree, otherwise result |
---|
87 | * is returned as a flat array |
---|
88 | * String 'userMode' : 'admin' returns result without user |
---|
89 | * right access applied ; 'public' returns |
---|
90 | * result with user right acces applied |
---|
91 | */ |
---|
92 | public function __construct($options=array()) |
---|
93 | { |
---|
94 | if(isset($options['filter'])) $this->setFilter($options['filter']); |
---|
95 | if(isset($options['galleryRoot'])) $this->setGalleryRoot($options['galleryRoot']); |
---|
96 | if(isset($options['tree'])) $this->setTree($options['tree']); |
---|
97 | if(isset($options['userMode'])) $this->setUserMode($options['userMode']); |
---|
98 | } |
---|
99 | |
---|
100 | /** |
---|
101 | * destructor dor the object |
---|
102 | */ |
---|
103 | public function __destruct() |
---|
104 | { |
---|
105 | unset($this->options); |
---|
106 | } |
---|
107 | |
---|
108 | /** |
---|
109 | * set the filter value to apply on the categories |
---|
110 | * |
---|
111 | * @param String $filer : the filter value |
---|
112 | * @return String : the filter value |
---|
113 | */ |
---|
114 | public function setFilter($filter) |
---|
115 | { |
---|
116 | if($filter==self::FILTER_ALL or |
---|
117 | $filter==self::FILTER_ACCESSIBLE or |
---|
118 | $filter==self::FILTER_PUBLIC) $this->options['filter']=$filter; |
---|
119 | |
---|
120 | if($this->options['userMode']==self::USER_MODE_PUBLIC and |
---|
121 | !($this->options['filter']==self::FILTER_ACCESSIBLE or $this->options['filter']==self::FILTER_PUBLIC)) $this->options['filter']==self::FILTER_ACCESSIBLE; |
---|
122 | |
---|
123 | return($this->options['filter']); |
---|
124 | } |
---|
125 | |
---|
126 | /** |
---|
127 | * get the filter value affected on the categories |
---|
128 | * |
---|
129 | * @return String : the filter |
---|
130 | */ |
---|
131 | public function getFilter() |
---|
132 | { |
---|
133 | return($this->options['filter']); |
---|
134 | } |
---|
135 | |
---|
136 | |
---|
137 | /** |
---|
138 | * set to true to add a root item named 'all the gallery' |
---|
139 | * id for this item will be equal to 0 |
---|
140 | * |
---|
141 | * @param Bool $galleryRoot : |
---|
142 | * @return Bool : |
---|
143 | */ |
---|
144 | public function setGalleryRoot($galleryRoot) |
---|
145 | { |
---|
146 | if(is_bool($galleryRoot)) $this->options['galleryRoot']=$galleryRoot; |
---|
147 | return($this->options['galleryRoot']); |
---|
148 | } |
---|
149 | |
---|
150 | |
---|
151 | /** |
---|
152 | * get if a root item named 'all the gallery' is present or not |
---|
153 | * |
---|
154 | * @return Bool : |
---|
155 | */ |
---|
156 | public function getGalleryRoot() |
---|
157 | { |
---|
158 | return($this->options['galleryRoot']); |
---|
159 | } |
---|
160 | |
---|
161 | |
---|
162 | /** |
---|
163 | * get if the result have to be returned as a tree or as a flat array |
---|
164 | * |
---|
165 | * @return Bool : |
---|
166 | */ |
---|
167 | public function getTree() |
---|
168 | { |
---|
169 | return($this->options['tree']); |
---|
170 | } |
---|
171 | |
---|
172 | |
---|
173 | /** |
---|
174 | * set if the result have to be returned as a tree or as a flat array |
---|
175 | * |
---|
176 | * @param Bool $tree : |
---|
177 | * @return Bool : |
---|
178 | */ |
---|
179 | public function setTree($tree) |
---|
180 | { |
---|
181 | if(is_bool($tree)) $this->options['tree']=$tree; |
---|
182 | return($this->options['tree']); |
---|
183 | } |
---|
184 | |
---|
185 | |
---|
186 | |
---|
187 | |
---|
188 | /** |
---|
189 | * returns the user mode currently applied |
---|
190 | * |
---|
191 | * @return String : |
---|
192 | */ |
---|
193 | public function getUserMode() |
---|
194 | { |
---|
195 | return($this->options['userMode']); |
---|
196 | } |
---|
197 | |
---|
198 | |
---|
199 | /** |
---|
200 | * set the user mode to apply |
---|
201 | * |
---|
202 | * @param String $userMode : |
---|
203 | * @return String : |
---|
204 | */ |
---|
205 | public function setUserMode($userMode) |
---|
206 | { |
---|
207 | if($userMode==self::USER_MODE_ADMIN || $userMode==self::USER_MODE_PUBLIC) $this->options['userMode']=$userMode; |
---|
208 | |
---|
209 | if($this->options['userMode']==self::USER_MODE_PUBLIC and |
---|
210 | !($this->options['filter']==self::FILTER_ACCESSIBLE or $this->options['filter']==self::FILTER_PUBLIC)) $this->options['filter']==self::FILTER_ACCESSIBLE; |
---|
211 | return($this->options['userMode']); |
---|
212 | } |
---|
213 | |
---|
214 | |
---|
215 | |
---|
216 | /** |
---|
217 | * build an ordered category list |
---|
218 | * returns an array, each item is an array like : |
---|
219 | * 'id' => the category Id |
---|
220 | * 'name' => the category name |
---|
221 | * 'level' => the category level |
---|
222 | * 'status' => the category status (0='private', 1='public') |
---|
223 | * 'childs' => the category have childs ? (true or false in flat mode, childs |
---|
224 | * in tree mode) |
---|
225 | * |
---|
226 | * @return Array : the list |
---|
227 | */ |
---|
228 | public function getCategoryList() |
---|
229 | { |
---|
230 | global $user; |
---|
231 | |
---|
232 | $returned=array(); |
---|
233 | |
---|
234 | if($this->options['galleryRoot']) |
---|
235 | { |
---|
236 | $startLevel=1; |
---|
237 | } |
---|
238 | else |
---|
239 | { |
---|
240 | $startLevel=0; |
---|
241 | } |
---|
242 | |
---|
243 | $sql="SELECT DISTINCT pct.id, pct.name, pct.global_rank AS rank, pct.status |
---|
244 | FROM ".CATEGORIES_TABLE." pct "; |
---|
245 | |
---|
246 | switch($this->options['filter']) |
---|
247 | { |
---|
248 | case self::FILTER_PUBLIC : |
---|
249 | $sql.=" WHERE pct.status = 'public' "; |
---|
250 | break; |
---|
251 | case self::FILTER_ACCESSIBLE : |
---|
252 | if(!is_admin()) |
---|
253 | { |
---|
254 | $sql.=" JOIN ".USER_CACHE_CATEGORIES_TABLE." pucc |
---|
255 | ON (pucc.cat_id = pct.id) AND pucc.user_id='".$user['id']."' "; |
---|
256 | } |
---|
257 | else |
---|
258 | { |
---|
259 | $sql.=" JOIN ( |
---|
260 | SELECT DISTINCT pgat.cat_id AS catId FROM ".GROUP_ACCESS_TABLE." pgat |
---|
261 | UNION DISTINCT |
---|
262 | SELECT DISTINCT puat.cat_id AS catId FROM ".USER_ACCESS_TABLE." puat |
---|
263 | UNION DISTINCT |
---|
264 | SELECT DISTINCT pct2.id AS catId FROM ".CATEGORIES_TABLE." pct2 WHERE pct2.status='public' |
---|
265 | ) pat |
---|
266 | ON pat.catId = pct.id "; |
---|
267 | } |
---|
268 | |
---|
269 | break; |
---|
270 | } |
---|
271 | $sql.="ORDER BY global_rank;"; |
---|
272 | |
---|
273 | $result=pwg_query($sql); |
---|
274 | if($result) |
---|
275 | { |
---|
276 | while($row=pwg_db_fetch_assoc($result)) |
---|
277 | { |
---|
278 | $row['level']=$startLevel+substr_count($row['rank'], '.'); |
---|
279 | |
---|
280 | /* rank is in formated without leading zero, giving bad order |
---|
281 | * 1 |
---|
282 | * 1.10 |
---|
283 | * 1.11 |
---|
284 | * 1.2 |
---|
285 | * 1.3 |
---|
286 | * .... |
---|
287 | * |
---|
288 | * this loop cp,vert all sub rank in four 0 format, allowing to order |
---|
289 | * categories easily |
---|
290 | * 0001 |
---|
291 | * 0001.0010 |
---|
292 | * 0001.0011 |
---|
293 | * 0001.0002 |
---|
294 | * 0001.0003 |
---|
295 | */ |
---|
296 | $row['rank']=explode('.', $row['rank']); |
---|
297 | foreach($row['rank'] as $key=>$rank) |
---|
298 | { |
---|
299 | $row['rank'][$key]=str_pad($rank, 4, '0', STR_PAD_LEFT); |
---|
300 | } |
---|
301 | $row['rank']=implode('.', $row['rank']); |
---|
302 | |
---|
303 | $row['name']=GPCCore::getUserLanguageDesc($row['name']); |
---|
304 | |
---|
305 | $returned[]=$row; |
---|
306 | } |
---|
307 | } |
---|
308 | |
---|
309 | if($this->options['galleryRoot']) |
---|
310 | { |
---|
311 | $returned[]=array( |
---|
312 | 'id' => 0, |
---|
313 | 'name' => l10n('All the gallery'), |
---|
314 | 'rank' => '0000', |
---|
315 | 'level' => 0, |
---|
316 | 'status' => 'public', |
---|
317 | 'childs' => null |
---|
318 | ); |
---|
319 | } |
---|
320 | |
---|
321 | usort($returned, array(&$this, 'compareCat')); |
---|
322 | |
---|
323 | if($this->options['tree']) |
---|
324 | { |
---|
325 | $index=0; |
---|
326 | $returned=$this->buildSubLevel($returned, $index); |
---|
327 | } |
---|
328 | else |
---|
329 | { |
---|
330 | //check if cats have childs & remove rank (enlight the response) |
---|
331 | $prevLevel=-1; |
---|
332 | for($i=count($returned)-1;$i>=0;$i--) |
---|
333 | { |
---|
334 | unset($returned[$i]['rank']); |
---|
335 | if($returned[$i]['status']=='private') |
---|
336 | { |
---|
337 | $returned[$i]['status']='0'; |
---|
338 | } |
---|
339 | else |
---|
340 | { |
---|
341 | $returned[$i]['status']='1'; |
---|
342 | } |
---|
343 | |
---|
344 | if($returned[$i]['level']>=$prevLevel) |
---|
345 | { |
---|
346 | $returned[$i]['childs']=false; |
---|
347 | } |
---|
348 | else |
---|
349 | { |
---|
350 | $returned[$i]['childs']=true; |
---|
351 | } |
---|
352 | $prevLevel=$returned[$i]['level']; |
---|
353 | } |
---|
354 | } |
---|
355 | |
---|
356 | return($returned); |
---|
357 | } |
---|
358 | |
---|
359 | /** |
---|
360 | * used for sort comparison |
---|
361 | * defined as public, but don't use it directly |
---|
362 | * |
---|
363 | * this function compare two categorie with their rank value |
---|
364 | */ |
---|
365 | public function compareCat($catA, $catB) |
---|
366 | { |
---|
367 | if($catA['rank'] == $catB['rank']) |
---|
368 | { |
---|
369 | return(0); |
---|
370 | } |
---|
371 | return( ($catA['rank'] < $catB['rank'])?-1:1 ); |
---|
372 | } |
---|
373 | |
---|
374 | |
---|
375 | /** |
---|
376 | * used to convert a flat array in a leveled array |
---|
377 | */ |
---|
378 | private function buildSubLevel(&$list, &$currentIndex) |
---|
379 | { |
---|
380 | $returned=array(); |
---|
381 | |
---|
382 | $localIndex=$currentIndex; |
---|
383 | $list[$localIndex]['childs']=array(); |
---|
384 | // reduce size of returned data |
---|
385 | unset($list[$currentIndex]['rank']); |
---|
386 | if($list[$currentIndex]['status']=='private') |
---|
387 | { |
---|
388 | $list[$currentIndex]['status']='0'; |
---|
389 | } |
---|
390 | else |
---|
391 | { |
---|
392 | $list[$currentIndex]['status']='1'; |
---|
393 | } |
---|
394 | $currentIndex++; |
---|
395 | |
---|
396 | |
---|
397 | while($currentIndex<count($list)) |
---|
398 | { |
---|
399 | if($list[$currentIndex]['level']>$list[$localIndex]['level']) |
---|
400 | { |
---|
401 | $list[$localIndex]['childs']=$this->buildSubLevel($list, $currentIndex); |
---|
402 | } |
---|
403 | else if($list[$currentIndex]['level']==$list[$localIndex]['level']) |
---|
404 | { |
---|
405 | $returned[]=$list[$localIndex]; |
---|
406 | |
---|
407 | $localIndex=$currentIndex; |
---|
408 | $list[$currentIndex]['childs']=array(); |
---|
409 | |
---|
410 | // reduce size of returned data |
---|
411 | unset($list[$currentIndex]['rank']); |
---|
412 | if($list[$currentIndex]['status']=='private') |
---|
413 | { |
---|
414 | $list[$currentIndex]['status']='0'; |
---|
415 | } |
---|
416 | else |
---|
417 | { |
---|
418 | $list[$currentIndex]['status']='1'; |
---|
419 | } |
---|
420 | |
---|
421 | $currentIndex++; |
---|
422 | } |
---|
423 | else |
---|
424 | { |
---|
425 | $returned[]=$list[$localIndex]; |
---|
426 | return($returned); |
---|
427 | } |
---|
428 | } |
---|
429 | $returned[]=$list[$localIndex]; |
---|
430 | |
---|
431 | return($returned); |
---|
432 | } |
---|
433 | |
---|
434 | } |
---|
435 | /* |
---|
436 | |
---|
437 | */ |
---|