Completed
Push — master ( 402923...3d1c18 )
by Michael
03:19
created
rss.php 1 patch
Indentation   +47 added lines, -47 removed lines patch added patch discarded remove patch
@@ -28,11 +28,11 @@  discard block
 block discarded – undo
28 28
 @$xoopsLogger->activated = false;
29 29
 
30 30
 if (!references_utils::getModuleOption('use_rss')) {
31
-    exit(_ERRORS);
31
+	exit(_ERRORS);
32 32
 }
33 33
 
34 34
 if (function_exists('mb_http_output')) {
35
-    mb_http_output('pass');
35
+	mb_http_output('pass');
36 36
 }
37 37
 $charset = 'utf-8';
38 38
 header('Content-Type:text/xml; charset=' . $charset);
@@ -42,52 +42,52 @@  discard block
 block discarded – undo
42 42
 $tpl->xoops_setCacheTime(references_utils::getModuleOption('rss_cache_time'));    // Temps de cache en secondes
43 43
 $uid = references_utils::getCurrentUserID();
44 44
 if (!$tpl->is_cached('db:references_rss.tpl', $uid)) {
45
-    $categoryTitle = '';
46
-    global $xoopsConfig;
47
-    $sitename = htmlspecialchars($xoopsConfig['sitename'], ENT_QUOTES);
48
-    $email    = $xoopsConfig['adminmail'];
49
-    $slogan   = htmlspecialchars($xoopsConfig['slogan'], ENT_QUOTES);
45
+	$categoryTitle = '';
46
+	global $xoopsConfig;
47
+	$sitename = htmlspecialchars($xoopsConfig['sitename'], ENT_QUOTES);
48
+	$email    = $xoopsConfig['adminmail'];
49
+	$slogan   = htmlspecialchars($xoopsConfig['slogan'], ENT_QUOTES);
50 50
 
51
-    $tpl->assign('charset', $charset);
52
-    $tpl->assign('channel_title', xoops_utf8_encode($sitename));
53
-    $tpl->assign('channel_link', XOOPS_URL . '/');
54
-    $tpl->assign('channel_desc', xoops_utf8_encode($slogan));
55
-    $tpl->assign('channel_lastbuild', formatTimestamp(time(), 'rss'));
56
-    $tpl->assign('channel_webmaster', xoops_utf8_encode($email));
57
-    $tpl->assign('channel_editor', xoops_utf8_encode($email));
58
-    $tpl->assign('channel_category', xoops_utf8_encode($categoryTitle));
59
-    $tpl->assign('channel_generator', xoops_utf8_encode(references_utils::getModuleName()));
60
-    $tpl->assign('channel_language', _LANGCODE);
61
-    $tpl->assign('image_url', XOOPS_URL . '/assets/images/logo.gif');
62
-    $dimention = getimagesize(XOOPS_ROOT_PATH . '/assets/images/logo.gif');
63
-    if (empty($dimention[0])) {
64
-        $width = 88;
65
-    } else {
66
-        $width = ($dimention[0] > 144) ? 144 : $dimention[0];
67
-    }
68
-    if (empty($dimention[1])) {
69
-        $height = 31;
70
-    } else {
71
-        $height = ($dimention[1] > 400) ? 400 : $dimention[1];
72
-    }
73
-    $tpl->assign('image_width', $width);
74
-    $tpl->assign('image_height', $height);
75
-    $start = 0;
76
-    $limit = references_utils::getModuleOption('nb_perpage');
77
-    $items = array();
51
+	$tpl->assign('charset', $charset);
52
+	$tpl->assign('channel_title', xoops_utf8_encode($sitename));
53
+	$tpl->assign('channel_link', XOOPS_URL . '/');
54
+	$tpl->assign('channel_desc', xoops_utf8_encode($slogan));
55
+	$tpl->assign('channel_lastbuild', formatTimestamp(time(), 'rss'));
56
+	$tpl->assign('channel_webmaster', xoops_utf8_encode($email));
57
+	$tpl->assign('channel_editor', xoops_utf8_encode($email));
58
+	$tpl->assign('channel_category', xoops_utf8_encode($categoryTitle));
59
+	$tpl->assign('channel_generator', xoops_utf8_encode(references_utils::getModuleName()));
60
+	$tpl->assign('channel_language', _LANGCODE);
61
+	$tpl->assign('image_url', XOOPS_URL . '/assets/images/logo.gif');
62
+	$dimention = getimagesize(XOOPS_ROOT_PATH . '/assets/images/logo.gif');
63
+	if (empty($dimention[0])) {
64
+		$width = 88;
65
+	} else {
66
+		$width = ($dimention[0] > 144) ? 144 : $dimention[0];
67
+	}
68
+	if (empty($dimention[1])) {
69
+		$height = 31;
70
+	} else {
71
+		$height = ($dimention[1] > 400) ? 400 : $dimention[1];
72
+	}
73
+	$tpl->assign('image_width', $width);
74
+	$tpl->assign('image_height', $height);
75
+	$start = 0;
76
+	$limit = references_utils::getModuleOption('nb_perpage');
77
+	$items = array();
78 78
 
79
-    $items = $h_references_articles->getRecentArticles($start, $limit);
80
-    foreach ($items as $item) {
81
-        $titre       = htmlspecialchars($item->getVar('article_title', 'n'), ENT_QUOTES);
82
-        $description = htmlspecialchars($item->getVar('article_text'), ENT_QUOTES);
83
-        $link        = REFERENCES_URL;
84
-        $tpl->append('items', array(
85
-            'title'       => xoops_utf8_encode($titre),
86
-            'link'        => $link,
87
-            'guid'        => $link,
88
-            'pubdate'     => formatTimestamp($item->getVar('article_timestamp'), 'rss'),
89
-            'description' => xoops_utf8_encode($description)
90
-        ));
91
-    }
79
+	$items = $h_references_articles->getRecentArticles($start, $limit);
80
+	foreach ($items as $item) {
81
+		$titre       = htmlspecialchars($item->getVar('article_title', 'n'), ENT_QUOTES);
82
+		$description = htmlspecialchars($item->getVar('article_text'), ENT_QUOTES);
83
+		$link        = REFERENCES_URL;
84
+		$tpl->append('items', array(
85
+			'title'       => xoops_utf8_encode($titre),
86
+			'link'        => $link,
87
+			'guid'        => $link,
88
+			'pubdate'     => formatTimestamp($item->getVar('article_timestamp'), 'rss'),
89
+			'description' => xoops_utf8_encode($description)
90
+		));
91
+	}
92 92
 }
93 93
 $tpl->display('db:references_rss.tpl', $uid);
Please login to merge, or discard this patch.
class/references_listFilter.php 1 patch
Indentation   +926 added lines, -926 removed lines patch added patch discarded remove patch
@@ -35,930 +35,930 @@
 block discarded – undo
35 35
  */
36 36
 class references_listFilter
