source: extensions/GrumPluginClasses/classes/GPCCategorySelector.class.inc.php @ 24506

Last change on this file since 24506 was 12215, checked in by grum, 13 years ago

fix bugs
bug:2160 - CategorySelector : extended description are not managed
+add some functions to GPCCore

  • Property svn:executable set to *
File size: 11.4 KB
Line 
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
57class 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*/
Note: See TracBrowser for help on using the repository browser.