1 |
<?php |
---|
2 |
|
---|
3 |
|
---|
4 |
|
---|
5 |
|
---|
6 |
|
---|
7 |
|
---|
8 |
|
---|
9 |
|
---|
10 |
|
---|
11 |
|
---|
12 |
|
---|
13 |
|
---|
14 |
|
---|
15 |
|
---|
16 |
|
---|
17 |
|
---|
18 |
|
---|
19 |
|
---|
20 |
|
---|
21 |
|
---|
22 |
|
---|
23 |
|
---|
24 |
|
---|
25 |
|
---|
26 |
|
---|
27 |
|
---|
28 |
|
---|
29 |
|
---|
30 |
|
---|
31 |
|
---|
32 |
|
---|
33 |
|
---|
34 |
|
---|
35 |
|
---|
36 |
|
---|
37 |
|
---|
38 |
|
---|
39 |
|
---|
40 |
|
---|
41 |
|
---|
42 |
require_once SGL_CORE_DIR. '/NestedSet.php'; |
---|
43 |
require_once SGL_MOD_DIR . '/user/classes/UserDAO.php'; |
---|
44 |
|
---|
45 |
define('SGL_MAX_RECURSION', 100); |
---|
46 |
|
---|
47 |
|
---|
48 |
|
---|
49 |
|
---|
50 |
|
---|
51 |
|
---|
52 |
|
---|
53 |
|
---|
54 |
|
---|
55 |
class SGL_Category |
---|
56 |
{ |
---|
57 |
var $_params = array(); |
---|
58 |
var $_nestedSetNode = array(); |
---|
59 |
var $_da = null; |
---|
60 |
|
---|
61 |
|
---|
62 |
* Constructor. |
---|
63 |
* |
---|
64 |
* @return void |
---|
65 |
*/ |
---|
66 |
function SGL_Category() |
---|
67 |
{ |
---|
68 |
SGL::logMessage(null, PEAR_LOG_DEBUG); |
---|
69 |
|
---|
70 |
$c = &SGL_Config::singleton(); |
---|
71 |
$this->conf = $c->getAll(); |
---|
72 |
|
---|
73 |
$this->da = & UserDAO::singleton(); |
---|
74 |
$this->dbh = & SGL_DB::singleton(); |
---|
75 |
|
---|
76 |
|
---|
77 |
$this->_params = array( |
---|
78 |
'tableStructure' => array( |
---|
79 |
'category_id' => 'id', |
---|
80 |
'root_id' => 'rootid', |
---|
81 |
'left_id' => 'l', |
---|
82 |
'right_id' => 'r', |
---|
83 |
'order_id' => 'norder', |
---|
84 |
'level_id' => 'level', |
---|
85 |
'parent_id' => 'parent', |
---|
86 |
'label' => 'label', |
---|
87 |
'perms' => 'perms', |
---|
88 |
), |
---|
89 |
'tableName' => $this->conf['table']['category'], |
---|
90 |
|
---|
91 |
'lockTableName' => $this->conf['db']['prefix'] . 'table_lock', |
---|
92 |
'sequenceName' => $this->conf['table']['category']); |
---|
93 |
} |
---|
94 |
|
---|
95 |
|
---|
96 |
* Create a Category with given values. |
---|
97 |
* |
---|
98 |
* @access public |
---|
99 |
* @param array $values Category values |
---|
100 |
* @return array NestedSet node created |
---|
101 |
*/ |
---|
102 |
function create(&$values) |
---|
103 |
{ |
---|
104 |
SGL::logMessage(null, PEAR_LOG_DEBUG); |
---|
105 |
|
---|
106 |
|
---|
107 |
if (!isset($values['label'])) |
---|
108 |
$values['label'] = 'New Category'; |
---|
109 |
|
---|
110 |
|
---|
111 |
$nestedSet = new SGL_NestedSet($this->_params); |
---|
112 |
|
---|
113 |
|
---|
114 |
if ($values['parent_id'] == 0) { |
---|
115 |
|
---|
116 |
$this->_nestedSetNode = $nestedSet->createRootNode($values); |
---|
117 |
} elseif ((int)$values['parent_id'] > 0) { |
---|
118 |
|
---|
119 |
$this->_nestedSetNode = $nestedSet->createSubNode($values['parent_id'], $values); |
---|
120 |
} else { |
---|
121 |
|
---|
122 |
SGL::raiseError('Incorrect parent node id passed to ' . __CLASS__ . '::' . |
---|
123 |
__FUNCTION__, SGL_ERROR_INVALIDARGS); |
---|
124 |
} |
---|
125 |
|
---|
126 |
|
---|
127 |
SGL_Cache::clear('blocks'); |
---|
128 |
SGL_Cache::clear('categorySelect'); |
---|
129 |
|
---|
130 |
return $this->_nestedSetNode; |
---|
131 |
} |
---|
132 |
|
---|
133 |
|
---|
134 |
* Update a Category with given values. |
---|
135 |
* |
---|
136 |
* @access public |
---|
137 |
* @param int $category_id Category ID to update |
---|
138 |
* @param array $values Values to set |
---|
139 |
* @return string An empty string if error while updating, else |
---|
140 |
* a message to display. |
---|
141 |
*/ |
---|
142 |
function update($category_id, &$values) |
---|
143 |
{ |
---|
144 |
$message = ''; |
---|
145 |
|
---|
146 |
SGL::logMessage(null, PEAR_LOG_DEBUG); |
---|
147 |
$nestedSet = new SGL_NestedSet($this->_params); |
---|
148 |
|
---|
149 |
|
---|
150 |
if (!$nestedSet->updateNode($category_id, $values)) { |
---|
151 |
SGL::raiseError('There was a problem updating the record', |
---|
152 |
SGL_ERROR_NOAFFECTEDROWS); |
---|
153 |
} |
---|
154 |
|
---|
155 |
|
---|
156 |
switch ($values['parent_id']) { |
---|
157 |
case $values['original_parent_id']: |
---|
158 |
|
---|
159 |
$message = 'Category details successfully updated'; |
---|
160 |
break; |
---|
161 |
|
---|
162 |
case $values['category_id']: |
---|
163 |
|
---|
164 |
$message = 'Category details updated, no data changed'; |
---|
165 |
break; |
---|
166 |
|
---|
167 |
case 0: |
---|
168 |
|
---|
169 |
$thisNode = $nestedSet->getNode($values['category_id']); |
---|
170 |
$moveNode = $nestedSet->moveTree($values['category_id'], $thisNode['root_id'], 'BE'); |
---|
171 |
|
---|
172 |
if (!is_a($thisNode, 'PEAR_Error') && !is_a($moveNode, 'PEAR_Error')) { |
---|
173 |
$message = 'Category details successfully updated'; |
---|
174 |
} |
---|
175 |
break; |
---|
176 |
|
---|
177 |
default: |
---|
178 |
|
---|
179 |
$moveNode = $nestedSet->moveTree($values['category_id'], $values['parent_id'], 'SUB'); |
---|
180 |
|
---|
181 |
if (!is_a($moveNode, 'PEAR_Error') && !is_a($moveNode, 'PEAR_Error')) { |
---|
182 |
$message = 'Category details successfully updated'; |
---|
183 |
} |
---|
184 |
break; |
---|
185 |
} |
---|
186 |
|
---|
187 |
|
---|
188 |
require_once SGL_CORE_DIR . '/CategoryPerms.php'; |
---|
189 |
$perms = & new SGL_CategoryPerms($category_id); |
---|
190 |
$perms->set('aPerms', $values['perms']); |
---|
191 |
$perms->update(); |
---|
192 |
|
---|
193 |
|
---|
194 |
SGL_Cache::clear('categorySelect'); |
---|
195 |
SGL_Cache::clear('blocks'); |
---|
196 |
|
---|
197 |
|
---|
198 |
return $message; |
---|
199 |
} |
---|
200 |
|
---|
201 |
|
---|
202 |
* Delete several Categories. |
---|
203 |
* |
---|
204 |
* @access public |
---|
205 |
* @param array $aDelete Array of Category IDs to delete |
---|
206 |
* @return void |
---|
207 |
*/ |
---|
208 |
function delete(&$aDelete) |
---|
209 |
{ |
---|
210 |
SGL::logMessage(null, PEAR_LOG_DEBUG); |
---|
211 |
|
---|
212 |
if (is_array($aDelete)) { |
---|
213 |
$nestedSet = new SGL_NestedSet($this->_params); |
---|
214 |
|
---|
215 |
// might have checked child nodes for deletion, in which case deleteNode() |
---|
216 |
// would try to delete nodes that no longer exist, after parent deletion, |
---|
217 |
// and therefore error, so test first to make sure they're still around |
---|
218 |
foreach ($aDelete as $index => $categoryId) { |
---|
219 |
if ($nestedSet->getNode($categoryId)) { |
---|
220 |
$nestedSet->deleteNode($categoryId); |
---|
221 |
} |
---|
222 |
} |
---|
223 |
} else { |
---|
224 |
SGL::raiseError("Incorrect parameter passed to " . __CLASS__ . '::' . |
---|
225 |
__FUNCTION__, SGL_ERROR_INVALIDARGS); |
---|
226 |
} |
---|
227 |
|
---|
228 |
|
---|
229 |
SGL_Cache::clear('categorySelect'); |
---|
230 |
SGL_Cache::clear('blocks'); |
---|
231 |
} |
---|
232 |
|
---|
233 |
|
---|
234 |
* Move a Category. |
---|
235 |
* |
---|
236 |
* @access public |
---|
237 |
* @param int $category_id Category ID to move |
---|
238 |
* @param int $target_id New parent |
---|
239 |
* @param int $pos New position |
---|
240 |
*/ |
---|
241 |
function move($category_id, $target_id, $pos) |
---|
242 |
{ |
---|
243 |
SGL::logMessage(null, PEAR_LOG_DEBUG); |
---|
244 |
$nestedSet = new SGL_NestedSet($this->_params); |
---|
245 |
|
---|
246 |
|
---|
247 |
$nestedSet->moveTree($category_id, $target_id, $pos); |
---|
248 |
|
---|
249 |
|
---|
250 |
SGL_Cache::clear('categorySelect'); |
---|
251 |
SGL_Cache::clear('blocks'); |
---|
252 |
} |
---|
253 |
|
---|
254 |
|
---|
255 |
* Load a Category, given its ID. |
---|
256 |
* |
---|
257 |
* @access public |
---|
258 |
* @param int $category_id Category ID to load |
---|
259 |
* @return bool TRUE if loaded, FALSE if error |
---|
260 |
*/ |
---|
261 |
function load($category_id) |
---|
262 |
{ |
---|
263 |
SGL::logMessage(null, PEAR_LOG_DEBUG); |
---|
264 |
|
---|
265 |
|
---|
266 |
if (!isset($category_id) || ($category_id == '0')) { |
---|
267 |
return false; |
---|
268 |
} |
---|
269 |
|
---|
270 |
|
---|
271 |
$nestedSet = new SGL_NestedSet($this->_params); |
---|
272 |
$this->_nestedSetNode = $nestedSet->getNode($category_id); |
---|
273 |
|
---|
274 |
|
---|
275 |
if (!isset($this->_nestedSetNode) || empty($this->_nestedSetNode)) { |
---|
276 |
SGL::raiseError('Invalid category ID passed', SGL_ERROR_INVALIDARGS); |
---|
277 |
return false; |
---|
278 |
} |
---|
279 |
return true; |
---|
280 |
} |
---|
281 |
|
---|
282 |
|
---|
283 |
* Get current Category values. |
---|
284 |
* |
---|
285 |
* Category must be loaded before using this function. |
---|
286 |
* |
---|
287 |
* @access public |
---|
288 |
* @return array NestedSet node representing the current Category |
---|
289 |
*/ |
---|
290 |
function getValues() |
---|
291 |
{ |
---|
292 |
SGL::logMessage(null, PEAR_LOG_DEBUG); |
---|
293 |
|
---|
294 |
|
---|
295 |
if (!isset($this->_nestedSetNode) || empty($this->_nestedSetNode)) { |
---|
296 |
SGL::raiseError('Category not loaded', SGL_ERROR_INVALIDCALL); |
---|
297 |
return null; |
---|
298 |
} |
---|
299 |
|
---|
300 |
return $this->_nestedSetNode; |
---|
301 |
} |
---|
302 |
|
---|
303 |
|
---|
304 |
* Get current Category permissions. |
---|
305 |
* |
---|
306 |
* Category must be loaded before using this function. |
---|
307 |
* |
---|
308 |
* @access public |
---|
309 |
* @return array Current Category permissions |
---|
310 |
*/ |
---|
311 |
function getPerms() |
---|
312 |
{ |
---|
313 |
SGL::logMessage(null, PEAR_LOG_DEBUG); |
---|
314 |
|
---|
315 |
|
---|
316 |
if (!isset($this->_nestedSetNode) || empty($this->_nestedSetNode)) { |
---|
317 |
SGL::raiseError('Category not loaded', SGL_ERROR_INVALIDCALL); |
---|
318 |
return null; |
---|
319 |
} |
---|
320 |
|
---|
321 |
|
---|
322 |
$aRoles = $this->da->getRoles(); |
---|
323 |
$aRoles[0] = 'guest'; |
---|
324 |
|
---|
325 |
|
---|
326 |
$aPerms = (isset($this->_nestedSetNode['perms']) && count($this->_nestedSetNode['perms'])) |
---|
327 |
? explode(',', $this->_nestedSetNode['perms']) |
---|
328 |
: array(); |
---|
329 |
|
---|
330 |
foreach ($aRoles as $roleId => $roleName) { |
---|
331 |
$tmp['role_id'] = $roleId; |
---|
332 |
$tmp['name'] = $roleName; |
---|
333 |
$tmp['isAllowed'] = (!in_array($roleId, $aPerms)) ? 1 : 0; |
---|
334 |
$perms[] = (object)$tmp; |
---|
335 |
} |
---|
336 |
|
---|
337 |
return $perms; |
---|
338 |
} |
---|
339 |
|
---|
340 |
|
---|
341 |
* Returns true if current user has perms to view a category. |
---|
342 |
* |
---|
343 |
* Category must be loaded before using this function. |
---|
344 |
* |
---|
345 |
* @access public |
---|
346 |
* @return bool |
---|
347 |
*/ |
---|
348 |
function hasPerms() |
---|
349 |
{ |
---|
350 |
|
---|
351 |
if (!isset($this->_nestedSetNode) || empty($this->_nestedSetNode)) { |
---|
352 |
return false; |
---|
353 |
} |
---|
354 |
$aPerms = $this->getPerms(); |
---|
355 |
$roleId = SGL_Session::get('rid'); |
---|
356 |
|
---|
357 |
foreach ($aPerms as $perm) { |
---|
358 |
if ($perm->role_id == $roleId) { |
---|
359 |
return $perm->isAllowed; |
---|
360 |
} |
---|
361 |
} |
---|
362 |
return false; |
---|
363 |
} |
---|
364 |
|
---|
365 |
|
---|
366 |
* Get a tree representing all Categories. |
---|
367 |
* |
---|
368 |
* @access public |
---|
369 |
* @return array Categories tree |
---|
370 |
*/ |
---|
371 |
function getTree() |
---|
372 |
{ |
---|
373 |
SGL::logMessage(null, PEAR_LOG_DEBUG); |
---|
374 |
|
---|
375 |
$nestedSet = new SGL_NestedSet($this->_params); |
---|
376 |
$nestedSet->setImage('folder', 'images/treeNav/file.png'); |
---|
377 |
$categoryTree = $nestedSet->getTree(); |
---|
378 |
$nestedSet->addImages($categoryTree); |
---|
379 |
|
---|
380 |
return $categoryTree; |
---|
381 |
} |
---|
382 |
|
---|
383 |
|
---|
384 |
* Retrieve children |
---|
385 |
* |
---|
386 |
* @access public |
---|
387 |
* @param int $id |
---|
388 |
* @return array categories children |
---|
389 |
*/ |
---|
390 |
function getChildren($id) |
---|
391 |
{ |
---|
392 |
if (!is_numeric($id)) { |
---|
393 |
SGL::raiseError('Wrong datatype passed to ' . __CLASS__ . '::' . |
---|
394 |
__FUNCTION__, SGL_ERROR_INVALIDARGS, PEAR_ERROR_DIE); |
---|
395 |
} |
---|
396 |
$query = " SELECT category_id, label |
---|
397 |
FROM " . $this->conf['table']['category'] . " |
---|
398 |
WHERE parent_id = $id |
---|
399 |
ORDER BY parent_id, order_id"; |
---|
400 |
|
---|
401 |
$result = $this->dbh->query($query); |
---|
402 |
$count = 0; |
---|
403 |
$aChildren = array(); |
---|
404 |
while ($row = $result->fetchRow(DB_FETCHMODE_ASSOC)) { |
---|
405 |
$aChildren[$count]['category_id'] = $row['category_id']; |
---|
406 |
$aChildren[$count]['label'] = $row['label']; |
---|
407 |
$count++; |
---|
408 |
} |
---|
409 |
|
---|
410 |
return $aChildren; |
---|
411 |
} |
---|
412 |
|
---|
413 |
|
---|
414 |
* Checks if an category is a branch |
---|
415 |
* |
---|
416 |
* @access public |
---|
417 |
* @param int $id |
---|
418 |
* @return boolean |
---|
419 |
*/ |
---|
420 |
function isBranch($id) |
---|
421 |
{ |
---|
422 |
$nestedSet = new SGL_NestedSet($this->_params); |
---|
423 |
$ns = $nestedSet->_getNestedSet(); |
---|
424 |
$node = $ns->pickNode($id, $keepAsArray = true, $alias = true); |
---|
425 |
if ($node) { |
---|
426 |
if (($node['r'] - $node['l']) > 1) { |
---|
427 |
return true; |
---|
428 |
} |
---|
429 |
} |
---|
430 |
return false; |
---|
431 |
} |
---|
432 |
|
---|
433 |
|
---|
434 |
* Generates breadcrumbs for category |
---|
435 |
* |
---|
436 |
* @access public |
---|
437 |
* @param integer $category_id |
---|
438 |
* @param boolean $links build links |
---|
439 |
* @param string $style CSS Class |
---|
440 |
* @param boolean $links add link to the current CatID |
---|
441 |
* @return string $finalHtmlString |
---|
442 |
*/ |
---|
443 |
function getBreadCrumbs($category_id, $links = true, $style = '', $lastLink = false) |
---|
444 |
{ |
---|
445 |
SGL::logMessage(null, PEAR_LOG_DEBUG); |
---|
446 |
if (!is_numeric($category_id)) { |
---|
447 |
SGL::raiseError("Invalid category ID, '$category_id', passed to " . |
---|
448 |
__CLASS__ . '::' . __FUNCTION__, SGL_ERROR_INVALIDARGS); |
---|
449 |
return false; |
---|
450 |
} |
---|
451 |
$nestedSet = new SGL_NestedSet($this->_params); |
---|
452 |
$node = $nestedSet->getNode($category_id); |
---|
453 |
|
---|
454 |
if (empty($node) || is_a($node, 'PEAR_Error')) { |
---|
455 |
return false; |
---|
456 |
} |
---|
457 |
$crumbs = $nestedSet->getBreadcrumbs($category_id); |
---|
458 |
$htmlString = ''; |
---|
459 |
|
---|
460 |
|
---|
461 |
$req = & SGL_Request::singleton(); |
---|
462 |
|
---|
463 |
|
---|
464 |
$managerName = $req->get('managerName'); |
---|
465 |
$action = $req->get('action'); |
---|
466 |
|
---|
467 |
|
---|
468 |
if (strtolower($managerName) == 'articleview' && |
---|
469 |
strtolower($action) == 'view') { |
---|
470 |
|
---|
471 |
$action = "summary"; |
---|
472 |
} |
---|
473 |
|
---|
474 |
|
---|
475 |
$url = SGL_Url::makeLink( $action, |
---|
476 |
$managerName, |
---|
477 |
$req->get('moduleName') |
---|
478 |
); |
---|
479 |
$url .= 'frmCatID/'; |
---|
480 |
|
---|
481 |
foreach ($crumbs as $crumb) { |
---|
482 |
if ($links) { |
---|
483 |
$htmlString .= "<a class='$style' href='$url".$crumb['category_id']."/'>" . |
---|
484 |
stripslashes($crumb['label']) . "</a> > "; |
---|
485 |
} else { |
---|
486 |
$htmlString .= stripslashes($crumb['label']) . " > "; |
---|
487 |
} |
---|
488 |
} |
---|
489 |
$finalHtmlString = ($lastLink) |
---|
490 |
? $htmlString . "<a class='$style' href='$url".$category_id."/'>" . $node['label'] ."</a>" |
---|
491 |
: $htmlString . $node['label']; |
---|
492 |
return $finalHtmlString; |
---|
493 |
} |
---|
494 |
|
---|
495 |
|
---|
496 |
* Retrieves category label |
---|
497 |
* |
---|
498 |
* @access public |
---|
499 |
* @param int $id |
---|
500 |
* @return string |
---|
501 |
*/ |
---|
502 |
function getLabel($id) |
---|
503 |
{ |
---|
504 |
$nestedSet = new SGL_NestedSet($this->_params); |
---|
505 |
$node = $nestedSet->getNode($id); |
---|
506 |
if (!PEAR::isError($node)) { |
---|
507 |
return $node['label']; |
---|
508 |
} else { |
---|
509 |
return false; |
---|
510 |
} |
---|
511 |
} |
---|
512 |
|
---|
513 |
function debug($id = 0) |
---|
514 |
{ |
---|
515 |
SGL::logMessage(null, PEAR_LOG_DEBUG); |
---|
516 |
$result = $this->getChildren($id); |
---|
517 |
$listString .= '<ul>'; |
---|
518 |
for ($x = 0; $x < count($result); $x++) { |
---|
519 |
$listString .= "<li>" . $result[$x]["label"] . "[" . $result[$x]['category_id'] . "]"; |
---|
520 |
|
---|
521 |
|
---|
522 |
if ($this->isBranch($result[$x]['category_id'])) { |
---|
523 |
$listString .= $this->debug($result[$x]['category_id']); |
---|
524 |
} |
---|
525 |
} |
---|
526 |
$listString .= '</ul>'; |
---|
527 |
return $listString; |
---|
528 |
} |
---|
529 |
|
---|
530 |
|
---|
531 |
function render() |
---|
532 |
{ |
---|
533 |
|
---|
534 |
} |
---|
535 |
} |
---|
536 |
?> |
---|