37 37
 {
38
-    const FILTER_DATA_TEXT    = 1;
39
-    const FILTER_DATA_NUMERIC = 2;
40
-
41
-    const FILTER_FIELD_TEXT          = 1;
42
-    const FILTER_FIELD_SELECT        = 2;
43
-    const FILTER_FIELD_SELECT_YES_NO = 3;
44
-
45
-    /**
46
-     * Préfixe des variables de sélection
47
-     */
48
-    const PREFIX = 'filter_';
49
-
50
-    /**
51
-     * Nom du module (utilisé pour la session)
52
-     */
53
-    const MODULE_NAME = 'references';
54
-
55
-    /**
56
-     * Contient toutes les variables participant au filtre (avec leur type et description)
57
-     *
58
-     * @var array
59
-     */
60
-    private $vars = array();
61
-
62
-    /**
63
-     * Handler des données
64
-     *
65
-     * @var reference
66
-     */
67
-    private $handler = null;
68
-
69
-    /**
70
-     * Nom de la zone d'opération (par exemple op=products)
71
-     *
72
-     * @var string
73
-     */
74
-    private $op = '';
75
-
76
-    /**
77
-     * action de l'opération en cour (par exemple op=products)
78
-     *
79
-     * @var string
80
-     */
81
-    private $operationName = '';
82
-
83
-    /**
84
-     * Nombre maximum d'éléments pas page
85
-     *
86
-     * @var intger
87
-     */
88
-    private $limit = 10;
89
-
90
-    /**
91
-     * Nom de la variable start
92
-     *
93
-     * @var string
94
-     */
95
-    private $startName = '';
96
-
97
-    /**
98
-     * Critère {@link Criteria} servant à choisir les données
99
-     *
100
-     * @var object
101
-     */
102
-    private $criteria = null;
103
-
104
-    /**
105
-     * Indique s'il y a un nouveau critère
106
-     *
107
-     * @var boolean
108
-     */
109
-    private $newFilter = false;
110
-
111
-    /**
112
-     * Indique si la méthode filter() a été appelée
113
-     *
114
-     * @var boolean
115
-     */
116
-    private $isInitialized = false;
117
-
118
-    /**
119
-     * Zone de tri pour retourner les données (dans getObjects)
120
-     *
121
-     * @var string
122
-     */
123
-    private $sortField = '';
124
-
125
-    /**
126
-     * Sens de tri
127
-     *
128
-     * @var string
129
-     */
130
-    private $sortOrder = '';
131
-
132
-    /**
133
-     * Liste de critères par défaut
134
-     *
135
-     * @var array
136
-     */
137
-    private $defaultCriterias = array();
138
-
139
-    /**
140
-     * L'url complète du script qui appelle
141
-     *
142
-     * @var string
143
-     */
144
-    private $baseUrl = '';
145
-
146
-    /**
147
-     * Indique si on conserve en session la position de départ
148
-     *
149
-     * @var boolean
150
-     */
151
-    private $keepStart = true;
152
-
153
-    /**
154
-     * Indique si l'autocomplétion est activée
155
-     *
156
-     * @var boolean
157
-     */
158
-    private $hasAutoComplete = false;
159
-
160
-    /**
161
-     * Url du dossier js dans le module
162
-     *
163
-     * @var string
164
-     */
165
-    private $jsFolderUrl = '';
166
-
167
-    /**
168
-     * Paramètres additionnels à ajouter aux paramètres du pager
169
-     * @var array
170
-     */
171
-    private $additionnalPagerParameters = array();
172
-
173
-    /**
174
-     * Paramètres additionnels à ajouter au bouton permettant de supprimer le filtre en cours
175
-     * @var array
176
-     */
177
-    private $additionnalClearButtonParameters = array();
178
-
179
-    /**
180
-     * Tableau des champs triables [clé] = nom du champ dans la base, valeur = libellé
181
-     * @var array
182
-     */
183
-    private $sortFields = array();
184
-
185
-    /**
186
-     * Initialise les paramètres avec des valeurs par défaut
187
-     */
188
-    private function setDefaultValues()
189
-    {
190
-        $this->handler                          = null;
191
-        $this->op                               = '';
192
-        $this->limit                            = 10;
193
-        $this->startName                        = 'start';
194
-        $this->operationName                    = 'op';
195
-        $this->sortField                        = '';
196
-        $this->sortOrder                        = 'asc';
197
-        $this->baseUrl                          = '';
198
-        $this->keepStart                        = true;
199
-        $this->hasAutoComplete                  = false;
200
-        $this->jsFolderUrl                      = '';
201
-        $this->additionnalPagerParameters       = array();
202
-        $this->additionnalClearButtonParameters = array();
203
-        $this->sortFields                       = array();    // Les champs qui peuvent être utilisés pour trier
204
-    }
205
-
206
-    /**
207
-     * Initialisation des données, handler et opération courante dans l'appelant
208
-     *
209
-     * @param mixed   $handler   Soit une référence au handler de données soit un tableau qui contient toutes les options (auxquel cas les autres paramètres sont inutiles)
210
-     * @param string  $operationName
211
-     * @param string  $operation Opération courante dans l'appelant
212
-     * @param string  $startName Nom du paramètre start
213
-     * @param integer $limit     Nombre maximum d'éléments par page
214
-     * @param string  $baseUrl   L'url complète du script appelant
215
-     * @param string  $sortField Zone de tri
216
-     * @param string  $sortOrder Sens de tri
217
-     * @param boolean $keepStart Indique si on conserve la position de départ
218
-     * @param string  $jsFolderUrl
219
-     * @package string $jsFolderUrl Url du répertoire qui contient les scripts Javascript
220
-     */
221
-    public function __construct($handler, $operationName = 'op', $operation = '', $startName = 'start', $limit = 10, $baseUrl = '', $sortField = '', $sortOrder = 'asc', $keepStart = true, $jsFolderUrl = '')
222
-    {
223
-        $this->setDefaultValues();
224
-        if (!is_array($handler)) {
225
-            $this->handler       = $handler;
226
-            $this->op            = $operation;
227
-            $this->limit         = $limit;
228
-            $this->startName     = $startName;
229
-            $this->operationName = $operationName;
230
-            $this->sortField     = $sortField;
231
-            $this->sortOrder     = $sortOrder;
232
-            $this->baseUrl       = $baseUrl;
233
-            $this->keepStart     = $keepStart;
234
-            $this->jsFolderUrl   = $jsFolderUrl;
235
-        } else {
236
-            foreach ($handler as $key => $value) {
237
-                $this->$key = $value;
238
-            }
239
-        }
240
-    }
241
-
242
-    /**
243
-     * Donne Ă  la classe le nom des champs sur lesquels on peut faire le tri
244
-     *
245
-     * @param  array $fields [clé] = nom du champ dans la base, valeur = libellé
246
-     * @return object
247
-     */
248
-    public function setSortFields($fields)
249
-    {
250
-        $this->sortFields = $fields;
251
-    }
252
-
253
-    /**
254
-     * Retourne les noms à utiliser pour les champs de tri (sélecteur de champ et ordre de tri)
255
-     *
256
-     * @return array [0] = Nom du sélecteur de champs, [1] = Nom du sélecteur pour le sens du tri
257
-     */
258
-    private function getSortPlaceHolderNames()
259
-    {
260
-        return array(self::PREFIX . 'sortFields', self::PREFIX . 'sortOrder');
261
-    }
262
-
263
-    /**
264
-     * Retourne 2 sélecteurs html pour choisir la zone de tri et le sens du tri
265
-     *
266
-     * @return string
267
-     */
268
-    public function getSortPlaceHolderHtmlCode()
269
-    {
270
-        $sortNames      = $this->getSortPlaceHolderNames();
271
-        $sortFieldsHtml = references_utils::htmlSelect($sortNames[0], $this->sortFields, $this->sortField, false);
272
-        $sortOrderHtml  = references_utils::htmlSelect($sortNames[1], array('asc' => _MD_REFERENCES_ASC, 'desc' => _MD_REFERENCES_DESC), $this->sortOrder, false);
273
-
274
-        return _MD_REFERENCES_SORT_BY . ' ' . $sortFieldsHtml . ' ' . $sortOrderHtml;
275
-    }
276
-
277
-    /**
278
-     * Permet de valoriser une option directement tout en chainant
279
-     *
280
-     * @param  string $optionName
281
-     * @param  mixed  $optionValue
282
-     * @return object
283
-     */
284
-    public function setOption($optionName, $optionValue)
285
-    {
286
-        $this->$optionName = $optionValue;
287
-
288
-        return $this;
289
-    }
290
-
291
-    /**
292
-     * Ajoute un nouveau critère par défaut à la liste des critères par défaut
293
-     *
294
-     * @param Criteria $criteria
295
-     */
296
-    public function addDefaultCriteria(Criteria $criteria)
297
-    {
298
-        $this->defaultCriterias[] = $criteria;
299
-    }
300
-
301
-    /**
302
-     * Retourne une valeur d'un tableau ou null si l'index n'existe pas
303
-     *
304
-     * @param array   $array        Le tableau Ă  traiter
305
-     * @param  string $index        L'index recherché
306
-     * @param  mixed  $defaultValue La valeur par défaut
307
-     * @return mixed
308
-     */
309
-    private function getArrayValue($array, $index, $defaultValue = false)
310
-    {
311
-        if ($index === 'autoComplete' && isset($array[$index]) && isset($array[$index]) == true) {
312
-            $this->hasAutoComplete = true;    // On en profite pour vérifier si un champ utilise l'autocomplétion
313
-        }
314
-
315
-        return isset($array[$index]) ? $array[$index] : $defaultValue;
316
-    }
317
-
318
-    /**
319
-     * Permet de faire l'autocomplétion d'un champ
320
-     *
321
-     * @param  string $query
322
-     * @param         $limit
323
-     * @param  string $fieldName
324
-     * @return string
325
-     */
326
-    public function autoComplete($query, $limit, $fieldName)
327
-    {
328
-        $return = '';
329
-        if (!$this->hasAutoComplete) {    // Si aucun champ n'est en autocomplétion, c'est pas la peine d'aller plus loin
330
-
331
-            return $return;
332
-        }
333
-        if (isset($this->vars[$fieldName])) {    // On vérifie que le champ demandé est bien en autocomplétion
334
-            if ($this->vars[$fieldName]['autoComplete'] == true) {
335
-                if ($this->vars[$fieldName]['dataType'] == self::FILTER_DATA_TEXT) {
336
-                    $criteria = new Criteria($fieldName, $query . '%', 'LIKE');
337
-                }
338
-                $criteria->setLimit((int)$limit);
339
-                $ret = $this->handler->getObjects($criteria);
340
-
341
-                if (count($ret) > 0) {
342
-                    foreach ($ret as $object) {
343
-                        $return .= $object->getVar($fieldName, 'n') . "\n";
344
-                    }
345
-                }
346
-            }
347
-        }
348
-
349
-        return $return;
350
-    }
351
-
352
-    /**
353
-     * Retourne le code Javascript à utiliser pour initialiser l'auto complétion (et donc à coller dans le code html)
354
-     *
355
-     * @param boolean $jqueryAlreadyLoaded Indique si jQuery est déjà chargé par l'appelant, auquel cas rien ne sert de le recharger
356
-     * @return string
357
-     */
358
-    public function getJavascriptInitCode($jqueryAlreadyLoaded = false)
359
-    {
360
-        $return = '';
361
-        if (!$this->hasAutoComplete) {
362
-            return $return;
363
-        }
364
-        $return = '';
365
-        $return .= "<link rel=\"stylesheet\" type=\"text/css\" media=\"all\" title=\"Style sheet\" href=\"" . $this->jsFolderUrl . "autocomplete/jquery.autocomplete.css\" />\n";
366
-        if (!$jqueryAlreadyLoaded) {
367
-            $return .= "<script type=\"text/javascript\" src=\"" . $this->jsFolderUrl . "jquery/jquery.js\"></script>\n";
368
-        }
369
-        $return .= "<script type=\"text/javascript\" src=\"" . $this->jsFolderUrl . "noconflict.js\"></script>\n";
370
-        $return .= "<script type=\"text/javascript\" src=\"" . $this->jsFolderUrl . "autocomplete/jquery.autocomplete.min.js\"></script>\n";
371
-        $return .= "<script type=\"text/javascript\">\n";
372
-        $return .= "jQuery(function($) {\n";
373
-        $return .= "var url='" . $this->baseUrl . "';\n";    // TODO: Supprimer "var" car cela limite sa portée !
374
-        $return .= "var handlerName='" . $this->handler->className . "';\n";
375
-
376
-        foreach ($this->vars as $fieldName => $parameters) {
377
-            if ($parameters['autoComplete'] == true) {
378
-                $field = self::PREFIX . $fieldName;
379
-                $return .= "$('#" . $field . "').autocomplete(url, {\n";
380
-                $return .= "extraParams: {\n";
381
-                $return .= "    field: '" . $fieldName . "',\n";
382
-                $return .= "    op: 'autocomplete',\n";
383
-                $return .= "    handler: handlerName\n";
384
-                $return .= "}\n";
385
-                $return .= "});\n";
386
-            }
387
-        }
388
-        $return .= "});\n";
389
-        $return .= "</script>\n";
390
-
391
-        return $return;
392
-    }
393
-
394
-    /**
395
-     * Initialisation des données du filtre
396
-     * Permet d'indiquer quelles sont les zones sur lesquelles on effectue des filtres ainsi que leur type
397
-     *
398
-     * @param  string $fieldName  Le nom du champs dans la table
399
-     * @param  array  $parameters Les paramètres de la zone sous la forme d'un tableau :
400
-     *                            [dataType]        Entier représentant le type de donnée (numérique ou chaine)
401
-     *                            [fieldType]       Le type de zone de saisie (zone de texte, liste déroulante, liste déroulante Oui/Non)
402
-     *                            [values]      La ou les valeurs de la zone de saisie (utilisé dans le cas d'un select)
403
-     *                            [size]            Largeur d'affichage pour les textbox
404
-     *                            [maxLength]       Largeur maximale pour les textbox
405
-     *                            [withNull]        Dans le cas des listes déroulantes, indique s'il faut une valeur nulle
406
-     *                            [minusOne]        Indique s'il faut retrancher 1 à la valeur saisie récupérée (cas classique des listes Oui/Non avec une valeur nulle)
407
-     *                            [style]            Dans le cas des liste déroulante, le style à appliquer à la liste
408
-     *                            [data]            A ne pas renseigner, contient la valeur saisie par l'utilisateur
409
-     *                            [operator]        Opérateur de comparaison pour le Criteria
410
-     *                            [autoComplete]  Indique si on active l'auto complétion sur le champs
411
-     * @return object L'objet courant pour pouvoir chainer
412
-     */
413
-    public function initFilter($fieldName, $parameters)
414
-    {
415
-        // Tableau des valeurs attendues avec leur valeur par défaut
416
-        $indexNames = array('dataType' => self::FILTER_DATA_TEXT, 'fieldType' => self::FILTER_FIELD_TEXT, 'values' => null, 'withNull' => false, 'size' => 5, 'maxLength' => 255, 'minusOne' => false, 'data' => null, 'style' => '', 'operator' => '=', 'autoComplete' => false);
417
-        $data       = array();
418
-        foreach ($indexNames as $indexName => $defaultValue) {
419
-            $data[$indexName] = $this->getArrayValue($parameters, $indexName, $defaultValue);
420
-        }
421
-        $this->vars[$fieldName] = $data;
422
-
423
-        return $this;
424
-    }
425
-
426
-    /**
427
-     * Retourne le nom du tableau Ă  utiliser pour la session
428
-     * @note : Le nom de la session est composé de : nom du module_nom du handler, par exemple references_references_articles
429
-     *
430
-     * @return string
431
-     */
432
-    private function getSessionName()
433
-    {
434
-        return self::MODULE_NAME . '_' . $this->handler->table;
435
-    }
436
-
437
-    /**
438
-     * Retourne le nom de la clé à utiliser pour la conservation du start en session
439
-     *
440
-     * @return string
441
-     */
442
-    private function getStartSessionName()
443
-    {
444
-        return $this->getSessionName() . '_start';
445
-    }
446
-
447
-    /**
448
-     * Réinitialisation des données avant traitement
449
-     *
450
-     * @return void
451
-     */
452
-    private function reinitializeFieldsValue()
453
-    {
454
-        foreach ($this->vars as $fieldName => $fieldProperties) {
455
-            if ($fieldProperties['dataType'] == self::FILTER_DATA_NUMERIC) {    // Zone numérique
456
-                $fieldProperties['data'] = 0;
457
-            } else {
458
-                $fieldProperties['data'] = '';
459
-            }
460
-            $this->vars[$fieldName] = $fieldProperties;
461
-        }
462
-    }
463
-
464
-    /**
465
-     * Ajoute les critères par défaut au critère général
466
-     *
467
-     * @return void
468
-     */
469
-    private function addDefaultCriterias()
470
-    {
471
-        if (is_array($this->defaultCriterias) && count($this->defaultCriterias) > 0) {
472
-            foreach ($this->defaultCriterias as $criteria) {
473
-                $this->criteria->add($criteria);
474
-            }
475
-        }
476
-
477
-        return $this;
478
-    }
479
-
480
-    /**
481
-     * Indique s'il y a des champs de tri
482
-     *
483
-     * @return boolean
484
-     */
485
-    private function areThereSortFields()
486
-    {
487
-        $return = false;
488
-        if (is_array($this->sortFields) && count($this->sortFields) > 0) {
489
-            $return = true;
490
-        }
491
-
492
-        return $return;
493
-    }
494
-
495
-    /**
496
-     * Indique si le nom du champ passé en paramètre fait partie de la liste des champs "triables"
497
-     *
498
-     * @param  string $fieldName
499
-     * @return boolean
500
-     */
501
-    private function isInSortFieldsList($fieldName)
502
-    {
503
-        return array_key_exists($fieldName, $this->sortFields);
504
-    }
505
-
506
-    /**
507
-     * Indique si le sens de tri passé en paramètre fait partie de la liste autorisée
508
-     *
509
-     * @param  string $order
510
-     * @return boolean
511
-     */
512
-    private function isInSortOrderList($order)
513
-    {
514
-        return in_array($order, array('asc', 'desc'));
515
-    }
516
-
517
-    /**
518
-     * Récupère, depuis la requête d'entrée, la zone de tri à utiliser et le sens du tri et place l'information en cookie
519
-     * pour que lorsque l'utilisateur se reconnecte, il retrouve ses informations de tri
520
-     *
521
-     * @return void
522
-     */
523
-    private function setSortFieldsFromRequest()
524
-    {
525
-        if (!$this->areThereSortFields()) {    // S'il n'y a pas de champs triables, on laisse tomber
526
-
527
-            return;
528
-        }
529
-        $sortField        = $sortOrder = '';
530
-        $cookieName       = $this->getSessionName();
531
-        $orderFieldsNames = $this->getSortPlaceHolderNames();
532
-        if (isset($_REQUEST[$orderFieldsNames[0]]) && isset($_REQUEST[$orderFieldsNames[1]])) {
533
-            $sortField = $_REQUEST[$orderFieldsNames[0]];
534
-            $sortOrder = $_REQUEST[$orderFieldsNames[1]];
535
-        } else {
536
-            if (isset($_SESSION[$cookieName . '_sortField'])) {
537
-                $sortField = $_SESSION[$cookieName . '_sortField'];
538
-            }
539
-            if (isset($_SESSION[$cookieName . '_sortOrder'])) {
540
-                $sortOrder = $_SESSION[$cookieName . '_sortOrder'];
541
-            }
542
-        }
543
-
544
-        if ($this->isInSortFieldsList($sortField) && $this->isInSortOrderList($sortOrder)) {
545
-            $this->sortField = $sortField;
546
-            $this->sortOrder = $sortOrder;
547
-        }
548
-        if (trim($sortField) != '' && trim($sortOrder) != '') {
549
-            $_SESSION[$cookieName . '_sortField'] = $sortField;
550
-            $_SESSION[$cookieName . '_sortOrder'] = $sortOrder;
551
-        }
552
-    }
553
-
554
-    /**
555
-     * Réinitialisation des données avant traitement
556
-     *
557
-     * @return void
558
-     */
559
-    private function setupFilter()
560
-    {
561
-        $this->reinitializeFieldsValue();
562
-        $this->newFilter     = false;
563
-        $this->isInitialized = true;
564
-        $this->criteria      = new CriteriaCompo();
565
-        $this->criteria->add(new Criteria($this->handler->keyName, 0, '<>'));
566
-        $this->addDefaultCriterias();
567
-    }
568
-
569
-    /**
570
-     * RAZ des données du filtre si cela a été demandé dans la requête
571
-     *
572
-     * @return void
573
-     */
574
-    private function isSetCleanFilter()
575
-    {
576
-        if (isset($_REQUEST['cleanFilter'])) {
577
-            $this->setStartInSession(0);
578
-            unset($_SESSION[$this->getSessionName()]);
579
-        }
580
-    }
581
-
582
-    /**
583
-     * Retourne le critère de filtrage courant
584
-     *
585
-     * @return object
586
-     */
587
-    public function getCriteria()
588
-    {
589
-        return $this->criteria;
590
-    }
591
-
592
-    /**
593
-     * Méthode à appeler juste après le constructeur pour qu'elle récupère les données saisies
594
-     *
595
-     * @return object L'objet courant pour pouvoir chainer
596
-     */
597
-    public function filter()
598
-    {
599
-        $this->setupFilter();                // Réinitialisations
600
-        $ts = MyTextSanitizer::getInstance();
601
-        $this->setSortFieldsFromRequest();    // On récupère la zone de tri éventuellement passée dans la requête
602
-        $this->isSetCleanFilter();
603
-
604
-        foreach ($this->vars as $fieldName => $fieldProperties) {
605
-            // On commence par récupérer toutes les valeurs
606
-            $formFieldName           = self::PREFIX . $fieldName;    // "filter_website_id" par exemple
607
-            $fieldProperties['data'] = null;    // Valeur par défaut
608
-            if (isset($_REQUEST[$formFieldName])) {
609
-                if ($fieldProperties['dataType'] == self::FILTER_DATA_NUMERIC) {    // Zone numérique
610
-                    if ((int)$_REQUEST[$formFieldName] != 0) {
611
-                        $fieldProperties['data'] = (int)$_REQUEST[$formFieldName];
612
-                        if (!$fieldProperties['minusOne']) {
613
-                            $this->criteria->add(new Criteria($fieldName, $fieldProperties['data'], $fieldProperties['operator']));
614
-                        } else {
615
-                            $this->criteria->add(new Criteria($fieldName, $fieldProperties['data'] - 1, $fieldProperties['operator']));
616
-                        }
617
-                        $this->newFilter = true;
618
-                    }
619
-                } else {    // Zone texte
620
-                    if (trim($_REQUEST[$formFieldName]) != '') {
621
-                        $fieldProperties['data'] = $_REQUEST[$formFieldName];
622
-                        if (!REFERENCES_EXACT_SEARCH) {
623
-                            $this->criteria->add(new Criteria($fieldName, '%' . $ts->addSlashes($fieldProperties['data']) . '%', 'LIKE'));
624
-                        } else {
625
-                            $this->criteria->add(new Criteria($fieldName, $ts->addSlashes($fieldProperties['data']) . '%', 'LIKE'));
626
-                        }
627
-                        $this->newFilter = true;
628
-                    }
629
-                }
630
-            }
631
-            $this->vars[$fieldName] = $fieldProperties;
632
-        }
633
-
634
-        if ($this->newFilter) {
635
-            $this->setStartInSession(0);
636
-        }
637
-
638
-        // Récupération des donées de la session s'il n'y a pas eu de filtre(s)
639
-        if (!$this->newFilter && isset($_SESSION[$this->getSessionName()])) {
640
-            $sessionFilterData = unserialize($_SESSION[$this->getSessionName()]);
641
-            if (isset($sessionFilterData['criteria']) && is_object($sessionFilterData['criteria'])) {
642
-                $this->criteria = $sessionFilterData['criteria'];
643
-                unset($sessionFilterData['criteria']);
644
-            }
645
-            foreach ($this->vars as $fieldName => $fieldProperties) {
646
-                if (isset($sessionFilterData[$fieldName])) {
647
-                    $fieldProperties['data'] = $sessionFilterData[$fieldName];
648
-                }
649
-                $this->vars[$fieldName] = $fieldProperties;
650
-            }
651
-            unset($_SESSION[$this->getSessionName()]);
652
-        }
653
-
654
-        // Mise en place des données dans la session
655
-        $dataForSession             = array();
656
-        $dataForSession['criteria'] = $this->criteria;
657
-        foreach ($this->vars as $fieldName => $fieldProperties) {
658
-            $dataForSession[$fieldName] = $fieldProperties['data'];
659
-        }
660
-        $_SESSION[$this->getSessionName()] = serialize($dataForSession);
661
-
662
-        return $this;
663
-    }
664
-
665
-    /**
666
-     * Retourne le nombre d'enregistrement en fonction des critères courants
667
-     *
668
-     * @return integer
669
-     */
670
-    public function getCount()
671
-    {
672
-        if (!$this->isInitialized) {
673
-            $this->filter();
674
-        }
675
-
676
-        return $this->handler->getCount($this->criteria);
677
-    }
678
-
679
-    /**
680
-     * Conserve la valeur de start en session
681
-     *
682
-     * @param  integer $start
683
-     * @return void
684
-     */
685
-    private function setStartInSession($start)
686
-    {
687
-        if ($this->keepStart) {
688
-            $startSessionName            = $this->getStartSessionName();
689
-            $_SESSION[$startSessionName] = (int)$start;
690
-        }
691
-    }
692
-
693
-    /**
694
-     * Retourne la valeur de ?start=x
695
-     *
696
-     * @return integer
697
-     */
698
-    private function getStartValue()
699
-    {
700
-        $start = 0;
701
-        if (isset($_REQUEST[$this->startName])) {
702
-            $start = (int)$_REQUEST[$this->startName];
703
-        } elseif ($this->keepStart) {
704
-            $startSessionName = $this->getStartSessionName();
705
-            if (isset($_SESSION[$startSessionName])) {
706
-                $start = (int)$_SESSION[$startSessionName];
707
-            }
708
-        }
709
-        // Mise en session
710
-        $this->setStartInSession($start);
711
-
712
-        return $start;
713
-    }
714
-
715
-    /**
716
-     * Permet d'ajouter un paramètre supplémentaire au pager
717
-     *
718
-     * @param  string $key
719
-     * @param  string $value
720
-     * @return object
721
-     */
722
-    public function addAdditionnalParameterToPager($key, $value = '')
723
-    {
724
-        $this->additionnalPagerParameters[$key] = $value;
725
-
726
-        return $this;
727
-    }
728
-
729
-    /**
730
-     * Permet d'ajouter un paramètre supplémentaire au bouton permettant de supprimer le filtre
731
-     *
732
-     * @param  string $key
733
-     * @param  string $value
734
-     * @return object
735
-     */
736
-    public function addAdditionnalParameterToClearButton($key, $value = '')
737
-    {
738
-        $this->additionnalClearButtonParameters[$key] = $value;
739
-
740
-        return $this;
741
-    }
742
-
743
-    /**
744
-     * Permet d'ajouter des paramètres supplémentaires au pager
745
-     *
746
-     * @param $array
747
-     * @return object
748
-     * @internal param string $key
749
-     * @internal param string $value
750
-     */
751
-    public function addAditionnalArrayParametersToPager($array)
752
-    {
753
-        if (count($array) > 0) {
754
-            foreach ($array as $key => $value) {
755
-                $this->addAdditionnalParameterToPager($key, $value);
756
-            }
757
-        }
758
-
759
-        return $this;
760
-    }
761
-
762
-    /**
763
-     * Retourne le pager Ă  utiliser
764
-     *
765
-     * @return mixed Null s'il n'y a pas lieu d'y avoir un pager, sinon un objet de type {@link XoopsPageNav}
766
-     */
767
-    public function getPager()
768
-    {
769
-        if (!$this->isInitialized) {
770
-            $this->filter();
771
-        }
772
-        require_once XOOPS_ROOT_PATH . '/class/pagenav.php';
773
-        $itemsCount  = $this->getCount();
774
-        $queryString = array();
775
-        if (trim($this->op) != '') {
776
-            $queryString[$this->operationName] = $this->op;
777
-        }
778
-        $pagenav = null;
779
-
780
-        if ($itemsCount > $this->limit) {
781
-            foreach ($this->vars as $fieldName => $fieldProperties) {
782
-                $formFieldName               = self::PREFIX . $fieldName;    // "filter_website_id" par exemple
783
-                $queryString[$formFieldName] = $fieldProperties['data'];
784
-            }
785
-            // Ajout des paramètres supplémentaires éventuels
786
-            if (count($this->additionnalPagerParameters) > 0) {
787
-                foreach ($this->additionnalPagerParameters as $key => $value) {
788
-                    $queryString[$key] = $value;
789
-                }
790
-            }
791
-            $start   = $this->getStartValue();
792
-            $pagenav = new XoopsPageNav($itemsCount, $this->limit, $start, $this->startName, http_build_query($queryString));
793
-        }
794
-
795
-        return $pagenav;
796
-    }
797
-
798
-    /**
799
-     * Retourne une liste d'objets en fonction des critères définis
800
-     *
801
-     * @return array
802
-     */
803
-    public function getObjects()
804
-    {
805
-        if (!$this->isInitialized) {
806
-            $this->filter();
807
-        }
808
-        $start    = $this->getStartValue();
809
-        $limit    = $this->limit;
810
-        $criteria = $this->criteria;
811
-        $criteria->setStart($start);
812
-        $criteria->setLimit($limit);
813
-
814
-        $criteria->setOrder($this->sortOrder);
815
-        if (trim($this->sortField) != '') {
816
-            $criteria->setSort($this->sortField);
817
-        } elseif (trim($this->handler->identifierName) != '') {
818
-            $criteria->setSort($this->handler->identifierName);
819
-        }
820
-
821
-        return $this->handler->getObjects($this->criteria);
822
-    }
823
-
824
-    /**
825
-     * Retourne la zone html à utiliser pour créer la zone de filtre (avec sa valeur saisie si c'est le cas)
826
-     *
827
-     * @param  string $fieldName La zone de saisie dont on veut récupérer le code html
828
-     * @return string
829
-     */
830
-    public function getFilterField($fieldName)
831
-    {
832
-        $html = '';
833
-        if (!$this->isInitialized) {
834
-            $this->filter();
835
-        }
836
-        if (!isset($this->vars[$fieldName])) {
837
-            trigger_error('Error, unknow field');
838
-
839
-            return $html;
840
-        }
841
-        $fieldData     = $this->vars[$fieldName];
842
-        $htmlFieldName = self::PREFIX . $fieldName;
843
-
844
-        switch ($fieldData['fieldType']) {
845
-            case self::FILTER_FIELD_TEXT:    // Zone de texte
846
-                $ts   = MyTextSanitizer::getInstance();
847
-                $html = "<input type='text' name='$htmlFieldName' id='$htmlFieldName' size='" . $fieldData['size'] . "' maxlength='" . $fieldData['maxLength'] . "' value='" . $ts->htmlSpecialChars($fieldData['data']) . "' />";
848
-                break;
849
-
850
-            case self::FILTER_FIELD_SELECT;     // Select
851
-                $style = '';
852
-                if (isset($fieldData['style']) && trim($fieldData['style']) != '') {
853
-                    $style = $fieldData['style'];
854
-                }
855
-                $html = references_utils::htmlSelect($htmlFieldName, $fieldData['values'], $fieldData['data'], $fieldData['withNull'], $style);
856
-                break;
857
-
858
-            case self::FILTER_FIELD_SELECT_YES_NO:    // Select de type Oui/Non
859
-                $html = references_utils::htmlSelect($htmlFieldName, array(2 => _YES, 1 => NO), $fieldData['data'], $fieldData['withNull']);
860
-                break;
861
-        }
862
-
863
-        return $html;
864
-    }
865
-
866
-    /**
867
-     * Assigne toutes les zones de filtre Ă  un template
868
-     *
869
-     * @param  object  $xoopsTpl
870
-     * @param  boolean $asArray   Est-ce qu'il faut placer le résultat dans un tableau ou assigner par nom de zone de filtre
871
-     * @param string   $arrayName Le nom du tableau Ă  utiliser
872
-     * @return void
873
-     */
874
-    public function assignFilterFieldsToTemplate(&$xoopsTpl, $asArray = true, $arrayName = 'filterFields')
875
-    {
876
-        $fields = array_keys($this->vars);
877
-        foreach ($fields as $field) {
878
-            if (!$asArray) {
879
-                $xoopsTpl->assign($field, $this->getFilterField($field));
880
-            } else {
881
-                $xoopsTpl->append($arrayName, $this->getFilterField($field));
882
-            }
883
-        }
884
-    }
885
-
886
-    /**
887
-     * Retourne le bouton utilisé pour supprimer le filtre en cours
888
-     *
889
-     * @return string
890
-     */
891
-    public function getClearFilterbutton()
892
-    {
893
-        $queryString                       = array();
894
-        $queryString[$this->operationName] = $this->op;
895
-        if (count($this->additionnalClearButtonParameters) > 0) {
896
-            foreach ($this->additionnalClearButtonParameters as $key => $value) {
897
-                $queryString[$key] = $value;
898
-            }
899
-        }
900
-        $queryString['cleanFilter'] = '1';
901
-        $baseurl                    = $this->baseUrl;
902
-
903
-        return "&nbsp;&nbsp;<a href='$baseurl?" . http_build_query($queryString) . "' title='" . _MD_REFERENCES_CLEAN_FILTER . "'><img align='top' src='../assets/images/clear_left.png' alt='" . _MD_REFERENCES_CLEAN_FILTER . "' /></a>";
904
-    }
905
-
906
-    /**
907
-     * Retourne le bouton permettant de lancer le filtrage
908
-     *
909
-     * @param string $description  Texte à faire apparaître sur le bouton
910
-     * @param array  $additionnals Champs supplémentaires à faire apparaître avec le bouton
911
-     * @return string
912
-     */
913
-    public function getGoButton($description = _GO, $additionnals = null)
914
-    {
915
-        $html = '';
916
-        if (trim($this->operationName) != '' && trim($this->op) != '') {
917
-            $html .= "<input type='hidden' name='" . $this->operationName . "' id='" . $this->operationName . "' value='" . $this->op . "' />";
918
-        }
919
-        if (!is_null($additionnals)) {
920
-            foreach ($additionnals as $key => $value) {
921
-                $html .= "<input type='hidden' name='" . $key . "' id='" . $key . "' value='" . $value . "' />";
922
-            }
923
-        }
924
-        $html .= "<input type='submit' name='btngo' id='btngo' value='$description' />";
925
-
926
-        return $html;
927
-    }
928
-
929
-    /**
930
-     * Retourne le nom de la zone utilisée pour trier les données
931
-     *
932
-     * @return string
933
-     */
934
-    public function getSortField()
935
-    {
936
-        return $this->sortField;
937
-    }
938
-
939
-    /**
940
-     * Retourne le sens de tri utilisé pour trier les données
941
-     *
942
-     * @return string
943
-     */
944
-    public function getSortOrder()
945
-    {
946
-        return $this->sortOrder();
947
-    }
948
-
949
-    /**
950
-     * Retourne la valeur d'un champ
951
-     *
952
-     * @param  string $fieldName
953
-     * @return mixed  La valeur du champ ou null si on ne trouve pas la zone
954
-     */
955
-    public function getFieldValue($fieldName)
956
-    {
957
-        $ret = null;
958
-        if (isset($this->vars[$fieldName])) {
959
-            $ret = $this->vars[$fieldName]['data'];
960
-        }
961
-
962
-        return $ret;
963
-    }
38
+	const FILTER_DATA_TEXT    = 1;
39
+	const FILTER_DATA_NUMERIC = 2;
40
+
41
+	const FILTER_FIELD_TEXT          = 1;
42
+	const FILTER_FIELD_SELECT        = 2;
43
+	const FILTER_FIELD_SELECT_YES_NO = 3;
44
+
45
+	/**
46
+	 * Préfixe des variables de sélection
47
+	 */
48
+	const PREFIX = 'filter_';
49
+
50
+	/**
51
+	 * Nom du module (utilisé pour la session)
52
+	 */
53
+	const MODULE_NAME = 'references';
54
+
55
+	/**
56
+	 * Contient toutes les variables participant au filtre (avec leur type et description)
57
+	 *
58
+	 * @var array
59
+	 */
60
+	private $vars = array();
61
+
62
+	/**
63
+	 * Handler des données
64
+	 *
65
+	 * @var reference
66
+	 */
67
+	private $handler = null;
68
+
69
+	/**
70
+	 * Nom de la zone d'opération (par exemple op=products)
71
+	 *
72
+	 * @var string
73
+	 */
74
+	private $op = '';
75
+
76
+	/**
77
+	 * action de l'opération en cour (par exemple op=products)
78
+	 *
79
+	 * @var string
80
+	 */
81
+	private $operationName = '';
82
+
83
+	/**
84
+	 * Nombre maximum d'éléments pas page
85
+	 *
86
+	 * @var intger
87
+	 */
88
+	private $limit = 10;
89
+
90
+	/**
91
+	 * Nom de la variable start
92
+	 *
93
+	 * @var string
94
+	 */
95
+	private $startName = '';
96
+
97
+	/**
98
+	 * Critère {@link Criteria} servant à choisir les données
99
+	 *
100
+	 * @var object
101
+	 */
102
+	private $criteria = null;
103
+
104
+	/**
105
+	 * Indique s'il y a un nouveau critère
106
+	 *
107
+	 * @var boolean
108
+	 */
109
+	private $newFilter = false;
110
+
111
+	/**
112
+	 * Indique si la méthode filter() a été appelée
113
+	 *
114
+	 * @var boolean
115
+	 */
116
+	private $isInitialized = false;
117
+
118
+	/**
119
+	 * Zone de tri pour retourner les données (dans getObjects)
120
+	 *
121
+	 * @var string
122
+	 */
123
+	private $sortField = '';
124
+
125
+	/**
126
+	 * Sens de tri
127
+	 *
128
+	 * @var string
129
+	 */
130
+	private $sortOrder = '';
131
+
132
+	/**
133
+	 * Liste de critères par défaut
134
+	 *
135
+	 * @var array
136
+	 */
137
+	private $defaultCriterias = array();
138
+
139
+	/**
140
+	 * L'url complète du script qui appelle
141
+	 *
142
+	 * @var string
143
+	 */
144
+	private $baseUrl = '';
145
+
146
+	/**
147
+	 * Indique si on conserve en session la position de départ
148
+	 *
149
+	 * @var boolean
150
+	 */
151
+	private $keepStart = true;
152
+
153
+	/**
154
+	 * Indique si l'autocomplétion est activée
155
+	 *
156
+	 * @var boolean
157
+	 */
158
+	private $hasAutoComplete = false;
159
+
160
+	/**
161
+	 * Url du dossier js dans le module
162
+	 *
163
+	 * @var string
164
+	 */
165
+	private $jsFolderUrl = '';
166
+
167
+	/**
168
+	 * Paramètres additionnels à ajouter aux paramètres du pager
169
+	 * @var array
170
+	 */
171
+	private $additionnalPagerParameters = array();
172
+
173
+	/**
174
+	 * Paramètres additionnels à ajouter au bouton permettant de supprimer le filtre en cours
175
+	 * @var array
176
+	 */
177
+	private $additionnalClearButtonParameters = array();
178
+
179
+	/**
180
+	 * Tableau des champs triables [clé] = nom du champ dans la base, valeur = libellé
181
+	 * @var array
182
+	 */
183
+	private $sortFields = array();
184
+
185
+	/**
186
+	 * Initialise les paramètres avec des valeurs par défaut
187
+	 */
188
+	private function setDefaultValues()
189
+	{
190
+		$this->handler                          = null;
191
+		$this->op                               = '';
192
+		$this->limit                            = 10;
193
+		$this->startName                        = 'start';
194
+		$this->operationName                    = 'op';
195
+		$this->sortField                        = '';
196
+		$this->sortOrder                        = 'asc';
197
+		$this->baseUrl                          = '';
198
+		$this->keepStart                        = true;
199
+		$this->hasAutoComplete                  = false;
200
+		$this->jsFolderUrl                      = '';
201
+		$this->additionnalPagerParameters       = array();
202
+		$this->additionnalClearButtonParameters = array();
203
+		$this->sortFields                       = array();    // Les champs qui peuvent être utilisés pour trier
204
+	}
205
+
206
+	/**
207
+	 * Initialisation des données, handler et opération courante dans l'appelant
208
+	 *
209
+	 * @param mixed   $handler   Soit une référence au handler de données soit un tableau qui contient toutes les options (auxquel cas les autres paramètres sont inutiles)
210
+	 * @param string  $operationName
211
+	 * @param string  $operation Opération courante dans l'appelant
212
+	 * @param string  $startName Nom du paramètre start
213
+	 * @param integer $limit     Nombre maximum d'éléments par page
214
+	 * @param string  $baseUrl   L'url complète du script appelant
215
+	 * @param string  $sortField Zone de tri
216
+	 * @param string  $sortOrder Sens de tri
217
+	 * @param boolean $keepStart Indique si on conserve la position de départ
218
+	 * @param string  $jsFolderUrl
219
+	 * @package string $jsFolderUrl Url du répertoire qui contient les scripts Javascript
220
+	 */
221
+	public function __construct($handler, $operationName = 'op', $operation = '', $startName = 'start', $limit = 10, $baseUrl = '', $sortField = '', $sortOrder = 'asc', $keepStart = true, $jsFolderUrl = '')
222
+	{
223
+		$this->setDefaultValues();
224
+		if (!is_array($handler)) {
225
+			$this->handler       = $handler;
226
+			$this->op            = $operation;
227
+			$this->limit         = $limit;
228
+			$this->startName     = $startName;
229
+			$this->operationName = $operationName;
230
+			$this->sortField     = $sortField;
231
+			$this->sortOrder     = $sortOrder;
232
+			$this->baseUrl       = $baseUrl;
233
+			$this->keepStart     = $keepStart;
234
+			$this->jsFolderUrl   = $jsFolderUrl;
235
+		} else {
236
+			foreach ($handler as $key => $value) {
237
+				$this->$key = $value;
238
+			}
239
+		}
240
+	}
241
+
242
+	/**
243
+	 * Donne Ă  la classe le nom des champs sur lesquels on peut faire le tri
244
+	 *
245
+	 * @param  array $fields [clé] = nom du champ dans la base, valeur = libellé
246
+	 * @return object
247
+	 */
248
+	public function setSortFields($fields)
249
+	{
250
+		$this->sortFields = $fields;
251
+	}
252
+
253
+	/**
254
+	 * Retourne les noms à utiliser pour les champs de tri (sélecteur de champ et ordre de tri)
255
+	 *
256
+	 * @return array [0] = Nom du sélecteur de champs, [1] = Nom du sélecteur pour le sens du tri
257
+	 */
258
+	private function getSortPlaceHolderNames()
259
+	{
260
+		return array(self::PREFIX . 'sortFields', self::PREFIX . 'sortOrder');
261
+	}
262
+
263
+	/**
264
+	 * Retourne 2 sélecteurs html pour choisir la zone de tri et le sens du tri
265
+	 *
266
+	 * @return string
267
+	 */
268
+	public function getSortPlaceHolderHtmlCode()
269
+	{
270
+		$sortNames      = $this->getSortPlaceHolderNames();
271
+		$sortFieldsHtml = references_utils::htmlSelect($sortNames[0], $this->sortFields, $this->sortField, false);
272
+		$sortOrderHtml  = references_utils::htmlSelect($sortNames[1], array('asc' => _MD_REFERENCES_ASC, 'desc' => _MD_REFERENCES_DESC), $this->sortOrder, false);
273
+
274
+		return _MD_REFERENCES_SORT_BY . ' ' . $sortFieldsHtml . ' ' . $sortOrderHtml;
275
+	}
276
+
277
+	/**
278
+	 * Permet de valoriser une option directement tout en chainant
279
+	 *
280
+	 * @param  string $optionName
281
+	 * @param  mixed  $optionValue
282
+	 * @return object
283
+	 */
284
+	public function setOption($optionName, $optionValue)
285
+	{
286
+		$this->$optionName = $optionValue;
287
+
288
+		return $this;
289
+	}
290
+
291
+	/**
292
+	 * Ajoute un nouveau critère par défaut à la liste des critères par défaut
293
+	 *
294
+	 * @param Criteria $criteria
295
+	 */
296
+	public function addDefaultCriteria(Criteria $criteria)
297
+	{
298
+		$this->defaultCriterias[] = $criteria;
299
+	}
300
+
301
+	/**
302
+	 * Retourne une valeur d'un tableau ou null si l'index n'existe pas
303
+	 *
304
+	 * @param array   $array        Le tableau Ă  traiter
305
+	 * @param  string $index        L'index recherché
306
+	 * @param  mixed  $defaultValue La valeur par défaut
307
+	 * @return mixed
308
+	 */
309
+	private function getArrayValue($array, $index, $defaultValue = false)
310
+	{
311
+		if ($index === 'autoComplete' && isset($array[$index]) && isset($array[$index]) == true) {
312
+			$this->hasAutoComplete = true;    // On en profite pour vérifier si un champ utilise l'autocomplétion
313
+		}
314
+
315
+		return isset($array[$index]) ? $array[$index] : $defaultValue;
316
+	}
317
+
318
+	/**
319
+	 * Permet de faire l'autocomplétion d'un champ
320
+	 *
321
+	 * @param  string $query
322
+	 * @param         $limit
323
+	 * @param  string $fieldName
324
+	 * @return string
325
+	 */
326
+	public function autoComplete($query, $limit, $fieldName)
327
+	{
328
+		$return = '';
329
+		if (!$this->hasAutoComplete) {    // Si aucun champ n'est en autocomplétion, c'est pas la peine d'aller plus loin
330
+
331
+			return $return;
332
+		}
333
+		if (isset($this->vars[$fieldName])) {    // On vérifie que le champ demandé est bien en autocomplétion
334
+			if ($this->vars[$fieldName]['autoComplete'] == true) {
335
+				if ($this->vars[$fieldName]['dataType'] == self::FILTER_DATA_TEXT) {
336
+					$criteria = new Criteria($fieldName, $query . '%', 'LIKE');
337
+				}
338
+				$criteria->setLimit((int)$limit);
339
+				$ret = $this->handler->getObjects($criteria);
340
+
341
+				if (count($ret) > 0) {
342
+					foreach ($ret as $object) {
343
+						$return .= $object->getVar($fieldName, 'n') . "\n";
344
+					}
345
+				}
346
+			}
347
+		}
348
+
349
+		return $return;
350
+	}
351
+
352
+	/**
353
+	 * Retourne le code Javascript à utiliser pour initialiser l'auto complétion (et donc à coller dans le code html)
354
+	 *
355
+	 * @param boolean $jqueryAlreadyLoaded Indique si jQuery est déjà chargé par l'appelant, auquel cas rien ne sert de le recharger
356
+	 * @return string
357
+	 */
358
+	public function getJavascriptInitCode($jqueryAlreadyLoaded = false)
359
+	{
360
+		$return = '';
361
+		if (!$this->hasAutoComplete) {
362
+			return $return;
363
+		}
364
+		$return = '';
365
+		$return .= "<link rel=\"stylesheet\" type=\"text/css\" media=\"all\" title=\"Style sheet\" href=\"" . $this->jsFolderUrl . "autocomplete/jquery.autocomplete.css\" />\n";
366
+		if (!$jqueryAlreadyLoaded) {
367
+			$return .= "<script type=\"text/javascript\" src=\"" . $this->jsFolderUrl . "jquery/jquery.js\"></script>\n";
368
+		}
369
+		$return .= "<script type=\"text/javascript\" src=\"" . $this->jsFolderUrl . "noconflict.js\"></script>\n";
370
+		$return .= "<script type=\"text/javascript\" src=\"" . $this->jsFolderUrl . "autocomplete/jquery.autocomplete.min.js\"></script>\n";
371
+		$return .= "<script type=\"text/javascript\">\n";
372
+		$return .= "jQuery(function($) {\n";
373
+		$return .= "var url='" . $this->baseUrl . "';\n";    // TODO: Supprimer "var" car cela limite sa portée !
374
+		$return .= "var handlerName='" . $this->handler->className . "';\n";
375
+
376
+		foreach ($this->vars as $fieldName => $parameters) {
377
+			if ($parameters['autoComplete'] == true) {
378
+				$field = self::PREFIX . $fieldName;
379
+				$return .= "$('#" . $field . "').autocomplete(url, {\n";
380
+				$return .= "extraParams: {\n";
381
+				$return .= "    field: '" . $fieldName . "',\n";
382
+				$return .= "    op: 'autocomplete',\n";
383
+				$return .= "    handler: handlerName\n";
384
+				$return .= "}\n";
385
+				$return .= "});\n";
386
+			}
387
+		}
388
+		$return .= "});\n";
389
+		$return .= "</script>\n";
390
+
391
+		return $return;
392
+	}
393
+
394
+	/**
395
+	 * Initialisation des données du filtre
396
+	 * Permet d'indiquer quelles sont les zones sur lesquelles on effectue des filtres ainsi que leur type
397
+	 *
398
+	 * @param  string $fieldName  Le nom du champs dans la table
399
+	 * @param  array  $parameters Les paramètres de la zone sous la forme d'un tableau :
400
+	 *                            [dataType]        Entier représentant le type de donnée (numérique ou chaine)
401
+	 *                            [fieldType]       Le type de zone de saisie (zone de texte, liste déroulante, liste déroulante Oui/Non)
402
+	 *                            [values]      La ou les valeurs de la zone de saisie (utilisé dans le cas d'un select)
403
+	 *                            [size]            Largeur d'affichage pour les textbox
404
+	 *                            [maxLength]       Largeur maximale pour les textbox
405
+	 *                            [withNull]        Dans le cas des listes déroulantes, indique s'il faut une valeur nulle
406
+	 *                            [minusOne]        Indique s'il faut retrancher 1 à la valeur saisie récupérée (cas classique des listes Oui/Non avec une valeur nulle)
407
+	 *                            [style]            Dans le cas des liste déroulante, le style à appliquer à la liste
408
+	 *                            [data]            A ne pas renseigner, contient la valeur saisie par l'utilisateur
409
+	 *                            [operator]        Opérateur de comparaison pour le Criteria
410
+	 *                            [autoComplete]  Indique si on active l'auto complétion sur le champs
411
+	 * @return object L'objet courant pour pouvoir chainer
412
+	 */
413
+	public function initFilter($fieldName, $parameters)
414
+	{
415
+		// Tableau des valeurs attendues avec leur valeur par défaut
416
+		$indexNames = array('dataType' => self::FILTER_DATA_TEXT, 'fieldType' => self::FILTER_FIELD_TEXT, 'values' => null, 'withNull' => false, 'size' => 5, 'maxLength' => 255, 'minusOne' => false, 'data' => null, 'style' => '', 'operator' => '=', 'autoComplete' => false);
417
+		$data       = array();
418
+		foreach ($indexNames as $indexName => $defaultValue) {
419
+			$data[$indexName] = $this->getArrayValue($parameters, $indexName, $defaultValue);
420
+		}
421
+		$this->vars[$fieldName] = $data;
422
+
423
+		return $this;
424
+	}
425
+
426
+	/**
427
+	 * Retourne le nom du tableau Ă  utiliser pour la session
428
+	 * @note : Le nom de la session est composé de : nom du module_nom du handler, par exemple references_references_articles
429
+	 *
430
+	 * @return string
431
+	 */
432
+	private function getSessionName()
433
+	{
434
+		return self::MODULE_NAME . '_' . $this->handler->table;
435
+	}
436
+
437
+	/**
438
+	 * Retourne le nom de la clé à utiliser pour la conservation du start en session
439
+	 *
440
+	 * @return string
441
+	 */
442
+	private function getStartSessionName()
443
+	{
444
+		return $this->getSessionName() . '_start';
445
+	}
446
+
447
+	/**
448
+	 * Réinitialisation des données avant traitement
449
+	 *
450
+	 * @return void
451
+	 */
452
+	private function reinitializeFieldsValue()
453
+	{
454
+		foreach ($this->vars as $fieldName => $fieldProperties) {
455
+			if ($fieldProperties['dataType'] == self::FILTER_DATA_NUMERIC) {    // Zone numérique
456
+				$fieldProperties['data'] = 0;
457
+			} else {
458
+				$fieldProperties['data'] = '';
459
+			}
460
+			$this->vars[$fieldName] = $fieldProperties;
461
+		}
462
+	}
463
+
464
+	/**
465
+	 * Ajoute les critères par défaut au critère général
466
+	 *
467
+	 * @return void
468
+	 */
469
+	private function addDefaultCriterias()
470
+	{
471
+		if (is_array($this->defaultCriterias) && count($this->defaultCriterias) > 0) {
472
+			foreach ($this->defaultCriterias as $criteria) {
473
+				$this->criteria->add($criteria);
474
+			}
475
+		}
476
+
477
+		return $this;
478
+	}
479
+
480
+	/**
481
+	 * Indique s'il y a des champs de tri
482
+	 *
483
+	 * @return boolean
484
+	 */
485
+	private function areThereSortFields()
486
+	{
487
+		$return = false;
488
+		if (is_array($this->sortFields) && count($this->sortFields) > 0) {
489
+			$return = true;
490
+		}
491
+
492
+		return $return;
493
+	}
494
+
495
+	/**
496
+	 * Indique si le nom du champ passé en paramètre fait partie de la liste des champs "triables"
497
+	 *
498
+	 * @param  string $fieldName
499
+	 * @return boolean
500
+	 */
501
+	private function isInSortFieldsList($fieldName)
502
+	{
503
+		return array_key_exists($fieldName, $this->sortFields);
504
+	}
505
+
506
+	/**
507
+	 * Indique si le sens de tri passé en paramètre fait partie de la liste autorisée
508
+	 *
509
+	 * @param  string $order
510
+	 * @return boolean
511
+	 */
512
+	private function isInSortOrderList($order)
513
+	{
514
+		return in_array($order, array('asc', 'desc'));
515
+	}
516
+
517
+	/**
518
+	 * Récupère, depuis la requête d'entrée, la zone de tri à utiliser et le sens du tri et place l'information en cookie
519
+	 * pour que lorsque l'utilisateur se reconnecte, il retrouve ses informations de tri
520
+	 *
521
+	 * @return void
522
+	 */
523
+	private function setSortFieldsFromRequest()
524
+	{
525
+		if (!$this->areThereSortFields()) {    // S'il n'y a pas de champs triables, on laisse tomber
526
+
527
+			return;
528
+		}
529
+		$sortField        = $sortOrder = '';
530
+		$cookieName       = $this->getSessionName();
531
+		$orderFieldsNames = $this->getSortPlaceHolderNames();
532
+		if (isset($_REQUEST[$orderFieldsNames[0]]) && isset($_REQUEST[$orderFieldsNames[1]])) {
533
+			$sortField = $_REQUEST[$orderFieldsNames[0]];
534
+			$sortOrder = $_REQUEST[$orderFieldsNames[1]];
535
+		} else {
536
+			if (isset($_SESSION[$cookieName . '_sortField'])) {
537
+				$sortField = $_SESSION[$cookieName . '_sortField'];
538
+			}
539
+			if (isset($_SESSION[$cookieName . '_sortOrder'])) {
540
+				$sortOrder = $_SESSION[$cookieName . '_sortOrder'];
541
+			}
542
+		}
543
+
544
+		if ($this->isInSortFieldsList($sortField) && $this->isInSortOrderList($sortOrder)) {
545
+			$this->sortField = $sortField;
546
+			$this->sortOrder = $sortOrder;
547
+		}
548
+		if (trim($sortField) != '' && trim($sortOrder) != '') {
549
+			$_SESSION[$cookieName . '_sortField'] = $sortField;
550
+			$_SESSION[$cookieName . '_sortOrder'] = $sortOrder;
551
+		}
552
+	}
553
+
554
+	/**
555
+	 * Réinitialisation des données avant traitement
556
+	 *
557
+	 * @return void
558
+	 */
559
+	private function setupFilter()
560
+	{
561
+		$this->reinitializeFieldsValue();
562
+		$this->newFilter     = false;
563
+		$this->isInitialized = true;
564
+		$this->criteria      = new CriteriaCompo();
565
+		$this->criteria->add(new Criteria($this->handler->keyName, 0, '<>'));
566
+		$this->addDefaultCriterias();
567
+	}
568
+
569
+	/**
570
+	 * RAZ des données du filtre si cela a été demandé dans la requête
571
+	 *
572
+	 * @return void
573
+	 */
574
+	private function isSetCleanFilter()
575
+	{
576
+		if (isset($_REQUEST['cleanFilter'])) {
577
+			$this->setStartInSession(0);
578
+			unset($_SESSION[$this->getSessionName()]);
579
+		}
580
+	}
581
+
582
+	/**
583
+	 * Retourne le critère de filtrage courant
584
+	 *
585
+	 * @return object
586
+	 */
587
+	public function getCriteria()
588
+	{
589
+		return $this->criteria;
590
+	}
591
+
592
+	/**
593
+	 * Méthode à appeler juste après le constructeur pour qu'elle récupère les données saisies
594
+	 *
595
+	 * @return object L'objet courant pour pouvoir chainer
596
+	 */
597
+	public function filter()
598
+	{
599
+		$this->setupFilter();                // Réinitialisations
600
+		$ts = MyTextSanitizer::getInstance();
601
+		$this->setSortFieldsFromRequest();    // On récupère la zone de tri éventuellement passée dans la requête
602
+		$this->isSetCleanFilter();
603
+
604
+		foreach ($this->vars as $fieldName => $fieldProperties) {
605
+			// On commence par récupérer toutes les valeurs
606
+			$formFieldName           = self::PREFIX . $fieldName;    // "filter_website_id" par exemple
607
+			$fieldProperties['data'] = null;    // Valeur par défaut
608
+			if (isset($_REQUEST[$formFieldName])) {
609
+				if ($fieldProperties['dataType'] == self::FILTER_DATA_NUMERIC) {    // Zone numérique
610
+					if ((int)$_REQUEST[$formFieldName] != 0) {
611
+						$fieldProperties['data'] = (int)$_REQUEST[$formFieldName];
612
+						if (!$fieldProperties['minusOne']) {
613
+							$this->criteria->add(new Criteria($fieldName, $fieldProperties['data'], $fieldProperties['operator']));
614
+						} else {
615
+							$this->criteria->add(new Criteria($fieldName, $fieldProperties['data'] - 1, $fieldProperties['operator']));
616
+						}
617
+						$this->newFilter = true;
618
+					}
619
+				} else {    // Zone texte
620
+					if (trim($_REQUEST[$formFieldName]) != '') {
621
+						$fieldProperties['data'] = $_REQUEST[$formFieldName];
622
+						if (!REFERENCES_EXACT_SEARCH) {
623
+							$this->criteria->add(new Criteria($fieldName, '%' . $ts->addSlashes($fieldProperties['data']) . '%', 'LIKE'));
624
+						} else {
625
+							$this->criteria->add(new Criteria($fieldName, $ts->addSlashes($fieldProperties['data']) . '%', 'LIKE'));
626
+						}
627
+						$this->newFilter = true;
628
+					}
629
+				}
630
+			}
631
+			$this->vars[$fieldName] = $fieldProperties;
632
+		}
633
+
634
+		if ($this->newFilter) {
635
+			$this->setStartInSession(0);
636
+		}
637
+
638
+		// Récupération des donées de la session s'il n'y a pas eu de filtre(s)
639
+		if (!$this->newFilter && isset($_SESSION[$this->getSessionName()])) {
640
+			$sessionFilterData = unserialize($_SESSION[$this->getSessionName()]);
641
+			if (isset($sessionFilterData['criteria']) && is_object($sessionFilterData['criteria'])) {
642
+				$this->criteria = $sessionFilterData['criteria'];
643
+				unset($sessionFilterData['criteria']);
644
+			}
645
+			foreach ($this->vars as $fieldName => $fieldProperties) {
646
+				if (isset($sessionFilterData[$fieldName])) {
647
+					$fieldProperties['data'] = $sessionFilterData[$fieldName];
648
+				}
649
+				$this->vars[$fieldName] = $fieldProperties;
650
+			}
651
+			unset($_SESSION[$this->getSessionName()]);
652
+		}
653
+
654
+		// Mise en place des données dans la session
655
+		$dataForSession             = array();
656
+		$dataForSession['criteria'] = $this->criteria;
657
+		foreach ($this->vars as $fieldName => $fieldProperties) {
658
+			$dataForSession[$fieldName] = $fieldProperties['data'];
659
+		}
660
+		$_SESSION[$this->getSessionName()] = serialize($dataForSession);
661
+
662
+		return $this;
663
+	}
664
+
665
+	/**
666
+	 * Retourne le nombre d'enregistrement en fonction des critères courants
667
+	 *
668
+	 * @return integer
669
+	 */
670
+	public function getCount()
671
+	{
672
+		if (!$this->isInitialized) {
673
+			$this->filter();
674
+		}
675
+
676
+		return $this->handler->getCount($this->criteria);
677
+	}
678
+
679
+	/**
680
+	 * Conserve la valeur de start en session
681
+	 *
682
+	 * @param  integer $start
683
+	 * @return void
684
+	 */
685
+	private function setStartInSession($start)
686
+	{
687
+		if ($this->keepStart) {
688
+			$startSessionName            = $this->getStartSessionName();
689
+			$_SESSION[$startSessionName] = (int)$start;
690
+		}
691
+	}
692
+
693
+	/**
694
+	 * Retourne la valeur de ?start=x
695
+	 *
696
+	 * @return integer
697
+	 */
698
+	private function getStartValue()
699
+	{
700
+		$start = 0;
701
+		if (isset($_REQUEST[$this->startName])) {
702
+			$start = (int)$_REQUEST[$this->startName];
703
+		} elseif ($this->keepStart) {
704
+			$startSessionName = $this->getStartSessionName();
705
+			if (isset($_SESSION[$startSessionName])) {
706
+				$start = (int)$_SESSION[$startSessionName];
707
+			}
708
+		}
709
+		// Mise en session
710
+		$this->setStartInSession($start);
711
+
712
+		return $start;
713
+	}
714
+
715
+	/**
716
+	 * Permet d'ajouter un paramètre supplémentaire au pager
717
+	 *
718
+	 * @param  string $key
719
+	 * @param  string $value
720
+	 * @return object
721
+	 */
722
+	public function addAdditionnalParameterToPager($key, $value = '')
723
+	{
724
+		$this->additionnalPagerParameters[$key] = $value;
725
+
726
+		return $this;
727
+	}
728
+
729
+	/**
730
+	 * Permet d'ajouter un paramètre supplémentaire au bouton permettant de supprimer le filtre
731
+	 *
732
+	 * @param  string $key
733
+	 * @param  string $value
734
+	 * @return object
735
+	 */
736
+	public function addAdditionnalParameterToClearButton($key, $value = '')
737
+	{
738
+		$this->additionnalClearButtonParameters[$key] = $value;
739
+
740
+		return $this;
741
+	}
742
+
743
+	/**
744
+	 * Permet d'ajouter des paramètres supplémentaires au pager
745
+	 *
746
+	 * @param $array
747
+	 * @return object
748
+	 * @internal param string $key
749
+	 * @internal param string $value
750
+	 */
751
+	public function addAditionnalArrayParametersToPager($array)
752
+	{
753
+		if (count($array) > 0) {
754
+			foreach ($array as $key => $value) {
755
+				$this->addAdditionnalParameterToPager($key, $value);
756
+			}
757
+		}
758
+
759
+		return $this;
760
+	}
761
+
762
+	/**
763
+	 * Retourne le pager Ă  utiliser
764
+	 *
765
+	 * @return mixed Null s'il n'y a pas lieu d'y avoir un pager, sinon un objet de type {@link XoopsPageNav}
766
+	 */
767
+	public function getPager()
768
+	{
769
+		if (!$this->isInitialized) {
770
+			$this->filter();
771
+		}
772
+		require_once XOOPS_ROOT_PATH . '/class/pagenav.php';
773
+		$itemsCount  = $this->getCount();
774
+		$queryString = array();
775
+		if (trim($this->op) != '') {
776
+			$queryString[$this->operationName] = $this->op;
777
+		}
778
+		$pagenav = null;
779
+
780
+		if ($itemsCount > $this->limit) {
781
+			foreach ($this->vars as $fieldName => $fieldProperties) {
782
+				$formFieldName               = self::PREFIX . $fieldName;    // "filter_website_id" par exemple
783
+				$queryString[$formFieldName] = $fieldProperties['data'];
784
+			}
785
+			// Ajout des paramètres supplémentaires éventuels
786
+			if (count($this->additionnalPagerParameters) > 0) {
787
+				foreach ($this->additionnalPagerParameters as $key => $value) {
788
+					$queryString[$key] = $value;
789
+				}
790
+			}
791
+			$start   = $this->getStartValue();
792
+			$pagenav = new XoopsPageNav($itemsCount, $this->limit, $start, $this->startName, http_build_query($queryString));
793
+		}
794
+
795
+		return $pagenav;
796
+	}
797
+
798
+	/**
799
+	 * Retourne une liste d'objets en fonction des critères définis
800
+	 *
801
+	 * @return array
802
+	 */
803
+	public function getObjects()
804
+	{
805
+		if (!$this->isInitialized) {
806
+			$this->filter();
807
+		}
808
+		$start    = $this->getStartValue();
809
+		$limit    = $this->limit;
810
+		$criteria = $this->criteria;
811
+		$criteria->setStart($start);
812
+		$criteria->setLimit($limit);
813
+
814
+		$criteria->setOrder($this->sortOrder);
815
+		if (trim($this->sortField) != '') {
816
+			$criteria->setSort($this->sortField);
817
+		} elseif (trim($this->handler->identifierName) != '') {
818
+			$criteria->setSort($this->handler->identifierName);
819
+		}
820
+
821
+		return $this->handler->getObjects($this->criteria);
822
+	}
823
+
824
+	/**
825
+	 * Retourne la zone html à utiliser pour créer la zone de filtre (avec sa valeur saisie si c'est le cas)
826
+	 *
827
+	 * @param  string $fieldName La zone de saisie dont on veut récupérer le code html
828
+	 * @return string
829
+	 */
830
+	public function getFilterField($fieldName)
831
+	{
832
+		$html = '';
833
+		if (!$this->isInitialized) {
834
+			$this->filter();
835
+		}
836
+		if (!isset($this->vars[$fieldName])) {
837
+			trigger_error('Error, unknow field');
838
+
839
+			return $html;
840
+		}
841
+		$fieldData     = $this->vars[$fieldName];
842
+		$htmlFieldName = self::PREFIX . $fieldName;
843
+
844
+		switch ($fieldData['fieldType']) {
845
+			case self::FILTER_FIELD_TEXT:    // Zone de texte
846
+				$ts   = MyTextSanitizer::getInstance();
847
+				$html = "<input type='text' name='$htmlFieldName' id='$htmlFieldName' size='" . $fieldData['size'] . "' maxlength='" . $fieldData['maxLength'] . "' value='" . $ts->htmlSpecialChars($fieldData['data']) . "' />";
848
+				break;
849
+
850
+			case self::FILTER_FIELD_SELECT;     // Select
851
+				$style = '';
852
+				if (isset($fieldData['style']) && trim($fieldData['style']) != '') {
853
+					$style = $fieldData['style'];
854
+				}
855
+				$html = references_utils::htmlSelect($htmlFieldName, $fieldData['values'], $fieldData['data'], $fieldData['withNull'], $style);
856
+				break;
857
+
858
+			case self::FILTER_FIELD_SELECT_YES_NO:    // Select de type Oui/Non
859
+				$html = references_utils::htmlSelect($htmlFieldName, array(2 => _YES, 1 => NO), $fieldData['data'], $fieldData['withNull']);
860
+				break;
861
+		}
862
+
863
+		return $html;
864
+	}
865
+
866
+	/**
867
+	 * Assigne toutes les zones de filtre Ă  un template
868
+	 *
869
+	 * @param  object  $xoopsTpl
870
+	 * @param  boolean $asArray   Est-ce qu'il faut placer le résultat dans un tableau ou assigner par nom de zone de filtre
871
+	 * @param string   $arrayName Le nom du tableau Ă  utiliser
872
+	 * @return void
873
+	 */
874
+	public function assignFilterFieldsToTemplate(&$xoopsTpl, $asArray = true, $arrayName = 'filterFields')
875
+	{
876
+		$fields = array_keys($this->vars);
877
+		foreach ($fields as $field) {
878
+			if (!$asArray) {
879
+				$xoopsTpl->assign($field, $this->getFilterField($field));
880
+			} else {
881
+				$xoopsTpl->append($arrayName, $this->getFilterField($field));
882
+			}
883
+		}
884
+	}
885
+
886
+	/**
887
+	 * Retourne le bouton utilisé pour supprimer le filtre en cours
888
+	 *
889
+	 * @return string
890
+	 */
891
+	public function getClearFilterbutton()
892
+	{
893
+		$queryString                       = array();
894
+		$queryString[$this->operationName] = $this->op;
895
+		if (count($this->additionnalClearButtonParameters) > 0) {
896
+			foreach ($this->additionnalClearButtonParameters as $key => $value) {
897
+				$queryString[$key] = $value;
898
+			}
899
+		}
900
+		$queryString['cleanFilter'] = '1';
901
+		$baseurl                    = $this->baseUrl;
902
+
903
+		return "&nbsp;&nbsp;<a href='$baseurl?" . http_build_query($queryString) . "' title='" . _MD_REFERENCES_CLEAN_FILTER . "'><img align='top' src='../assets/images/clear_left.png' alt='" . _MD_REFERENCES_CLEAN_FILTER . "' /></a>";
904
+	}
905
+
906
+	/**
907
+	 * Retourne le bouton permettant de lancer le filtrage
908
+	 *
909
+	 * @param string $description  Texte à faire apparaître sur le bouton
910
+	 * @param array  $additionnals Champs supplémentaires à faire apparaître avec le bouton
911
+	 * @return string
912
+	 */
913
+	public function getGoButton($description = _GO, $additionnals = null)
914
+	{
915
+		$html = '';
916
+		if (trim($this->operationName) != '' && trim($this->op) != '') {
917
+			$html .= "<input type='hidden' name='" . $this->operationName . "' id='" . $this->operationName . "' value='" . $this->op . "' />";
918
+		}
919
+		if (!is_null($additionnals)) {
920
+			foreach ($additionnals as $key => $value) {
921
+				$html .= "<input type='hidden' name='" . $key . "' id='" . $key . "' value='" . $value . "' />";
922
+			}
923
+		}
924
+		$html .= "<input type='submit' name='btngo' id='btngo' value='$description' />";
925
+
926
+		return $html;
927
+	}
928
+
929
+	/**
930
+	 * Retourne le nom de la zone utilisée pour trier les données
931
+	 *
932
+	 * @return string
933
+	 */
934
+	public function getSortField()
935
+	{
936
+		return $this->sortField;
937
+	}
938
+
939
+	/**
940
+	 * Retourne le sens de tri utilisé pour trier les données
941
+	 *
942
+	 * @return string
943
+	 */
944
+	public function getSortOrder()
945
+	{
946
+		return $this->sortOrder();
947
+	}
948
+
949
+	/**
950
+	 * Retourne la valeur d'un champ
951
+	 *
952
+	 * @param  string $fieldName
953
+	 * @return mixed  La valeur du champ ou null si on ne trouve pas la zone
954
+	 */
955
+	public function getFieldValue($fieldName)
956
+	{
957
+		$ret = null;
958
+		if (isset($this->vars[$fieldName])) {
959
+			$ret = $this->vars[$fieldName]['data'];
960
+		}
961
+
962
+		return $ret;
963
+	}
964 964
 }
