source: extensions/GrumPluginClasses/classes/GPCRequestBuilder.class.inc.php @ 16012

Last change on this file since 16012 was 16012, checked in by grum, 12 years ago

feature:2634- compatibility with Piwigo 2.4
+add some objects on js framework

File size: 45.1 KB
Line 
1<?php
2/* -----------------------------------------------------------------------------
3  class name: GCPRequestBuilder
4  class version  : 1.1.7
5  plugin version : 3.5.2
6  date           : 2012-06-24
7
8  ------------------------------------------------------------------------------
9  Author     : Grum
10    email    : grum@piwigo.org
11    website  : http://photos.grum.com
12    PWG user : http://forum.phpwebgallery.net/profile.php?id=3706
13
14    << May the Little SpaceFrog be with you ! >>
15  ------------------------------------------------------------------------------
16  *
17  * theses classes provides base functions to manage search pictures in the
18  * database
19  *
20  *
21  * HOW TO USE IT ?
22  * ===============
23  *
24  * when installing the plugin, you have to register the usage of the request
25  * builder
26  *
27  * 1/ Create a RBCallback class
28  *  - extends the GPCSearchCallback class ; the name of the extended class must
29  *    be "RBCallBack%" => replace the "%" by the plugin name
30  *     for example : 'ThePlugin' => 'RBCallBackThePlugin'
31  *
32  * 2/ In the plugin 'maintain.inc.php' file :
33  *  - function plugin_install, add :
34  *       GPCRequestBuilder::register('plugin name', 'path to the RBCallback classe');
35  *          for example : GPCRequestBuilder::register('ThePlugin', $piwigo_path.'plugins/ThePlugin/rbcallback_file_name.php');
36  *
37  *
38  *  - function plugin_uninstall, add :
39  *       GPCRequestBuilder::unregister('plugin name');
40  *          for example : GPCRequestBuilder::unregister('ThePlugin');
41  *
42  * 3/ In the plugin code, put somewhere
43  *     GPCRequestBuilder::loadJSandCSS();
44  *     => this will load specific JS and CSS in the page, by adding url in the
45  *        the header, so try to put this where you're used to prepare the header
46  *
47  * 4/ to display the request builder, just add the returned string in the html
48  *    page
49  *       $stringForTheTemplate=GPCRequestBuilder::displaySearchPage();
50  *
51  *
52  *
53  * HOW DOES THE REQUEST BUILDER WORKS ?
54  * ====================================
55  *
56  * the request builder works in 2 steps :
57  *  - first step  : build a cache, to associate all image id corresponding to
58  *                  the search criterion
59  *                  the cache is an association of request ID/image id
60  *  - second step : use the cache to retrieve images informations
61  *
62  ------------------------------------------------------------------------------
63  :: HISTORY
64
65| release | date       |
66| 1.0.0   | 2010/04/30 | * start coding
67|         |            |
68| 1.1.0   | 2010/09/08 | * add functionnalities to manage complex requests
69|         |            |
70| 1.1.1   | 2010/10/14 | * fix bug on the buildGroupRequest function
71|         |            |   . adding 'DISTINCT' keyword to the SQL requests
72|         |            |
73|         |            | * ajax management moved into the gpc_ajax.php file
74|         |            |
75|         |            | * fix bug on user level access to picture
76|         |            |
77| 1.1.2   | 2010/11/01 | * mantis bug:1984
78|         |            |   . RBuilder returns an error message when one picture
79|         |            |     have multiple categories
80|         |            |
81| 1.1.3   | 2011/01/31 | * mantis bug:2156
82|         |            |   . undefined variable on RBuilder screens
83|         |            |
84| 1.1.4   | 2011/01/31 | * mantis bug:2167
85|         |            |
86| 1.1.5   | 2011/04/10 | * Compatibility with piwigo 2.2
87|         |            |
88| 1.1.6   | 2011/05/15 | * mantis bug:2302
89|         |            |   . Request builder user interface don't work
90|         |            |
91| 1.1.7   | 2012/06/24 | * use some GPCCore function instead of code
92|         |            |
93|         |            |
94|         |            |
95
96  --------------------------------------------------------------------------- */
97
98if(!defined('GPC_DIR')) define('GPC_DIR' , baseName(dirname(dirname(__FILE__))));
99if(!defined('GPC_PATH')) define('GPC_PATH' , PHPWG_PLUGINS_PATH . GPC_DIR . '/');
100
101include_once('GPCTables.class.inc.php');
102
103/**
104 *
105 * Preparing the temporary table => doCache()
106 * ------------------------------------------
107 * To prepare the cache, the request builder use the following functions :
108 *  - getImageId
109 *  - getFrom
110 *  - getWhere
111 *  - getHaving
112 *
113 * Preparing the cache table => doCache()
114 * --------------------------------------
115 * To prepare the cache, the request builder use the following functions :
116 *  => the getFilter function is used to prepare the filter for the getPage()
117 *     function ; not used to build the cache
118 *
119 * Retrieving the results => getPage()
120 * -----------------------------------
121 * To retrieve the image informations, the request builder uses the following
122 * functions :
123 *  - getSelect
124 *  - getFrom
125 *  - getJoin
126 *  - getFilter (in fact, the result of this function is stored by the doCache()
127 *               function while the cache is builded, but it is used only when
128 *               retrieving the results for multirecord tables)
129 *  - formatData
130 *
131 *
132 * Example
133 * -------
134 * Consider the table "tableA" like this
135 *
136 *  - (*) imageId
137 *  - (*) localId
138 *  -     att1
139 *  -     att2
140 *  The primary key is the 'imageId'+'localId' attributes
141 *    => for one imageId, you can have ZERO or more than ONE record
142 *       when you register the class, you have to set the $multiRecord parameter
143 *       to 'y'
144 *
145 *  gatImageId returns      : "tableA.imageId"
146 *  getSelect returns       : "tableA.att1, tableA.att2"
147 *  getFrom returns         : "tableA"
148 *  getWhere returns        : "tableA.localId= xxxx AND tableA.att1 = zzzz"
149 *  getJoin returns         : "tableA.imageId = pit.id"
150 *  getFilter returns       : "tableA.localId= xxxx"
151 *
152 *  Examples :
153 *   - plugin AdvancedMetadata use getFilter
154 *   - plugin AdvancedSearchEngine, module ASETag use getHaving and getWhere
155 */
156class GPCSearchCallback {
157
158  /**
159   * the getImageId returns the name of the image id attribute
160   * return String
161   */
162  static public function getImageId()
163  {
164    return("");
165  }
166
167  /**
168   * the getSelect function must return an attribute list separated with a comma
169   *
170   * "att1, att2, att3, att4"
171   *
172   * you can specifie tables names and aliases
173   *
174   * "table1.att1 AS alias1, table1.att2 AS alias2, table2.att3 AS alias3"
175   */
176  static public function getSelect($param="")
177  {
178    return("");
179  }
180
181  /**
182   * the getFrom function must return a tables list separated with a comma
183   *
184   * "table1, (table2 left join table3 on table2.key = table3.key), table4"
185   */
186  static public function getFrom($param="")
187  {
188    return("");
189  }
190
191  /**
192   * the getWhere function must return a ready to use where clause
193   *
194   * "(att1 = value0 OR att2 = value1) AND att4 LIKE value2 "
195   */
196  static public function getWhere($param="")
197  {
198    return("");
199  }
200
201
202  /**
203   * the getHaving function return a ready to user HAVING clause
204   *
205   * " FIND_IN_SET(value0, GROUP_CONCAT(DISTINCT att1 SEPARATOR ',')) AND
206   *   FIND_IN_SET(value0, GROUP_CONCAT(DISTINCT att1 SEPARATOR ',')) "
207   *
208   */
209  static public function getHaving($param="")
210  {
211    return("");
212  }
213
214
215  /**
216   * the getJoin function must return a ready to use sql statement allowing to
217   * join the IMAGES table (key : pit.id) with given conditions
218   *
219   * "att3 = pit.id "
220   */
221  static public function getJoin($param="")
222  {
223    return("");
224  }
225
226
227  /**
228   * the getFilter function must return a ready to use where clause
229   * this where clause is used to filter the cache when the used tables can
230   * return more than one result
231   *
232   * the filter can be empty, can be equal to the where clause, or can be equal
233   * to a sub part of the where clause
234   *
235   * in most case, return "" is the best solution
236   *
237   */
238  static public function getFilter($param="")
239  {
240    //return(self::getWhere($param));
241    return("");
242  }
243
244
245  /**
246   * this function is called by the request builder, allowing to display plugin
247   * data with a specific format
248   *
249   * @param Array $attributes : array of ('attribute_name' => 'attribute_value')
250   * @return String : HTML formatted value
251   */
252  static public function formatData($attributes)
253  {
254    return(print_r($attributes, true));
255  }
256
257
258  /**
259   * this function is called by the request builder to make the search page, and
260   * must return the HTML & JS code of the dialogbox used to select criterion
261   *
262   * Notes :
263   *  - the dialogbox is a JS object with a public method 'show'
264   *  - when the method show is called, one parameter is given by the request
265   *    builder ; the parameter is an object defined as this :
266   *      {
267   *        cBuilder: an instance of the criteriaBuilder object used in the page,
268   *      }
269   *
270   *
271   *
272   *
273   * @param String $mode : can take 'admin' or 'public' values, allowing to
274   *                       return different interface if needed
275   * @return String : HTML formatted value
276   */
277  static public function getInterfaceContent($mode='admin')
278  {
279    return("");
280  }
281
282  /**
283   * this function returns the label displayed in the criterion menu
284   *
285   * @return String : label displayed in the criterions menu
286   */
287  static public function getInterfaceLabel()
288  {
289    return(l10n('gpc_rb_unknown_interface'));
290  }
291
292  /**
293   * this function returns the name of the dialog box class
294   *
295   * @return String : name of the dialogbox class
296   */
297  static public function getInterfaceDBClass()
298  {
299    return('');
300  }
301
302
303}
304
305
306//load_language('rbuilder.lang', GPC_PATH);
307
308
309class GPCRequestBuilder {
310
311  static public $pluginName = 'GPCRequestBuilder';
312  static public $version = '1.1.4';
313
314  static private $tables = Array();
315  static protected $tGlobalId=0;
316
317  /**
318   * register a plugin using GPCRequestBuilder
319   *
320   * @param String $pluginName : the plugin name
321   * @param String $fileName : the php filename where the callback function can
322   *                           be found
323   * @return Boolean : true if registering is Ok, otherwise false
324   */
325  static public function register($plugin, $fileName)
326  {
327    $config=Array();
328    if(!GPCCore::loadConfig(self::$pluginName, $config))
329    {
330      $config['registered']=array();
331    }
332
333    $config['registered'][$plugin]=Array(
334      'name' => $plugin,
335      'fileName' => $fileName,
336      'date' => date("Y-m-d H:i:s"),
337      'version' => self::$version
338    );
339    return(GPCCore::saveConfig(self::$pluginName, $config));
340  }
341
342  /**
343   * unregister a plugin using GPCRequestBuilder
344   *
345   * assume that if the plugin was not registerd before, unregistering returns
346   * a true value
347   *
348   * @param String $pluginName : the plugin name
349   * @return Boolean : true if registering is Ok, otherwise false
350   */
351  static public function unregister($plugin)
352  {
353    $config=Array();
354    if(GPCCore::loadConfig(self::$pluginName, $config))
355    {
356      if(array_key_exists('registered', $config))
357      {
358        if(array_key_exists($plugin, $config['registered']))
359        {
360          unset($config['registered'][$plugin]);
361          return(GPCCore::saveConfig(self::$pluginName, $config));
362        }
363      }
364    }
365    // assume if the plugin was not registered before, unregistering it is OK
366    return(true);
367  }
368
369  /**
370   * @return Array : list of registered plugins
371   */
372  static public function getRegistered()
373  {
374    $config=Array();
375    if(GPCCore::loadConfig(self::$pluginName, $config))
376    {
377      if(array_key_exists('registered', $config))
378      {
379        return($config['registered']);
380      }
381    }
382    return(Array());
383  }
384
385
386  /**
387   * initialise the class
388   *
389   * @param String $prefixeTable : the piwigo prefixe used on tables name
390   * @param String $pluginNameFile : the plugin name used for tables name
391   */
392  static public function init($prefixeTable, $pluginNameFile)
393  {
394    $list=Array('request', 'result_cache', 'temp');
395
396    for($i=0;$i<count($list);$i++)
397    {
398      self::$tables[$list[$i]]=$prefixeTable.$pluginNameFile.'_'.$list[$i];
399    }
400  }
401
402  /**
403   * create the tables needed by RequestBuilder (used during the gpc process install)
404   */
405  static public function createTables()
406  {
407    $tablesDef=array(
408"CREATE TABLE `".self::$tables['request']."` (
409  `id` int(10) unsigned NOT NULL auto_increment,
410  `user_id` int(10) unsigned NOT NULL,
411  `date` datetime NOT NULL,
412  `num_items` int(10) unsigned NOT NULL default '0',
413  `execution_time` float unsigned NOT NULL default '0',
414  `connected_plugin` char(255) NOT NULL,
415  `filter` text NOT NULL,
416  `parameters` text NOT NULL,
417  PRIMARY KEY  (`id`)
418)
419CHARACTER SET utf8 COLLATE utf8_general_ci",
420
421"CREATE TABLE `".self::$tables['result_cache']."` (
422  `id` int(10) unsigned NOT NULL,
423  `image_id` int(10) unsigned NOT NULL,
424  PRIMARY KEY  (`id`,`image_id`)
425)
426CHARACTER SET utf8 COLLATE utf8_general_ci",
427
428"CREATE TABLE `".self::$tables['temp']."` (
429  `requestId` char(30) NOT NULL,
430  `imageId` mediumint(8) unsigned NOT NULL,
431  PRIMARY KEY  (`requestId`,`imageId`)
432)
433CHARACTER SET utf8 COLLATE utf8_general_ci",
434  );
435
436    $tablef= new GPCTables(self::$tables);
437    $tablef->create($tablesDef);
438
439    return(true);
440  }
441
442  /**
443   * update the tables needed by RequestBuilder (used during the gpc process
444   * activation)
445   */
446  static public function updateTables($pluginPreviousRelease)
447  {
448    $tablef=new GPCTables(array(self::$tables['temp']));
449
450    switch($pluginPreviousRelease)
451    {
452      case '03.01.00':
453        $tablesCreate=array();
454        $tablesUpdate=array();
455
456        $tablesCreate[]=
457"CREATE TABLE `".self::$tables['temp']."` (
458  `requestId` char(30) NOT NULL,
459  `imageId` mediumint(8) unsigned NOT NULL,
460  PRIMARY KEY  (`requestId`,`imageId`)
461)
462CHARACTER SET utf8 COLLATE utf8_general_ci";
463
464        $tablesUpdate[self::$tables['request']]['filter']=
465"ADD COLUMN  `filter` text NOT NULL default '' ";
466
467
468
469        $tablef->create($tablesCreate);
470        $tablef->updateTablesFields($tablesUpdate);
471        // no break ! need to be updated like the next release
472        // break;
473      case '03.01.01':
474      case '03.02.00':
475      case '03.02.01':
476      case '03.03.00':
477      case '03.03.01':
478        $tablesUpdate=array();
479
480        $tablesUpdate[self::$tables['request']]['parameters']=
481"ADD COLUMN `parameters` TEXT NOT NULL AFTER `filter`";
482
483        $tablef->updateTablesFields($tablesUpdate);
484        // no break ! need to be updated like the next release
485        // break;
486    }
487
488    return(true);
489  }
490
491  /**
492   * delete the tables needed by RequestBuilder
493   */
494  static public function deleteTables()
495  {
496    $tablef= new GPCTables(self::$tables);
497    $tablef->drop();
498    return(true);
499  }
500
501
502  /**
503   * delete the config
504   */
505  static public function deleteConfig()
506  {
507    GPCCore::deleteConfig(self::$pluginName);
508  }
509
510  /**
511   * this function add and handler on the 'loc_end_page_header' to add request
512   * builder JS script & specific CSS on the page
513   *
514   * use it when the displayed page need an access to the criteriaBuilder GUI
515   *
516   */
517  static public function loadJSandCSS()
518  {
519    load_language('rbuilder.lang', GPC_PATH);
520    add_event_handler('loc_begin_page_header', array('GPCRequestBuilder', 'insertJSandCSSFiles'), 9);
521  }
522
523
524  /**
525   * insert JS a CSS file in header
526   *
527   * the function is declared public because it used by the 'loc_begin_page_header'
528   * event callback
529   *
530   * DO NOT USE IT DIRECTLY
531   *
532   */
533  static public function insertJSandCSSFiles()
534  {
535    global $template;
536
537
538    $baseName=basename(dirname(dirname(__FILE__))).'/css/';
539    GPCCore::addHeaderCSS('gpc.rbuilder', 'plugins/'.$baseName.'rbuilder.css', 25);
540
541    //$template->append('head_elements', '<link href="plugins/'.$baseName.'rbuilder.css" type="text/css" rel="stylesheet"/>');
542    if(defined('IN_ADMIN')) GPCCore::addHeaderCSS('gpc.rbuilderT', 'plugins/'.$baseName.'rbuilder_'.$template->get_themeconf('name').'.css', 26);
543    //$template->append('head_elements', '<link href="plugins/'.$baseName.'rbuilder_'.$template->get_themeconf('name').'.css" type="text/css" rel="stylesheet"/>');
544
545
546    $baseName=basename(dirname(dirname(__FILE__))).'/js/';
547    GPCCore::addHeaderJS('jquery', 'themes/default/js/jquery.js');
548    GPCCore::addHeaderJS('jquery.ui', 'themes/default/js/ui/jquery.ui.core.js', array('jquery'));
549    GPCCore::addHeaderJS('jquery.ui.widget', 'themes/default/js/ui/jquery.ui.widget.js', array('jquery.ui'));
550    GPCCore::addHeaderJS('jquery.ui.mouse', 'themes/default/js/ui/jquery.ui.mouse.js', array('jquery.ui.widget'));
551    GPCCore::addHeaderJS('jquery.ui.position', 'themes/default/js/ui/jquery.ui.position.js', array('jquery.ui.widget'));
552    GPCCore::addHeaderJS('jquery.ui.draggable', 'themes/default/js/ui/jquery.ui.draggable.js', array('jquery.ui.widget'));
553    GPCCore::addHeaderJS('jquery.ui.dialog', 'themes/default/js/ui/jquery.ui.dialog.js', array('jquery.ui.widget'));
554    GPCCore::addHeaderJS('jquery.ui.slider', 'themes/default/js/ui/jquery.ui.slider.js', array('jquery.ui.widget'));
555
556    GPCCore::addHeaderJS('gpc.external.inestedsortable', 'plugins/'.$baseName.'external/iNestedSortablePack.js', array('jquery', 'jquery.ui'));
557    GPCCore::addHeaderJS('gpc.rbCriteriaBuilder', 'plugins/'.$baseName.'rbCriteriaBuilder.js', array('gpc.external.inestedsortable'));
558
559    GPCCore::addHeaderContent('js',
560"
561var requestBuilderOptions = {
562      textAND:\"".l10n('gpc_rb_textAND')."\",
563      textOR:\"".l10n('gpc_rb_textOR')."\",
564      textNoCriteria:\"".l10n('There is no criteria ! At least, one criteria is required to do search...')."\",
565      textSomethingWrong:\"".l10n('gpc_something_is_wrong_on_the_server_side')."\",
566      textCaddieUpdated:\"".l10n('gpc_the_caddie_is_updated')."\",
567      helpEdit:\"".l10n('gpc_help_edit_criteria')."\",
568      helpDelete:\"".l10n('gpc_help_delete_criteria')."\",
569      helpMove:\"".l10n('gpc_help_move_criteria')."\",
570      helpSwitchCondition:\"".l10n('gpc_help_switch_condition')."\",
571      ajaxUrl:'plugins/GrumPluginClasses/gpc_ajax.php',
572      token:'".get_pwg_token()."'
573    };
574"
575);
576  }
577
578
579  /**
580   * execute request from the ajax call
581   *
582   * @return String : a ready to use HTML code
583   */
584  static public function executeRequest($ajaxfct)
585  {
586    $result='';
587    switch($ajaxfct)
588    {
589      case 'public.rbuilder.searchExecute':
590        $result=self::doCache();
591        break;
592      case 'public.rbuilder.searchGetPage':
593        $result=self::getPage($_REQUEST['requestNumber'], $_REQUEST['page'], $_REQUEST['numPerPage']);
594        break;
595    }
596    return($result);
597  }
598
599
600  /**
601   * clear the cache table
602   *
603   * @param Boolean $clearAll : if set to true, clear all records without
604   *                            checking timestamp
605   */
606  static public function clearCache($clearAll=false)
607  {
608    if($clearAll)
609    {
610      $sql="DELETE FROM ".self::$tables['result_cache'];
611    }
612    else
613    {
614      $sql="DELETE pgrc FROM ".self::$tables['result_cache']." pgrc
615              LEFT JOIN ".self::$tables['request']." pgr
616                ON pgrc.id = pgr.id
617              WHERE pgr.date < '".date('Y-m-d H:i:s', strtotime("-2 hour"))."'";
618    }
619    pwg_query($sql);
620  }
621
622  /**
623   * prepare the temporary table used for multirecord requests
624   *
625   * @param Integer $requestNumber : id of request
626   * @return String : name of the request key temporary table
627   */
628  static private function prepareTempTable($requestNumber)
629  {
630    //$tableName=call_user_func(Array('RBCallBack'.$plugin, 'getFrom'));
631    //$imageIdName=call_user_func(Array('RBCallBack'.$plugin, 'getImageId'));
632
633    $tempClauses=array();
634    foreach($_REQUEST['extraData'] as $key => $extraData)
635    {
636      $tempClauses[$key]=array(
637        'plugin' => $extraData['owner'],
638        'where' => call_user_func(Array('RBCallBack'.$extraData['owner'], 'getWhere'), $extraData['param']),
639        'having' => call_user_func(Array('RBCallBack'.$extraData['owner'], 'getHaving'), $extraData['param']),
640      );
641    }
642
643    $sql="INSERT INTO ".self::$tables['temp']." ".self::buildGroupRequest($_REQUEST[$_REQUEST['requestName']], $tempClauses, $_REQUEST['operator'], ' AND ', $requestNumber);
644//echo $sql;
645    $result=pwg_query($sql);
646
647    return($requestNumber);
648  }
649
650  /**
651   * clear the temporary table used for multirecord requests
652   *
653   * @param Array $requestNumber : the requestNumber to delete
654   */
655  static private function clearTempTable($requestNumber)
656  {
657    $sql="DELETE FROM ".self::$tables['temp']." WHERE requestId = '$requestNumber';";
658    pwg_query($sql);
659  }
660
661
662  /**
663   * execute a query, and place result in cache
664   *
665   *
666   * @return String : queryNumber;numberOfItems
667   */
668  static private function doCache()
669  {
670    global $user;
671
672    self::clearCache();
673
674    $registeredPlugin=self::getRegistered();
675    $requestNumber=self::getNewRequest($user['id']);
676
677    $build=Array(
678      'SELECT' => 'pit.id',
679      'FROM' => '',
680      'WHERE' => 'pit.level <= '.$user['level'],
681      'GROUPBY' => '',
682      'FILTER' => ''
683    );
684    $tmpBuild=Array(
685      'FROM' => Array(
686        '('.IMAGES_TABLE.' pit LEFT JOIN '.IMAGE_CATEGORY_TABLE.' pic ON pit.id = pic.image_id)' /*JOIN IMAGES & IMAGE_CATEGORY tables*/
687       .'   JOIN '.USER_CACHE_CATEGORIES_TABLE.' pucc ON pucc.cat_id=pic.category_id',  /* IMAGE_CATEGORY & USER_CACHE_CATEGORIES_TABLE tables*/
688
689      ),
690      'WHERE' => Array(),
691      'JOIN' => Array(999=>'pucc.user_id='.$user['id']),
692      'GROUPBY' => Array(
693        'pit.id'
694      ),
695      'FILTER' => Array(),
696    );
697
698    /* build data request for plugins
699     *
700     * Array('Plugin1' =>
701     *          Array(
702     *            criteriaNumber1 => pluginParam1,
703     *            criteriaNumber2 => pluginParam2,
704     *            criteriaNumberN => pluginParamN
705     *          ),
706     *       'Plugin2' =>
707     *          Array(
708     *            criteriaNumber1 => pluginParam1,
709     *            criteriaNumber2 => pluginParam2,
710     *            criteriaNumberN => pluginParamN
711     *          )
712     * )
713     *
714     */
715    $pluginNeeded=Array();
716    $pluginList=Array();
717    $tempName=Array();
718    foreach($_REQUEST['extraData'] as $key => $val)
719    {
720      $pluginNeeded[$val['owner']][$key]=$_REQUEST['extraData'][$key]['param'];
721      $pluginList[$val['owner']]=$val['owner'];
722    }
723
724    /* for each plugin, include the rb callback class file */
725    foreach($pluginList as $val)
726    {
727      if(file_exists($registeredPlugin[$val]['fileName']))
728      {
729        include_once($registeredPlugin[$val]['fileName']);
730      }
731    }
732
733    /* prepare the temp table for the request */
734    self::prepareTempTable($requestNumber);
735    $tmpBuild['FROM'][]=self::$tables['temp'];
736    $tmpBuild['JOIN'][]=self::$tables['temp'].".requestId = '".$requestNumber."'
737                        AND ".self::$tables['temp'].".imageId = pit.id";
738
739    /* for each needed plugin, prepare the filter */
740    foreach($pluginNeeded as $key => $val)
741    {
742      foreach($val as $itemNumber => $param)
743      {
744        $tmpFilter=call_user_func(Array('RBCallBack'.$key, 'getFilter'), $param);
745
746        if(trim($tmpFilter)!="") $tmpBuild['FILTER'][$key][]='('.$tmpFilter.')';
747      }
748    }
749
750
751    /* build FROM
752     *
753     */
754    $build['FROM']=implode(',', $tmpBuild['FROM']);
755    unset($tmpBuild['FROM']);
756
757    /* build WHERE
758     */
759    self::cleanArray($tmpBuild['WHERE']);
760    if(count($tmpBuild['WHERE'])>0)
761    {
762      $build['WHERE']=' ('.self::buildGroup($_REQUEST[$_REQUEST['requestName']], $tmpBuild['WHERE'], $_REQUEST['operator'], ' AND ').') ';
763    }
764    unset($tmpBuild['WHERE']);
765
766
767    /* build FILTER
768     */
769    self::cleanArray($tmpBuild['FILTER']);
770    if(count($tmpBuild['FILTER'])>0)
771    {
772      $tmp=array();
773      foreach($tmpBuild['FILTER'] as $key=>$val)
774      {
775        $tmp[$key]='('.implode(' OR ', $val).')';
776      }
777      $build['FILTER']=' ('.implode(' AND ', $tmp).') ';
778    }
779    unset($tmpBuild['FILTER']);
780
781
782    /* for each plugin, adds jointure with the IMAGE table
783     */
784    self::cleanArray($tmpBuild['JOIN']);
785    if(count($tmpBuild['JOIN'])>0)
786    {
787      if($build['WHERE']!='') $build['WHERE'].=' AND ';
788      $build['WHERE'].=' ('.implode(' AND ', $tmpBuild['JOIN']).') ';
789    }
790    unset($tmpBuild['JOIN']);
791
792    self::cleanArray($tmpBuild['GROUPBY']);
793    if(count($tmpBuild['GROUPBY'])>0)
794    {
795      $build['GROUPBY'].=' '.implode(', ', $tmpBuild['GROUPBY']).' ';
796    }
797    unset($tmpBuild['GROUPBY']);
798
799
800
801    $sql=' FROM '.$build['FROM'];
802    if($build['WHERE']!='')
803    {
804      $sql.=' WHERE '.$build['WHERE'];
805    }
806    if($build['GROUPBY']!='')
807    {
808      $sql.=' GROUP BY '.$build['GROUPBY'];
809    }
810
811    $sql.=" ORDER BY pit.id ";
812
813    $sql="INSERT INTO ".self::$tables['result_cache']." (SELECT DISTINCT $requestNumber, ".$build['SELECT']." $sql)";
814
815//echo $sql;
816    $returned="0;0";
817
818    $result=pwg_query($sql);
819    if($result)
820    {
821      $numberItems=pwg_db_changes($result);
822      self::updateRequest($requestNumber, $numberItems, 0, implode(',', $pluginList), $build['FILTER'], $_REQUEST['extraData']);
823
824      $returned="$requestNumber;".$numberItems;
825    }
826
827    self::clearTempTable($requestNumber);
828
829    return($returned);
830  }
831
832  /**
833   * return a page content. use the cache table to find request result
834   *
835   * @param Integer $requestNumber : the request number (from cache table)
836   * @param Integer $pageNumber : the page to be returned
837   * @param Integer $numPerPage : the number of items returned on a page
838   * @param String $mode : if mode = 'count', the function returns the number of
839   *                       rows ; otherwise, returns rows in a html string
840   * @return String : formatted HTML code
841   */
842  static private function getPage($requestNumber, $pageNumber, $numPerPage)
843  {
844    global $conf, $user;
845    $request=self::getRequest($requestNumber);
846
847    if($request===false)
848    {
849      return("KO");
850    }
851
852    $limitFrom=$numPerPage*($pageNumber-1);
853
854    $pluginNeeded=explode(',', $request['connected_plugin']);
855    $registeredPlugin=self::getRegistered();
856
857    $build=Array(
858      'SELECT' => '',
859      'FROM' => '',
860      'WHERE' => '',
861      'GROUPBY' => '',
862    );
863    $tmpBuild=Array(
864      'SELECT' => Array(
865        'RB_PIT' => "pit.id AS imageId, pit.name AS imageName, pit.path AS imagePath", // from the piwigo's image table
866        'RB_PIC' => "GROUP_CONCAT( pic.category_id SEPARATOR ',') AS imageCategoriesId",     // from the piwigo's image_category table
867        'RB_PCT' => "GROUP_CONCAT( CASE WHEN pct.name IS NULL THEN '' ELSE pct.name END SEPARATOR '#sep#') AS imageCategoriesNames,
868                     GROUP_CONCAT( CASE WHEN pct.permalink IS NULL THEN '' ELSE pct.permalink END SEPARATOR '#sep#') AS imageCategoriesPLink,
869                     GROUP_CONCAT( CASE WHEN pct.dir IS NULL THEN 'V' ELSE 'P' END) AS imageCategoriesDir",   //from the piwigo's categories table
870      ),
871      'FROM' => Array(
872        // join rb result_cache table with piwigo's images table, joined with the piwigo's image_category table, joined with the categories table
873        'RB' => "(((".self::$tables['result_cache']." pgrc
874                  RIGHT JOIN ".IMAGES_TABLE." pit
875                  ON pgrc.image_id = pit.id)
876                    RIGHT JOIN ".IMAGE_CATEGORY_TABLE." pic
877                    ON pit.id = pic.image_id)
878                       RIGHT JOIN ".CATEGORIES_TABLE." pct
879                       ON pct.id = pic.category_id)
880                          RIGHT JOIN ".USER_CACHE_CATEGORIES_TABLE." pucc
881                          ON pucc.cat_id = pic.category_id",
882      ),
883      'WHERE' => Array(
884        'RB' => "pgrc.id=".$requestNumber." AND pucc.user_id=".$user['id'],
885        ),
886      'JOIN' => Array(),
887      'GROUPBY' => Array(
888        'RB' => "pit.id"
889      )
890    );
891
892
893    $extraData=array();
894    foreach($request['parameters'] as $data)
895    {
896      $extraData[$data['owner']]=$data['param'];
897    }
898
899    /* for each needed plugin :
900     *  - include the file
901     *  - call the static public function getFrom, getJoin, getSelect
902     */
903    foreach($pluginNeeded as $key => $val)
904    {
905      if(array_key_exists($val, $registeredPlugin))
906      {
907        if(file_exists($registeredPlugin[$val]['fileName']))
908        {
909          include_once($registeredPlugin[$val]['fileName']);
910
911          $tmp=explode(',', call_user_func(Array('RBCallBack'.$val, 'getSelect'), $extraData[$val]));
912          foreach($tmp as $key2=>$val2)
913          {
914            $tmp[$key2]=self::groupConcatAlias($val2, '#sep#');
915          }
916          $tmpBuild['SELECT'][$val]=implode(',', $tmp);
917          $tmpBuild['FROM'][$val]=call_user_func(Array('RBCallBack'.$val, 'getFrom'), $extraData[$val]);
918          $tmpBuild['JOIN'][$val]=call_user_func(Array('RBCallBack'.$val, 'getJoin'), $extraData[$val]);
919        }
920      }
921    }
922
923    /* build SELECT
924     *
925     */
926    $build['SELECT']=implode(',', $tmpBuild['SELECT']);
927
928    /* build FROM
929     *
930     */
931    $build['FROM']=implode(',', $tmpBuild['FROM']);
932    unset($tmpBuild['FROM']);
933
934
935    /* build WHERE
936     */
937    if($request['filter']!='') $tmpBuild['WHERE'][]=$request['filter'];
938    $build['WHERE']=implode(' AND ', $tmpBuild['WHERE']);
939    unset($tmpBuild['WHERE']);
940
941    /* for each plugin, adds jointure with the IMAGE table
942     */
943    self::cleanArray($tmpBuild['JOIN']);
944    if(count($tmpBuild['JOIN'])>0)
945    {
946      $build['WHERE'].=' AND ('.implode(' AND ', $tmpBuild['JOIN']).') ';
947    }
948    unset($tmpBuild['JOIN']);
949
950    self::cleanArray($tmpBuild['GROUPBY']);
951    if(count($tmpBuild['GROUPBY'])>0)
952    {
953      $build['GROUPBY'].=' '.implode(', ', $tmpBuild['GROUPBY']).' ';
954    }
955    unset($tmpBuild['GROUPBY']);
956
957
958    $imagesList=Array();
959
960    $sql='SELECT DISTINCT '.$build['SELECT']
961        .' FROM '.$build['FROM']
962        .' WHERE '.$build['WHERE']
963        .' GROUP BY '.$build['GROUPBY'];
964
965    $sql.=' ORDER BY pit.id '
966         .' LIMIT '.$limitFrom.', '.$numPerPage;
967
968//echo $sql;
969    $result=pwg_query($sql);
970    if($result)
971    {
972      while($row=pwg_db_fetch_assoc($result))
973      {
974        // affect standard datas
975        $datas['imageThumbnail']=DerivativeImage::thumb_url(array('id'=>$row['imageId'], 'path'=>$row['imagePath']));
976        $datas['imageId']=$row['imageId'];
977        $datas['imagePath']=$row['imagePath'];
978        $datas['imageName']=$row['imageName'];
979
980        $datas['imageCategoriesId']=explode(',', $row['imageCategoriesId']);
981        $datas['imageCategoriesNames']=explode('#sep#', $row['imageCategoriesNames']);
982        $datas['imageCategoriesPLink']=explode('#sep#', $row['imageCategoriesPLink']);
983        $datas['imageCategoriesDir']=explode(',', $row['imageCategoriesDir']);
984
985        $datas['imageCategories']=Array();
986        for($i=0;$i<count($datas['imageCategoriesId']);$i++)
987        {
988          $datas['imageCategories'][]=array(
989            'id' => $datas['imageCategoriesId'][$i],
990            'name' => $datas['imageCategoriesNames'][$i],
991            'dirType' => $datas['imageCategoriesDir'][$i],
992            'pLinks' => $datas['imageCategoriesPLink'][$i],
993            'link'=> make_picture_url(
994                        array(
995                          'image_id' => $datas['imageId'],
996                          'category' => array
997                            (
998                              'id' => $datas['imageCategoriesId'][$i],
999                              'name' => $datas['imageCategoriesNames'][$i],
1000                              'permalink' => $datas['imageCategoriesPLink'][$i]
1001                            )
1002                        )
1003                      )
1004          );
1005        }
1006
1007        /* affect datas for each plugin
1008         *
1009         * each plugin have to format the data in an HTML code
1010         *
1011         * so, for each plugin :
1012         *  - look the attributes given in the SELECT clause
1013         *  - for each attributes, associate the returned value of the record
1014         *  - affect in datas an index equals to the plugin pluginName, with returned HTML code ; HTML code is get from a formatData function
1015         *
1016         * Example :
1017         *  plugin ColorStart provide 2 attributes 'csColors' and 'csColorsPct'
1018         *
1019         *  we affect to the $attributes var :
1020         *  $attributes['csColors'] = $row['csColors'];
1021         *  $attributes['csColorsPct'] = $row['csColorsPct'];
1022         *
1023         *  call the ColorStat RB callback formatData with the $attributes => the function return a HTML code ready to use in the template
1024         *
1025         *  affect $datas['ColorStat'] = $the_returned_html_code;
1026         *
1027         *
1028         */
1029        foreach($tmpBuild['SELECT'] as $key => $val)
1030        {
1031          if($key!='RB_PIT' && $key!='RB_PIC' && $key!='RB_PCT')
1032          {
1033            $tmp=explode(',', $val);
1034
1035            $attributes=Array();
1036
1037            foreach($tmp as $key2 => $val2)
1038            {
1039              $name=self::getAttribute($val2);
1040              $attributes[$name]=$row[$name];
1041            }
1042
1043            $datas['plugin'][$key]=call_user_func(Array('RBCallBack'.$key, 'formatData'), $attributes);
1044
1045            unset($tmp);
1046            unset($attributes);
1047          }
1048        }
1049        $imagesList[]=$datas;
1050        unset($datas);
1051      }
1052    }
1053
1054    return(self::toHtml($imagesList));
1055    //return("get page : $requestNumber, $pageNumber, $numPerPage<br>$debug<br>$sql");
1056  }
1057
1058  /**
1059   * remove all empty value from an array
1060   * @param Array a$array : the array to clean
1061   */
1062  static private function cleanArray(&$array)
1063  {
1064    foreach($array as $key => $val)
1065    {
1066      if(is_array($val))
1067      {
1068        self::cleanArray($val);
1069        if(count($val)==0) unset($array[$key]);
1070      }
1071      elseif(trim($val)=='') unset($array[$key]);
1072    }
1073  }
1074
1075  /**
1076   * returns the alias for an attribute
1077   *
1078   *  item1                          => returns item1
1079   *  table1.item1                   => returns item1
1080   *  table1.item1 AS alias1         => returns alias1
1081   *  item1 AS alias1                => returns alias1
1082   *  GROUP_CONCAT( .... ) AS alias1 => returns alias1
1083   *
1084   * @param String $var : value to examine
1085   * @return String : the attribute name
1086   */
1087  static private function getAttribute($val)
1088  {
1089    preg_match('/(?:GROUP_CONCAT\(.*\)|(?:[A-Z0-9_]*)\.)?([A-Z0-9_]*)(?:\s+AS\s+([A-Z0-9_]*))?/i', trim($val), $result);
1090    if(array_key_exists(2, $result))
1091    {
1092      return($result[2]);
1093    }
1094    elseif(array_key_exists(1, $result))
1095    {
1096      return($result[1]);
1097    }
1098    else
1099    {
1100      return($val);
1101    }
1102  }
1103
1104
1105  /**
1106   * returns a a sql statement GROUP_CONCAT for an alias
1107   *
1108   *  item1                  => returns GROUP_CONCAT(item1 SEPARATOR $sep) AS item1
1109   *  table1.item1           => returns GROUP_CONCAT(table1.item1 SEPARATOR $sep) AS item1
1110   *  table1.item1 AS alias1 => returns GROUP_CONCAT(table1.item1 SEPARATOR $sep) AS alias1
1111   *  item1 AS alias1        => returns GROUP_CONCAT(item1 SEPARATOR $sep) AS alias1
1112   *
1113   * @param String $val : value to examine
1114   * @param String $sep : the separator
1115   * @return String : the attribute name
1116   */
1117  static private function groupConcatAlias($val, $sep=',')
1118  {
1119    /*
1120     * table1.item1 AS alias1
1121     *
1122     * $result[3] = alias1
1123     * $result[2] = item1
1124     * $result[1] = table1.item1
1125     */
1126    preg_match('/((?:(?:[A-Z0-9_]*)\.)?([A-Z0-9_]*))(?:\s+AS\s+([A-Z0-9_]*))?/i', trim($val), $result);
1127    if(array_key_exists(3, $result))
1128    {
1129      return("GROUP_CONCAT(DISTINCT ".$result[1]." SEPARATOR '$sep') AS ".$result[3]);
1130    }
1131    elseif(array_key_exists(2, $result))
1132    {
1133      return("GROUP_CONCAT(DISTINCT ".$result[1]." SEPARATOR '$sep') AS ".$result[2]);
1134    }
1135    else
1136    {
1137      return("GROUP_CONCAT(DISTINCT $val SEPARATOR '$sep') AS ".$val);
1138    }
1139  }
1140
1141
1142  /**
1143   * get a new request number and create it in the request table
1144   *
1145   * @param Integer $userId : id of the user
1146   * @return Integer : the new request number, -1 if something wrong appened
1147   */
1148  static private function getNewRequest($userId)
1149  {
1150    $sql="INSERT INTO ".self::$tables['request']." VALUES('', '$userId', '".date('Y-m-d H:i:s')."', 0, 0, '', '', '')";
1151    $result=pwg_query($sql);
1152    if($result)
1153    {
1154      return(pwg_db_insert_id());
1155    }
1156    return(-1);
1157  }
1158
1159  /**
1160   * update request properties
1161   *
1162   * @param Integer $request_id : the id of request to update
1163   * @param Integer $numItems : number of items found in the request
1164   * @param Float $executionTime : time in second to execute the request
1165   * @param String $pluginList : list of used plugins
1166   * @param String $parameters : parameters given for the request
1167   * @return Boolean : true if request was updated, otherwise false
1168   */
1169  static private function updateRequest($requestId, $numItems, $executionTime, $pluginList, $additionalFilter, $parameters)
1170  {
1171    $sql="UPDATE ".self::$tables['request']."
1172            SET num_items = $numItems,
1173                execution_time = $executionTime,
1174                connected_plugin = '$pluginList',
1175                filter = '".mysql_escape_string($additionalFilter)."',
1176                parameters = '".serialize($parameters)."'
1177            WHERE id = $requestId";
1178    $result=pwg_query($sql);
1179    if($result)
1180    {
1181      return(true);
1182    }
1183    return(false);
1184  }
1185
1186  /**
1187   * returns request properties
1188   *
1189   * @param Integer $request_id : the id of request to update
1190   * @return Array : properties for request, false if request doesn't exist
1191   */
1192  static private function getRequest($requestId)
1193  {
1194    $returned=false;
1195    $sql="SELECT user_id, date, num_items, execution_time, connected_plugin, filter, parameters
1196          FROM ".self::$tables['request']."
1197          WHERE id = $requestId";
1198    $result=pwg_query($sql);
1199    if($result)
1200    {
1201      while($row=pwg_db_fetch_assoc($result))
1202      {
1203        if($row['parameters']!='') $row['parameters']=unserialize($row['parameters']);
1204        $returned=$row;
1205      }
1206    }
1207    return($returned);
1208  }
1209
1210
1211  /**
1212   * internal function used by the executeRequest function for single record
1213   * requests
1214   *
1215   * this function is called recursively
1216   *
1217   * @param Array $groupContent :
1218   * @param Array $items :
1219   * @return String : a where clause
1220   */
1221  static private function buildGroup($groupContent, $items, $groups, $operator)
1222  {
1223    $returned=Array();
1224    foreach($groupContent as $key => $val)
1225    {
1226      if(strpos($val['id'], 'iCbGroup')!==false)
1227      {
1228        preg_match('/[0-9]*$/i', $val['id'], $groupNumber);
1229        $returned[]=self::buildGroup($val['children'], $items, $groups, $groups[$groupNumber[0]]);
1230      }
1231      else
1232      {
1233        preg_match('/[0-9]*$/i', $val['id'], $itemNumber);
1234        $returned[]=" (".$items[$itemNumber[0]].") ";
1235      }
1236    }
1237    return('('.implode($operator, $returned).')');
1238  }
1239
1240
1241  /**
1242   * internal function used by the executeRequest function for multi records
1243   * requests
1244   *
1245   * this function is called recursively
1246   *
1247   * @param Array $groupContent :
1248   * @param Array $clausesItems : array with 'where' and 'having' conditions (and 'plugin' for the plugin)
1249   * @param Array $groups : operators of each group
1250   * @param String $operator : 'OR' or 'AND', according with the current group operator
1251   * @param String $requestNumber : the request number
1252   * @return String : part of a SQL request
1253   */
1254  static private function buildGroupRequest($groupContent, $clausesItems, $groups, $operator, $requestNumber)
1255  {
1256    $returnedS='';
1257    $returned=Array();
1258    foreach($groupContent as $key => $val)
1259    {
1260      if(strpos($val['id'], 'iCbGroup')!==false)
1261      {
1262        preg_match('/[0-9]*$/i', $val['id'], $groupNumber);
1263
1264        $groupValue=self::buildGroupRequest($val['children'], $clausesItems, $groups, $groups[$groupNumber[0]], $requestNumber);
1265
1266        if($groupValue!='')
1267          $returned[]=array(
1268            'mode'  => 'group',
1269            'value' => $groupValue
1270          );
1271      }
1272      else
1273      {
1274        preg_match('/[0-9]*$/i', $val['id'], $itemNumber);
1275
1276        $returned[]=array(
1277          'mode'  => 'item',
1278          'plugin' => $clausesItems[$itemNumber[0]]['plugin'],
1279          'valueWhere' => ($clausesItems[$itemNumber[0]]['where']!='')?" (".$clausesItems[$itemNumber[0]]['where'].") ":'',
1280          'valueHaving' => ($clausesItems[$itemNumber[0]]['having'])?" (".$clausesItems[$itemNumber[0]]['having'].") ":'',
1281        );
1282      }
1283    }
1284
1285    if(count($returned)>0)
1286    {
1287      if(strtolower(trim($operator))=='and')
1288      {
1289        $tId=0;
1290        foreach($returned as $key=>$val)
1291        {
1292          if($tId>0) $returnedS.=" JOIN ";
1293
1294          if($val['mode']=='item')
1295          {
1296            $returnedS.="(SELECT DISTINCT ".call_user_func(Array('RBCallBack'.$val['plugin'], 'getImageId'))." AS imageId
1297                          FROM ".call_user_func(Array('RBCallBack'.$val['plugin'], 'getFrom'));
1298            if($val['valueWhere']!='') $returnedS.=" WHERE ".$val['valueWhere'];
1299            if($val['valueHaving']!='')
1300              $returnedS.=" GROUP BY imageId
1301                            HAVING ".$val['valueHaving'];
1302            $returnedS.=") t".self::$tGlobalId." ";
1303          }
1304          else
1305          {
1306            $returnedS.="(".$val['value'].") t".self::$tGlobalId." ";
1307          }
1308
1309          if($tId>0) $returnedS.=" ON t".(self::$tGlobalId-1).".imageId = t".self::$tGlobalId.".imageId ";
1310          $tId++;
1311          self::$tGlobalId++;
1312        }
1313        $returnedS="SELECT DISTINCT '$requestNumber', t".(self::$tGlobalId-$tId).".imageId FROM ".$returnedS;
1314      }
1315      else
1316      {
1317        foreach($returned as $key=>$val)
1318        {
1319          if($returnedS!='') $returnedS.=" UNION DISTINCT ";
1320
1321          if($val['mode']=='item')
1322          {
1323            $returnedS.="SELECT DISTINCT '$requestNumber', t".self::$tGlobalId.".imageId
1324                          FROM (SELECT ".call_user_func(Array('RBCallBack'.$val['plugin'], 'getImageId'))." AS imageId
1325                                FROM ".call_user_func(Array('RBCallBack'.$val['plugin'], 'getFrom'));
1326            if($val['valueWhere']!='') $returnedS.=" WHERE ".$val['valueWhere'];
1327            if($val['valueHaving']!='')
1328              $returnedS.=" GROUP BY imageId
1329                            HAVING ".$val['valueHaving'];
1330            $returnedS.=") t".self::$tGlobalId." ";
1331          }
1332          else
1333          {
1334            $returnedS.="SELECT DISTINCT '$requestNumber', t".self::$tGlobalId.".imageId FROM (".$val['value'].") t".self::$tGlobalId;
1335          }
1336
1337          self::$tGlobalId++;
1338        }
1339      }
1340    }
1341
1342    return($returnedS);
1343  }
1344
1345
1346  /**
1347   * convert a list of images to HTML
1348   *
1349   * @param Array $imagesList : list of images id & associated datas
1350   * @return String : list formatted into HTML code
1351   */
1352  static protected function toHtml($imagesList)
1353  {
1354    global $template;
1355
1356    $template->set_filename('result_items',
1357                dirname(dirname(__FILE__)).'/templates/GPCRequestBuilder_result.tpl');
1358
1359
1360
1361    $template->assign('datas', $imagesList);
1362
1363    return($template->parse('result_items', true));
1364  }
1365
1366
1367  /**
1368   * returns allowed (or not allowed) categories for a user
1369   *
1370   * used the USER_CACHE_TABLE if possible
1371   *
1372   * @param Integer $userId : a valid user Id
1373   * @return String : IN(...), NOT IN(...) or nothing if there is no restriction
1374   *                  for the user
1375   */
1376  public function getUserCategories($userId)
1377  {
1378/*
1379    $returned='';
1380    if($user['forbidden_categories']!='')
1381    {
1382      $returned=Array(
1383        'JOIN' => 'AND ('.IMAGE_CATEGORY.'.category_id NOT IN ('.$user['forbidden_categories'].') ) ',
1384        'FROM' => IMAGE_CATEGORY
1385      );
1386
1387
1388    }
1389    *
1390    *
1391    */
1392  }
1393
1394
1395  /**
1396   * display search page
1397   *
1398   * @param Array $filter : an array of string ; each item is the name of a
1399   *                        registered plugin
1400   *                        if no parameters are given, no filter is applied
1401   *                        otherwise only plugin wich name is given are
1402   *                        accessible
1403   */
1404  static public function displaySearchPage($filter=array())
1405  {
1406    global $template, $lang;
1407
1408    if(is_string($filter)) $filter=array($filter);
1409    $filter=array_flip($filter);
1410
1411    GPCCore::addHeaderJS('jquery.ui', 'themes/default/js/ui/jquery.ui.core.js', array('jquery'));
1412    GPCCore::addHeaderJS('jquery.ui.widget', 'themes/default/js/ui/jquery.ui.widget.js', array('jquery.ui'));
1413    GPCCore::addHeaderJS('jquery.ui.mouse', 'themes/default/js/ui/jquery.ui.mouse.js', array('jquery.ui.widget'));
1414    GPCCore::addHeaderJS('jquery.ui.position', 'themes/default/js/ui/jquery.ui.position.js', array('jquery.ui.widget'));
1415    GPCCore::addHeaderJS('jquery.ui.draggable', 'themes/default/js/ui/jquery.ui.draggable.js', array('jquery.ui.widget'));
1416    GPCCore::addHeaderJS('jquery.ui.dialog', 'themes/default/js/ui/jquery.ui.dialog.js', array('jquery.ui.widget'));
1417    GPCCore::addHeaderJS('jquery.ui.slider', 'themes/default/js/ui/jquery.ui.slider.js', array('jquery.ui.widget'));
1418    GPCCore::addHeaderJS('gpc.pagesNavigator', 'plugins/GrumPluginClasses/js/pagesNavigator.js');
1419    GPCCore::addHeaderJS('gpc.rbSearch', 'plugins/GrumPluginClasses/js/rbSearch.js');
1420
1421    $template->set_filename('gpc_search_page',
1422                dirname(dirname(__FILE__)).'/templates/GPCRequestBuilder_search.tpl');
1423
1424    $registeredPlugin=self::getRegistered();
1425    $dialogBox=Array();
1426    foreach($registeredPlugin as $key=>$val)
1427    {
1428      if(array_key_exists($key, $registeredPlugin) and
1429         (count($filter)==0 or array_key_exists($key, $filter)))
1430      {
1431        if(file_exists($registeredPlugin[$key]['fileName']))
1432        {
1433          include_once($registeredPlugin[$key]['fileName']);
1434
1435          $dialogBox[]=Array(
1436            'handle' => $val['name'].'DB',
1437            'dialogBoxClass' => call_user_func(Array('RBCallBack'.$key, 'getInterfaceDBClass')),
1438            'label' => call_user_func(Array('RBCallBack'.$key, 'getInterfaceLabel')),
1439            'content' => call_user_func(Array('RBCallBack'.$key, 'getInterfaceContent')),
1440          );
1441        }
1442      }
1443    }
1444
1445    $datas=Array(
1446      'dialogBox' => $dialogBox,
1447      'themeName' => defined('IN_ADMIN')?$template->get_themeconf('name'):'',
1448    );
1449
1450    $template->assign('datas', $datas);
1451
1452    return($template->parse('gpc_search_page', true));
1453  } //displaySearchPage
1454
1455}
1456
1457
1458?>
Note: See TracBrowser for help on using the repository browser.