[ Index ] |
|
Code source de eGroupWare 1.2.106-2 |
1 <?php 2 /**************************************************************************\ 3 * eGroupWare API - Categories * 4 * This file written by Joseph Engo <jengo@phpgroupware.org> * 5 * and Bettina Gille [ceb@phpgroupware.org] * 6 * Category manager * 7 * Copyright (C) 2000, 2001 Joseph Engo, Bettina Gille * 8 * Copyright (C) 2002, 2003 Bettina Gille * 9 * Reworked 11/2005 by RalfBecker-AT-outdoor-training.de * 10 * ------------------------------------------------------------------------ * 11 * This library is part of the eGroupWare API * 12 * http://www.egroupware.org * 13 * ------------------------------------------------------------------------ * 14 * This library is free software; you can redistribute it and/or modify it * 15 * under the terms of the GNU Lesser General Public License as published by * 16 * the Free Software Foundation; either version 2.1 of the License, * 17 * or any later version. * 18 * This library is distributed in the hope that it will be useful, but * 19 * WITHOUT ANY WARRANTY; without even the implied warranty of * 20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * 21 * See the GNU Lesser General Public License for more details. * 22 * You should have received a copy of the GNU Lesser General Public License * 23 * along with this library; if not, write to the Free Software Foundation, * 24 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * 25 \**************************************************************************/ 26 /* $Id: class.categories.inc.php 21368 2006-04-14 09:53:05Z ralfbecker $ */ 27 28 /** 29 * class to manage categories in eGroupWare 30 * 31 * @license LGPL 32 * @package api 33 * @subpackage categories 34 */ 35 class categories 36 { 37 var $account_id; 38 var $app_name; 39 var $db; 40 var $total_records; 41 var $grants; 42 var $table = 'egw_categories'; 43 var $cache_id2cat_data = array(); // a little bit of caching for id2name and return_single 44 45 /** 46 * constructor for categories class 47 * 48 * @param int/string $accountid='' account id or lid, default to current user 49 * @param string $app_name='' app name defaults to current app 50 */ 51 function categories($accountid='',$app_name = '') 52 { 53 if (!$app_name) $app_name = $GLOBALS['egw_info']['flags']['currentapp']; 54 55 $this->account_id = (int) get_account_id($accountid); 56 $this->app_name = $app_name; 57 $this->db = clone($GLOBALS['egw']->db); 58 $this->db->set_app('phpgwapi'); 59 $this->grants = $GLOBALS['egw']->acl->get_grants($app_name); 60 } 61 62 /** 63 * return sql for predifined filters 64 * 65 * @param string $type eiterh subs, mains, appandmains, appandsubs, noglobal or noglobalapp 66 * @return string with sql to add to the where clause 67 */ 68 function filter($type) 69 { 70 switch ($type) 71 { 72 case 'subs': $where = 'cat_parent != 0'; break; 73 case 'mains': $where = 'cat_parent = 0'; break; 74 case 'appandmains': $where = 'cat_appname='.$this->db->quote($this->app_name).' AND cat_parent = 0'; break; 75 case 'appandsubs': $where = 'cat_appname='.$this->db->quote($this->app_name).' AND cat_parent != 0'; break; 76 case 'noglobal': $where = 'cat_appname != '.$this->db->quote($this->app_name); break; 77 case 'noglobalapp': $where = 'cat_appname='.$this->db->quote($this->app_name).' AND cat_owner != '.(int)$this->account_id; break; 78 default: return False; 79 } 80 return $where; 81 } 82 83 /** 84 * returns the total number of categories for app, subs or mains 85 * 86 * @param $for one of either 'app' 'subs' or 'mains' 87 * @return integer count of categories 88 */ 89 function total($for = 'app') 90 { 91 switch($for) 92 { 93 case 'app': $where = array('cat_appname' => $this->app_name); break; 94 case 'appandmains': $where = array('cat_appname' => $this->app_name,'cat_parent' => 0); break; 95 case 'appandsubs': $where = array('cat_appname' => $this->app_name,'cat_parent != 0'); break; 96 case 'subs': $where = 'cat_parent != 0'; break; 97 case 'mains': $where = 'cat_parent = 0'; break; 98 default: return False; 99 } 100 101 $this->db->select($this->table,'COUNT(*)',$where,__LINE__,__FILE__); 102 103 return $this->db->next_record() ? $this->db->f(0) : 0; 104 } 105 106 /** 107 * return_all_children 108 * returns array with id's of all children from $cat_id and $cat_id itself! 109 * 110 * @param $cat_id integer cat-id to search for 111 * @return array of cat-id's 112 */ 113 function return_all_children($cat_id) 114 { 115 $all_children = array($cat_id); 116 117 $children = $this->return_array('subs',0,False,'','','',True,$cat_id,-1,'id'); 118 if (is_array($children) && count($children)) 119 { 120 foreach($children as $child) 121 { 122 $all_children = array_merge($all_children,$this->return_all_children($child['id'])); 123 } 124 } 125 //echo "<p>categories::return_all_children($cat_id)=(".implode(',',$all_children).")</p>\n"; 126 return $all_children; 127 } 128 129 /** 130 * return an array populated with categories 131 * 132 * @param string $type defaults to 'all' 133 * @param int $start see $limit 134 * @param boolean $limit if true limited query starting with $start 135 * @param string $query='' query-pattern 136 * @param string $sort='' sort order, either defaults to 'ASC' 137 * @param string $order='' order by 138 * @param boolean $globals includes the global egroupware categories or not 139 * @param int $parent_id=0 if > 0 return subcats or $parent_id 140 * @param int $lastmod = -1 if > 0 return only cats modified since then 141 * @param string $column='' if column-name given only that column is returned, not the full array with all cat-data 142 * @return array or cats 143 */ 144 function return_array($type,$start,$limit = True,$query = '',$sort = '',$order = '',$globals = False, $parent_id = '', $lastmod = -1, $column = '') 145 { 146 if ($globals) 147 { 148 $global_cats = " OR cat_appname='phpgw'"; 149 } 150 151 if (($filter = $this->filter($type))) $filter = ' AND '.$filter; 152 153 if (!$sort) $sort = 'ASC'; 154 155 if (!empty($order) && preg_match('/^[a-zA-Z_(), ]+$/',$order) && (empty($sort) || preg_match('/^(ASC|DESC|asc|desc)$/',$sort))) 156 { 157 $ordermethod = 'ORDER BY '.$order.' '.$sort; 158 } 159 else 160 { 161 $ordermethod = 'ORDER BY cat_main, cat_level, cat_name ASC'; 162 } 163 164 if ($this->account_id == '-1') 165 { 166 $grant_cats = ' cat_owner=-1 '; 167 } 168 else 169 { 170 if (is_array($this->grants)) 171 { 172 $grant_cats = ' (cat_owner=' . $this->account_id . " OR cat_owner=-1 OR cat_access='public' AND cat_owner IN (" . implode(',',array_keys($this->grants)) . ')) '; 173 } 174 else 175 { 176 $grant_cats = ' cat_owner=' . $this->account_id . ' OR cat_owner=-1 '; 177 } 178 } 179 180 if ($parent_id > 0) 181 { 182 $parent_filter = ' AND cat_parent=' . (int)$parent_id; 183 } 184 185 if ($query) 186 { 187 $query = $this->db->quote('%'.$query.'%'); 188 $querymethod = " AND (cat_name LIKE $query OR cat_description LIKE $query) "; 189 } 190 191 if($lastmod > 0) 192 { 193 $querymethod .= ' AND last_mod > ' . (int)$lastmod; 194 } 195 196 $where = '(cat_appname=' . $this->db->quote($this->app_name) . ' AND ' . $grant_cats . $global_cats . ')' 197 . $parent_filter . $querymethod . $filter; 198 199 $this->db->select($this->table,'COUNT(*)',$where,__LINE__,__FILE__); 200 $this->total_records = $this->db->next_record() ? $this->db->f(0) : 0; 201 202 if (!$this->total_records) return false; 203 204 $this->db->select($this->table,'*',$where,__LINE__,__FILE__,$limit ? (int) $start : false,$ordermethod); 205 while (($cat = $this->db->row(true,'cat_'))) 206 { 207 $cat['app_name'] = $cat['appname']; 208 $this->cache_id2cat_data[$cat['id']] = $cat; 209 210 if ($column) 211 { 212 $cats[] = array($column => isset($cat[$column]) ? $cat[$column] : $cat['id']); 213 } 214 else 215 { 216 $cats[] = $cat; 217 } 218 } 219 return $cats; 220 } 221 222 /** 223 * return a sorted array populated with categories 224 * 225 * @param int $start see $limit 226 * @param boolean $limit if true limited query starting with $start 227 * @param string $query='' query-pattern 228 * @param string $sort='' sort order, either defaults to 'ASC' 229 * @param string $order='' order by 230 * @param boolean $globals includes the global egroupware categories or not 231 * @param int $parent_id=0 if > 0 return subcats or $parent_id 232 * @return array with cats 233 */ 234 function return_sorted_array($start,$limit=True,$query='',$sort='',$order='',$globals=False, $parent_id=0) 235 { 236 if ($globals) 237 { 238 $global_cats = " OR cat_appname='phpgw'"; 239 } 240 241 if (!$sort) $sort = 'ASC'; 242 243 if (!empty($order) && preg_match('/^[a-zA-Z_, ]+$/',$order) && (empty($sort) || preg_match('/^(ASC|DESC|asc|desc)$/',$sort))) 244 { 245 $ordermethod = 'ORDER BY '.$order.' '.$sort; 246 } 247 else 248 { 249 $ordermethod = ' ORDER BY cat_name ASC'; 250 } 251 252 if ($this->account_id == '-1') 253 { 254 $grant_cats = " cat_owner='-1' "; 255 } 256 else 257 { 258 if (is_array($this->grants)) 259 { 260 $grant_cats = " (cat_owner='" . $this->account_id . "' OR cat_owner='-1' OR cat_access='public' AND cat_owner IN (" . implode(',',array_keys($this->grants)) . ")) "; 261 } 262 else 263 { 264 $grant_cats = " cat_owner='" . $this->account_id . "' OR cat_owner='-1' "; 265 } 266 } 267 $parent_select = ' AND cat_parent=' . (int)$parent_id; 268 269 if ($query) 270 { 271 $query = $this->db->quote('%'.$query.'%'); 272 $querymethod = " AND (cat_name LIKE $query OR cat_description LIKE $query) "; 273 } 274 275 $where = '(cat_appname=' . $this->db->quote($this->app_name) . ' AND ' . $grant_cats . $global_cats . ')' . $querymethod; 276 277 $parents = $cats = array(); 278 $this->db->select($this->table,'*',$where . $parent_select,__LINE__,__FILE__,false,$ordermethod); 279 while (($cat = $this->db->row(true,'cat_'))) 280 { 281 $cat['app_name'] = $cat['appname']; 282 $this->cache_id2cat_data[$cat['id']] = $cat; 283 284 $cats[] = $cat; 285 $parents[] = $cat['id']; 286 } 287 while (count($parents)) 288 { 289 $sub_select = ' AND cat_parent IN (' . implode(',',$parents) . ')'; 290 $parents = $children = array(); 291 $this->db->select($this->table,'*',$where . $sub_select,__LINE__,__FILE__,false, $ordermethod); 292 while (($cat = $this->db->row(true,'cat_'))) 293 { 294 $cat['app_name'] = $cat['appname']; 295 $this->cache_id2cat_data[$cat['id']] = $cat; 296 297 $parents[] = $cat['id']; 298 $children[$cat['parent']][] = $cat; 299 } 300 // sort the cats into the mains 301 if (count($children)) 302 { 303 $cats2 = $cats; 304 $cats = array(); 305 foreach($cats2 as $cat) 306 { 307 $cats[] = $cat; 308 if (isset($children[$cat['id']])) 309 { 310 foreach($children[$cat['id']] as $child) 311 { 312 $cats[] = $child; 313 } 314 } 315 } 316 } 317 } 318 $this->total_records = count($cats); 319 320 if ($limit) 321 { 322 return array_slice($cats,(int)$start,$GLOBALS['egw_info']['user']['preferences']['common']['maxmatchs']); 323 } 324 return $cats; 325 } 326 327 /** 328 * read a single category 329 * 330 * We use a shared cache together with id2name 331 * 332 * @param int $id id of category 333 * @return array/boolean array with one array of cat-data or false if cat not found 334 */ 335 function return_single($id = '') 336 { 337 if (!isset($this->cache_id2cat_data[$id])) 338 { 339 $this->db->select($this->table,'*',array('cat_id' => $id),__LINE__,__FILE__); 340 341 if(($cat = $this->db->row(true,'cat_'))) 342 { 343 $cat['app_name'] = $cat['appname']; 344 } 345 $this->cache_id2cat_data[$id] = $cat; 346 } 347 return $this->cache_id2cat_data[$id] ? array($this->cache_id2cat_data[$id]) : false; 348 } 349 350 /** 351 * return into a select box, list or other formats 352 * 353 * @param string/array $format string 'select' or 'list', or array with all params 354 * @param string $type='' subs or mains 355 * @param int/array $selected - cat_id or array with cat_id values 356 * @param boolean $globals True or False, includes the global egroupware categories or not 357 * @return string populated with categories 358 */ 359 function formatted_list($format,$type='',$selected = '',$globals = False,$site_link = 'site') 360 { 361 if(is_array($format)) 362 { 363 $type = ($format['type']?$format['type']:'all'); 364 $selected = (isset($format['selected'])?$format['selected']:''); 365 $self = (isset($format['self'])?$format['self']:''); 366 $globals = (isset($format['globals'])?$format['globals']:True); 367 $site_link = (isset($format['site_link'])?$format['site_link']:'site'); 368 $format = $format['format'] ? $format['format'] : 'select'; 369 } 370 371 if (!is_array($selected)) 372 { 373 $selected = explode(',',$selected); 374 } 375 376 if ($type != 'all') 377 { 378 $cats = $this->return_array($type,0,False,'','','',$globals); 379 } 380 else 381 { 382 $cats = $this->return_sorted_array(0,False,'','','',$globals); 383 } 384 385 if (!$cats) return ''; 386 387 if($self) 388 { 389 foreach($cats as $key => $cat) 390 { 391 if ($cat['id'] == $self) 392 { 393 unset($cats[$key]); 394 } 395 } 396 } 397 398 switch ($format) 399 { 400 case 'select': 401 foreach($cats as $cat) 402 { 403 $s .= '<option value="' . $cat['id'] . '"'; 404 if (in_array($cat['id'],$selected)) 405 { 406 $s .= ' selected="selected"'; 407 } 408 $s .= '>'.str_repeat(' ',$cat['level']); 409 $s .= $GLOBALS['egw']->strip_html($cat['name']); 410 if ($cat['app_name'] == 'phpgw' || $cat['owner'] == '-1') 411 { 412 $s .= ' ♦'; 413 } 414 $s .= '</option>' . "\n"; 415 } 416 break; 417 418 case 'list': 419 $space = ' '; 420 421 $s = '<table border="0" cellpadding="2" cellspacing="2">' . "\n"; 422 423 foreach($cats as $cat) 424 { 425 $image_set = ' '; 426 427 if (in_array($cat['id'],$selected)) 428 { 429 $image_set = '<img src="' . EGW_IMAGES_DIR . '/roter_pfeil.gif">'; 430 } 431 if (($cat['level'] == 0) && !in_array($cat['id'],$selected)) 432 { 433 $image_set = '<img src="' . EGW_IMAGES_DIR . '/grauer_pfeil.gif">'; 434 } 435 $space_set = str_repeat($space,$cat['level']); 436 437 $s .= '<tr>' . "\n"; 438 $s .= '<td width="8">' . $image_set . '</td>' . "\n"; 439 $s .= '<td>' . $space_set . '<a href="' . $GLOBALS['egw']->link($site_link,'cat_id=' . $cat['id']) . '">' 440 . $GLOBALS['egw']->strip_html($cat['name']) 441 . '</a></td>' . "\n" 442 . '</tr>' . "\n"; 443 } 444 $s .= '</table>' . "\n"; 445 break; 446 } 447 return $s; 448 } 449 /** 450 * @deprecated use formatted_list 451 */ 452 function formated_list($format,$type='',$selected = '',$globals = False,$site_link = 'site') 453 { 454 return $this->formatted_list($format,$type,$selected,$globals,$site_link); 455 } 456 457 /** 458 * add a category 459 * 460 * @param array $value cat-data 461 * @return int new cat-id 462 */ 463 function add($values) 464 { 465 if ((int)$values['parent'] > 0) 466 { 467 $values['level'] = $this->id2name($values['parent'],'level')+1; 468 $values['main'] = $this->id2name($values['parent'],'main'); 469 } 470 $this->db->insert($this->table,array( 471 'cat_parent' => $values['parent'], 472 'cat_owner' => $this->account_id, 473 'cat_access' => $values['access'], 474 'cat_appname' => $this->app_name, 475 'cat_name' => $values['name'], 476 'cat_description' => $values['descr'], 477 'cat_data' => $values['data'], 478 'cat_main' => $values['main'], 479 'cat_level' => $values['level'], 480 'last_mod' => time(), 481 ),(int)$values['id'] > 0 ? array('cat_id' => $values['id']) : array(),__LINE__,__FILE__); 482 483 $id = (int)$values['id'] > 0 ? (int)$values['id'] : $this->db->get_last_insert_id($this->table,'cat_id'); 484 485 if (!(int)$values['parent']) 486 { 487 $this->db->update($this->table,array('cat_main' => $id),array('cat_id' => $id),__LINE__,__FILE__); 488 } 489 return $id; 490 } 491 492 /** 493 * delete a category 494 * 495 * @param int $cat_id category id 496 * @param boolean $drop_subs=false if true delete sub-cats too 497 * @param boolean $modify_subs=false if true make the subs owned by the parent of $cat_id 498 */ 499 function delete($cat_id, $drop_subs = False, $modify_subs = False) 500 { 501 if ($modify_subs) 502 { 503 $new_parent = $this->id2name($cat_id,'parent'); 504 505 foreach ((array) $this->return_sorted_array('',False,'','','',False, $cat_id) as $cat) 506 { 507 if ($cat['level'] == 1) 508 { 509 $this->db->update($this->table,array( 510 'cat_level' => 0, 511 'cat_parent' => 0, 512 'cat_main' => $cat['id'], 513 ),array( 514 'cat_id' => $cat['id'], 515 'cat_appname' => $this->app_name, 516 ),__LINE__,__FILE__); 517 518 $new_main = $cat['id']; 519 } 520 else 521 { 522 $update = array('cat_level' => $cat['level']-1); 523 524 if ($new_main) $update['cat_main'] = $new_main; 525 526 if ($cat['parent'] == $cat_id) $update['cat_parent'] = $new_parent; 527 528 $this->db->update($this->table,$update,array( 529 'cat_id' => $cat['id'], 530 'cat_appname' => $this->app_name, 531 ),__LINE__,__FILE__); 532 } 533 } 534 } 535 if ($drop_subs) 536 { 537 $where = array('cat_id='.(int)$cat_id.' OR cat_parent='.(int)$cat_id.' OR cat_main='.(int)$cat_id); 538 } 539 else 540 { 541 $where['cat_id'] = $cat_id; 542 } 543 $where['cat_appname'] = $this->app_name; 544 545 $this->db->delete($this->table,$where,__LINE__,__FILE__); 546 } 547 548 /** 549 * edit / update a category 550 * 551 * @param array $values array with cat-data (it need to be complete, as everything get's written) 552 * @return int cat-id 553 */ 554 function edit($values) 555 { 556 if (isset($values['old_parent']) && (int)$values['old_parent'] != (int)$values['parent']) 557 { 558 $this->delete($values['id'],False,True); 559 560 return $this->add($values); 561 } 562 else 563 { 564 if ($values['parent'] > 0) 565 { 566 $values['main'] = $this->id2name($values['parent'],'main'); 567 $values['level'] = $this->id2name($values['parent'],'level') + 1; 568 } 569 else 570 { 571 $values['main'] = $values['id']; 572 $values['level'] = 0; 573 } 574 } 575 $this->db->update($this->table,array( 576 'cat_name' => $values['name'], 577 'cat_description' => $values['descr'], 578 'cat_data' => $values['data'], 579 'cat_parent' => $values['parent'], 580 'cat_access' => $values['access'], 581 'cat_main' => $values['main'], 582 'cat_level' => $values['level'], 583 'last_mod' => time(), 584 ),array( 585 'cat_id' => $values['id'], 586 'cat_appname' => $this->app_name, 587 ),__LINE__,__FILE__); 588 589 return (int)$values['id']; 590 } 591 592 /** 593 * return category id for a given name, only application cat, which are global or owned by the user are returned! 594 * 595 * @param string $cat_name cat-name 596 * @return int cat-id or 0 if not found 597 */ 598 function name2id($cat_name) 599 { 600 static $cache = array(); // a litle bit of caching 601 602 if (isset($cache[$cat_name])) return $cache[$cat_name]; 603 604 $this->db->select($this->table,'cat_id',array( 605 'cat_name' => $cat_name, 606 'cat_appname' => $this->app_name, 607 '(cat_owner = '.(int)$this->account_id.' OR cat_owner = -1)', 608 ),__LINE__,__FILE__); 609 610 if (!$this->db->next_record()) return 0; // cat not found, dont cache it, as it might be created in this request 611 612 return $cache[$cat_name] = (int) $this->db->f('cat_id'); 613 } 614 615 /** 616 * return category information for a given id 617 * 618 * We use a shared cache together with return_single 619 * 620 * @param int $cat_id=0 cat-id 621 * @param string $item='name requested information 622 * @return string information or '--' if not found or !$cat_id 623 */ 624 function id2name($cat_id=0, $item='name') 625 { 626 if(!$cat_id) return '--'; 627 628 if (!isset($this->cache_id2cat_data[$cat_id])) $this->return_single($cat_id); 629 630 if (!$item) $item = 'parent'; 631 632 if ($this->cache_id2cat_data[$cat_id][$item]) 633 { 634 return $this->cache_id2cat_data[$cat_id][$item]; 635 } 636 elseif ($item == 'name') 637 { 638 return '--'; 639 } 640 return null; 641 } 642 643 /** 644 * return category name for a given id 645 * 646 * @deprecated This is only a temp wrapper, use id2name() to keep things matching across the board. (jengo) 647 * @param int $cat_id 648 * @return string cat_name category name 649 */ 650 function return_name($cat_id) 651 { 652 return $this->id2name($cat_id); 653 } 654 655 /** 656 * check if a category id and/or name exists, if id AND name are given the check is for a category with same name and different id (!) 657 * 658 * @param string $type subs or mains 659 * @param string $cat_name='' category name 660 * @param int $cat_id=0 category id 661 * @param int $parent=0 category id of parent 662 * @return int/boolean cat_id or false if cat not exists 663 */ 664 function exists($type,$cat_name = '',$cat_id = 0,$parent = 0) 665 { 666 static $cache = array(); // a litle bit of caching 667 668 if (isset($cache[$type][$cat_name][$cat_id])) return $cache[$type][$cat_name][$cat_id]; 669 670 $where = array($this->filter($type)); 671 672 if ($cat_name) 673 { 674 $where['cat_name'] = $cat_name; 675 676 if ($cat_id) $where[] = 'cat_id != '.(int)$cat_id; 677 } 678 elseif ($cat_id) 679 { 680 $where['cat_id'] = $cat_id; 681 } 682 if ($parent) $where['cat_parent'] = $parent; 683 684 $this->db->select($this->table,'cat_id',$where,__LINE__,__FILE__); 685 686 return $cache[$type][$cat_name][$cat_id] = $this->db->next_record() && $this->db->f(0); 687 } 688 689 /** 690 * Change the owner of all cats owned by $owner to $to OR deletes them if !$to 691 * 692 * @param int $owner owner or the cats to delete or change 693 * @param int $to=0 new owner or 0 to delete the cats 694 * @param string $app='' if given only cats matching $app are modifed/deleted 695 */ 696 function change_owner($owner,$to=0,$app='') 697 { 698 $where = array('cat_owner' => $owner); 699 700 if ($app) $where['cat_appname'] = $app; 701 702 if ((int)$to) 703 { 704 $this->db->update($this->table,array('cat_owner' => $to),$where,__LINE__,__FILE__); 705 } 706 else 707 { 708 $this->db->delete($this->table,$where,__LINE__,__FILE__); 709 } 710 } 711 }
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
Généré le : Sun Feb 25 17:20:01 2007 | par Balluche grâce à PHPXref 0.7 |