Please login to merge, or discard this patch.
class/references_plugins.php 1 patch
Indentation   +236 added lines, -236 removed lines patch added patch discarded remove patch
@@ -25,266 +25,266 @@
 block discarded – undo
25 25
  */
26 26
 class references_plugins
27 27
 {
28
-    /**
29
-     * Dictionnaire des évènements
30
-     */
31
-    const EVENT_ON_REFERENCE_CREATE = 'onReferenceCreate';
32
-    const EVENT_ON_CATEGORY_CREATE  = 'onCategoryCreate';
28
+	/**
29
+	 * Dictionnaire des évènements
30
+	 */
31
+	const EVENT_ON_REFERENCE_CREATE = 'onReferenceCreate';
32
+	const EVENT_ON_CATEGORY_CREATE  = 'onCategoryCreate';
33 33
 
34
-    // Pour limiter les dépendances
35
-    const MODULE_DIRNAME = REFERENCES_DIRNAME;
34
+	// Pour limiter les dépendances
35
+	const MODULE_DIRNAME = REFERENCES_DIRNAME;
36 36
 
37
-    /**
38
-     * Types d'évènements
39
-     */
40
-    const PLUGIN_ACTION = 0;
41
-    const PLUGIN_FILTER = 1;
37
+	/**
38
+	 * Types d'évènements
39
+	 */
40
+	const PLUGIN_ACTION = 0;
41
+	const PLUGIN_FILTER = 1;
42 42
 
43
-    /**
44
-     * Nom du script Php inclut qui contient l'inscription des plugins
45
-     */
46
-    const PLUGIN_SCRIPT_NAME = 'plugins.php';
43
+	/**
44
+	 * Nom du script Php inclut qui contient l'inscription des plugins
45
+	 */
46
+	const PLUGIN_SCRIPT_NAME = 'plugins.php';
47 47
 
48
-    /**
49
-     * Dans le fichier Php qui contient l'inscription des plugins, méthode à appeler pour récupérer la liste des plugins
50
-     */
51
-    const PLUGIN_DESCRIBE_METHOD = 'registerEvents';
48
+	/**
49
+	 * Dans le fichier Php qui contient l'inscription des plugins, méthode à appeler pour récupérer la liste des plugins
50
+	 */
51
+	const PLUGIN_DESCRIBE_METHOD = 'registerEvents';
52 52
 
53
-    /**
54
-     * Nom de la variable de session qui contient la liste des plugins détachés
55
-     */
56
-    const PLUGIN_UNPLUG_SESSION_NAME = 'references_plugins';
53
+	/**
54
+	 * Nom de la variable de session qui contient la liste des plugins détachés
55
+	 */
56
+	const PLUGIN_UNPLUG_SESSION_NAME = 'references_plugins';
57 57
 
58
-    /**
59
-     * Priorités des plugins
60
-     * @var constant
61
-     */
62
-    const EVENT_PRIORITY_1 = 1;    // Priorité la plus haute
63
-    const EVENT_PRIORITY_2 = 2;
64
-    const EVENT_PRIORITY_3 = 3;
65
-    const EVENT_PRIORITY_4 = 4;
66
-    const EVENT_PRIORITY_5 = 5;    // Priorité la plus basse
58
+	/**
59
+	 * Priorités des plugins
60
+	 * @var constant
61
+	 */
62
+	const EVENT_PRIORITY_1 = 1;    // Priorité la plus haute
63
+	const EVENT_PRIORITY_2 = 2;
64
+	const EVENT_PRIORITY_3 = 3;
65
+	const EVENT_PRIORITY_4 = 4;
66
+	const EVENT_PRIORITY_5 = 5;    // Priorité la plus basse
67 67
 
68
-    /**
69
-     * Utilisé pour construire le nom de la classe
70
-     */
71
-    private $pluginsTypeLabel = array(self::PLUGIN_ACTION => 'Action', self::PLUGIN_FILTER => 'Filter');
68
+	/**
69
+	 * Utilisé pour construire le nom de la classe
70
+	 */
71
+	private $pluginsTypeLabel = array(self::PLUGIN_ACTION => 'Action', self::PLUGIN_FILTER => 'Filter');
72 72
 
73
-    /**
74
-     * Nom des classes qu'il faut étendre en tant que plugin
75
-     */
76
-    private $pluginsClassName = array(self::PLUGIN_ACTION => 'references_action', self::PLUGIN_FILTER => 'references_filter');
73
+	/**
74
+	 * Nom des classes qu'il faut étendre en tant que plugin
75
+	 */
76
+	private $pluginsClassName = array(self::PLUGIN_ACTION => 'references_action', self::PLUGIN_FILTER => 'references_filter');
77 77
 
78
-    /**
79
-     * Nom de chacun des dossiers en fonction du type de plugin
80
-     */
81
-    private $pluginsTypesFolder = array(self::PLUGIN_ACTION => 'actions', self::PLUGIN_FILTER => 'filters');
78
+	/**
79
+	 * Nom de chacun des dossiers en fonction du type de plugin
80
+	 */
81
+	private $pluginsTypesFolder = array(self::PLUGIN_ACTION => 'actions', self::PLUGIN_FILTER => 'filters');
82 82
 
83
-    /**
84
-     * Contient l'unique instance de l'objet
85
-     * @var object
86
-     */
87
-    private static $instance = false;
83
+	/**
84
+	 * Contient l'unique instance de l'objet
85
+	 * @var object
86
+	 */
87
+	private static $instance = false;
88 88
 
89
-    /**
90
-     * Liste des évènements
91
-     * @var array
92
-     */
93
-    private static $events = array();
89
+	/**
90
+	 * Liste des évènements
91
+	 * @var array
92
+	 */
93
+	private static $events = array();
94 94
 
95
-    /**
96
-     * Retourne l'instance unique de la classe
97
-     *
98
-     * @return object
99
-     */
100
-    public static function getInstance()
101
-    {
102
-        static $instance;
103
-        if (null === $instance) {
104
-            $instance = new static();
105
-        }
95
+	/**
96
+	 * Retourne l'instance unique de la classe
97
+	 *
98
+	 * @return object
99
+	 */
100
+	public static function getInstance()
101
+	{
102
+		static $instance;
103
+		if (null === $instance) {
104
+			$instance = new static();
105
+		}
106 106
 
107
-        return $instance;
108
-    }
107
+		return $instance;
108
+	}
109 109
 
110
-    /**
111
-     * Chargement des 2 types de plugins
112
-     *
113
-     */
114
-    private function __construct()
115
-    {
116
-        $this->events = array();
117
-        $this->loadPlugins();
118
-    }
110
+	/**
111
+	 * Chargement des 2 types de plugins
112
+	 *
113
+	 */
114
+	private function __construct()
115
+	{
116
+		$this->events = array();
117
+		$this->loadPlugins();
118
+	}
119 119
 
120
-    /**
121
-     * Chargement des plugins (actions et filtres)
122
-     * @return void
123
-     */
124
-    public function loadPlugins()
125
-    {
126
-        $this->loadPluginsFiles(REFERENCES_PLUGINS_PATH . $this->pluginsTypesFolder[self::PLUGIN_ACTION], self::PLUGIN_ACTION);
127
-        $this->loadPluginsFiles(REFERENCES_PLUGINS_PATH . $this->pluginsTypesFolder[self::PLUGIN_FILTER], self::PLUGIN_FILTER);
128
-    }
120
+	/**
121
+	 * Chargement des plugins (actions et filtres)
122
+	 * @return void
123
+	 */
124
+	public function loadPlugins()
125
+	{
126
+		$this->loadPluginsFiles(REFERENCES_PLUGINS_PATH . $this->pluginsTypesFolder[self::PLUGIN_ACTION], self::PLUGIN_ACTION);
127
+		$this->loadPluginsFiles(REFERENCES_PLUGINS_PATH . $this->pluginsTypesFolder[self::PLUGIN_FILTER], self::PLUGIN_FILTER);
128
+	}
129 129
 
130
-    /**
131
-     * Vérifie que le fichier Php passé en paramètre contient bien une classe de filtre ou d'action et si c'est le cas, le charge dans la liste des plugins
132
-     * @param string  $fullPathName Chemin complet vers le fichier (répertoire + nom)
133
-     * @param integer $type         Type de plugin recherché (action ou filtre)
134
-     * @param string  $pluginFolder Le nom du répertoire dans lequel se trouve le fichier (le "dernier nom")
135
-     * @return void
136
-     */
137
-    private function loadClass($fullPathName, $type, $pluginFolder)
138
-    {
139
-        require_once $fullPathName;
140
-        // Du style referencesRegionalizationFilter
141
-        $className = self::MODULE_DIRNAME . ucfirst(strtolower($pluginFolder)) . $this->pluginsTypeLabel[$type];
142
-        if (class_exists($className) && get_parent_class($className) == $this->pluginsClassName[$type]) {
143
-            // TODO: Vérifier que l'évènement n'est pas déjà en mémoire
144
-            $events = call_user_func(array($className, self::PLUGIN_DESCRIBE_METHOD));
145
-            foreach ($events as $event) {
146
-                $eventName                                         = $event[0];
147
-                $eventPriority                                     = $event[1];
148
-                $fileToInclude                                     = REFERENCES_PLUGINS_PATH . $this->pluginsTypesFolder[$type] . DIRECTORY_SEPARATOR . $pluginFolder . DIRECTORY_SEPARATOR . $event[2];
149
-                $classToCall                                       = $event[3];
150
-                $methodToCall                                      = $event[4];
151
-                $this->events[$type][$eventName][$eventPriority][] = array('fullPathName' => $fileToInclude, 'className' => $classToCall, 'method' => $methodToCall);
152
-            }
153
-        }
154
-    }
130
+	/**
131
+	 * Vérifie que le fichier Php passé en paramètre contient bien une classe de filtre ou d'action et si c'est le cas, le charge dans la liste des plugins
132
+	 * @param string  $fullPathName Chemin complet vers le fichier (répertoire + nom)
133
+	 * @param integer $type         Type de plugin recherché (action ou filtre)
134
+	 * @param string  $pluginFolder Le nom du répertoire dans lequel se trouve le fichier (le "dernier nom")
135
+	 * @return void
136
+	 */
137
+	private function loadClass($fullPathName, $type, $pluginFolder)
138
+	{
139
+		require_once $fullPathName;
140
+		// Du style referencesRegionalizationFilter
141
+		$className = self::MODULE_DIRNAME . ucfirst(strtolower($pluginFolder)) . $this->pluginsTypeLabel[$type];
142
+		if (class_exists($className) && get_parent_class($className) == $this->pluginsClassName[$type]) {
143
+			// TODO: Vérifier que l'évènement n'est pas déjà en mémoire
144
+			$events = call_user_func(array($className, self::PLUGIN_DESCRIBE_METHOD));
145
+			foreach ($events as $event) {
146
+				$eventName                                         = $event[0];
147
+				$eventPriority                                     = $event[1];
148
+				$fileToInclude                                     = REFERENCES_PLUGINS_PATH . $this->pluginsTypesFolder[$type] . DIRECTORY_SEPARATOR . $pluginFolder . DIRECTORY_SEPARATOR . $event[2];
149
+				$classToCall                                       = $event[3];
150
+				$methodToCall                                      = $event[4];
151
+				$this->events[$type][$eventName][$eventPriority][] = array('fullPathName' => $fileToInclude, 'className' => $classToCall, 'method' => $methodToCall);
152
+			}
153
+		}
154
+	}
155 155
 
156
-    /**
157
-     * Part à la recherche d'un type de plugin dans les répertoires
158
-     *
159
-     * @param  string $path La racine
160
-     * @param integer $type Le type de plugin recherché (action ou filtre)
161
-     * @return void
162
-     */
163
-    private function loadPluginsFiles($path, $type)
164
-    {
165
-        $objects = new DirectoryIterator($path);
166
-        foreach ($objects as $object) {
167
-            if ($object->isDir() && !$object->isDot()) {
168
-                $file = $path . DIRECTORY_SEPARATOR . $object->current() . DIRECTORY_SEPARATOR . self::PLUGIN_SCRIPT_NAME;
169
-                if (file_exists($file)) {
170
-                    $this->loadClass($file, $type, $object->current());
171
-                }
172
-            }
173
-        }
174
-    }
156
+	/**
157
+	 * Part à la recherche d'un type de plugin dans les répertoires
158
+	 *
159
+	 * @param  string $path La racine
160
+	 * @param integer $type Le type de plugin recherché (action ou filtre)
161
+	 * @return void
162
+	 */
163
+	private function loadPluginsFiles($path, $type)
164
+	{
165
+		$objects = new DirectoryIterator($path);
166
+		foreach ($objects as $object) {
167
+			if ($object->isDir() && !$object->isDot()) {
168
+				$file = $path . DIRECTORY_SEPARATOR . $object->current() . DIRECTORY_SEPARATOR . self::PLUGIN_SCRIPT_NAME;
169
+				if (file_exists($file)) {
170
+					$this->loadClass($file, $type, $object->current());
171
+				}
172
+			}
173
+		}
174
+	}
175 175
 
176
-    /**
177
-     * Déclenchement d'une action et appel des plugins liés
178
-     *
179
-     * @param string                       $eventToFire L'action déclenchée
180
-     * @param object|references_parameters $parameters  Les paramètres à passer à chaque plugin
181
-     * @return object L'objet lui même pour chaîner
182
-     */
183
-    public function fireAction($eventToFire, references_parameters $parameters = null)
184
-    {
185
-        if (!isset($this->events[self::PLUGIN_ACTION][$eventToFire])) {
186
-            trigger_error(sprintf(_MD_REFERENCES_PLUGINS_ERROR_1, $eventToFire));
176
+	/**
177
+	 * Déclenchement d'une action et appel des plugins liés
178
+	 *
179
+	 * @param string                       $eventToFire L'action déclenchée
180
+	 * @param object|references_parameters $parameters  Les paramètres à passer à chaque plugin
181
+	 * @return object L'objet lui même pour chaîner
182
+	 */
183
+	public function fireAction($eventToFire, references_parameters $parameters = null)
184
+	{
185
+		if (!isset($this->events[self::PLUGIN_ACTION][$eventToFire])) {
186
+			trigger_error(sprintf(_MD_REFERENCES_PLUGINS_ERROR_1, $eventToFire));
187 187
 
188
-            return $this;
189
-        }
190
-        ksort($this->events[self::PLUGIN_ACTION][$eventToFire]);    // Tri par prioritďż˝
191
-        foreach ($this->events[self::PLUGIN_ACTION][$eventToFire] as $priority => $events) {
192
-            foreach ($events as $event) {
193
-                if ($this->isUnplug(self::PLUGIN_ACTION, $eventToFire, $event['fullPathName'], $event['className'], $event['method'])) {
194
-                    continue;
195
-                }
196
-                require_once $event['fullPathName'];
197
-                if (!class_exists($event['className'])) {
198
-                    $class = new $event['className'];
199
-                }
200
-                if (!method_exists($event['className'], $event['method'])) {
201
-                    continue;
202
-                }
203
-                call_user_func(array($event['className'], $event['method']), $parameters);
204
-                unset($class);
205
-            }
206
-        }
188
+			return $this;
189
+		}
190
+		ksort($this->events[self::PLUGIN_ACTION][$eventToFire]);    // Tri par prioritďż˝
191
+		foreach ($this->events[self::PLUGIN_ACTION][$eventToFire] as $priority => $events) {
192
+			foreach ($events as $event) {
193
+				if ($this->isUnplug(self::PLUGIN_ACTION, $eventToFire, $event['fullPathName'], $event['className'], $event['method'])) {
194
+					continue;
195
+				}
196
+				require_once $event['fullPathName'];
197
+				if (!class_exists($event['className'])) {
198
+					$class = new $event['className'];
199
+				}
200
+				if (!method_exists($event['className'], $event['method'])) {
201
+					continue;
202
+				}
203
+				call_user_func(array($event['className'], $event['method']), $parameters);
204
+				unset($class);
205
+			}
206
+		}
207 207
 
208
-        return $this;
209
-    }
208
+		return $this;
209
+	}
210 210
 
211
-    /**
212
-     * Déclenchement d'un filtre et appel des plugins liés
213
-     *
214
-     * @param string                       $eventToFire Le filtre appelé
215
-     * @param object|references_parameters $parameters  Les paramètres à passer à chaque plugin
216
-     * @return object Le contenu de l'objet passé en paramètre
217
-     */
218
-    public function fireFilter($eventToFire, references_parameters $parameters)
219
-    {
220
-        if (!isset($this->events[self::PLUGIN_FILTER][$eventToFire])) {
221
-            trigger_error(sprintf(_MD_REFERENCES_PLUGINS_ERROR_1, $eventToFire));
211
+	/**
212
+	 * Déclenchement d'un filtre et appel des plugins liés
213
+	 *
214
+	 * @param string                       $eventToFire Le filtre appelé
215
+	 * @param object|references_parameters $parameters  Les paramètres à passer à chaque plugin
216
+	 * @return object Le contenu de l'objet passé en paramètre
217
+	 */
218
+	public function fireFilter($eventToFire, references_parameters $parameters)
219
+	{
220
+		if (!isset($this->events[self::PLUGIN_FILTER][$eventToFire])) {
221
+			trigger_error(sprintf(_MD_REFERENCES_PLUGINS_ERROR_1, $eventToFire));
222 222
 
223
-            return $this;
224
-        }
225
-        ksort($this->events[self::PLUGIN_FILTER][$eventToFire]);    // Tri par priorité
226
-        foreach ($this->events[self::PLUGIN_FILTER][$eventToFire] as $priority => $events) {
227
-            foreach ($events as $event) {
228
-                if ($this->isUnplug(self::PLUGIN_FILTER, $eventToFire, $event['fullPathName'], $event['className'], $event['method'])) {
229
-                    continue;
230
-                }
231
-                require_once $event['fullPathName'];
232
-                if (!method_exists($event['className'], $event['method'])) {
233
-                    continue;
234
-                }
235
-                //if (!class_exists($event['className'])) {
236
-                $class = new $event['className'];
237
-                //}
238
-                $class->$event['method']($parameters);
239
-                //call_user_func(array($event['className'], $event['method']), $parameters);
240
-                unset($class);
241
-            }
242
-        }
223
+			return $this;
224
+		}
225
+		ksort($this->events[self::PLUGIN_FILTER][$eventToFire]);    // Tri par priorité
226
+		foreach ($this->events[self::PLUGIN_FILTER][$eventToFire] as $priority => $events) {
227
+			foreach ($events as $event) {
228
+				if ($this->isUnplug(self::PLUGIN_FILTER, $eventToFire, $event['fullPathName'], $event['className'], $event['method'])) {
229
+					continue;
230
+				}
231
+				require_once $event['fullPathName'];
232
+				if (!method_exists($event['className'], $event['method'])) {
233
+					continue;
234
+				}
235
+				//if (!class_exists($event['className'])) {
236
+				$class = new $event['className'];
237
+				//}
238
+				$class->$event['method']($parameters);
239
+				//call_user_func(array($event['className'], $event['method']), $parameters);
240
+				unset($class);
241
+			}
242
+		}
243 243
 
244
-        if (!is_null($parameters)) {
245
-            return $parameters;
246
-        }
247
-    }
244
+		if (!is_null($parameters)) {
245
+			return $parameters;
246
+		}
247
+	}
248 248
 
249
-    /**
250
-     * Indique si un plugin s'est détaché d'un évènement particulier
251
-     *
252
-     * @param  integer $eventType
253
-     * @param  string  $eventToFire
254
-     * @param  string  $fullPathName
255
-     * @param  string  $className
256
-     * @param  string  $method
257
-     * @return boolean
258
-     */
259
-    public function isUnplug($eventType, $eventToFire, $fullPathName, $className, $method)
260
-    {
261
-        $unplug = array();
262
-        if (isset($_SESSION[self::PLUGIN_UNPLUG_SESSION_NAME])) {
263
-            $unplug = $_SESSION[self::PLUGIN_UNPLUG_SESSION_NAME];
264
-        } else {
265
-            return false;
266
-        }
249
+	/**
250
+	 * Indique si un plugin s'est détaché d'un évènement particulier
251
+	 *
252
+	 * @param  integer $eventType
253
+	 * @param  string  $eventToFire
254
+	 * @param  string  $fullPathName
255
+	 * @param  string  $className
256
+	 * @param  string  $method
257
+	 * @return boolean
258
+	 */
259
+	public function isUnplug($eventType, $eventToFire, $fullPathName, $className, $method)
260
+	{
261
+		$unplug = array();
262
+		if (isset($_SESSION[self::PLUGIN_UNPLUG_SESSION_NAME])) {
263
+			$unplug = $_SESSION[self::PLUGIN_UNPLUG_SESSION_NAME];
264
+		} else {
265
+			return false;
266
+		}
267 267
 
268
-        return isset($unplug[$eventType][$eventToFire][$fullPathName][$className][$method]);
269
-    }
268
+		return isset($unplug[$eventType][$eventToFire][$fullPathName][$className][$method]);
269
+	}
270 270
 
271
-    /**
272
-     * Permet à un plugin de se détacher d'un évènement
273
-     *
274
-     * @param  integer $eventType
275
-     * @param  string  $eventToFire
276
-     * @param  string  $fullPathName
277
-     * @param  string  $className
278
-     * @param  string  $method
279
-     * @return void
280
-     */
281
-    public function unplugFromEvent($eventType, $eventToFire, $fullPathName, $className, $method)
282
-    {
283
-        $unplug = array();
284
-        if (isset($_SESSION[self::PLUGIN_UNPLUG_SESSION_NAME])) {
285
-            $unplug = $_SESSION[self::PLUGIN_UNPLUG_SESSION_NAME];
286
-        }
287
-        $unplug[$eventType][$eventToFire][$fullPathName][$className][$method] = true;
288
-        $_SESSION[self::PLUGIN_UNPLUG_SESSION_NAME]                           = $unplug;
289
-    }
271
+	/**
272
+	 * Permet à un plugin de se détacher d'un évènement
273
+	 *
274
+	 * @param  integer $eventType
275
+	 * @param  string  $eventToFire
276
+	 * @param  string  $fullPathName
277
+	 * @param  string  $className
278
+	 * @param  string  $method
279
+	 * @return void
280
+	 */
281
+	public function unplugFromEvent($eventType, $eventToFire, $fullPathName, $className, $method)
282
+	{
283
+		$unplug = array();
284
+		if (isset($_SESSION[self::PLUGIN_UNPLUG_SESSION_NAME])) {
285
+			$unplug = $_SESSION[self::PLUGIN_UNPLUG_SESSION_NAME];
286
+		}
287
+		$unplug[$eventType][$eventToFire][$fullPathName][$className][$method] = true;
288
+		$_SESSION[self::PLUGIN_UNPLUG_SESSION_NAME]                           = $unplug;
289
+	}
290 290
 }
Please login to merge, or discard this patch.
class/lite.php 1 patch
Indentation   +836 added lines, -836 removed lines patch added patch discarded remove patch
@@ -28,840 +28,840 @@
 block discarded – undo
28 28
 class references_Cache_Lite
29 29
 {
30 30
 
31
-    // --- Private properties ---
32
-
33
-    /**
34
-     * Directory where to put the cache files
35
-     * (make sure to add a trailing slash)
36
-     *
37
-     * @var string $_cacheDir
38
-     */
39
-    public $_cacheDir = '/tmp/';
40
-
41
-    /**
42
-     * Enable / disable caching
43
-     *
44
-     * (can be very usefull for the debug of cached scripts)
45
-     *
46
-     * @var boolean $_caching
47
-     */
48
-    public $_caching = true;
49
-
50
-    /**
51
-     * Cache lifetime (in seconds)
52
-     *
53
-     * If null, the cache is valid forever.
54
-     *
55
-     * @var int $_lifeTime
56
-     */
57
-    public $_lifeTime = 3600;
58
-
59
-    /**
60
-     * Enable / disable fileLocking
61
-     *
62
-     * (can avoid cache corruption under bad circumstances)
63
-     *
64
-     * @var boolean $_fileLocking
65
-     */
66
-    public $_fileLocking = true;
67
-
68
-    /**
69
-     * Timestamp of the last valid cache
70
-     *
71
-     * @var int $_refreshTime
72
-     */
73
-    public $_refreshTime;
74
-
75
-    /**
76
-     * File name (with path)
77
-     *
78
-     * @var string $_file
79
-     */
80
-    public $_file;
81
-
82
-    /**
83
-     * File name (without path)
84
-     *
85
-     * @var string $_fileName
86
-     */
87
-    public $_fileName;
88
-
89
-    /**
90
-     * Enable / disable write control (the cache is read just after writing to detect corrupt entries)
91
-     *
92
-     * Enable write control will lightly slow the cache writing but not the cache reading
93
-     * Write control can detect some corrupt cache files but maybe it's not a perfect control
94
-     *
95
-     * @var boolean $_writeControl
96
-     */
97
-    public $_writeControl = true;
98
-
99
-    /**
100
-     * Enable / disable read control
101
-     *
102
-     * If enabled, a control key is embeded in cache file and this key is compared with the one
103
-     * calculated after the reading.
104
-     *
105
-     * @var boolean $_writeControl
106
-     */
107
-    public $_readControl = true;
108
-
109
-    /**
110
-     * Type of read control (only if read control is enabled)
111
-     *
112
-     * Available values are :
113
-     * 'md5' for a md5 hash control (best but slowest)
114
-     * 'crc32' for a crc32 hash control (lightly less safe but faster, better choice)
115
-     * 'strlen' for a length only test (fastest)
116
-     *
117
-     * @var boolean $_readControlType
118
-     */
119
-    public $_readControlType = 'crc32';
120
-
121
-    /**
122
-     * Pear error mode (when raiseError is called)
123
-     *
124
-     * (see PEAR doc)
125
-     *
126
-     * @see setToDebug()
127
-     * @var int $_pearErrorMode
128
-     */
129
-    public $_pearErrorMode = REFERENCES_CACHE_LITE_ERROR_RETURN;
130
-
131
-    /**
132
-     * Current cache id
133
-     *
134
-     * @var string $_id
135
-     */
136
-    public $_id;
137
-
138
-    /**
139
-     * Current cache group
140
-     *
141
-     * @var string $_group
142
-     */
143
-    public $_group;
144
-
145
-    /**
146
-     * Enable / Disable "Memory Caching"
147
-     *
148
-     * NB : There is no lifetime for memory caching !
149
-     *
150
-     * @var boolean $_memoryCaching
151
-     */
152
-    public $_memoryCaching = false;
153
-
154
-    /**
155
-     * Enable / Disable "Only Memory Caching"
156
-     * (be carefull, memory caching is "beta quality")
157
-     *
158
-     * @var boolean $_onlyMemoryCaching
159
-     */
160
-    public $_onlyMemoryCaching = false;
161
-
162
-    /**
163
-     * Memory caching array
164
-     *
165
-     * @var array $_memoryCachingArray
166
-     */
167
-    public $_memoryCachingArray = array();
168
-
169
-    /**
170
-     * Memory caching counter
171
-     *
172
-     * @var int $memoryCachingCounter
173
-     */
174
-    public $_memoryCachingCounter = 0;
175
-
176
-    /**
177
-     * Memory caching limit
178
-     *
179
-     * @var int $memoryCachingLimit
180
-     */
181
-    public $_memoryCachingLimit = 1000;
182
-
183
-    /**
184
-     * File Name protection
185
-     *
186
-     * if set to true, you can use any cache id or group name
187
-     * if set to false, it can be faster but cache ids and group names
188
-     * will be used directly in cache file names so be carefull with
189
-     * special characters...
190
-     *
191
-     * @var boolean $fileNameProtection
192
-     */
193
-    public $_fileNameProtection = true;
194
-
195
-    /**
196
-     * Enable / disable automatic serialization
197
-     *
198
-     * it can be used to save directly datas which aren't strings
199
-     * (but it's slower)
200
-     *
201
-     * @var boolean $_serialize
202
-     */
203
-    public $_automaticSerialization = false;
204
-
205
-    /**
206
-     * Disable / Tune the automatic cleaning process
207
-     *
208
-     * The automatic cleaning process destroy too old (for the given life time)
209
-     * cache files when a new cache file is written.
210
-     * 0               => no automatic cache cleaning
211
-     * 1               => systematic cache cleaning
212
-     * x (integer) > 1 => automatic cleaning randomly 1 times on x cache write
213
-     *
214
-     * @var int $_automaticCleaning
215
-     */
216
-    public $_automaticCleaningFactor = 0;
217
-
218
-    /**
219
-     * Nested directory level
220
-     *
221
-     * Set the hashed directory structure level. 0 means "no hashed directory
222
-     * structure", 1 means "one level of directory", 2 means "two levels"...
223
-     * This option can speed up Cache_Lite only when you have many thousands of
224
-     * cache file. Only specific benchs can help you to choose the perfect value
225
-     * for you. Maybe, 1 or 2 is a good start.
226
-     *
227
-     * @var int $_hashedDirectoryLevel
228
-     */
229
-    public $_hashedDirectoryLevel = 0;
230
-
231
-    /**
232
-     * Umask for hashed directory structure
233
-     *
234
-     * @var int $_hashedDirectoryUmask
235
-     */
236
-    public $_hashedDirectoryUmask = 0700;
237
-
238
-    /**
239
-     * API break for error handling in REFERENCES_CACHE_LITE_ERROR_RETURN mode
240
-     *
241
-     * In REFERENCES_CACHE_LITE_ERROR_RETURN mode, error handling was not good because
242
-     * for example save() method always returned a boolean (a PEAR_Error object
243
-     * would be better in REFERENCES_CACHE_LITE_ERROR_RETURN mode). To correct this without
244
-     * breaking the API, this option (false by default) can change this handling.
245
-     *
246
-     * @var boolean
247
-     */
248
-    public $_errorHandlingAPIBreak = false;
249
-
250
-    // --- Public methods ---
251
-
252
-    /**
253
-     * Constructor
254
-     *
255
-     * $options is an assoc. Available options are :
256
-     * $options = array(
257
-     *     'cacheDir' => directory where to put the cache files (string) ,
258
-     *     'caching' => enable / disable caching (boolean) ,
259
-     *     'lifeTime' => cache lifetime in seconds (int) ,
260
-     *     'fileLocking' => enable / disable fileLocking (boolean) ,
261
-     *     'writeControl' => enable / disable write control (boolean) ,
262
-     *     'readControl' => enable / disable read control (boolean) ,
263
-     *     'readControlType' => type of read control 'crc32', 'md5', 'strlen' (string) ,
264
-     *     'pearErrorMode' => pear error mode (when raiseError is called) (cf PEAR doc) (int) ,
265
-     *     'memoryCaching' => enable / disable memory caching (boolean) ,
266
-     *     'onlyMemoryCaching' => enable / disable only memory caching (boolean) ,
267
-     *     'memoryCachingLimit' => max nbr of records to store into memory caching (int) ,
268
-     *     'fileNameProtection' => enable / disable automatic file name protection (boolean) ,
269
-     *     'automaticSerialization' => enable / disable automatic serialization (boolean) ,
270
-     *     'automaticCleaningFactor' => distable / tune automatic cleaning process (int) ,
271
-     *     'hashedDirectoryLevel' => level of the hashed directory system (int) ,
272
-     *     'hashedDirectoryUmask' => umask for hashed directory structure (int) ,
273
-     *     'errorHandlingAPIBreak' => API break for better error handling ? (boolean)
274
-     * );
275
-     *
276
-     * @param array $options options
277
-     * @access public
278
-     */
279
-    public function __construct($options = array(null))
280
-    {
281
-        foreach ($options as $key => $value) {
282
-            $this->setOption($key, $value);
283
-        }
284
-    }
285
-
286
-    /**
287
-     * Generic way to set a Cache_Lite option
288
-     *
289
-     * see Cache_Lite constructor for available options
290
-     *
291
-     * @var string $name  name of the option
292
-     * @var mixed  $value value of the option
293
-     * @access public
294
-     */
295
-    public function setOption($name, $value)
296
-    {
297
-        $availableOptions = array(
298
-            'errorHandlingAPIBreak',
299
-            'hashedDirectoryUmask',
300
-            'hashedDirectoryLevel',
301
-            'automaticCleaningFactor',
302
-            'automaticSerialization',
303
-            'fileNameProtection',
304
-            'memoryCaching',
305
-            'onlyMemoryCaching',
306
-            'memoryCachingLimit',
307
-            'cacheDir',
308
-            'caching',
309
-            'lifeTime',
310
-            'fileLocking',
311
-            'writeControl',
312
-            'readControl',
313
-            'readControlType',
314
-            'pearErrorMode'
315
-        );
316
-        if (in_array($name, $availableOptions)) {
317
-            $property        = '_' . $name;
318
-            $this->$property = $value;
319
-        }
320
-    }
321
-
322
-    /**
323
-     * Test if a cache is available and (if yes) return it
324
-     *
325
-     * @param string  $id                     cache id
326
-     * @param string  $group                  name of the cache group
327
-     * @param boolean $doNotTestCacheValidity if set to true, the cache validity won't be tested
328
-     * @return string data of the cache (else : false)
329
-     * @access public
330
-     */
331
-    public function get($id, $group = 'default', $doNotTestCacheValidity = false)
332
-    {
333
-        $this->_id    = $id;
334
-        $this->_group = $group;
335
-        $data         = false;
336
-        if ($this->_caching) {
337
-            $this->_setRefreshTime();
338
-            $this->_setFileName($id, $group);
339
-            clearstatcache();
340
-            if ($this->_memoryCaching) {
341
-                if (isset($this->_memoryCachingArray[$this->_file])) {
342
-                    if ($this->_automaticSerialization) {
343
-                        return unserialize($this->_memoryCachingArray[$this->_file]);
344
-                    }
345
-
346
-                    return $this->_memoryCachingArray[$this->_file];
347
-                }
348
-                if ($this->_onlyMemoryCaching) {
349
-                    return false;
350
-                }
351
-            }
352
-            if ($doNotTestCacheValidity || is_null($this->_refreshTime)) {
353
-                if (file_exists($this->_file)) {
354
-                    $data = $this->_read();
355
-                }
356
-            } else {
357
-                if (file_exists($this->_file) && (@filemtime($this->_file) > $this->_refreshTime)) {
358
-                    $data = $this->_read();
359
-                }
360
-            }
361
-            if ($data && $this->_memoryCaching) {
362
-                $this->_memoryCacheAdd($data);
363
-            }
364
-            if ($this->_automaticSerialization && is_string($data)) {
365
-                $data = unserialize($data);
366
-            }
367
-
368
-            return $data;
369
-        }
370
-
371
-        return false;
372
-    }
373
-
374
-    /**
375
-     * Save some data in a cache file
376
-     *
377
-     * @param string $data  data to put in cache (can be another type than strings if automaticSerialization is on)
378
-     * @param string $id    cache id
379
-     * @param string $group name of the cache group
380
-     * @return boolean true if no problem (else : false or a PEAR_Error object)
381
-     * @access public
382
-     */
383
-    public function save($data, $id = null, $group = 'default')
384
-    {
385
-        if ($this->_caching) {
386
-            if ($this->_automaticSerialization) {
387
-                $data = serialize($data);
388
-            }
389
-            if (isset($id)) {
390
-                $this->_setFileName($id, $group);
391
-            }
392
-            if ($this->_memoryCaching) {
393
-                $this->_memoryCacheAdd($data);
394
-                if ($this->_onlyMemoryCaching) {
395
-                    return true;
396
-                }
397
-            }
398
-            if ($this->_automaticCleaningFactor > 0 && ($this->_automaticCleaningFactor == 1 || mt_rand(1, $this->_automaticCleaningFactor) == 1)) {
399
-                $this->clean(false, 'old');
400
-            }
401
-            if ($this->_writeControl) {
402
-                $res = $this->_writeAndControl($data);
403
-                if (is_bool($res)) {
404
-                    if ($res) {
405
-                        return true;
406
-                    }
407
-                    // if $res if false, we need to invalidate the cache
408
-                    @touch($this->_file, time() - 2 * abs($this->_lifeTime));
409
-
410
-                    return false;
411
-                }
412
-            } else {
413
-                $res = $this->_write($data);
414
-            }
415
-            if (is_object($res)) {
416
-                // $res is a PEAR_Error object
417
-                if (!$this->_errorHandlingAPIBreak) {
418
-                    return false; // we return false (old API)
419
-                }
420
-            }
421
-
422
-            return $res;
423
-        }
424
-
425
-        return false;
426
-    }
427
-
428
-    /**
429
-     * Remove a cache file
430
-     *
431
-     * @param string  $id                cache id
432
-     * @param string  $group             name of the cache group
433
-     * @param boolean $checkbeforeunlink check if file exists before removing it
434
-     * @return boolean true if no problem
435
-     * @access public
436
-     */
437
-    public function remove($id, $group = 'default', $checkbeforeunlink = false)
438
-    {
439
-        $this->_setFileName($id, $group);
440
-        if ($this->_memoryCaching) {
441
-            if (isset($this->_memoryCachingArray[$this->_file])) {
442
-                unset($this->_memoryCachingArray[$this->_file]);
443
-                --$this->_memoryCachingCounter;
444
-            }
445
-            if ($this->_onlyMemoryCaching) {
446
-                return true;
447
-            }
448
-        }
449
-        if ($checkbeforeunlink) {
450
-            if (!file_exists($this->_file)) {
451
-                return true;
452
-            }
453
-        }
454
-
455
-        return $this->_unlink($this->_file);
456
-    }
457
-
458
-    /**
459
-     * Clean the cache
460
-     *
461
-     * if no group is specified all cache files will be destroyed
462
-     * else only cache files of the specified group will be destroyed
463
-     *
464
-     * @param bool|string $group              name of the cache group
465
-     * @param string      $mode               flush cache mode : 'old', 'ingroup', 'notingroup',
466
-     *                                        'callback_myFunction'
467
-     * @return bool true if no problem
468
-     * @access public
469
-     */
470
-    public function clean($group = false, $mode = 'ingroup')
471
-    {
472
-        return $this->_cleanDir($this->_cacheDir, $group, $mode);
473
-    }
474
-
475
-    /**
476
-     * Set to debug mode
477
-     *
478
-     * When an error is found, the script will stop and the message will be displayed
479
-     * (in debug mode only).
480
-     *
481
-     * @access public
482
-     */
483
-    public function setToDebug()
484
-    {
485
-        $this->setOption('pearErrorMode', REFERENCES_CACHE_LITE_ERROR_DIE);
486
-    }
487
-
488
-    /**
489
-     * Set a new life time
490
-     *
491
-     * @param int $newLifeTime new life time (in seconds)
492
-     * @access public
493
-     */
494
-    public function setLifeTime($newLifeTime)
495
-    {
496
-        $this->_lifeTime = $newLifeTime;
497
-        $this->_setRefreshTime();
498
-    }
499
-
500
-    /**
501
-     * Save the state of the caching memory array into a cache file cache
502
-     *
503
-     * @param string $id    cache id
504
-     * @param string $group name of the cache group
505
-     * @access public
506
-     */
507
-    public function saveMemoryCachingState($id, $group = 'default')
508
-    {
509
-        if ($this->_caching) {
510
-            $array = array(
511
-                'counter' => $this->_memoryCachingCounter,
512
-                'array'   => $this->_memoryCachingArray
513
-            );
514
-            $data  = serialize($array);
515
-            $this->save($data, $id, $group);
516
-        }
517
-    }
518
-
519
-    /**
520
-     * Load the state of the caching memory array from a given cache file cache
521
-     *
522
-     * @param string  $id                     cache id
523
-     * @param string  $group                  name of the cache group
524
-     * @param boolean $doNotTestCacheValidity if set to true, the cache validity won't be tested
525
-     * @access public
526
-     */
527
-    public function getMemoryCachingState($id, $group = 'default', $doNotTestCacheValidity = false)
528
-    {
529
-        if ($this->_caching) {
530
-            if ($data = $this->get($id, $group, $doNotTestCacheValidity)) {
531
-                $array                       = unserialize($data);
532
-                $this->_memoryCachingCounter = $array['counter'];
533
-                $this->_memoryCachingArray   = $array['array'];
534
-            }
535
-        }
536
-    }
537
-
538
-    /**
539
-     * Return the cache last modification time
540
-     *
541
-     * BE CAREFUL : THIS METHOD IS FOR HACKING ONLY !
542
-     *
543
-     * @return int last modification time
544
-     */
545
-    public function lastModified()
546
-    {
547
-        return @filemtime($this->_file);
548
-    }
549
-
550
-    /**
551
-     * Trigger a PEAR error
552
-     *
553
-     * To improve performances, the PEAR.php file is included dynamically.
554
-     * The file is so included only when an error is triggered. So, in most
555
-     * cases, the file isn't included and perfs are much better.
556
-     *
557
-     * @param string $msg  error message
558
-     * @param int    $code error code
559
-     * @access public
560
-     * @return object
561
-     */
562
-    public function raiseError($msg, $code)
563
-    {
564
-        include_once('PEAR.php');
565
-
566
-        return references_PEAR::raiseError($msg, $code, $this->_pearErrorMode);
567
-    }
568
-
569
-    /**
570
-     * Extend the life of a valid cache file
571
-     *
572
-     * see http://pear.php.net/bugs/bug.php?id=6681
573
-     *
574
-     * @access public
575
-     */
576
-    public function extendLife()
577
-    {
578
-        @touch($this->_file);
579
-    }
580
-
581
-    // --- Private methods ---
582
-
583
-    /**
584
-     * Compute & set the refresh time
585
-     *
586
-     * @access private
587
-     */
588
-    public function _setRefreshTime()
589
-    {
590
-        if (is_null($this->_lifeTime)) {
591
-            $this->_refreshTime = null;
592
-        } else {
593
-            $this->_refreshTime = time() - $this->_lifeTime;
594
-        }
595
-    }
596
-
597
-    /**
598
-     * Remove a file
599
-     *
600
-     * @param string $file complete file path and name
601
-     * @return boolean true if no problem
602
-     * @access private
603
-     */
604
-    public function _unlink($file)
605
-    {
606
-        if (!@unlink($file)) {
607
-            return $this->raiseError('Cache_Lite : Unable to remove cache !', -3);
608
-        }
609
-
610
-        return true;
611
-    }
612
-
613
-    /**
614
-     * Recursive function for cleaning cache file in the given directory
615
-     *
616
-     * @param string      $dir   directory complete path (with a trailing slash)
617
-     * @param bool|string $group name of the cache group
618
-     * @param string      $mode  flush cache mode : 'old', 'ingroup', 'notingroup',
619
-     *                           'callback_myFunction'
620
-     * @return bool true if no problem
621
-     * @access private
622
-     */
623
-    public function _cleanDir($dir, $group = false, $mode = 'ingroup')
624
-    {
625
-        if ($this->_fileNameProtection) {
626
-            $motif = $group ? 'cache_' . md5($group) . '_' : 'cache_';
627
-        } else {
628
-            $motif = $group ? 'cache_' . $group . '_' : 'cache_';
629
-        }
630
-        if ($this->_memoryCaching) {
631
-            foreach ($this->_memoryCachingArray as $key => $v) {
632
-                if (strpos($key, $motif) !== false) {
633
-                    unset($this->_memoryCachingArray[$key]);
634
-                    --$this->_memoryCachingCounter;
635
-                }
636
-            }
637
-            if ($this->_onlyMemoryCaching) {
638
-                return true;
639
-            }
640
-        }
641
-        if (!($dh = opendir($dir))) {
642
-            return $this->raiseError('Cache_Lite : Unable to open cache directory !', -4);
643
-        }
644
-        $result = true;
645
-        while ($file = readdir($dh)) {
646
-            if (($file !== '.') && ($file !== '..')) {
647
-                if (substr($file, 0, 6) === 'cache_') {
648
-                    $file2 = $dir . $file;
649
-                    if (is_file($file2)) {
650
-                        switch (substr($mode, 0, 9)) {
651
-                            case 'old':
652
-                                // files older than lifeTime get deleted from cache
653
-                                if (!is_null($this->_lifeTime)) {
654
-                                    if ((time() - @filemtime($file2)) > $this->_lifeTime) {
655
-                                        $result = ($result and $this->_unlink($file2));
656
-                                    }
657
-                                }
658
-                                break;
659
-                            case 'notingrou':
660
-                                if (strpos($file2, $motif) === false) {
661
-                                    $result = ($result and $this->_unlink($file2));
662
-                                }
663
-                                break;
664
-                            case 'callback_':
665
-                                $func = substr($mode, 9, strlen($mode) - 9);
666
-                                if ($func($file2, $group)) {
667
-                                    $result = ($result and $this->_unlink($file2));
668
-                                }
669
-                                break;
670
-                            case 'ingroup':
671
-                            default:
672
-                                if (strpos($file2, $motif) !== false) {
673
-                                    $result = ($result and $this->_unlink($file2));
674
-                                }
675
-                                break;
676
-                        }
677
-                    }
678
-                    if (is_dir($file2) and ($this->_hashedDirectoryLevel > 0)) {
679
-                        $result = ($result and $this->_cleanDir($file2 . '/', $group, $mode));
680
-                    }
681
-                }
682
-            }
683
-        }
684
-
685
-        return $result;
686
-    }
687
-
688
-    /**
689
-     * Add some date in the memory caching array
690
-     *
691
-     * @param string $data data to cache
692
-     * @access private
693
-     */
694
-    public function _memoryCacheAdd($data)
695
-    {
696
-        $this->_memoryCachingArray[$this->_file] = $data;
697
-        if ($this->_memoryCachingCounter >= $this->_memoryCachingLimit) {
698
-            list($key,) = each($this->_memoryCachingArray);
699
-            unset($this->_memoryCachingArray[$key]);
700
-        } else {
701
-            ++$this->_memoryCachingCounter;
702
-        }
703
-    }
704
-
705
-    /**
706
-     * Make a file name (with path)
707
-     *
708
-     * @param string $id    cache id
709
-     * @param string $group name of the group
710
-     * @access private
711
-     */
712
-    public function _setFileName($id, $group)
713
-    {
714
-        if ($this->_fileNameProtection) {
715
-            $suffix = 'cache_' . md5($group) . '_' . md5($id);
716
-        } else {
717
-            $suffix = 'cache_' . $group . '_' . $id;
718
-        }
719
-        $root = $this->_cacheDir;
720
-        if ($this->_hashedDirectoryLevel > 0) {
721
-            $hash = md5($suffix);
722
-            for ($i = 0; $i < $this->_hashedDirectoryLevel; ++$i) {
723
-                $root = $root . 'cache_' . substr($hash, 0, $i + 1) . '/';
724
-            }
725
-        }
726
-        $this->_fileName = $suffix;
727
-        $this->_file     = $root . $suffix;
728
-    }
729
-
730
-    /**
731
-     * Read the cache file and return the content
732
-     *
733
-     * @return string content of the cache file (else : false or a PEAR_Error object)
734
-     * @access private
735
-     */
736
-    public function _read()
737
-    {
738
-        $fp = @fopen($this->_file, 'rb');
739
-        if ($this->_fileLocking) {
740
-            @flock($fp, LOCK_SH);
741
-        }
742
-        if ($fp) {
743
-            clearstatcache();
744
-            $length = @filesize($this->_file);
745
-            //            $mqr = get_magic_quotes_runtime();
746
-            //            @set_magic_quotes_runtime(0);
747
-            if ($this->_readControl) {
748
-                $hashControl = @fread($fp, 32);
749
-                $length      = $length - 32;
750
-            }
751
-            if ($length) {
752
-                $data = @fread($fp, $length);
753
-            } else {
754
-                $data = '';
755
-            }
756
-            //            @set_magic_quotes_runtime($mqr);
757
-            if ($this->_fileLocking) {
758
-                @flock($fp, LOCK_UN);
759
-            }
760
-            @fclose($fp);
761
-            if ($this->_readControl) {
762
-                $hashData = $this->_hash($data, $this->_readControlType);
763
-                if ($hashData != $hashControl) {
764
-                    if (!is_null($this->_lifeTime)) {
765
-                        @touch($this->_file, time() - 2 * abs($this->_lifeTime));
766
-                    } else {
767
-                        @unlink($this->_file);
768
-                    }
769
-
770
-                    return false;
771
-                }
772
-            }
773
-
774
-            return $data;
775
-        }
776
-
777
-        return $this->raiseError('Cache_Lite : Unable to read cache !', -2);
778
-    }
779
-
780
-    /**
781
-     * Write the given data in the cache file
782
-     *
783
-     * @param string $data data to put in cache
784
-     * @return boolean true if ok (a PEAR_Error object else)
785
-     * @access private
786
-     */
787
-    public function _write($data)
788
-    {
789
-        if ($this->_hashedDirectoryLevel > 0) {
790
-            $hash = md5($this->_fileName);
791
-            $root = $this->_cacheDir;
792
-            for ($i = 0; $i < $this->_hashedDirectoryLevel; ++$i) {
793
-                $root = $root . 'cache_' . substr($hash, 0, $i + 1) . '/';
794
-                if (!(@is_dir($root))) {
795
-                    @mkdir($root, $this->_hashedDirectoryUmask);
796
-                }
797
-            }
798
-        }
799
-        $fp = @fopen($this->_file, 'wb');
800
-        if ($fp) {
801
-            if ($this->_fileLocking) {
802
-                @flock($fp, LOCK_EX);
803
-            }
804
-            if ($this->_readControl) {
805
-                @fwrite($fp, $this->_hash($data, $this->_readControlType), 32);
806
-            }
807
-            //            $mqr = get_magic_quotes_runtime();
808
-            //            @set_magic_quotes_runtime(0);
809
-            @fwrite($fp, $data);
810
-            //            @set_magic_quotes_runtime($mqr);
811
-            if ($this->_fileLocking) {
812
-                @flock($fp, LOCK_UN);
813
-            }
814
-            @fclose($fp);
815
-
816
-            return true;
817
-        }
818
-
819
-        return $this->raiseError('Cache_Lite : Unable to write cache file : ' . $this->_file, -1);
820
-    }
821
-
822
-    /**
823
-     * Write the given data in the cache file and control it just after to avoir corrupted cache entries
824
-     *
825
-     * @param string $data data to put in cache
826
-     * @return boolean true if the test is ok (else : false or a PEAR_Error object)
827
-     * @access private
828
-     */
829
-    public function _writeAndControl($data)
830
-    {
831
-        $result = $this->_write($data);
832
-        if (is_object($result)) {
833
-            return $result; # We return the PEAR_Error object
834
-        }
835
-        $dataRead = $this->_read();
836
-        if (is_object($dataRead)) {
837
-            return $dataRead; # We return the PEAR_Error object
838
-        }
839
-        if (is_bool($dataRead) && (!$dataRead)) {
840
-            return false;
841
-        }
842
-
843
-        return ($dataRead == $data);
844
-    }
845
-
846
-    /**
847
-     * Make a control key with the string containing datas
848
-     *
849
-     * @param string $data        data
850
-     * @param string $controlType type of control 'md5', 'crc32' or 'strlen'
851
-     * @return string control key
852
-     * @access private
853
-     */
854
-    public function _hash($data, $controlType)
855
-    {
856
-        switch ($controlType) {
857
-            case 'md5':
858
-                return md5($data);
859
-            case 'crc32':
860
-                return sprintf('% 32d', crc32($data));
861
-            case 'strlen':
862
-                return sprintf('% 32d', strlen($data));
863
-            default:
864
-                return $this->raiseError('Unknown controlType ! (available values are only \'md5\', \'crc32\', \'strlen\')', -5);
865
-        }
866
-    }
31
+	// --- Private properties ---
32
+
33
+	/**
34
+	 * Directory where to put the cache files
35
+	 * (make sure to add a trailing slash)
36
+	 *
37
+	 * @var string $_cacheDir
38
+	 */
39
+	public $_cacheDir = '/tmp/';
40
+
41
+	/**
42
+	 * Enable / disable caching
43
+	 *
44
+	 * (can be very usefull for the debug of cached scripts)
45
+	 *
46
+	 * @var boolean $_caching
47
+	 */
48
+	public $_caching = true;
49
+
50
+	/**
51
+	 * Cache lifetime (in seconds)
52
+	 *
53
+	 * If null, the cache is valid forever.
54
+	 *
55
+	 * @var int $_lifeTime
56
+	 */
57
+	public $_lifeTime = 3600;
58
+
59
+	/**
60
+	 * Enable / disable fileLocking
61
+	 *
62
+	 * (can avoid cache corruption under bad circumstances)
63
+	 *
64
+	 * @var boolean $_fileLocking
65
+	 */
66
+	public $_fileLocking = true;
67
+
68
+	/**
69
+	 * Timestamp of the last valid cache
70
+	 *
71
+	 * @var int $_refreshTime
72
+	 */
73
+	public $_refreshTime;
74
+
75
+	/**
76
+	 * File name (with path)
77
+	 *
78
+	 * @var string $_file
79
+	 */
80
+	public $_file;
81
+
82
+	/**
83
+	 * File name (without path)
84
+	 *
85
+	 * @var string $_fileName
86
+	 */
87
+	public $_fileName;
88
+
89
+	/**
90
+	 * Enable / disable write control (the cache is read just after writing to detect corrupt entries)
91
+	 *
92
+	 * Enable write control will lightly slow the cache writing but not the cache reading
93
+	 * Write control can detect some corrupt cache files but maybe it's not a perfect control
94
+	 *
95
+	 * @var boolean $_writeControl
96
+	 */
97
+	public $_writeControl = true;
98
+
99
+	/**
100
+	 * Enable / disable read control
101
+	 *
102
+	 * If enabled, a control key is embeded in cache file and this key is compared with the one
103
+	 * calculated after the reading.
104
+	 *
105
+	 * @var boolean $_writeControl
106
+	 */
107
+	public $_readControl = true;
108
+
109
+	/**
110
+	 * Type of read control (only if read control is enabled)
111
+	 *
112
+	 * Available values are :
113
+	 * 'md5' for a md5 hash control (best but slowest)
114
+	 * 'crc32' for a crc32 hash control (lightly less safe but faster, better choice)
115
+	 * 'strlen' for a length only test (fastest)
116
+	 *
117
+	 * @var boolean $_readControlType
118
+	 */
119
+	public $_readControlType = 'crc32';
120
+
121
+	/**
122
+	 * Pear error mode (when raiseError is called)
123
+	 *
124
+	 * (see PEAR doc)
125
+	 *
126
+	 * @see setToDebug()
127
+	 * @var int $_pearErrorMode
128
+	 */
129
+	public $_pearErrorMode = REFERENCES_CACHE_LITE_ERROR_RETURN;
130
+
131
+	/**
132
+	 * Current cache id
133
+	 *
134
+	 * @var string $_id
135
+	 */
136
+	public $_id;
137
+
138
+	/**
139
+	 * Current cache group
140
+	 *
141
+	 * @var string $_group
142
+	 */
143
+	public $_group;
144
+
145
+	/**
146
+	 * Enable / Disable "Memory Caching"
147
+	 *
148
+	 * NB : There is no lifetime for memory caching !
149
+	 *
150
+	 * @var boolean $_memoryCaching
151
+	 */
152
+	public $_memoryCaching = false;
153
+
154
+	/**
155
+	 * Enable / Disable "Only Memory Caching"
156
+	 * (be carefull, memory caching is "beta quality")
157
+	 *
158
+	 * @var boolean $_onlyMemoryCaching
159
+	 */
160
+	public $_onlyMemoryCaching = false;
161
+
162
+	/**
163
+	 * Memory caching array
164
+	 *
165
+	 * @var array $_memoryCachingArray
166
+	 */
167
+	public $_memoryCachingArray = array();
168
+
169
+	/**
170
+	 * Memory caching counter
171
+	 *
172
+	 * @var int $memoryCachingCounter
173
+	 */
174
+	public $_memoryCachingCounter = 0;
175
+
176
+	/**
177
+	 * Memory caching limit
178
+	 *
179
+	 * @var int $memoryCachingLimit
180
+	 */
181
+	public $_memoryCachingLimit = 1000;
182
+
183
+	/**
184
+	 * File Name protection
185
+	 *
186
+	 * if set to true, you can use any cache id or group name
187
+	 * if set to false, it can be faster but cache ids and group names
188
+	 * will be used directly in cache file names so be carefull with
189
+	 * special characters...
190
+	 *
191
+	 * @var boolean $fileNameProtection
192
+	 */
193
+	public $_fileNameProtection = true;
194
+
195
+	/**
196
+	 * Enable / disable automatic serialization
197
+	 *
198
+	 * it can be used to save directly datas which aren't strings
199
+	 * (but it's slower)
200
+	 *
201
+	 * @var boolean $_serialize
202
+	 */
203
+	public $_automaticSerialization = false;
204
+
205
+	/**
206
+	 * Disable / Tune the automatic cleaning process
207
+	 *
208
+	 * The automatic cleaning process destroy too old (for the given life time)
209
+	 * cache files when a new cache file is written.
210
+	 * 0               => no automatic cache cleaning
211
+	 * 1               => systematic cache cleaning
212
+	 * x (integer) > 1 => automatic cleaning randomly 1 times on x cache write
213
+	 *
214
+	 * @var int $_automaticCleaning
215
+	 */
216
+	public $_automaticCleaningFactor = 0;
217
+
218
+	/**
219
+	 * Nested directory level
220
+	 *
221
+	 * Set the hashed directory structure level. 0 means "no hashed directory
222
+	 * structure", 1 means "one level of directory", 2 means "two levels"...
223
+	 * This option can speed up Cache_Lite only when you have many thousands of
224
+	 * cache file. Only specific benchs can help you to choose the perfect value
225
+	 * for you. Maybe, 1 or 2 is a good start.
226
+	 *
227
+	 * @var int $_hashedDirectoryLevel
228
+	 */
229
+	public $_hashedDirectoryLevel = 0;
230
+
231
+	/**
232
+	 * Umask for hashed directory structure
233
+	 *
234
+	 * @var int $_hashedDirectoryUmask
235
+	 */
236
+	public $_hashedDirectoryUmask = 0700;
237
+
238
+	/**
239
+	 * API break for error handling in REFERENCES_CACHE_LITE_ERROR_RETURN mode
240
+	 *
241
+	 * In REFERENCES_CACHE_LITE_ERROR_RETURN mode, error handling was not good because
242
+	 * for example save() method always returned a boolean (a PEAR_Error object
243
+	 * would be better in REFERENCES_CACHE_LITE_ERROR_RETURN mode). To correct this without
244
+	 * breaking the API, this option (false by default) can change this handling.
245
+	 *
246
+	 * @var boolean
247
+	 */
248
+	public $_errorHandlingAPIBreak = false;
249
+
250
+	// --- Public methods ---
251
+
252
+	/**
253
+	 * Constructor
254
+	 *
255
+	 * $options is an assoc. Available options are :
256
+	 * $options = array(
257
+	 *     'cacheDir' => directory where to put the cache files (string) ,
258
+	 *     'caching' => enable / disable caching (boolean) ,
259
+	 *     'lifeTime' => cache lifetime in seconds (int) ,
260
+	 *     'fileLocking' => enable / disable fileLocking (boolean) ,
261
+	 *     'writeControl' => enable / disable write control (boolean) ,
262
+	 *     'readControl' => enable / disable read control (boolean) ,
263
+	 *     'readControlType' => type of read control 'crc32', 'md5', 'strlen' (string) ,
264
+	 *     'pearErrorMode' => pear error mode (when raiseError is called) (cf PEAR doc) (int) ,
265
+	 *     'memoryCaching' => enable / disable memory caching (boolean) ,
266
+	 *     'onlyMemoryCaching' => enable / disable only memory caching (boolean) ,
267
+	 *     'memoryCachingLimit' => max nbr of records to store into memory caching (int) ,
268
+	 *     'fileNameProtection' => enable / disable automatic file name protection (boolean) ,
269
+	 *     'automaticSerialization' => enable / disable automatic serialization (boolean) ,
270
+	 *     'automaticCleaningFactor' => distable / tune automatic cleaning process (int) ,
271
+	 *     'hashedDirectoryLevel' => level of the hashed directory system (int) ,
272
+	 *     'hashedDirectoryUmask' => umask for hashed directory structure (int) ,
273
+	 *     'errorHandlingAPIBreak' => API break for better error handling ? (boolean)
274
+	 * );
275
+	 *
276
+	 * @param array $options options
277
+	 * @access public
278
+	 */
279
+	public function __construct($options = array(null))
280
+	{
281
+		foreach ($options as $key => $value) {
282
+			$this->setOption($key, $value);
283
+		}
284
+	}
285
+
286
+	/**
287
+	 * Generic way to set a Cache_Lite option
288
+	 *
289
+	 * see Cache_Lite constructor for available options
290
+	 *
291
+	 * @var string $name  name of the option
292
+	 * @var mixed  $value value of the option
293
+	 * @access public
294
+	 */
295
+	public function setOption($name, $value)
296
+	{
297
+		$availableOptions = array(
298
+			'errorHandlingAPIBreak',
299
+			'hashedDirectoryUmask',
300
+			'hashedDirectoryLevel',
301
+			'automaticCleaningFactor',
302
+			'automaticSerialization',
303
+			'fileNameProtection',
304
+			'memoryCaching',
305
+			'onlyMemoryCaching',
306
+			'memoryCachingLimit',
307
+			'cacheDir',
308
+			'caching',
309
+			'lifeTime',
310
+			'fileLocking',
311
+			'writeControl',
312
+			'readControl',
313
+			'readControlType',
314
+			'pearErrorMode'
315
+		);
316
+		if (in_array($name, $availableOptions)) {
317
+			$property        = '_' . $name;
318
+			$this->$property = $value;
319
+		}
320
+	}
321
+
322
+	/**
323
+	 * Test if a cache is available and (if yes) return it
324
+	 *
325
+	 * @param string  $id                     cache id
326
+	 * @param string  $group                  name of the cache group
327
+	 * @param boolean $doNotTestCacheValidity if set to true, the cache validity won't be tested
328
+	 * @return string data of the cache (else : false)
329
+	 * @access public
330
+	 */
331
+	public function get($id, $group = 'default', $doNotTestCacheValidity = false)
332
+	{
333
+		$this->_id    = $id;
334
+		$this->_group = $group;
335
+		$data         = false;
336
+		if ($this->_caching) {
337
+			$this->_setRefreshTime();
338
+			$this->_setFileName($id, $group);
339
+			clearstatcache();
340
+			if ($this->_memoryCaching) {
341
+				if (isset($this->_memoryCachingArray[$this->_file])) {
342
+					if ($this->_automaticSerialization) {
343
+						return unserialize($this->_memoryCachingArray[$this->_file]);
344
+					}
345
+
346
+					return $this->_memoryCachingArray[$this->_file];
347
+				}
348
+				if ($this->_onlyMemoryCaching) {
349
+					return false;
350
+				}
351
+			}
352
+			if ($doNotTestCacheValidity || is_null($this->_refreshTime)) {
353
+				if (file_exists($this->_file)) {
354
+					$data = $this->_read();
355
+				}
356
+			} else {
357
+				if (file_exists($this->_file) && (@filemtime($this->_file) > $this->_refreshTime)) {
358
+					$data = $this->_read();
359
+				}
360
+			}
361
+			if ($data && $this->_memoryCaching) {
362
+				$this->_memoryCacheAdd($data);
363
+			}
364
+			if ($this->_automaticSerialization && is_string($data)) {
365
+				$data = unserialize($data);
366
+			}
367
+
368
+			return $data;
369
+		}
370
+
371
+		return false;
372
+	}
373
+
374
+	/**
375
+	 * Save some data in a cache file
376
+	 *
377
+	 * @param string $data  data to put in cache (can be another type than strings if automaticSerialization is on)
378
+	 * @param string $id    cache id
379
+	 * @param string $group name of the cache group
380
+	 * @return boolean true if no problem (else : false or a PEAR_Error object)
381
+	 * @access public
382
+	 */
383
+	public function save($data, $id = null, $group = 'default')
384
+	{
385
+		if ($this->_caching) {
386
+			if ($this->_automaticSerialization) {
387
+				$data = serialize($data);
388
+			}
389
+			if (isset($id)) {
390
+				$this->_setFileName($id, $group);
391
+			}
392
+			if ($this->_memoryCaching) {
393
+				$this->_memoryCacheAdd($data);
394
+				if ($this->_onlyMemoryCaching) {
395
+					return true;
396
+				}
397
+			}
398
+			if ($this->_automaticCleaningFactor > 0 && ($this->_automaticCleaningFactor == 1 || mt_rand(1, $this->_automaticCleaningFactor) == 1)) {
399
+				$this->clean(false, 'old');
400
+			}
401
+			if ($this->_writeControl) {
402
+				$res = $this->_writeAndControl($data);
403
+				if (is_bool($res)) {
404
+					if ($res) {
405
+						return true;
406
+					}
407
+					// if $res if false, we need to invalidate the cache
408
+					@touch($this->_file, time() - 2 * abs($this->_lifeTime));
409
+
410
+					return false;
411
+				}
412
+			} else {
413
+				$res = $this->_write($data);
414
+			}
415
+			if (is_object($res)) {
416
+				// $res is a PEAR_Error object
417
+				if (!$this->_errorHandlingAPIBreak) {
418
+					return false; // we return false (old API)
419
+				}
420
+			}
421
+
422
+			return $res;
423
+		}
424
+
425
+		return false;
426
+	}
427
+
428
+	/**
429
+	 * Remove a cache file
430
+	 *
431
+	 * @param string  $id                cache id
432
+	 * @param string  $group             name of the cache group
433
+	 * @param boolean $checkbeforeunlink check if file exists before removing it
434
+	 * @return boolean true if no problem
435
+	 * @access public
436
+	 */
437
+	public function remove($id, $group = 'default', $checkbeforeunlink = false)
438
+	{
439
+		$this->_setFileName($id, $group);
440
+		if ($this->_memoryCaching) {
441
+			if (isset($this->_memoryCachingArray[$this->_file])) {
442
+				unset($this->_memoryCachingArray[$this->_file]);
443
+				--$this->_memoryCachingCounter;
444
+			}
445
+			if ($this->_onlyMemoryCaching) {
446
+				return true;
447
+			}
448
+		}
449
+		if ($checkbeforeunlink) {
450
+			if (!file_exists($this->_file)) {
451
+				return true;
452
+			}
453
+		}
454
+
455
+		return $this->_unlink($this->_file);
456
+	}
457
+
458
+	/**
459
+	 * Clean the cache
460
+	 *
461
+	 * if no group is specified all cache files will be destroyed
462
+	 * else only cache files of the specified group will be destroyed
463
+	 *
464
+	 * @param bool|string $group              name of the cache group
465
+	 * @param string      $mode               flush cache mode : 'old', 'ingroup', 'notingroup',
466
+	 *                                        'callback_myFunction'
467
+	 * @return bool true if no problem
468
+	 * @access public
469
+	 */
470
+	public function clean($group = false, $mode = 'ingroup')
471
+	{
472
+		return $this->_cleanDir($this->_cacheDir, $group, $mode);
473
+	}
474
+
475
+	/**
476
+	 * Set to debug mode
477
+	 *
478
+	 * When an error is found, the script will stop and the message will be displayed
479
+	 * (in debug mode only).
480
+	 *
481
+	 * @access public
482
+	 */
483
+	public function setToDebug()
484
+	{
485
+		$this->setOption('pearErrorMode', REFERENCES_CACHE_LITE_ERROR_DIE);
486
+	}
487
+
488
+	/**
489
+	 * Set a new life time
490
+	 *
491
+	 * @param int $newLifeTime new life time (in seconds)
492
+	 * @access public
493
+	 */
494
+	public function setLifeTime($newLifeTime)
495
+	{
496
+		$this->_lifeTime = $newLifeTime;
497
+		$this->_setRefreshTime();
498
+	}
499
+
500
+	/**
501
+	 * Save the state of the caching memory array into a cache file cache
502
+	 *
503
+	 * @param string $id    cache id
504
+	 * @param string $group name of the cache group
505
+	 * @access public
506
+	 */
507
+	public function saveMemoryCachingState($id, $group = 'default')
508
+	{
509
+		if ($this->_caching) {
510
+			$array = array(
511
+				'counter' => $this->_memoryCachingCounter,
512
+				'array'   => $this->_memoryCachingArray
513
+			);
514
+			$data  = serialize($array);
515
+			$this->save($data, $id, $group);
516
+		}
517
+	}
518
+
519
+	/**
520
+	 * Load the state of the caching memory array from a given cache file cache
521
+	 *
522
+	 * @param string  $id                     cache id
523
+	 * @param string  $group                  name of the cache group
524
+	 * @param boolean $doNotTestCacheValidity if set to true, the cache validity won't be tested
525
+	 * @access public
526
+	 */
527
+	public function getMemoryCachingState($id, $group = 'default', $doNotTestCacheValidity = false)
528
+	{
529
+		if ($this->_caching) {
530
+			if ($data = $this->get($id, $group, $doNotTestCacheValidity)) {
531
+				$array                       = unserialize($data);
532
+				$this->_memoryCachingCounter = $array['counter'];
533
+				$this->_memoryCachingArray   = $array['array'];
534
+			}
535
+		}
536
+	}
537
+
538
+	/**
539
+	 * Return the cache last modification time
540
+	 *
541
+	 * BE CAREFUL : THIS METHOD IS FOR HACKING ONLY !
542
+	 *
543
+	 * @return int last modification time
544
+	 */
545
+	public function lastModified()
546
+	{
547
+		return @filemtime($this->_file);
548
+	}
549
+
550
+	/**
551
+	 * Trigger a PEAR error
552
+	 *
553
+	 * To improve performances, the PEAR.php file is included dynamically.
554
+	 * The file is so included only when an error is triggered. So, in most
555
+	 * cases, the file isn't included and perfs are much better.
556
+	 *
557
+	 * @param string $msg  error message
558
+	 * @param int    $code error code
559
+	 * @access public
560
+	 * @return object
561
+	 */
562
+	public function raiseError($msg, $code)
563
+	{
564
+		include_once('PEAR.php');
565
+
566
+		return references_PEAR::raiseError($msg, $code, $this->_pearErrorMode);
567
+	}
568
+
569
+	/**
570
+	 * Extend the life of a valid cache file
571
+	 *
572
+	 * see http://pear.php.net/bugs/bug.php?id=6681
573
+	 *
574
+	 * @access public
575
+	 */
576
+	public function extendLife()
577
+	{
578
+		@touch($this->_file);
579
+	}
580
+
581
+	// --- Private methods ---
582
+
583
+	/**
584
+	 * Compute & set the refresh time
585
+	 *
586
+	 * @access private
587
+	 */
588
+	public function _setRefreshTime()
589
+	{
590
+		if (is_null($this->_lifeTime)) {
591
+			$this->_refreshTime = null;
592
+		} else {
593
+			$this->_refreshTime = time() - $this->_lifeTime;
594
+		}
595
+	}
596
+
597
+	/**
598
+	 * Remove a file
599
+	 *
600
+	 * @param string $file complete file path and name
601
+	 * @return boolean true if no problem
602
+	 * @access private
603
+	 */
604
+	public function _unlink($file)
605
+	{
606
+		if (!@unlink($file)) {
607
+			return $this->raiseError('Cache_Lite : Unable to remove cache !', -3);
608
+		}
609
+
610
+		return true;
611
+	}
612
+
613
+	/**
614
+	 * Recursive function for cleaning cache file in the given directory
615
+	 *
616
+	 * @param string      $dir   directory complete path (with a trailing slash)
617
+	 * @param bool|string $group name of the cache group
618
+	 * @param string      $mode  flush cache mode : 'old', 'ingroup', 'notingroup',
619
+	 *                           'callback_myFunction'
620
+	 * @return bool true if no problem
621
+	 * @access private
622
+	 */
623
+	public function _cleanDir($dir, $group = false, $mode = 'ingroup')
624
+	{
625
+		if ($this->_fileNameProtection) {
626
+			$motif = $group ? 'cache_' . md5($group) . '_' : 'cache_';
627
+		} else {
628
+			$motif = $group ? 'cache_' . $group . '_' : 'cache_';
629
+		}
630
+		if ($this->_memoryCaching) {
631
+			foreach ($this->_memoryCachingArray as $key => $v) {
632
+				if (strpos($key, $motif) !== false) {
633
+					unset($this->_memoryCachingArray[$key]);
634
+					--$this->_memoryCachingCounter;
635
+				}
636
+			}
637
+			if ($this->_onlyMemoryCaching) {
638
+				return true;
639
+			}
640
+		}
641
+		if (!($dh = opendir($dir))) {
642
+			return $this->raiseError('Cache_Lite : Unable to open cache directory !', -4);
643
+		}
644
+		$result = true;
645
+		while ($file = readdir($dh)) {
646
+			if (($file !== '.') && ($file !== '..')) {
647
+				if (substr($file, 0, 6) === 'cache_') {
648
+					$file2 = $dir . $file;
649
+					if (is_file($file2)) {
650
+						switch (substr($mode, 0, 9)) {
651
+							case 'old':
652
+								// files older than lifeTime get deleted from cache
653
+								if (!is_null($this->_lifeTime)) {
654
+									if ((time() - @filemtime($file2)) > $this->_lifeTime) {
655
+										$result = ($result and $this->_unlink($file2));
656
+									}
657
+								}
658
+								break;
659
+							case 'notingrou':
660
+								if (strpos($file2, $motif) === false) {
661
+									$result = ($result and $this->_unlink($file2));
662
+								}
663
+								break;
664
+							case 'callback_':
665
+								$func = substr($mode, 9, strlen($mode) - 9);
666
+								if ($func($file2, $group)) {
667
+									$result = ($result and $this->_unlink($file2));
668
+								}
669
+								break;
670
+							case 'ingroup':
671
+							default:
672
+								if (strpos($file2, $motif) !== false) {
673
+									$result = ($result and $this->_unlink($file2));
674
+								}
675
+								break;
676
+						}
677
+					}
678
+					if (is_dir($file2) and ($this->_hashedDirectoryLevel > 0)) {
679
+						$result = ($result and $this->_cleanDir($file2 . '/', $group, $mode));
680
+					}
681
+				}
682
+			}
683
+		}
684
+
685
+		return $result;
686
+	}
687
+
688
+	/**
689
+	 * Add some date in the memory caching array
690
+	 *
691
+	 * @param string $data data to cache
692
+	 * @access private
693
+	 */
694
+	public function _memoryCacheAdd($data)
695
+	{
696
+		$this->_memoryCachingArray[$this->_file] = $data;
697
+		if ($this->_memoryCachingCounter >= $this->_memoryCachingLimit) {
698
+			list($key,) = each($this->_memoryCachingArray);
699
+			unset($this->_memoryCachingArray[$key]);
700
+		} else {
701
+			++$this->_memoryCachingCounter;
702
+		}
703
+	}
704
+
705
+	/**
706
+	 * Make a file name (with path)
707
+	 *
708
+	 * @param string $id    cache id
709
+	 * @param string $group name of the group
710
+	 * @access private
711
+	 */
712
+	public function _setFileName($id, $group)
713
+	{
714
+		if ($this->_fileNameProtection) {
715
+			$suffix = 'cache_' . md5($group) . '_' . md5($id);
716
+		} else {
717
+			$suffix = 'cache_' . $group . '_' . $id;
718
+		}
719
+		$root = $this->_cacheDir;
720
+		if ($this->_hashedDirectoryLevel > 0) {
721
+			$hash = md5($suffix);
722
+			for ($i = 0; $i < $this->_hashedDirectoryLevel; ++$i) {
723
+				$root = $root . 'cache_' . substr($hash, 0, $i + 1) . '/';
724
+			}
725
+		}
726
+		$this->_fileName = $suffix;
727
+		$this->_file     = $root . $suffix;
728
+	}
729
+
730
+	/**
731
+	 * Read the cache file and return the content
732
+	 *
733
+	 * @return string content of the cache file (else : false or a PEAR_Error object)
734
+	 * @access private
735
+	 */
736
+	public function _read()
737
+	{
738
+		$fp = @fopen($this->_file, 'rb');
739
+		if ($this->_fileLocking) {
740
+			@flock($fp, LOCK_SH);
741
+		}
742
+		if ($fp) {
743
+			clearstatcache();
744
+			$length = @filesize($this->_file);
745
+			//            $mqr = get_magic_quotes_runtime();
746
+			//            @set_magic_quotes_runtime(0);
747
+			if ($this->_readControl) {
748
+				$hashControl = @fread($fp, 32);
749
+				$length      = $length - 32;
750
+			}
751
+			if ($length) {
752
+				$data = @fread($fp, $length);
753
+			} else {
754
+				$data = '';
755
+			}
756
+			//            @set_magic_quotes_runtime($mqr);
757
+			if ($this->_fileLocking) {
758
+				@flock($fp, LOCK_UN);
759
+			}
760
+			@fclose($fp);
761
+			if ($this->_readControl) {
762
+				$hashData = $this->_hash($data, $this->_readControlType);
763
+				if ($hashData != $hashControl) {
764
+					if (!is_null($this->_lifeTime)) {
765
+						@touch($this->_file, time() - 2 * abs($this->_lifeTime));
766
+					} else {
767
+						@unlink($this->_file);
768
+					}
769
+
770
+					return false;
771
+				}
772
+			}
773
+
774
+			return $data;
775
+		}
776
+
777
+		return $this->raiseError('Cache_Lite : Unable to read cache !', -2);
778
+	}
779
+
780
+	/**
781
+	 * Write the given data in the cache file
782
+	 *
783
+	 * @param string $data data to put in cache
784
+	 * @return boolean true if ok (a PEAR_Error object else)
785
+	 * @access private
786
+	 */
787
+	public function _write($data)
788
+	{
789
+		if ($this->_hashedDirectoryLevel > 0) {
790
+			$hash = md5($this->_fileName);
791
+			$root = $this->_cacheDir;
792
+			for ($i = 0; $i < $this->_hashedDirectoryLevel; ++$i) {
793
+				$root = $root . 'cache_' . substr($hash, 0, $i + 1) . '/';
794
+				if (!(@is_dir($root))) {
795
+					@mkdir($root, $this->_hashedDirectoryUmask);
796
+				}
797
+			}
798
+		}
799
+		$fp = @fopen($this->_file, 'wb');
800
+		if ($fp) {
801
+			if ($this->_fileLocking) {
802
+				@flock($fp, LOCK_EX);
803
+			}
804
+			if ($this->_readControl) {
805
+				@fwrite($fp, $this->_hash($data, $this->_readControlType), 32);
806
+			}
807
+			//            $mqr = get_magic_quotes_runtime();
808
+			//            @set_magic_quotes_runtime(0);
809
+			@fwrite($fp, $data);
810
+			//            @set_magic_quotes_runtime($mqr);
811
+			if ($this->_fileLocking) {
812
+				@flock($fp, LOCK_UN);
813
+			}
814
+			@fclose($fp);
815
+
816
+			return true;
817
+		}
818
+
819
+		return $this->raiseError('Cache_Lite : Unable to write cache file : ' . $this->_file, -1);
820
+	}
821
+
822
+	/**
823
+	 * Write the given data in the cache file and control it just after to avoir corrupted cache entries
824
+	 *
825
+	 * @param string $data data to put in cache
826
+	 * @return boolean true if the test is ok (else : false or a PEAR_Error object)
827
+	 * @access private
828
+	 */
829
+	public function _writeAndControl($data)
830
+	{
831
+		$result = $this->_write($data);
832
+		if (is_object($result)) {
833
+			return $result; # We return the PEAR_Error object
834
+		}
835
+		$dataRead = $this->_read();
836
+		if (is_object($dataRead)) {
837
+			return $dataRead; # We return the PEAR_Error object
838
+		}
839
+		if (is_bool($dataRead) && (!$dataRead)) {
840
+			return false;
841
+		}
842
+
843
+		return ($dataRead == $data);
844
+	}
845
+
846
+	/**
847
+	 * Make a control key with the string containing datas
848
+	 *
849
+	 * @param string $data        data
850
+	 * @param string $controlType type of control 'md5', 'crc32' or 'strlen'
851
+	 * @return string control key
852
+	 * @access private
853
+	 */
854
+	public function _hash($data, $controlType)
855
+	{
856
+		switch ($controlType) {
857
+			case 'md5':
858
+				return md5($data);
859
+			case 'crc32':
860
+				return sprintf('% 32d', crc32($data));
861
+			case 'strlen':
862
+				return sprintf('% 32d', strlen($data));
863
+			default:
864
+				return $this->raiseError('Unknown controlType ! (available values are only \'md5\', \'crc32\', \'strlen\')', -5);
865
+		}
866
+	}
867 867
 }
Please login to merge, or discard this patch.
class/references_handlers.php 1 patch
Indentation   +27 added lines, -27 removed lines patch added patch discarded remove patch
@@ -24,34 +24,34 @@
 block discarded – undo
24 24
  */
25 25
 class references_handler
26 26
 {
27
-    public         $h_references_articles   = null;
28
-    public         $h_references_categories = null;
29
-    private static $instance                = false;
27
+	public         $h_references_articles   = null;
28
+	public         $h_references_categories = null;
29
+	private static $instance                = false;
30 30
 
31
-    /**
32
-     * Singleton
33
-     */
34
-    private function __construct()
35
-    {
36
-        $handlersNames = array('references_articles', 'references_categories');
37
-        foreach ($handlersNames as $handlerName) {
38
-            $internalName        = 'h_' . $handlerName;
39
-            $this->$internalName = xoops_getModuleHandler($handlerName, REFERENCES_DIRNAME);
40
-        }
41
-    }
31
+	/**
32
+	 * Singleton
33
+	 */
34
+	private function __construct()
35
+	{
36
+		$handlersNames = array('references_articles', 'references_categories');
37
+		foreach ($handlersNames as $handlerName) {
38
+			$internalName        = 'h_' . $handlerName;
39
+			$this->$internalName = xoops_getModuleHandler($handlerName, REFERENCES_DIRNAME);
40
+		}
41
+	}
42 42
 
43
-    /**
44
-     * Retourne l'instance unique de la clanss
45
-     *
46
-     * @return object
47
-     */
48
-    public static function getInstance()
49
-    {
50
-        static $instance;
51
-        if (null === $instance) {
52
-            $instance = new static();
53
-        }
43
+	/**
44
+	 * Retourne l'instance unique de la clanss
45
+	 *
46
+	 * @return object
47
+	 */
48
+	public static function getInstance()
49
+	{
50
+		static $instance;
51
+		if (null === $instance) {
52
+			$instance = new static();
53
+		}
54 54
 
55
-        return $instance;
56
-    }
55
+		return $instance;
56
+	}
57 57
 }
Please login to merge, or discard this patch.
class/registryfile.php 1 patch
Indentation   +57 added lines, -57 removed lines patch added patch discarded remove patch
@@ -21,68 +21,68 @@
 block discarded – undo
21 21
  */
22 22
 class references_registryfile
23 23
 {
24
-    public $filename;    // Nom du fichier ďż˝ traiter
24
+	public $filename;    // Nom du fichier ďż˝ traiter
25 25
 
26
-    /**
27
-     * Access the only instance of this class
28
-     *
29
-     * @return object
30
-     *
31
-     * @static
32
-     * @staticvar   object
33
-     */
34
-    public static function getInstance()
35
-    {
36
-        static $instance;
37
-        if (null === $instance) {
38
-            $instance = new static();
39
-        }
26
+	/**
27
+	 * Access the only instance of this class
28
+	 *
29
+	 * @return object
30
+	 *
31
+	 * @static
32
+	 * @staticvar   object
33
+	 */
34
+	public static function getInstance()
35
+	{
36
+		static $instance;
37
+		if (null === $instance) {
38
+			$instance = new static();
39
+		}
40 40
 
41
-        return $instance;
42
-    }
41
+		return $instance;
42
+	}
43 43
 
44
-    public function __construct($fichier = null)
45
-    {
46
-        $this->setfile($fichier);
47
-    }
44
+	public function __construct($fichier = null)
45
+	{
46
+		$this->setfile($fichier);
47
+	}
48 48
 
49
-    public function setfile($fichier = null)
50
-    {
51
-        if ($fichier) {
52
-            $this->filename = XOOPS_UPLOAD_PATH . DIRECTORY_SEPARATOR . $fichier;
53
-        }
54
-    }
49
+	public function setfile($fichier = null)
50
+	{
51
+		if ($fichier) {
52
+			$this->filename = XOOPS_UPLOAD_PATH . DIRECTORY_SEPARATOR . $fichier;
53
+		}
54
+	}
55 55
 
56
-    public function getfile($fichier = null)
57
-    {
58
-        $fw = '';
59
-        if (!$fichier) {
60
-            $fw = $this->filename;
61
-        } else {
62
-            $fw = XOOPS_UPLOAD_PATH . DIRECTORY_SEPARATOR . $fichier;
63
-        }
64
-        if (file_exists($fw)) {
65
-            return file_get_contents($fw);
66
-        } else {
67
-            return '';
68
-        }
69
-    }
56
+	public function getfile($fichier = null)
57
+	{
58
+		$fw = '';
59
+		if (!$fichier) {
60
+			$fw = $this->filename;
61
+		} else {
62
+			$fw = XOOPS_UPLOAD_PATH . DIRECTORY_SEPARATOR . $fichier;
63
+		}
64
+		if (file_exists($fw)) {
65
+			return file_get_contents($fw);
66
+		} else {
67
+			return '';
68
+		}
69
+	}
70 70
 
71
-    public function savefile($content, $fichier = null)
72
-    {
73
-        $fw = '';
74
-        if (!$fichier) {
75
-            $fw = $this->filename;
76
-        } else {
77
-            $fw = XOOPS_UPLOAD_PATH . DIRECTORY_SEPARATOR . $fichier;
78
-        }
79
-        if (file_exists($fw)) {
80
-            @unlink($fw);
81
-        }
82
-        $fp = fopen($fw, 'w') || exit('Error, impossible to create the file ' . $this->filename);
83
-        fwrite($fp, $content);
84
-        fclose($fp);
71
+	public function savefile($content, $fichier = null)
72
+	{
73
+		$fw = '';
74
+		if (!$fichier) {
75
+			$fw = $this->filename;
76
+		} else {
77
+			$fw = XOOPS_UPLOAD_PATH . DIRECTORY_SEPARATOR . $fichier;
78
+		}
79
+		if (file_exists($fw)) {
80
+			@unlink($fw);
81
+		}
82
+		$fp = fopen($fw, 'w') || exit('Error, impossible to create the file ' . $this->filename);
83
+		fwrite($fp, $content);
84
+		fclose($fp);
85 85
 
86
-        return true;
87
-    }
86
+		return true;
87
+	}
88 88
 }
Please login to merge, or discard this patch.
class/PEAR.php 1 patch
Indentation   +980 added lines, -980 removed lines patch added patch discarded remove patch
@@ -40,25 +40,25 @@  discard block
 block discarded – undo
40 40
 define('references_PEAR_ERROR_EXCEPTION', 32);
41 41
 /**#@-*/
42 42
 define('references_PEAR_ZE2', function_exists('version_compare')
43
-                              && version_compare(zend_version(), '2-dev', 'ge'));
43
+							  && version_compare(zend_version(), '2-dev', 'ge'));
44 44
 
45 45
 if (substr(PHP_OS, 0, 3) == 'WIN') {
46
-    define('references_OS_WINDOWS', true);
47
-    define('references_OS_UNIX', false);
48
-    define('references_PEAR_OS', 'Windows');
46
+	define('references_OS_WINDOWS', true);
47
+	define('references_OS_UNIX', false);
48
+	define('references_PEAR_OS', 'Windows');
49 49
 } else {
50
-    define('references_OS_WINDOWS', false);
51
-    define('references_OS_UNIX', true);
52
-    define('references_PEAR_OS', 'Unix'); // blatant assumption
50
+	define('references_OS_WINDOWS', false);
51
+	define('references_OS_UNIX', true);
52
+	define('references_PEAR_OS', 'Unix'); // blatant assumption
53 53
 }
54 54
 
55 55
 // instant backwards compatibility
56 56
 if (!defined('PATH_SEPARATOR')) {
57
-    if (references_OS_WINDOWS) {
58
-        define('PATH_SEPARATOR', ';');
59
-    } else {
60
-        define('PATH_SEPARATOR', ':');
61
-    }
57
+	if (references_OS_WINDOWS) {
58
+		define('PATH_SEPARATOR', ';');
59
+	} else {
60
+		define('PATH_SEPARATOR', ':');
61
+	}
62 62
 }
63 63
 
64 64
 $GLOBALS['_PEAR_default_error_mode']     = references_PEAR_ERROR_RETURN;
@@ -101,712 +101,712 @@  discard block
 block discarded – undo
101 101
  */
102 102
 class references_PEAR
103 103
 {
104
-    // {{{ properties
105
-
106
-    /**
107
-     * Whether to enable internal debug messages.
108
-     *
109
-     * @var bool
110
-     * @access  private
111
-     */
112
-    public $_debug = false;
113
-
114
-    /**
115
-     * Default error mode for this object.
116
-     *
117
-     * @var int
118
-     * @access  private
119
-     */
120
-    public $_default_error_mode = null;
121
-
122
-    /**
123
-     * Default error options used for this object when error mode
124
-     * is references_PEAR_ERROR_TRIGGER.
125
-     *
126
-     * @var int
127
-     * @access  private
128
-     */
129
-    public $_default_error_options = null;
130
-
131
-    /**
132
-     * Default error handler (callback) for this object, if error mode is
133
-     * references_PEAR_ERROR_CALLBACK.
134
-     *
135
-     * @var string
136
-     * @access  private
137
-     */
138
-    public $_default_error_handler = '';
139
-
140
-    /**
141
-     * Which class to use for error objects.
142
-     *
143
-     * @var string
144
-     * @access  private
145
-     */
146
-    public $_error_class = 'PEAR_Error';
147
-
148
-    /**
149
-     * An array of expected errors.
150
-     *
151
-     * @var array
152
-     * @access  private
153
-     */
154
-    public $_expected_errors = array();
155
-
156
-    // }}}
157
-
158
-    // {{{ constructor
159
-
160
-    /**
161
-     * Constructor.  Registers this object in
162
-     * $_PEAR_destructor_object_list for destructor emulation if a
163
-     * destructor object exists.
164
-     *
165
-     * @param  string $error_class (optional) which class to use for
166
-     *                             error objects, defaults to PEAR_Error.
167
-     * @access public
168
-     */
169
-    public function __construct($error_class = null)
170
-    {
171
-        $classname = strtolower(get_class($this));
172
-        if ($this->_debug) {
173
-            print "PEAR constructor called, class=$classname\n";
174
-        }
175
-        if ($error_class !== null) {
176
-            $this->_error_class = $error_class;
177
-        }
178
-        while ($classname && strcasecmp($classname, 'pear')) {
179
-            $destructor = "_$classname";
180
-            if (method_exists($this, $destructor)) {
181
-                global $_PEAR_destructor_object_list;
182
-                $_PEAR_destructor_object_list[] = &$this;
183
-                if (!isset($GLOBALS['_PEAR_SHUTDOWN_REGISTERED'])) {
184
-                    register_shutdown_function('references_PEAR_call_destructors');
185
-                    $GLOBALS['_PEAR_SHUTDOWN_REGISTERED'] = true;
186
-                }
187
-                break;
188
-            } else {
189
-                $classname = get_parent_class($classname);
190
-            }
191
-        }
192
-    }
193
-
194
-    // }}}
195
-    // {{{ destructor
196
-
197
-    /**
198
-     * Destructor (the emulated type of...).  Does nothing right now,
199
-     * but is included for forward compatibility, so subclass
200
-     * destructors should always call it.
201
-     *
202
-     * See the note in the class desciption about output from
203
-     * destructors.
204
-     *
205
-     * @access public
206
-     * @return void
207
-     */
208
-    public function _PEAR()
209
-    {
210
-        if ($this->_debug) {
211
-            printf("PEAR destructor called, class=%s\n", strtolower(get_class($this)));
212
-        }
213
-    }
214
-
215
-    // }}}
216
-    // {{{ getStaticProperty()
217
-
218
-    /**
219
-     * If you have a class that's mostly/entirely static, and you need static
220
-     * properties, you can use this method to simulate them. Eg. in your method(s)
221
-     * do this: $myVar = &references_PEAR::getStaticProperty('myclass', 'myVar');
222
-     * You MUST use a reference, or they will not persist!
223
-     *
224
-     * @access public
225
-     * @param  string $class The calling classname, to prevent clashes
226
-     * @param  string $var   The variable to retrieve.
227
-     * @return mixed   A reference to the variable. If not set it will be
228
-     *                       auto initialised to NULL.
229
-     */
230
-    public function &getStaticProperty($class, $var)
231
-    {
232
-        static $properties;
233
-        if (!isset($properties[$class])) {
234
-            $properties[$class] = array();
235
-        }
236
-        if (!array_key_exists($var, $properties[$class])) {
237
-            $properties[$class][$var] = null;
238
-        }
239
-
240
-        return $properties[$class][$var];
241
-    }
242
-
243
-    // }}}
244
-    // {{{ registerShutdownFunc()
245
-
246
-    /**
247
-     * Use this function to register a shutdown method for static
248
-     * classes.
249
-     *
250
-     * @access public
251
-     * @param  mixed $func The function name (or array of class/method) to call
252
-     * @param  mixed $args The arguments to pass to the function
253
-     * @return void
254
-     */
255
-    public function registerShutdownFunc($func, $args = array())
256
-    {
257
-        // if we are called statically, there is a potential
258
-        // that no shutdown func is registered.  Bug #6445
259
-        if (!isset($GLOBALS['_PEAR_SHUTDOWN_REGISTERED'])) {
260
-            register_shutdown_function('references__PEAR_call_destructors');
261
-            $GLOBALS['_PEAR_SHUTDOWN_REGISTERED'] = true;
262
-        }
263
-        $GLOBALS['_PEAR_shutdown_funcs'][] = array($func, $args);
264
-    }
265
-
266
-    // }}}
267
-    // {{{ isError()
268
-
269
-    /**
270
-     * Tell whether a value is a PEAR error.
271
-     *
272
-     * @param  mixed $data the value to test
273
-     * @param  int   $code if $data is an error object, return true
274
-     *                     only if $code is a string and
275
-     *                     $obj->getMessage() == $code or
276
-     *                     $code is an integer and $obj->getCode() == $code
277
-     * @access  public
278
-     * @return bool  true if parameter is an error
279
-     */
280
-    public function isError($data, $code = null)
281
-    {
282
-        if (is_a($data, 'PEAR_Error')) {
283
-            if (is_null($code)) {
284
-                return true;
285
-            } elseif (is_string($code)) {
286
-                return $data->getMessage() == $code;
287
-            } else {
288
-                return $data->getCode() == $code;
289
-            }
290
-        }
291
-
292
-        return false;
293
-    }
294
-
295
-    // }}}
296
-    // {{{ setErrorHandling()
297
-
298
-    /**
299
-     * Sets how errors generated by this object should be handled.
300
-     * Can be invoked both in objects and statically.  If called
301
-     * statically, setErrorHandling sets the default behaviour for all
302
-     * PEAR objects.  If called in an object, setErrorHandling sets
303
-     * the default behaviour for that object.
304
-     *
305
-     * @param int   $mode
306
-     *                       One of references_PEAR_ERROR_RETURN, references_PEAR_ERROR_PRINT,
307
-     *                       references_PEAR_ERROR_TRIGGER, references_PEAR_ERROR_DIE,
308
-     *                       references_PEAR_ERROR_CALLBACK or references_PEAR_ERROR_EXCEPTION.
309
-     *
310
-     * @param mixed $options
311
-     *                       When $mode is references_PEAR_ERROR_TRIGGER, this is the error level (one
312
-     *                       of E_USER_NOTICE, E_USER_WARNING or E_USER_ERROR).
313
-     *
314
-     *        When $mode is references_PEAR_ERROR_CALLBACK, this parameter is expected
315
-     *        to be the callback function or method.  A callback
316
-     *        function is a string with the name of the function, a
317
-     *        callback method is an array of two elements: the element
318
-     *        at index 0 is the object, and the element at index 1 is
319
-     *        the name of the method to call in the object.
320
-     *
321
-     *        When $mode is references_PEAR_ERROR_PRINT or references_PEAR_ERROR_DIE, this is
322
-     *        a printf format string used when printing the error
323
-     *        message.
324
-     *
325
-     * @access public
326
-     * @return void
327
-     * @see    references_PEAR_ERROR_RETURN
328
-     * @see    references_PEAR_ERROR_PRINT
329
-     * @see    references_PEAR_ERROR_TRIGGER
330
-     * @see    references_PEAR_ERROR_DIE
331
-     * @see    references_PEAR_ERROR_CALLBACK
332
-     * @see    references_PEAR_ERROR_EXCEPTION
333
-     *
334
-     */
335
-
336
-    public function setErrorHandling($mode = null, $options = null)
337
-    {
338
-        if (isset($this) && is_a($this, 'PEAR')) {
339
-            $setmode    = &$this->_default_error_mode;
340
-            $setoptions = &$this->_default_error_options;
341
-        } else {
342
-            $setmode    = &$GLOBALS['_PEAR_default_error_mode'];
343
-            $setoptions = &$GLOBALS['_PEAR_default_error_options'];
344
-        }
345
-
346
-        switch ($mode) {
347
-            case references_PEAR_ERROR_EXCEPTION:
348
-            case references_PEAR_ERROR_RETURN:
349
-            case references_PEAR_ERROR_PRINT:
350
-            case references_PEAR_ERROR_TRIGGER:
351
-            case references_PEAR_ERROR_DIE:
352
-            case null:
353
-                $setmode    = $mode;
354
-                $setoptions = $options;
355
-                break;
356
-
357
-            case references_PEAR_ERROR_CALLBACK:
358
-                $setmode = $mode;
359
-                // class/object method callback
360
-                if (is_callable($options)) {
361
-                    $setoptions = $options;
362
-                } else {
363
-                    trigger_error('invalid error callback', E_USER_WARNING);
364
-                }
365
-                break;
366
-
367
-            default:
368
-                trigger_error('invalid error mode', E_USER_WARNING);
369
-                break;
370
-        }
371
-    }
372
-
373
-    // }}}
374
-    // {{{ expectError()
375
-
376
-    /**
377
-     * This method is used to tell which errors you expect to get.
378
-     * Expected errors are always returned with error mode
379
-     * references_PEAR_ERROR_RETURN.  Expected error codes are stored in a stack,
380
-     * and this method pushes a new element onto it.  The list of
381
-     * expected errors are in effect until they are popped off the
382
-     * stack with the popExpect() method.
383
-     *
384
-     * Note that this method can not be called statically
385
-     *
386
-     * @param mixed $code a single error code or an array of error codes to expect
387
-     *
388
-     * @return int the new depth of the "expected errors" stack
389
-     * @access public
390
-     */
391
-    public function expectError($code = '*')
392
-    {
393
-        if (is_array($code)) {
394
-            array_push($this->_expected_errors, $code);
395
-        } else {
396
-            array_push($this->_expected_errors, array($code));
397
-        }
398
-
399
-        return count($this->_expected_errors);
400
-    }
401
-
402
-    // }}}
403
-    // {{{ popExpect()
404
-
405
-    /**
406
-     * This method pops one element off the expected error codes
407
-     * stack.
408
-     *
409
-     * @return array the list of error codes that were popped
410
-     */
411
-    public function popExpect()
412
-    {
413
-        return array_pop($this->_expected_errors);
414
-    }
415
-
416
-    // }}}
417
-    // {{{ _checkDelExpect()
418
-
419
-    /**
420
-     * This method checks unsets an error code if available
421
-     *
422
-     * @param mixed error code
423
-     * @return bool true if the error code was unset, false otherwise
424
-     * @access private
425
-     */
426
-    public function _checkDelExpect($error_code)
427
-    {
428
-        $deleted = false;
429
-
430
-        foreach ($this->_expected_errors as $key => $error_array) {
431
-            if (in_array($error_code, $error_array)) {
432
-                unset($this->_expected_errors[$key][array_search($error_code, $error_array)]);
433
-                $deleted = true;
434
-            }
435
-
436
-            // clean up empty arrays
437
-            if (0 == count($this->_expected_errors[$key])) {
438
-                unset($this->_expected_errors[$key]);
439
-            }
440
-        }
441
-
442
-        return $deleted;
443
-    }
444
-
445
-    // }}}
446
-    // {{{ delExpect()
447
-
448
-    /**
449
-     * This method deletes all occurences of the specified element from
450
-     * the expected error codes stack.
451
-     *
452
-     * @param  mixed $error_code error code that should be deleted
453
-     * @return mixed list of error codes that were deleted or error
454
-     * @access public
455
-     */
456
-    public function delExpect($error_code)
457
-    {
458
-        $deleted = false;
459
-
460
-        if (is_array($error_code) && (0 != count($error_code))) {
461
-            // $error_code is a non-empty array here;
462
-            // we walk through it trying to unset all
463
-            // values
464
-            foreach ($error_code as $key => $error) {
465
-                if ($this->_checkDelExpect($error)) {
466
-                    $deleted = true;
467
-                } else {
468
-                    $deleted = false;
469
-                }
470
-            }
471
-
472
-            return $deleted ? true : references_PEAR::raiseError('The expected error you submitted does not exist'); // IMPROVE ME
473
-        } elseif (!empty($error_code)) {
474
-            // $error_code comes alone, trying to unset it
475
-            if ($this->_checkDelExpect($error_code)) {
476
-                return true;
477
-            } else {
478
-                return references_PEAR::raiseError('The expected error you submitted does not exist'); // IMPROVE ME
479
-            }
480
-        } else {
481
-            // $error_code is empty
482
-            return references_PEAR::raiseError('The expected error you submitted is empty'); // IMPROVE ME
483
-        }
484
-    }
485
-
486
-    // }}}
487
-    // {{{ raiseError()
488
-
489
-    /**
490
-     * This method is a wrapper that returns an instance of the
491
-     * configured error class with this object's default error
492
-     * handling applied.  If the $mode and $options parameters are not
493
-     * specified, the object's defaults are used.
494
-     *
495
-     * @param mixed  $message     a text error message or a PEAR error object
496
-     *
497
-     * @param int    $code        a numeric error code (it is up to your class
498
-     *                            to define these if you want to use codes)
499
-     *
500
-     * @param int    $mode        One of references_PEAR_ERROR_RETURN, references_PEAR_ERROR_PRINT,
501
-     *                            references_PEAR_ERROR_TRIGGER, references_PEAR_ERROR_DIE,
502
-     *                            references_PEAR_ERROR_CALLBACK, references_PEAR_ERROR_EXCEPTION.
503
-     *
504
-     * @param mixed  $options     If $mode is references_PEAR_ERROR_TRIGGER, this parameter
505
-     *                            specifies the PHP-internal error level (one of
506
-     *                            E_USER_NOTICE, E_USER_WARNING or E_USER_ERROR).
507
-     *                            If $mode is references_PEAR_ERROR_CALLBACK, this
508
-     *                            parameter specifies the callback function or
509
-     *                            method.  In other error modes this parameter
510
-     *                            is ignored.
511
-     *
512
-     * @param string $userinfo    If you need to pass along for example debug
513
-     *                            information, this parameter is meant for that.
514
-     *
515
-     * @param string $error_class The returned error object will be
516
-     *                            instantiated from this class, if specified.
517
-     *
518
-     * @param bool   $skipmsg     If true, raiseError will only pass error codes,
519
-     *                            the error message parameter will be dropped.
520
-     *
521
-     * @access public
522
-     * @return object a PEAR error object
523
-     * @see    references_PEAR::setErrorHandling
524
-     * @since  PHP 4.0.5
525
-     */
526
-    public function &raiseError($message = null, $code = null, $mode = null, $options = null, $userinfo = null, $error_class = null, $skipmsg = false)
527
-    {
528
-        // The error is yet a PEAR error object
529
-        if (is_object($message)) {
530
-            $code                          = $message->getCode();
531
-            $userinfo                      = $message->getUserInfo();
532
-            $error_class                   = $message->getType();
533
-            $message->error_message_prefix = '';
534
-            $message                       = $message->getMessage();
535
-        }
536
-
537
-        if (isset($this) && isset($this->_expected_errors) && count($this->_expected_errors) > 0 && count($exp = end($this->_expected_errors))) {
538
-            if ($exp[0] === '*'
539
-                || (is_int(reset($exp)) && in_array($code, $exp))
540
-                || (is_string(reset($exp)) && in_array($message, $exp))
541
-            ) {
542
-                $mode = references_PEAR_ERROR_RETURN;
543
-            }
544
-        }
545
-        // No mode given, try global ones
546
-        if ($mode === null) {
547
-            // Class error handler
548
-            if (isset($this) && isset($this->_default_error_mode)) {
549
-                $mode    = $this->_default_error_mode;
550
-                $options = $this->_default_error_options;
551
-                // Global error handler
552
-            } elseif (isset($GLOBALS['_PEAR_default_error_mode'])) {
553
-                $mode    = $GLOBALS['_PEAR_default_error_mode'];
554
-                $options = $GLOBALS['_PEAR_default_error_options'];
555
-            }
556
-        }
557
-
558
-        if ($error_class !== null) {
559
-            $ec = $error_class;
560
-        } elseif (isset($this) && isset($this->_error_class)) {
561
-            $ec = $this->_error_class;
562
-        } else {
563
-            $ec = 'references_PEAR_Error';
564
-        }
565
-        if ($skipmsg) {
566
-            $a = new $ec($code, $mode, $options, $userinfo);
567
-
568
-            return $a;
569
-        } else {
570
-            $a = new $ec($message, $code, $mode, $options, $userinfo);
571
-
572
-            return $a;
573
-        }
574
-    }
575
-
576
-    // }}}
577
-    // {{{ throwError()
578
-
579
-    /**
580
-     * Simpler form of raiseError with fewer options.  In most cases
581
-     * message, code and userinfo are enough.
582
-     *
583
-     * @param string $message
584
-     *
585
-     * @param null   $code
586
-     * @param null   $userinfo
587
-     * @return object
588
-     */
589
-    public function &throwError($message = null, $code = null, $userinfo = null)
590
-    {
591
-        if (isset($this) && is_a($this, 'PEAR')) {
592
-            $a = &$this->raiseError($message, $code, null, null, $userinfo);
593
-
594
-            return $a;
595
-        } else {
596
-            $a = &references_PEAR::raiseError($message, $code, null, null, $userinfo);
597
-
598
-            return $a;
599
-        }
600
-    }
601
-
602
-    // }}}
603
-    public function staticPushErrorHandling($mode, $options = null)
604
-    {
605
-        $stack       = &$GLOBALS['_PEAR_error_handler_stack'];
606
-        $def_mode    = &$GLOBALS['_PEAR_default_error_mode'];
607
-        $def_options = &$GLOBALS['_PEAR_default_error_options'];
608
-        $stack[]     = array($def_mode, $def_options);
609
-        switch ($mode) {
610
-            case references_PEAR_ERROR_EXCEPTION:
611
-            case references_PEAR_ERROR_RETURN:
612
-            case references_PEAR_ERROR_PRINT:
613
-            case references_PEAR_ERROR_TRIGGER:
614
-            case references_PEAR_ERROR_DIE:
615
-            case null:
616
-                $def_mode    = $mode;
617
-                $def_options = $options;
618
-                break;
619
-
620
-            case references_PEAR_ERROR_CALLBACK:
621
-                $def_mode = $mode;
622
-                // class/object method callback
623
-                if (is_callable($options)) {
624
-                    $def_options = $options;
625
-                } else {
626
-                    trigger_error('invalid error callback', E_USER_WARNING);
627
-                }
628
-                break;
629
-
630
-            default:
631
-                trigger_error('invalid error mode', E_USER_WARNING);
632
-                break;
633
-        }
634
-        $stack[] = array($mode, $options);
635
-
636
-        return true;
637
-    }
638
-
639
-    public function staticPopErrorHandling()
640
-    {
641
-        $stack      = &$GLOBALS['_PEAR_error_handler_stack'];
642
-        $setmode    = &$GLOBALS['_PEAR_default_error_mode'];
643
-        $setoptions = &$GLOBALS['_PEAR_default_error_options'];
644
-        array_pop($stack);
645
-        list($mode, $options) = $stack[count($stack) - 1];
646
-        array_pop($stack);
647
-        switch ($mode) {
648
-            case references_PEAR_ERROR_EXCEPTION:
649
-            case references_PEAR_ERROR_RETURN:
650
-            case references_PEAR_ERROR_PRINT:
651
-            case references_PEAR_ERROR_TRIGGER:
652
-            case references_PEAR_ERROR_DIE:
653
-            case null:
654
-                $setmode    = $mode;
655
-                $setoptions = $options;
656
-                break;
657
-
658
-            case references_PEAR_ERROR_CALLBACK:
659
-                $setmode = $mode;
660
-                // class/object method callback
661
-                if (is_callable($options)) {
662
-                    $setoptions = $options;
663
-                } else {
664
-                    trigger_error('invalid error callback', E_USER_WARNING);
665
-                }
666
-                break;
667
-
668
-            default:
669
-                trigger_error('invalid error mode', E_USER_WARNING);
670
-                break;
671
-        }
672
-
673
-        return true;
674
-    }
675
-
676
-    // {{{ pushErrorHandling()
677
-
678
-    /**
679
-     * Push a new error handler on top of the error handler options stack. With this
680
-     * you can easily override the actual error handler for some code and restore
681
-     * it later with popErrorHandling.
682
-     *
683
-     * @param mixed $mode    (same as setErrorHandling)
684
-     * @param mixed $options (same as setErrorHandling)
685
-     *
686
-     * @return bool Always true
687
-     *
688
-     * @see references_PEAR::setErrorHandling
689
-     */
690
-    public function pushErrorHandling($mode, $options = null)
691
-    {
692
-        $stack = &$GLOBALS['_PEAR_error_handler_stack'];
693
-        if (isset($this) && is_a($this, 'PEAR')) {
694
-            $def_mode    = &$this->_default_error_mode;
695
-            $def_options = &$this->_default_error_options;
696
-        } else {
697
-            $def_mode    = &$GLOBALS['_PEAR_default_error_mode'];
698
-            $def_options = &$GLOBALS['_PEAR_default_error_options'];
699
-        }
700
-        $stack[] = array($def_mode, $def_options);
701
-
702
-        if (isset($this) && is_a($this, 'PEAR')) {
703
-            $this->setErrorHandling($mode, $options);
704
-        } else {
705
-            references_PEAR::setErrorHandling($mode, $options);
706
-        }
707
-        $stack[] = array($mode, $options);
708
-
709
-        return true;
710
-    }
711
-
712
-    // }}}
713
-    // {{{ popErrorHandling()
714
-
715
-    /**
716
-     * Pop the last error handler used
717
-     *
718
-     * @return bool Always true
719
-     *
720
-     * @see references_PEAR::pushErrorHandling
721
-     */
722
-    public function popErrorHandling()
723
-    {
724
-        $stack = &$GLOBALS['_PEAR_error_handler_stack'];
725
-        array_pop($stack);
726
-        list($mode, $options) = $stack[count($stack) - 1];
727
-        array_pop($stack);
728
-        if (isset($this) && is_a($this, 'PEAR')) {
729
-            $this->setErrorHandling($mode, $options);
730
-        } else {
731
-            references_PEAR::setErrorHandling($mode, $options);
732
-        }
733
-
734
-        return true;
735
-    }
736
-
737
-    // }}}
738
-    // {{{ loadExtension()
739
-
740
-    /**
741
-     * OS independant PHP extension load. Remember to take care
742
-     * on the correct extension name for case sensitive OSes.
743
-     *
744
-     * @param string $ext The extension name
745
-     * @return bool Success or not on the dl() call
746
-     */
747
-    public function loadExtension($ext)
748
-    {
749
-        if (!extension_loaded($ext)) {
750
-            // if either returns true dl() will produce a FATAL error, stop that
751
-            if ((ini_get('enable_dl') != 1) || (ini_get('safe_mode') == 1)) {
752
-                return false;
753
-            }
754
-            if (references_OS_WINDOWS) {
755
-                $suffix = '.dll';
756
-            } elseif (PHP_OS === 'HP-UX') {
757
-                $suffix = '.sl';
758
-            } elseif (PHP_OS === 'AIX') {
759
-                $suffix = '.a';
760
-            } elseif (PHP_OS === 'OSX') {
761
-                $suffix = '.bundle';
762
-            } else {
763
-                $suffix = '.so';
764
-            }
765
-
766
-            return @dl('php_' . $ext . $suffix) || @dl($ext . $suffix);
767
-        }
768
-
769
-        return true;
770
-    }
771
-
772
-    // }}}
104
+	// {{{ properties
105
+
106
+	/**
107
+	 * Whether to enable internal debug messages.
108
+	 *
109
+	 * @var bool
110
+	 * @access  private
111
+	 */
112
+	public $_debug = false;
113
+
114
+	/**
115
+	 * Default error mode for this object.
116
+	 *
117
+	 * @var int
118
+	 * @access  private
119
+	 */
120
+	public $_default_error_mode = null;
121
+
122
+	/**
123
+	 * Default error options used for this object when error mode
124
+	 * is references_PEAR_ERROR_TRIGGER.
125
+	 *
126
+	 * @var int
127
+	 * @access  private
128
+	 */
129
+	public $_default_error_options = null;
130
+
131
+	/**
132
+	 * Default error handler (callback) for this object, if error mode is
133
+	 * references_PEAR_ERROR_CALLBACK.
134
+	 *
135
+	 * @var string
136
+	 * @access  private
137
+	 */
138
+	public $_default_error_handler = '';
139
+
140
+	/**
141
+	 * Which class to use for error objects.
142
+	 *
143
+	 * @var string
144
+	 * @access  private
145
+	 */
146
+	public $_error_class = 'PEAR_Error';
147
+
148
+	/**
149
+	 * An array of expected errors.
150
+	 *
151
+	 * @var array
152
+	 * @access  private
153
+	 */
154
+	public $_expected_errors = array();
155
+
156
+	// }}}
157
+
158
+	// {{{ constructor
159
+
160
+	/**
161
+	 * Constructor.  Registers this object in
162
+	 * $_PEAR_destructor_object_list for destructor emulation if a
163
+	 * destructor object exists.
164
+	 *
165
+	 * @param  string $error_class (optional) which class to use for
166
+	 *                             error objects, defaults to PEAR_Error.
167
+	 * @access public
168
+	 */
169
+	public function __construct($error_class = null)
170
+	{
171
+		$classname = strtolower(get_class($this));
172
+		if ($this->_debug) {
173
+			print "PEAR constructor called, class=$classname\n";
174
+		}
175
+		if ($error_class !== null) {
176
+			$this->_error_class = $error_class;
177
+		}
178
+		while ($classname && strcasecmp($classname, 'pear')) {
179
+			$destructor = "_$classname";
180
+			if (method_exists($this, $destructor)) {
181
+				global $_PEAR_destructor_object_list;
182
+				$_PEAR_destructor_object_list[] = &$this;
183
+				if (!isset($GLOBALS['_PEAR_SHUTDOWN_REGISTERED'])) {
184
+					register_shutdown_function('references_PEAR_call_destructors');
185
+					$GLOBALS['_PEAR_SHUTDOWN_REGISTERED'] = true;
186
+				}
187
+				break;
188
+			} else {
189
+				$classname = get_parent_class($classname);
190
+			}
191
+		}
192
+	}
193
+
194
+	// }}}
195
+	// {{{ destructor
196
+
197
+	/**
198
+	 * Destructor (the emulated type of...).  Does nothing right now,
199
+	 * but is included for forward compatibility, so subclass
200
+	 * destructors should always call it.
201
+	 *
202
+	 * See the note in the class desciption about output from
203
+	 * destructors.
204
+	 *
205
+	 * @access public
206
+	 * @return void
207
+	 */
208
+	public function _PEAR()
209
+	{
210
+		if ($this->_debug) {
211
+			printf("PEAR destructor called, class=%s\n", strtolower(get_class($this)));
212
+		}
213
+	}
214
+
215
+	// }}}
216
+	// {{{ getStaticProperty()
217
+
218
+	/**
219
+	 * If you have a class that's mostly/entirely static, and you need static
220
+	 * properties, you can use this method to simulate them. Eg. in your method(s)
221
+	 * do this: $myVar = &references_PEAR::getStaticProperty('myclass', 'myVar');
222
+	 * You MUST use a reference, or they will not persist!
223
+	 *
224
+	 * @access public
225
+	 * @param  string $class The calling classname, to prevent clashes
226
+	 * @param  string $var   The variable to retrieve.
227
+	 * @return mixed   A reference to the variable. If not set it will be
228
+	 *                       auto initialised to NULL.
229
+	 */
230
+	public function &getStaticProperty($class, $var)
231
+	{
232
+		static $properties;
233
+		if (!isset($properties[$class])) {
234
+			$properties[$class] = array();
235
+		}
236
+		if (!array_key_exists($var, $properties[$class])) {
237
+			$properties[$class][$var] = null;
238
+		}
239
+
240
+		return $properties[$class][$var];
241
+	}
242
+
243
+	// }}}
244
+	// {{{ registerShutdownFunc()
245
+
246
+	/**
247
+	 * Use this function to register a shutdown method for static
248
+	 * classes.
249
+	 *
250
+	 * @access public
251
+	 * @param  mixed $func The function name (or array of class/method) to call
252
+	 * @param  mixed $args The arguments to pass to the function
253
+	 * @return void
254
+	 */
255
+	public function registerShutdownFunc($func, $args = array())
256
+	{
257
+		// if we are called statically, there is a potential
258
+		// that no shutdown func is registered.  Bug #6445
259
+		if (!isset($GLOBALS['_PEAR_SHUTDOWN_REGISTERED'])) {
260
+			register_shutdown_function('references__PEAR_call_destructors');
261
+			$GLOBALS['_PEAR_SHUTDOWN_REGISTERED'] = true;
262
+		}
263
+		$GLOBALS['_PEAR_shutdown_funcs'][] = array($func, $args);
264
+	}
265
+
266
+	// }}}
267
+	// {{{ isError()
268
+
269
+	/**
270
+	 * Tell whether a value is a PEAR error.
271
+	 *
272
+	 * @param  mixed $data the value to test
273
+	 * @param  int   $code if $data is an error object, return true
274
+	 *                     only if $code is a string and
275
+	 *                     $obj->getMessage() == $code or
276
+	 *                     $code is an integer and $obj->getCode() == $code
277
+	 * @access  public
278
+	 * @return bool  true if parameter is an error
279
+	 */
280
+	public function isError($data, $code = null)
281
+	{
282
+		if (is_a($data, 'PEAR_Error')) {
283
+			if (is_null($code)) {
284
+				return true;
285
+			} elseif (is_string($code)) {
286
+				return $data->getMessage() == $code;
287
+			} else {
288
+				return $data->getCode() == $code;
289
+			}
290
+		}
291
+
292
+		return false;
293
+	}
294
+
295
+	// }}}
296
+	// {{{ setErrorHandling()
297
+
298
+	/**
299
+	 * Sets how errors generated by this object should be handled.
300
+	 * Can be invoked both in objects and statically.  If called
301
+	 * statically, setErrorHandling sets the default behaviour for all
302
+	 * PEAR objects.  If called in an object, setErrorHandling sets
303
+	 * the default behaviour for that object.
304
+	 *
305
+	 * @param int   $mode
306
+	 *                       One of references_PEAR_ERROR_RETURN, references_PEAR_ERROR_PRINT,
307
+	 *                       references_PEAR_ERROR_TRIGGER, references_PEAR_ERROR_DIE,
308
+	 *                       references_PEAR_ERROR_CALLBACK or references_PEAR_ERROR_EXCEPTION.
309
+	 *
310
+	 * @param mixed $options
311
+	 *                       When $mode is references_PEAR_ERROR_TRIGGER, this is the error level (one
312
+	 *                       of E_USER_NOTICE, E_USER_WARNING or E_USER_ERROR).
313
+	 *
314
+	 *        When $mode is references_PEAR_ERROR_CALLBACK, this parameter is expected
315
+	 *        to be the callback function or method.  A callback
316
+	 *        function is a string with the name of the function, a
317
+	 *        callback method is an array of two elements: the element
318
+	 *        at index 0 is the object, and the element at index 1 is
319
+	 *        the name of the method to call in the object.
320
+	 *
321
+	 *        When $mode is references_PEAR_ERROR_PRINT or references_PEAR_ERROR_DIE, this is
322
+	 *        a printf format string used when printing the error
323
+	 *        message.
324
+	 *
325
+	 * @access public
326
+	 * @return void
327
+	 * @see    references_PEAR_ERROR_RETURN
328
+	 * @see    references_PEAR_ERROR_PRINT
329
+	 * @see    references_PEAR_ERROR_TRIGGER
330
+	 * @see    references_PEAR_ERROR_DIE
331
+	 * @see    references_PEAR_ERROR_CALLBACK
332
+	 * @see    references_PEAR_ERROR_EXCEPTION
333
+	 *
334
+	 */
335
+
336
+	public function setErrorHandling($mode = null, $options = null)
337
+	{
338
+		if (isset($this) && is_a($this, 'PEAR')) {
339
+			$setmode    = &$this->_default_error_mode;
340
+			$setoptions = &$this->_default_error_options;
341
+		} else {
342
+			$setmode    = &$GLOBALS['_PEAR_default_error_mode'];
343
+			$setoptions = &$GLOBALS['_PEAR_default_error_options'];
344
+		}
345
+
346
+		switch ($mode) {
347
+			case references_PEAR_ERROR_EXCEPTION:
348
+			case references_PEAR_ERROR_RETURN:
349
+			case references_PEAR_ERROR_PRINT:
350
+			case references_PEAR_ERROR_TRIGGER:
351
+			case references_PEAR_ERROR_DIE:
352
+			case null:
353
+				$setmode    = $mode;
354
+				$setoptions = $options;
355
+				break;
356
+
357
+			case references_PEAR_ERROR_CALLBACK:
358
+				$setmode = $mode;
359
+				// class/object method callback
360
+				if (is_callable($options)) {
361
+					$setoptions = $options;
362
+				} else {
363
+					trigger_error('invalid error callback', E_USER_WARNING);
364
+				}
365
+				break;
366
+
367
+			default:
368
+				trigger_error('invalid error mode', E_USER_WARNING);
369
+				break;
370
+		}
371
+	}
372
+
373
+	// }}}
374
+	// {{{ expectError()
375
+
376
+	/**
377
+	 * This method is used to tell which errors you expect to get.
378
+	 * Expected errors are always returned with error mode
379
+	 * references_PEAR_ERROR_RETURN.  Expected error codes are stored in a stack,
380
+	 * and this method pushes a new element onto it.  The list of
381
+	 * expected errors are in effect until they are popped off the
382
+	 * stack with the popExpect() method.
383
+	 *
384
+	 * Note that this method can not be called statically
385
+	 *
386
+	 * @param mixed $code a single error code or an array of error codes to expect
387
+	 *
388
+	 * @return int the new depth of the "expected errors" stack
389
+	 * @access public
390
+	 */
391
+	public function expectError($code = '*')
392
+	{
393
+		if (is_array($code)) {
394
+			array_push($this->_expected_errors, $code);
395
+		} else {
396
+			array_push($this->_expected_errors, array($code));
397
+		}
398
+
399
+		return count($this->_expected_errors);
400
+	}
401
+
402
+	// }}}
403
+	// {{{ popExpect()
404
+
405
+	/**
406
+	 * This method pops one element off the expected error codes
407
+	 * stack.
408
+	 *
409
+	 * @return array the list of error codes that were popped
410
+	 */
411
+	public function popExpect()
412
+	{
413
+		return array_pop($this->_expected_errors);
414
+	}
415
+
416
+	// }}}
417
+	// {{{ _checkDelExpect()
418
+
419
+	/**
420
+	 * This method checks unsets an error code if available
421
+	 *
422
+	 * @param mixed error code
423
+	 * @return bool true if the error code was unset, false otherwise
424
+	 * @access private
425
+	 */
426
+	public function _checkDelExpect($error_code)
427
+	{
428
+		$deleted = false;
429
+
430
+		foreach ($this->_expected_errors as $key => $error_array) {
431
+			if (in_array($error_code, $error_array)) {
432
+				unset($this->_expected_errors[$key][array_search($error_code, $error_array)]);
433
+				$deleted = true;
434
+			}
435
+
436
+			// clean up empty arrays
437
+			if (0 == count($this->_expected_errors[$key])) {
438
+				unset($this->_expected_errors[$key]);
439
+			}
440
+		}
441
+
442
+		return $deleted;
443
+	}
444
+
445
+	// }}}
446
+	// {{{ delExpect()
447
+
448
+	/**
449
+	 * This method deletes all occurences of the specified element from
450
+	 * the expected error codes stack.
451
+	 *
452
+	 * @param  mixed $error_code error code that should be deleted
453
+	 * @return mixed list of error codes that were deleted or error
454
+	 * @access public
455
+	 */
456
+	public function delExpect($error_code)
457
+	{
458
+		$deleted = false;
459
+
460
+		if (is_array($error_code) && (0 != count($error_code))) {
461
+			// $error_code is a non-empty array here;
462
+			// we walk through it trying to unset all
463
+			// values
464
+			foreach ($error_code as $key => $error) {
465
+				if ($this->_checkDelExpect($error)) {
466
+					$deleted = true;
467
+				} else {
468
+					$deleted = false;
469
+				}
470
+			}
471
+
472
+			return $deleted ? true : references_PEAR::raiseError('The expected error you submitted does not exist'); // IMPROVE ME
473
+		} elseif (!empty($error_code)) {
474
+			// $error_code comes alone, trying to unset it
475
+			if ($this->_checkDelExpect($error_code)) {
476
+				return true;
477
+			} else {
478
+				return references_PEAR::raiseError('The expected error you submitted does not exist'); // IMPROVE ME
479
+			}
480
+		} else {
481
+			// $error_code is empty
482
+			return references_PEAR::raiseError('The expected error you submitted is empty'); // IMPROVE ME
483
+		}
484
+	}
485
+
486
+	// }}}
487
+	// {{{ raiseError()
488
+
489
+	/**
490
+	 * This method is a wrapper that returns an instance of the
491
+	 * configured error class with this object's default error
492
+	 * handling applied.  If the $mode and $options parameters are not
493
+	 * specified, the object's defaults are used.
494
+	 *
495
+	 * @param mixed  $message     a text error message or a PEAR error object
496
+	 *
497
+	 * @param int    $code        a numeric error code (it is up to your class
498
+	 *                            to define these if you want to use codes)
499
+	 *
500
+	 * @param int    $mode        One of references_PEAR_ERROR_RETURN, references_PEAR_ERROR_PRINT,
501
+	 *                            references_PEAR_ERROR_TRIGGER, references_PEAR_ERROR_DIE,
502
+	 *                            references_PEAR_ERROR_CALLBACK, references_PEAR_ERROR_EXCEPTION.
503
+	 *
504
+	 * @param mixed  $options     If $mode is references_PEAR_ERROR_TRIGGER, this parameter
505
+	 *                            specifies the PHP-internal error level (one of
506
+	 *                            E_USER_NOTICE, E_USER_WARNING or E_USER_ERROR).
507
+	 *                            If $mode is references_PEAR_ERROR_CALLBACK, this
508
+	 *                            parameter specifies the callback function or
509
+	 *                            method.  In other error modes this parameter
510
+	 *                            is ignored.
511
+	 *
512
+	 * @param string $userinfo    If you need to pass along for example debug
513
+	 *                            information, this parameter is meant for that.
514
+	 *
515
+	 * @param string $error_class The returned error object will be
516
+	 *                            instantiated from this class, if specified.
517
+	 *
518
+	 * @param bool   $skipmsg     If true, raiseError will only pass error codes,
519
+	 *                            the error message parameter will be dropped.
520
+	 *
521
+	 * @access public
522
+	 * @return object a PEAR error object
523
+	 * @see    references_PEAR::setErrorHandling
524
+	 * @since  PHP 4.0.5
525
+	 */
526
+	public function &raiseError($message = null, $code = null, $mode = null, $options = null, $userinfo = null, $error_class = null, $skipmsg = false)
527
+	{
528
+		// The error is yet a PEAR error object
529
+		if (is_object($message)) {
530
+			$code                          = $message->getCode();
531
+			$userinfo                      = $message->getUserInfo();
532
+			$error_class                   = $message->getType();
533
+			$message->error_message_prefix = '';
534
+			$message                       = $message->getMessage();
535
+		}
536
+
537
+		if (isset($this) && isset($this->_expected_errors) && count($this->_expected_errors) > 0 && count($exp = end($this->_expected_errors))) {
538
+			if ($exp[0] === '*'
539
+				|| (is_int(reset($exp)) && in_array($code, $exp))
540
+				|| (is_string(reset($exp)) && in_array($message, $exp))
541
+			) {
542
+				$mode = references_PEAR_ERROR_RETURN;
543
+			}
544
+		}
545
+		// No mode given, try global ones
546
+		if ($mode === null) {
547
+			// Class error handler
548
+			if (isset($this) && isset($this->_default_error_mode)) {
549
+				$mode    = $this->_default_error_mode;
550
+				$options = $this->_default_error_options;
551
+				// Global error handler
552
+			} elseif (isset($GLOBALS['_PEAR_default_error_mode'])) {
553
+				$mode    = $GLOBALS['_PEAR_default_error_mode'];
554
+				$options = $GLOBALS['_PEAR_default_error_options'];
555
+			}
556
+		}
557
+
558
+		if ($error_class !== null) {
559
+			$ec = $error_class;
560
+		} elseif (isset($this) && isset($this->_error_class)) {
561
+			$ec = $this->_error_class;
562
+		} else {
563
+			$ec = 'references_PEAR_Error';
564
+		}
565
+		if ($skipmsg) {
566
+			$a = new $ec($code, $mode, $options, $userinfo);
567
+
568
+			return $a;
569
+		} else {
570
+			$a = new $ec($message, $code, $mode, $options, $userinfo);
571
+
572
+			return $a;
573
+		}
574
+	}
575
+
576
+	// }}}
577
+	// {{{ throwError()
578
+
579
+	/**
580
+	 * Simpler form of raiseError with fewer options.  In most cases
581
+	 * message, code and userinfo are enough.
582
+	 *
583
+	 * @param string $message
584
+	 *
585
+	 * @param null   $code
586
+	 * @param null   $userinfo
587
+	 * @return object
588
+	 */
589
+	public function &throwError($message = null, $code = null, $userinfo = null)
590
+	{
591
+		if (isset($this) && is_a($this, 'PEAR')) {
592
+			$a = &$this->raiseError($message, $code, null, null, $userinfo);
593
+
594
+			return $a;
595
+		} else {
596
+			$a = &references_PEAR::raiseError($message, $code, null, null, $userinfo);
597
+
598
+			return $a;
599
+		}
600
+	}
601
+
602
+	// }}}
603
+	public function staticPushErrorHandling($mode, $options = null)
604
+	{
605
+		$stack       = &$GLOBALS['_PEAR_error_handler_stack'];
606
+		$def_mode    = &$GLOBALS['_PEAR_default_error_mode'];
607
+		$def_options = &$GLOBALS['_PEAR_default_error_options'];
608
+		$stack[]     = array($def_mode, $def_options);
609
+		switch ($mode) {
610
+			case references_PEAR_ERROR_EXCEPTION:
611
+			case references_PEAR_ERROR_RETURN:
612
+			case references_PEAR_ERROR_PRINT:
613
+			case references_PEAR_ERROR_TRIGGER:
614
+			case references_PEAR_ERROR_DIE:
615
+			case null:
616
+				$def_mode    = $mode;
617
+				$def_options = $options;
618
+				break;
619
+
620
+			case references_PEAR_ERROR_CALLBACK:
621
+				$def_mode = $mode;
622
+				// class/object method callback
623
+				if (is_callable($options)) {
624
+					$def_options = $options;
625
+				} else {
626
+					trigger_error('invalid error callback', E_USER_WARNING);
627
+				}
628
+				break;
629
+
630
+			default:
631
+				trigger_error('invalid error mode', E_USER_WARNING);
632
+				break;
633
+		}
634
+		$stack[] = array($mode, $options);
635
+
636
+		return true;
637
+	}
638
+
639
+	public function staticPopErrorHandling()
640
+	{
641
+		$stack      = &$GLOBALS['_PEAR_error_handler_stack'];
642
+		$setmode    = &$GLOBALS['_PEAR_default_error_mode'];
643
+		$setoptions = &$GLOBALS['_PEAR_default_error_options'];
644
+		array_pop($stack);
645
+		list($mode, $options) = $stack[count($stack) - 1];
646
+		array_pop($stack);
647
+		switch ($mode) {
648
+			case references_PEAR_ERROR_EXCEPTION:
649
+			case references_PEAR_ERROR_RETURN:
650
+			case references_PEAR_ERROR_PRINT:
651
+			case references_PEAR_ERROR_TRIGGER:
652
+			case references_PEAR_ERROR_DIE:
653
+			case null:
654
+				$setmode    = $mode;
655
+				$setoptions = $options;
656
+				break;
657
+
658
+			case references_PEAR_ERROR_CALLBACK:
659
+				$setmode = $mode;
660
+				// class/object method callback
661
+				if (is_callable($options)) {
662
+					$setoptions = $options;
663
+				} else {
664
+					trigger_error('invalid error callback', E_USER_WARNING);
665
+				}
666
+				break;
667
+
668
+			default:
669
+				trigger_error('invalid error mode', E_USER_WARNING);
670
+				break;
671
+		}
672
+
673
+		return true;
674
+	}
675
+
676
+	// {{{ pushErrorHandling()
677
+
678
+	/**
679
+	 * Push a new error handler on top of the error handler options stack. With this
680
+	 * you can easily override the actual error handler for some code and restore
681
+	 * it later with popErrorHandling.
682
+	 *
683
+	 * @param mixed $mode    (same as setErrorHandling)
684
+	 * @param mixed $options (same as setErrorHandling)
685
+	 *
686
+	 * @return bool Always true
687
+	 *
688
+	 * @see references_PEAR::setErrorHandling
689
+	 */
690
+	public function pushErrorHandling($mode, $options = null)
691
+	{
692
+		$stack = &$GLOBALS['_PEAR_error_handler_stack'];
693
+		if (isset($this) && is_a($this, 'PEAR')) {
694
+			$def_mode    = &$this->_default_error_mode;
695
+			$def_options = &$this->_default_error_options;
696
+		} else {
697
+			$def_mode    = &$GLOBALS['_PEAR_default_error_mode'];
698
+			$def_options = &$GLOBALS['_PEAR_default_error_options'];
699
+		}
700
+		$stack[] = array($def_mode, $def_options);
701
+
702
+		if (isset($this) && is_a($this, 'PEAR')) {
703
+			$this->setErrorHandling($mode, $options);
704
+		} else {
705
+			references_PEAR::setErrorHandling($mode, $options);
706
+		}
707
+		$stack[] = array($mode, $options);
708
+
709
+		return true;
710
+	}
711
+
712
+	// }}}
713
+	// {{{ popErrorHandling()
714
+
715
+	/**
716
+	 * Pop the last error handler used
717
+	 *
718
+	 * @return bool Always true
719
+	 *
720
+	 * @see references_PEAR::pushErrorHandling
721
+	 */
722
+	public function popErrorHandling()
723
+	{
724
+		$stack = &$GLOBALS['_PEAR_error_handler_stack'];
725
+		array_pop($stack);
726
+		list($mode, $options) = $stack[count($stack) - 1];
727
+		array_pop($stack);
728
+		if (isset($this) && is_a($this, 'PEAR')) {
729
+			$this->setErrorHandling($mode, $options);
730
+		} else {
731
+			references_PEAR::setErrorHandling($mode, $options);
732
+		}
733
+
734
+		return true;
735
+	}
736
+
737
+	// }}}
738
+	// {{{ loadExtension()
739
+
740
+	/**
741
+	 * OS independant PHP extension load. Remember to take care
742
+	 * on the correct extension name for case sensitive OSes.
743
+	 *
744
+	 * @param string $ext The extension name
745
+	 * @return bool Success or not on the dl() call
746
+	 */
747
+	public function loadExtension($ext)
748
+	{
749
+		if (!extension_loaded($ext)) {
750
+			// if either returns true dl() will produce a FATAL error, stop that
751
+			if ((ini_get('enable_dl') != 1) || (ini_get('safe_mode') == 1)) {
752
+				return false;
753
+			}
754
+			if (references_OS_WINDOWS) {
755
+				$suffix = '.dll';
756
+			} elseif (PHP_OS === 'HP-UX') {
757
+				$suffix = '.sl';
758
+			} elseif (PHP_OS === 'AIX') {
759
+				$suffix = '.a';
760
+			} elseif (PHP_OS === 'OSX') {
761
+				$suffix = '.bundle';
762
+			} else {
763
+				$suffix = '.so';
764
+			}
765
+
766
+			return @dl('php_' . $ext . $suffix) || @dl($ext . $suffix);
767
+		}
768
+
769
+		return true;
770
+	}
771
+
772
+	// }}}
773 773
 }
774 774
 
775 775
 // {{{ _PEAR_call_destructors()
776 776
 
777 777
 function references_PEAR_call_destructors()
778 778
 {
779
-    global $_PEAR_destructor_object_list;
780
-    if (is_array($_PEAR_destructor_object_list)
781
-        && count($_PEAR_destructor_object_list)
782
-    ) {
783
-        reset($_PEAR_destructor_object_list);
784
-        if (references_PEAR::getStaticProperty('PEAR', 'destructlifo')) {
785
-            $_PEAR_destructor_object_list = array_reverse($_PEAR_destructor_object_list);
786
-        }
787
-        while (list($k, $objref) = each($_PEAR_destructor_object_list)) {
788
-            $classname = get_class($objref);
789
-            while ($classname) {
790
-                $destructor = "_$classname";
791
-                if (method_exists($objref, $destructor)) {
792
-                    $objref->$destructor();
793
-                    break;
794
-                } else {
795
-                    $classname = get_parent_class($classname);
796
-                }
797
-            }
798
-        }
799
-        // Empty the object list to ensure that destructors are
800
-        // not called more than once.
801
-        $_PEAR_destructor_object_list = array();
802
-    }
803
-
804
-    // Now call the shutdown functions
805
-    if (is_array($GLOBALS['_PEAR_shutdown_funcs']) and !empty($GLOBALS['_PEAR_shutdown_funcs'])) {
806
-        foreach ($GLOBALS['_PEAR_shutdown_funcs'] as $value) {
807
-            call_user_func_array($value[0], $value[1]);
808
-        }
809
-    }
779
+	global $_PEAR_destructor_object_list;
780
+	if (is_array($_PEAR_destructor_object_list)
781
+		&& count($_PEAR_destructor_object_list)
782
+	) {
783
+		reset($_PEAR_destructor_object_list);
784
+		if (references_PEAR::getStaticProperty('PEAR', 'destructlifo')) {
785
+			$_PEAR_destructor_object_list = array_reverse($_PEAR_destructor_object_list);
786
+		}
787
+		while (list($k, $objref) = each($_PEAR_destructor_object_list)) {
788
+			$classname = get_class($objref);
789
+			while ($classname) {
790
+				$destructor = "_$classname";
791
+				if (method_exists($objref, $destructor)) {
792
+					$objref->$destructor();
793
+					break;
794
+				} else {
795
+					$classname = get_parent_class($classname);
796
+				}
797
+			}
798
+		}
799
+		// Empty the object list to ensure that destructors are
800
+		// not called more than once.
801
+		$_PEAR_destructor_object_list = array();
802
+	}
803
+
804
+	// Now call the shutdown functions
805
+	if (is_array($GLOBALS['_PEAR_shutdown_funcs']) and !empty($GLOBALS['_PEAR_shutdown_funcs'])) {
806
+		foreach ($GLOBALS['_PEAR_shutdown_funcs'] as $value) {
807
+			call_user_func_array($value[0], $value[1]);
808
+		}
809
+	}
810 810
 }
811 811
 
812 812
 // }}}
@@ -829,274 +829,274 @@  discard block
 block discarded – undo
829 829
  */
830 830
 class references_PEAR_Error
831 831
 {
832
-    // {{{ properties
833
-
834
-    public $error_message_prefix = '';
835
-    public $mode                 = references_PEAR_ERROR_RETURN;
836
-    public $level                = E_USER_NOTICE;
837
-    public $code                 = -1;
838
-    public $message              = '';
839
-    public $userinfo             = '';
840
-    public $backtrace            = null;
841
-
842
-    // }}}
843
-    // {{{ constructor
844
-
845
-    /**
846
-     * PEAR_Error constructor
847
-     *
848
-     * @param string $message  message
849
-     *
850
-     * @param int    $code     (optional) error code
851
-     *
852
-     * @param int    $mode     (optional) error mode, one of: references_PEAR_ERROR_RETURN,
853
-     *                         references_PEAR_ERROR_PRINT, references_PEAR_ERROR_DIE, references_PEAR_ERROR_TRIGGER,
854
-     *                         references_PEAR_ERROR_CALLBACK or references_PEAR_ERROR_EXCEPTION
855
-     *
856
-     * @param mixed  $options  (optional) error level, _OR_ in the case of
857
-     *                         references_PEAR_ERROR_CALLBACK, the callback function or object/method
858
-     *                         tuple.
859
-     *
860
-     * @param string $userinfo (optional) additional user/debug info
861
-     *
862
-     * @access public
863
-     *
864
-     */
865
-    public function __construct($message = 'unknown error', $code = null, $mode = null, $options = null, $userinfo = null)
866
-    {
867
-        if ($mode === null) {
868
-            $mode = references_PEAR_ERROR_RETURN;
869
-        }
870
-        $this->message  = $message;
871
-        $this->code     = $code;
872
-        $this->mode     = $mode;
873
-        $this->userinfo = $userinfo;
874
-        if (!references_PEAR::getStaticProperty('PEAR_Error', 'skiptrace')) {
875
-            $this->backtrace = debug_backtrace();
876
-            if (isset($this->backtrace[0]) && isset($this->backtrace[0]['object'])) {
877
-                unset($this->backtrace[0]['object']);
878
-            }
879
-        }
880
-        if ($mode & references_PEAR_ERROR_CALLBACK) {
881
-            $this->level    = E_USER_NOTICE;
882
-            $this->callback = $options;
883
-        } else {
884
-            if ($options === null) {
885
-                $options = E_USER_NOTICE;
886
-            }
887
-            $this->level    = $options;
888
-            $this->callback = null;
889
-        }
890
-        if ($this->mode & references_PEAR_ERROR_PRINT) {
891
-            if (is_null($options) || is_int($options)) {
892
-                $format = '%s';
893
-            } else {
894
-                $format = $options;
895
-            }
896
-            printf($format, $this->getMessage());
897
-        }
898
-        if ($this->mode & references_PEAR_ERROR_TRIGGER) {
899
-            trigger_error($this->getMessage(), $this->level);
900
-        }
901
-        if ($this->mode & references_PEAR_ERROR_DIE) {
902
-            $msg = $this->getMessage();
903
-            if (is_null($options) || is_int($options)) {
904
-                $format = '%s';
905
-                if (substr($msg, -1) !== "\n") {
906
-                    $msg .= "\n";
907
-                }
908
-            } else {
909
-                $format = $options;
910
-            }
911
-            die(sprintf($format, $msg));
912
-        }
913
-        if ($this->mode & references_PEAR_ERROR_CALLBACK) {
914
-            if (is_callable($this->callback)) {
915
-                call_user_func($this->callback, $this);
916
-            }
917
-        }
918
-        if ($this->mode & references_PEAR_ERROR_EXCEPTION) {
919
-            trigger_error('references_PEAR_ERROR_EXCEPTION is obsolete, use class PEAR_Exception for exceptions', E_USER_WARNING);
920
-            eval('$e = new Exception($this->message, $this->code);throw($e);');
921
-        }
922
-    }
923
-
924
-    // }}}
925
-    // {{{ getMode()
926
-
927
-    /**
928
-     * Get the error mode from an error object.
929
-     *
930
-     * @return int error mode
931
-     * @access public
932
-     */
933
-    public function getMode()
934
-    {
935
-        return $this->mode;
936
-    }
937
-
938
-    // }}}
939
-    // {{{ getCallback()
940
-
941
-    /**
942
-     * Get the callback function/method from an error object.
943
-     *
944
-     * @return mixed callback function or object/method array
945
-     * @access public
946
-     */
947
-    public function getCallback()
948
-    {
949
-        return $this->callback;
950
-    }
951
-
952
-    // }}}
953
-    // {{{ getMessage()
954
-
955
-    /**
956
-     * Get the error message from an error object.
957
-     *
958
-     * @return string full error message
959
-     * @access public
960
-     */
961
-    public function getMessage()
962
-    {
963
-        return ($this->error_message_prefix . $this->message);
964
-    }
965
-
966
-    // }}}
967
-    // {{{ getCode()
968
-
969
-    /**
970
-     * Get error code from an error object
971
-     *
972
-     * @return int error code
973
-     * @access public
974
-     */
975
-    public function getCode()
976
-    {
977
-        return $this->code;
978
-    }
979
-
980
-    // }}}
981
-    // {{{ getType()
982
-
983
-    /**
984
-     * Get the name of this error/exception.
985
-     *
986
-     * @return string error/exception name (type)
987
-     * @access public
988
-     */
989
-    public function getType()
990
-    {
991
-        return get_class($this);
992
-    }
993
-
994
-    // }}}
995
-    // {{{ getUserInfo()
996
-
997
-    /**
998
-     * Get additional user-supplied information.
999
-     *
1000
-     * @return string user-supplied information
1001
-     * @access public
1002
-     */
1003
-    public function getUserInfo()
1004
-    {
1005
-        return $this->userinfo;
1006
-    }
1007
-
1008
-    // }}}
1009
-    // {{{ getDebugInfo()
1010
-
1011
-    /**
1012
-     * Get additional debug information supplied by the application.
1013
-     *
1014
-     * @return string debug information
1015
-     * @access public
1016
-     */
1017
-    public function getDebugInfo()
1018
-    {
1019
-        return $this->getUserInfo();
1020
-    }
1021
-
1022
-    // }}}
1023
-    // {{{ getBacktrace()
1024
-
1025
-    /**
1026
-     * Get the call backtrace from where the error was generated.
1027
-     * Supported with PHP 4.3.0 or newer.
1028
-     *
1029
-     * @param  int $frame (optional) what frame to fetch
1030
-     * @return array Backtrace, or NULL if not available.
1031
-     * @access public
1032
-     */
1033
-    public function getBacktrace($frame = null)
1034
-    {
1035
-        if (defined('PEAR_IGNORE_BACKTRACE')) {
1036
-            return null;
1037
-        }
1038
-        if ($frame === null) {
1039
-            return $this->backtrace;
1040
-        }
1041
-
1042
-        return $this->backtrace[$frame];
1043
-    }
1044
-
1045
-    // }}}
1046
-    // {{{ addUserInfo()
1047
-
1048
-    public function addUserInfo($info)
1049
-    {
1050
-        if (empty($this->userinfo)) {
1051
-            $this->userinfo = $info;
1052
-        } else {
1053
-            $this->userinfo .= " ** $info";
1054
-        }
1055
-    }
1056
-
1057
-    // }}}
1058
-    // {{{ toString()
1059
-
1060
-    /**
1061
-     * Make a string representation of this object.
1062
-     *
1063
-     * @return string a string with an object summary
1064
-     * @access public
1065
-     */
1066
-    public function toString()
1067
-    {
1068
-        $modes  = array();
1069
-        $levels = array(
1070
-            E_USER_NOTICE  => 'notice',
1071
-            E_USER_WARNING => 'warning',
1072
-            E_USER_ERROR   => 'error'
1073
-        );
1074
-        if ($this->mode & references_PEAR_ERROR_CALLBACK) {
1075
-            if (is_array($this->callback)) {
1076
-                $callback = (is_object($this->callback[0]) ? strtolower(get_class($this->callback[0])) : $this->callback[0]) . '::' . $this->callback[1];
1077
-            } else {
1078
-                $callback = $this->callback;
1079
-            }
1080
-
1081
-            return sprintf('[%s: message="%s" code=%d mode=callback ' . 'callback=%s prefix="%s" info="%s"]', strtolower(get_class($this)), $this->message, $this->code, $callback, $this->error_message_prefix, $this->userinfo);
1082
-        }
1083
-        if ($this->mode & references_PEAR_ERROR_PRINT) {
1084
-            $modes[] = 'print';
1085
-        }
1086
-        if ($this->mode & references_PEAR_ERROR_TRIGGER) {
1087
-            $modes[] = 'trigger';
1088
-        }
1089
-        if ($this->mode & references_PEAR_ERROR_DIE) {
1090
-            $modes[] = 'die';
1091
-        }
1092
-        if ($this->mode & references_PEAR_ERROR_RETURN) {
1093
-            $modes[] = 'return';
1094
-        }
1095
-
1096
-        return sprintf('[%s: message="%s" code=%d mode=%s level=%s ' . 'prefix="%s" info="%s"]', strtolower(get_class($this)), $this->message, $this->code, implode('|', $modes), $levels[$this->level], $this->error_message_prefix, $this->userinfo);
1097
-    }
1098
-
1099
-    // }}}
832
+	// {{{ properties
833
+
834
+	public $error_message_prefix = '';
835
+	public $mode                 = references_PEAR_ERROR_RETURN;
836
+	public $level                = E_USER_NOTICE;
837
+	public $code                 = -1;
838
+	public $message              = '';
839
+	public $userinfo             = '';
840
+	public $backtrace            = null;
841
+
842
+	// }}}
843
+	// {{{ constructor
844
+
845
+	/**
846
+	 * PEAR_Error constructor
847
+	 *
848
+	 * @param string $message  message
849
+	 *
850
+	 * @param int    $code     (optional) error code
851
+	 *
852
+	 * @param int    $mode     (optional) error mode, one of: references_PEAR_ERROR_RETURN,
853
+	 *                         references_PEAR_ERROR_PRINT, references_PEAR_ERROR_DIE, references_PEAR_ERROR_TRIGGER,
854
+	 *                         references_PEAR_ERROR_CALLBACK or references_PEAR_ERROR_EXCEPTION
855
+	 *
856
+	 * @param mixed  $options  (optional) error level, _OR_ in the case of
857
+	 *                         references_PEAR_ERROR_CALLBACK, the callback function or object/method
858
+	 *                         tuple.
859
+	 *
860
+	 * @param string $userinfo (optional) additional user/debug info
861
+	 *
862
+	 * @access public
863
+	 *
864
+	 */
865
+	public function __construct($message = 'unknown error', $code = null, $mode = null, $options = null, $userinfo = null)
866
+	{
867
+		if ($mode === null) {
868
+			$mode = references_PEAR_ERROR_RETURN;
869
+		}
870
+		$this->message  = $message;
871
+		$this->code     = $code;
872
+		$this->mode     = $mode;
873
+		$this->userinfo = $userinfo;
874
+		if (!references_PEAR::getStaticProperty('PEAR_Error', 'skiptrace')) {
875
+			$this->backtrace = debug_backtrace();
876
+			if (isset($this->backtrace[0]) && isset($this->backtrace[0]['object'])) {
877
+				unset($this->backtrace[0]['object']);
878
+			}
879
+		}
880
+		if ($mode & references_PEAR_ERROR_CALLBACK) {
881
+			$this->level    = E_USER_NOTICE;
882
+			$this->callback = $options;
883
+		} else {
884
+			if ($options === null) {
885
+				$options = E_USER_NOTICE;
886
+			}
887
+			$this->level    = $options;
888
+			$this->callback = null;
889
+		}
890
+		if ($this->mode & references_PEAR_ERROR_PRINT) {
891
+			if (is_null($options) || is_int($options)) {
892
+				$format = '%s';
893
+			} else {
894
+				$format = $options;
895
+			}
896
+			printf($format, $this->getMessage());
897
+		}
898
+		if ($this->mode & references_PEAR_ERROR_TRIGGER) {
899
+			trigger_error($this->getMessage(), $this->level);
900
+		}
901
+		if ($this->mode & references_PEAR_ERROR_DIE) {
902
+			$msg = $this->getMessage();
903
+			if (is_null($options) || is_int($options)) {
904
+				$format = '%s';
905
+				if (substr($msg, -1) !== "\n") {
906
+					$msg .= "\n";
907
+				}
908
+			} else {
909
+				$format = $options;
910
+			}
911
+			die(sprintf($format, $msg));
912
+		}
913
+		if ($this->mode & references_PEAR_ERROR_CALLBACK) {
914
+			if (is_callable($this->callback)) {
915
+				call_user_func($this->callback, $this);
916
+			}
917
+		}
918
+		if ($this->mode & references_PEAR_ERROR_EXCEPTION) {
919
+			trigger_error('references_PEAR_ERROR_EXCEPTION is obsolete, use class PEAR_Exception for exceptions', E_USER_WARNING);
920
+			eval('$e = new Exception($this->message, $this->code);throw($e);');
921
+		}
922
+	}
923
+
924
+	// }}}
925
+	// {{{ getMode()
926
+
927
+	/**
928
+	 * Get the error mode from an error object.
929
+	 *
930
+	 * @return int error mode
931
+	 * @access public
932
+	 */
933
+	public function getMode()
934
+	{
935
+		return $this->mode;
936
+	}
937
+
938
+	// }}}
939
+	// {{{ getCallback()
940
+
941
+	/**
942
+	 * Get the callback function/method from an error object.
943
+	 *
944
+	 * @return mixed callback function or object/method array
945
+	 * @access public
946
+	 */
947
+	public function getCallback()
948
+	{
949
+		return $this->callback;
950
+	}
951
+
952
+	// }}}
953
+	// {{{ getMessage()
954
+
955
+	/**
956
+	 * Get the error message from an error object.
957
+	 *
958
+	 * @return string full error message
959
+	 * @access public
960
+	 */
961
+	public function getMessage()
962
+	{
963
+		return ($this->error_message_prefix . $this->message);
964
+	}
965
+
966
+	// }}}
967
+	// {{{ getCode()
968
+
969
+	/**
970
+	 * Get error code from an error object
971
+	 *
972
+	 * @return int error code
973
+	 * @access public
974
+	 */
975
+	public function getCode()
976
+	{
977
+		return $this->code;
978
+	}
979
+
980
+	// }}}
981
+	// {{{ getType()
982
+
983
+	/**
984
+	 * Get the name of this error/exception.
985
+	 *
986
+	 * @return string error/exception name (type)
987
+	 * @access public
988
+	 */
989
+	public function getType()
990
+	{
991
+		return get_class($this);
992
+	}
993
+
994
+	// }}}
995
+	// {{{ getUserInfo()
996
+
997
+	/**
998
+	 * Get additional user-supplied information.
999
+	 *
1000
+	 * @return string user-supplied information
1001
+	 * @access public
1002
+	 */
1003
+	public function getUserInfo()
1004
+	{
1005
+		return $this->userinfo;
1006
+	}
1007
+
1008
+	// }}}
1009
+	// {{{ getDebugInfo()
1010
+
1011
+	/**
1012
+	 * Get additional debug information supplied by the application.
1013
+	 *
1014
+	 * @return string debug information
1015
+	 * @access public
1016
+	 */
1017
+	public function getDebugInfo()
1018
+	{
1019
+		return $this->getUserInfo();
1020
+	}
1021
+
1022
+	// }}}
1023
+	// {{{ getBacktrace()
1024
+
1025
+	/**
1026
+	 * Get the call backtrace from where the error was generated.
1027
+	 * Supported with PHP 4.3.0 or newer.
1028
+	 *
1029
+	 * @param  int $frame (optional) what frame to fetch
1030
+	 * @return array Backtrace, or NULL if not available.
1031
+	 * @access public
1032
+	 */
1033
+	public function getBacktrace($frame = null)
1034
+	{
1035
+		if (defined('PEAR_IGNORE_BACKTRACE')) {
1036
+			return null;
1037
+		}
1038
+		if ($frame === null) {
1039
+			return $this->backtrace;
1040
+		}
1041
+
1042
+		return $this->backtrace[$frame];
1043
+	}
1044
+
1045
+	// }}}
1046
+	// {{{ addUserInfo()
1047
+
1048
+	public function addUserInfo($info)
1049
+	{
1050
+		if (empty($this->userinfo)) {
1051
+			$this->userinfo = $info;
1052
+		} else {
1053
+			$this->userinfo .= " ** $info";
1054
+		}
1055
+	}
1056
+
1057
+	// }}}
1058
+	// {{{ toString()
1059
+
1060
+	/**
1061
+	 * Make a string representation of this object.
1062
+	 *
1063
+	 * @return string a string with an object summary
1064
+	 * @access public
1065
+	 */
1066
+	public function toString()
1067
+	{
1068
+		$modes  = array();
1069
+		$levels = array(
1070
+			E_USER_NOTICE  => 'notice',
1071
+			E_USER_WARNING => 'warning',
1072
+			E_USER_ERROR   => 'error'
1073
+		);
1074
+		if ($this->mode & references_PEAR_ERROR_CALLBACK) {
1075
+			if (is_array($this->callback)) {
1076
+				$callback = (is_object($this->callback[0]) ? strtolower(get_class($this->callback[0])) : $this->callback[0]) . '::' . $this->callback[1];
1077
+			} else {
1078
+				$callback = $this->callback;
1079
+			}
1080
+
1081
+			return sprintf('[%s: message="%s" code=%d mode=callback ' . 'callback=%s prefix="%s" info="%s"]', strtolower(get_class($this)), $this->message, $this->code, $callback, $this->error_message_prefix, $this->userinfo);
1082
+		}
1083
+		if ($this->mode & references_PEAR_ERROR_PRINT) {
1084
+			$modes[] = 'print';
1085
+		}
1086
+		if ($this->mode & references_PEAR_ERROR_TRIGGER) {
1087
+			$modes[] = 'trigger';
1088
+		}
1089
+		if ($this->mode & references_PEAR_ERROR_DIE) {
1090
+			$modes[] = 'die';
1091
+		}
1092
+		if ($this->mode & references_PEAR_ERROR_RETURN) {
1093
+			$modes[] = 'return';
1094
+		}
1095
+
1096
+		return sprintf('[%s: message="%s" code=%d mode=%s level=%s ' . 'prefix="%s" info="%s"]', strtolower(get_class($this)), $this->message, $this->code, implode('|', $modes), $levels[$this->level], $this->error_message_prefix, $this->userinfo);
1097
+	}
1098
+
1099
+	// }}}
1100 1100
 }
1101 1101
 
1102 1102
 /*
Please login to merge, or discard this patch.
class/references_parameters.php 1 patch
Indentation   +52 added lines, -52 removed lines patch added patch discarded remove patch
@@ -30,62 +30,62 @@
 block discarded – undo
30 30
  */
31 31
 class references_parameters extends ArrayObject
32 32
 {
33
-    /**
34
-     * Permet de valoriser un indice de la classe comme si c'était une propriété de la classe
35
-     *
36
-     * @example $enregistrement->nom_du_champ = 'ma chaine'
37
-     *
38
-     * @param string $key   Le nom du champ Ă  traiter
39
-     * @param mixed  $value La valeur Ă  lui attribuer
40
-     * @return object
41
-     */
42
-    public function __set($key, $value)
43
-    {
44
-        parent::offsetSet($key, $value);
33
+	/**
34
+	 * Permet de valoriser un indice de la classe comme si c'était une propriété de la classe
35
+	 *
36
+	 * @example $enregistrement->nom_du_champ = 'ma chaine'
37
+	 *
38
+	 * @param string $key   Le nom du champ Ă  traiter
39
+	 * @param mixed  $value La valeur Ă  lui attribuer
40
+	 * @return object
41
+	 */
42
+	public function __set($key, $value)
43
+	{
44
+		parent::offsetSet($key, $value);
45 45
 
46
-        return $this;
47
-    }
46
+		return $this;
47
+	}
48 48
 
49
-    /**
50
-     * Valorisation d'un indice de la classe en utilisant un appel de fonction basé sur le principe suivant :
51
-     *      $maClasse->setLimit(10);
52
-     * Il est possible de chainer comme ceci : $maClasse->setStart(0)->setLimit(10);
53
-     *
54
-     * @param  string $method
55
-     * @param  mixed  $args
56
-     * @return object
57
-     */
58
-    public function __call($method, $args)
59
-    {
60
-        if (substr($method, 0, 3) === 'set') {
61
-            parent::offsetSet(strtolower(substr($method, 3, 1)) . substr($method, 4), $args[0]);
49
+	/**
50
+	 * Valorisation d'un indice de la classe en utilisant un appel de fonction basé sur le principe suivant :
51
+	 *      $maClasse->setLimit(10);
52
+	 * Il est possible de chainer comme ceci : $maClasse->setStart(0)->setLimit(10);
53
+	 *
54
+	 * @param  string $method
55
+	 * @param  mixed  $args
56
+	 * @return object
57
+	 */
58
+	public function __call($method, $args)
59
+	{
60
+		if (substr($method, 0, 3) === 'set') {
61
+			parent::offsetSet(strtolower(substr($method, 3, 1)) . substr($method, 4), $args[0]);
62 62
 
63
-            return $this;
64
-        } else {    // Affichage de la valeur
63
+			return $this;
64
+		} else {    // Affichage de la valeur
65 65
 
66
-            return parent::offsetGet($method);
67
-        }
68
-    }
66
+			return parent::offsetGet($method);
67
+		}
68
+	}
69 69
 
70
-    /**
71
-     * Méthode qui essaye de faire la même chose que la méthode extend() de jQuery
72
-     *
73
-     * On lui passe les valeurs par défaut que l'on attend et la méthode les compare avec les valeurs actuelles
74
-     * Si des valeurs manquent, elles sont ajoutées
75
-     *
76
-     * @param  references_parameters $defaultValues
77
-     * @return references_parameters
78
-     */
79
-    public function extend(self $defaultValues)
80
-    {
81
-        $result = new self;
82
-        $result = $this;
83
-        foreach ($defaultValues as $key => $value) {
84
-            if (!isset($result[$key])) {
85
-                $result[$key] = $value;
86
-            }
87
-        }
70
+	/**
71
+	 * Méthode qui essaye de faire la même chose que la méthode extend() de jQuery
72
+	 *
73
+	 * On lui passe les valeurs par défaut que l'on attend et la méthode les compare avec les valeurs actuelles
74
+	 * Si des valeurs manquent, elles sont ajoutées
75
+	 *
76
+	 * @param  references_parameters $defaultValues
77
+	 * @return references_parameters
78
+	 */
79
+	public function extend(self $defaultValues)
80
+	{
81
+		$result = new self;
82
+		$result = $this;
83
+		foreach ($defaultValues as $key => $value) {
84
+			if (!isset($result[$key])) {
85
+				$result[$key] = $value;
86
+			}
87
+		}
88 88
 
89
-        return $result;
90
-    }
89
+		return $result;
90
+	}
91 91
 }
Please login to merge, or discard this patch.
category.php 1 patch
Indentation   +16 added lines, -16 removed lines patch added patch discarded remove patch
@@ -34,21 +34,21 @@  discard block
 block discarded – undo
34 34
 
35 35
 $category_id = isset($_GET['category_id']) ? (int)$_GET['category_id'] : 0;
36 36
 if ($category_id == 0) {
37
-    header('Location: index.php', true, 301);
38
-    exit;
39
-    //references_utils::redirect('', 'index.php', 0);
37
+	header('Location: index.php', true, 301);
38
+	exit;
39
+	//references_utils::redirect('', 'index.php', 0);
40 40
 }
41 41
 // Chargement de la catégorie
42 42
 $category = null;
43 43
 $category = $h_references_categories->get($category_id);
44 44
 if (!is_object($category)) {
45
-    references_utils::redirect(_MD_REFERENCES_ERROR2, 'index.php', 4);
45
+	references_utils::redirect(_MD_REFERENCES_ERROR2, 'index.php', 4);
46 46
 }
47 47
 
48 48
 // Vérification des permissions
49 49
 $handlers = references_handler::getInstance();
50 50
 if (!$handlers->h_references_categories->userCanSeeCategory($category)) {
51
-    references_utils::redirect(_NOPERM, 'index.php', 4);
51
+	references_utils::redirect(_NOPERM, 'index.php', 4);
52 52
 }
53 53
 
54 54
 $xoopsTpl->assign('category', $category->toArray());
@@ -64,9 +64,9 @@  discard block
 block discarded – undo
64 64
 $xoTheme->addScript(REFERENCES_JS_URL . 'js/mootools.js');
65 65
 $xoTheme->addScript(REFERENCES_JS_URL . 'js/mootools-1.2-more.js');
66 66
 if (isset($xoopsConfig) && file_exists(REFERENCES_PATH . 'language/' . $xoopsConfig['language'] . '/slimbox.js')) {
67
-    $xoTheme->addScript(REFERENCES_URL . 'language/' . $xoopsConfig['language'] . '/slimbox.js');
67
+	$xoTheme->addScript(REFERENCES_URL . 'language/' . $xoopsConfig['language'] . '/slimbox.js');
68 68
 } else {
69
-    $xoTheme->addScript(REFERENCES_JS_URL . 'js/slimbox.js');
69
+	$xoTheme->addScript(REFERENCES_JS_URL . 'js/slimbox.js');
70 70
 }
71 71
 
72 72
 $categoriesSelect = $h_references_categories->getCategoriesSelect('categoriesSelect', $category->getVar('category_id'));
@@ -78,15 +78,15 @@  discard block
 block discarded – undo
78 78
 $xoopsTpl->assign('thumbsWidth', references_utils::getModuleOption('thumbs_width'));
79 79
 $xoopsTpl->assign('thumbsHeight', references_utils::getModuleOption('thumbs_height'));
80 80
 if ($limit > 0) {
81
-    $items          = array();
82
-    $items          = $h_references_articles->getRecentArticles($start, $limit, references_utils::getModuleOption('sort_field'), references_utils::getModuleOption('sort_order'), true, $category_id);
83
-    $categoryTitle  = $category->getVar('category_title');
84
-    $categoryWeight = $category->getVar('category_weight');
85
-    if (count($items) > 0) {
86
-        foreach ($items as $item) {
87
-            $xoopsTpl->append('articles', $item->toArray());
88
-        }
89
-    }
81
+	$items          = array();
82
+	$items          = $h_references_articles->getRecentArticles($start, $limit, references_utils::getModuleOption('sort_field'), references_utils::getModuleOption('sort_order'), true, $category_id);
83
+	$categoryTitle  = $category->getVar('category_title');
84
+	$categoryWeight = $category->getVar('category_weight');
85
+	if (count($items) > 0) {
86
+		foreach ($items as $item) {
87
+			$xoopsTpl->append('articles', $item->toArray());
88
+		}
89
+	}
90 90
 }
91 91
 $xoopsTpl->assign('isAdmin', references_utils::isAdmin());
92 92
 $title = $category->getVar('category_title', 'n') . ' - ' . $xoopsModule->name();
Please login to merge, or discard this patch.