1<?php 2// (c) Copyright by authors of the Tiki Wiki CMS Groupware Project 3// 4// All Rights Reserved. See copyright.txt for details and a complete list of authors. 5// Licensed under the GNU LESSER GENERAL PUBLIC LICENSE. See license.txt for details. 6// $Id$ 7 8//this script may only be included - so its better to die if called directly. 9if (strpos($_SERVER['SCRIPT_NAME'], basename(__FILE__)) !== false) { 10 header('location: index.php'); 11 exit; 12} 13 14class ObjectLib extends TikiLib 15{ 16 const SecondsPerDay = 86400; 17 18 /** 19 * Create an object record for the given Tiki object if one doesn't already exist. 20 * Returns the object record OID. If the designated object does not exist, may return NULL. 21 * If the object type is not handled and $checkHandled is TRUE, fail and return FALSE. 22 * $checkHandled A boolean indicating whether only handled object types should be accepted when the object has no object record (legacy). 23 * When creating, if $description is given, use the description, name and URL given as information. 24 * Otherwise retrieve it from the object (if $checkHandled is FALSE, fill with empty strings if the object type is not handled). 25 * Handled object types: "article", "blog", "calendar", "directory", "faq", 26 * "file", "file gallery", "forum", "image gallery", "poll", "quiz", "tracker", "trackeritem", "wiki page" and "template". 27 * 28 * Remember to update get_supported_types if this changes 29 */ 30 function add_object($type, $itemId, $checkHandled = true, $description = null, $name = null, $href = null) 31 { 32 $objectId = $this->get_object_id($type, $itemId); 33 34 if ($objectId) { 35 if (! empty($description) || ! empty($name) || ! empty($href)) { 36 $query = "update `tiki_objects` set `description`=?,`name`=?,`href`=? where `objectId`=?"; 37 $this->query($query, [$description, $name, $href, $objectId]); 38 } 39 } else { 40 if (is_null($description)) { 41 switch ($type) { 42 case 'article': 43 $artlib = TikiLib::lib('art'); 44 $info = $artlib->get_article($itemId); 45 46 $description = $info['heading']; 47 $name = $info['title']; 48 $href = 'tiki-read_article.php?articleId=' . $itemId; 49 break; 50 51 case 'blog': 52 $bloglib = TikiLib::lib('blog'); 53 $info = $bloglib->get_blog($itemId); 54 55 $description = $info['description']; 56 $name = $info['title']; 57 $href = 'tiki-view_blog.php?blogId=' . $itemId; 58 break; 59 60 case 'calendar': 61 $calendarlib = TikiLib::lib('calendar'); 62 $info = $calendarlib->get_calendar($itemId); 63 64 $description = $info['description']; 65 $name = $info['name']; 66 $href = 'tiki-calendar.php?calId=' . $itemId; 67 break; 68 69 case 'directory': 70 $info = $this->get_directory($itemId); 71 72 $description = $info['description']; 73 $name = $info['name']; 74 $href = 'tiki-directory_browse.php?parent=' . $itemId; 75 break; 76 77 case 'faq': 78 $info = TikiLib::lib('faq')->get_faq($itemId); 79 80 $description = $info['description']; 81 $name = $info['title']; 82 $href = 'tiki-view_faq.php?faqId=' . $itemId; 83 break; 84 85 case 'file': 86 $filegallib = TikiLib::lib('filegal'); 87 $info = $filegallib->get_file_info($itemId, false, false, false); 88 89 $description = $info['description']; 90 $name = $info['name']; 91 $href = 'tiki-upload_file.php?fileId=' . $itemId; 92 break; 93 94 case 'file gallery': 95 $filegallib = TikiLib::lib('filegal'); 96 $info = $filegallib->get_file_gallery($itemId); 97 98 $description = $info['description']; 99 $name = $info['name']; 100 $href = 'tiki-list_file_gallery.php?galleryId=' . $itemId; 101 break; 102 103 case 'forum': 104 $commentslib = TikiLib::lib('comments'); 105 $info = $commentslib->get_forum($itemId); 106 107 $description = $info['description']; 108 $name = $info['name']; 109 $href = 'tiki-view_forum.php?forumId=' . $itemId; 110 break; 111 112 case 'image gallery': 113 $info = $this->get_gallery($itemId); 114 115 $description = $info['description']; 116 $name = $info['name']; 117 $href = 'tiki-browse_gallery.php?galleryId=' . $itemId; 118 break; 119 120 case 'perspective': 121 $info = TikiLib::lib('perspective')->get_perspective($itemId); 122 $name = $info['name']; 123 $href = 'tiki-switch_perspective.php?perspective=' . $itemId; 124 break; 125 126 case 'poll': 127 $polllib = TikiLib::lib('poll'); 128 $info = $polllib->get_poll($itemId); 129 130 $description = $info['title']; 131 $name = $info['title']; 132 $href = 'tiki-poll_form.php?pollId=' . $itemId; 133 break; 134 135 case 'quiz': 136 $info = TikiLib::lib('quiz')->get_quiz($itemId); 137 138 $description = $info['description']; 139 $name = $info['name']; 140 $href = 'tiki-take_quiz.php?quizId=' . $itemId; 141 break; 142 143 case 'tracker': 144 $trklib = TikiLib::lib('trk'); 145 $info = $trklib->get_tracker($itemId); 146 147 $description = $info['description']; 148 $name = $info['name']; 149 $href = 'tiki-view_tracker.php?trackerId=' . $itemId; 150 break; 151 152 case 'trackeritem': 153 $trklib = TikiLib::lib('trk'); 154 $info = $trklib->get_tracker_item($itemId); 155 156 $description = ''; 157 $name = $trklib->get_isMain_value($info['trackerId'], $itemId); 158 $href = "tiki-view_tracker_item.php?itemId=$itemId&trackerId=" . $info['trackerId']; 159 break; 160 161 case 'wiki page': 162 if (! ($info = $this->get_page_info($itemId))) { 163 return; 164 } 165 $description = $info["description"]; 166 $name = $itemId; 167 $href = 'tiki-index.php?page=' . urlencode($itemId); 168 break; 169 170 case 'template': 171 $info = TikiLib::lib('template')->get_template($itemId); 172 173 $description = ''; 174 $name = $info['name']; 175 $href = "tiki-admin_content_templates.php?templateId=$itemId"; 176 break; 177 178 default: 179 if ($checkHandled) { 180 return false; 181 } else { 182 $description = ''; 183 $name = ''; 184 $href = ''; 185 } 186 } 187 } 188 $objectId = $this->insert_object($type, $itemId, $description, $name, $href); 189 } 190 191 return $objectId; 192 } 193 194 /** 195 * Returns an array of object types supported (and therefore can be categorised etc) 196 * 197 * @return array 198 */ 199 static function get_supported_types() 200 { 201 return [ 202 'article', 203 'blog', 204 'calendar', 205 'directory', 206 'faq', 207 'file', 208 'file gallery', 209 'forum', 210 'image gallery', 211 'perspective', 212 'poll', 213 'quiz', 214 'tracker', 215 'trackeritem', 216 'wiki page', 217 'template', 218 ]; 219 } 220 221 function getSelectorType($type) 222 { 223 $supported = [ 224 'category' => 'category', 225 'file_gallery' => 'file gallery', 226 'forum' => 'forum', 227 'group' => 'group', 228 'tracker' => 'tracker', 229 'tracker_field' => 'trackerfield', 230 'trackerfield' => 'trackerfield', 231 'wiki_page' => 'wiki page', 232 'wiki page' => 'wiki page', 233 'template' => 'template', 234 ]; 235 236 if (isset($supported[$type])) { 237 return $supported[$type]; 238 } else { 239 return false; 240 } 241 } 242 243 function insert_object($type, $itemId, $description = '', $name = '', $href = '') 244 { 245 if (! $itemId) { 246 // When called with a blank page name or any other empty value, no insertion should be made 247 return false; 248 } 249 250 $tikilib = TikiLib::lib('tiki'); 251 $table = $this->table('tiki_objects'); 252 return $table->insert( 253 [ 254 'type' => $type, 255 'itemId' => (string) $itemId, 256 'description' => $description, 257 'name' => $name, 258 'href' => $href, 259 'created' => (int) $tikilib->now, 260 'hits' => 0, 261 'comments_locked' => 'n', 262 ] 263 ); 264 } 265 266 function get_object_id($type, $itemId) 267 { 268 $query = "select `objectId` from `tiki_objects` where `type`=? and `itemId`=?"; 269 return $this->getOne($query, [$type, $itemId]); 270 } 271 272 // Returns an array containing the object ids of objects of the same type. 273 // Each entry uses the item id as key and the object id as key. Items with no object id are ignored. 274 function get_object_ids($type, $itemIds) 275 { 276 if (empty($itemIds)) { 277 return []; 278 } 279 280 $query = 'select `objectId`, `itemId` from `tiki_objects` where `type`=? and `itemId` IN (' . 281 implode(',', array_fill(0, count($itemIds), '?')) . ')'; 282 283 $result = $this->query($query, array_merge([$type], $itemIds)); 284 $objectIds = []; 285 286 while ($res = $result->fetchRow()) { 287 $objectIds[$res['itemId']] = $res['objectId']; 288 } 289 return $objectIds; 290 } 291 292 function get_needed_perm($objectType, $action) 293 { 294 switch ($objectType) { 295 case 'wiki page': 296 case 'wiki': 297 switch ($action) { 298 case 'view': 299 case 'read': 300 return 'tiki_p_view'; 301 302 case 'edit': 303 return 'tiki_p_edit'; 304 } 305 case 'article': 306 switch ($action) { 307 case 'view': 308 case 'read': 309 return 'tiki_p_read_article'; 310 311 case 'edit': 312 return 'tiki_p_edit_article'; 313 } 314 case 'post': 315 switch ($action) { 316 case 'view': 317 case 'read': 318 return 'tiki_p_read_blog'; 319 320 case 'edit': 321 return 'tiki_p_create_blog'; 322 } 323 324 case 'blog': 325 switch ($action) { 326 case 'view': 327 case 'read': 328 return 'tiki_p_read_blog'; 329 330 case 'edit': 331 return 'tiki_p_create_blog'; 332 } 333 334 case 'faq': 335 switch ($action) { 336 case 'view': 337 case 'read': 338 return 'tiki_p_view_faqs'; 339 340 case 'edit': 341 return 'tiki_p_admin_faqs'; 342 } 343 344 case 'file gallery': 345 switch ($action) { 346 case 'view': 347 case 'read': 348 return 'tiki_p_view_file_gallery'; 349 350 case 'edit': 351 return 'tiki-admin_file_galleries'; 352 } 353 354 case 'image gallery': 355 switch ($action) { 356 case 'view': 357 case 'read': 358 return 'tiki_p_view_image_gallery'; 359 360 case 'edit': 361 return 'tiki_p_admin_galleries'; 362 } 363 364 case 'poll': 365 switch ($action) { 366 case 'view': 367 case 'read': 368 return 'tiki_p_vote_poll'; 369 370 case 'edit': 371 return 'tiki_p_admin'; 372 } 373 374 case 'comment': 375 case 'comments': 376 switch ($action) { 377 case 'view': 378 case 'read': 379 return 'tiki_p_read_comments'; 380 381 case 'edit': 382 return 'tiki_p_edit_comments'; 383 } 384 385 case 'trackeritem': 386 switch ($action) { 387 case 'view': 388 case 'read': 389 return 'tiki_p_view_trackers'; 390 391 case 'edit': 392 return 'tiki_p_modify_tracker_items'; 393 } 394 395 case 'trackeritem_closed': 396 switch ($action) { 397 case 'view': 398 case 'read': 399 return 'tiki_p_view_trackers'; 400 401 case 'edit': 402 return 'tiki_p_modify_tracker_items_closed'; 403 } 404 405 case 'trackeritem_pending': 406 switch ($action) { 407 case 'view': 408 case 'read': 409 return 'tiki_p_view_trackers'; 410 411 case 'edit': 412 return 'tiki_p_modify_tracker_items_pending'; 413 } 414 415 case 'tracker': 416 switch ($action) { 417 case 'view': 418 case 'read': 419 return 'tiki_p_list_trackers'; 420 421 case 'edit': 422 return 'tiki_p_admin_trackers'; 423 } 424 425 case 'template': 426 switch ($action) { 427 case 'view': 428 case 'read': 429 return 'tiki_p_use_content_templates'; 430 431 case 'edit': 432 return 'tiki_p_edit_content_templates'; 433 } 434 default: 435 return ''; 436 } 437 } 438 439 function get_info($objectType, $object) 440 { 441 switch ($objectType) { 442 case 'wiki': 443 case 'wiki page': 444 $tikilib = TikiLib::lib('tiki'); 445 $info = $tikilib->get_page_info($object); 446 return ['title' => $object, 'data' => $info['data'], 'is_html' => $info['is_html']]; 447 448 case 'article': 449 $artlib = TikiLib::lib('art'); 450 $info = $artlib->get_article($object); 451 return ['title' => $info['title'], 'data' => $info['body']]; 452 453 case 'file gallery': 454 $info = TikiLib::lib('filegal')->get_file_gallery_info($object); 455 return ['title' => $info['name']]; 456 457 case 'blog': 458 $info = TikiLib::lib('blog')->get_blog($object); 459 return ['title' => $info['title']]; 460 461 case 'post': 462 case 'blog post': 463 case 'blogpost': 464 $info = TikiLib::lib('blog')->get_post($object); 465 return ['title' => $info['title']]; 466 467 case 'forum': 468 $info = TikiLib::lib('comments')->get_forum($object); 469 return ['title' => $info['name']]; 470 471 case 'forum post': 472 $info = TikiLib::lib('comments')->get_comment($object); 473 return ['title' => $info['title']]; 474 475 case 'tracker': 476 $info = TikiLib::lib('trk')->get_tracker($object); 477 return ['title' => $info['name']]; 478 479 case 'trackerfield': 480 $info = TikiLib::lib('trk')->get_tracker_field($object); 481 return ['title' => $info['name']]; 482 483 case 'goal': 484 return TikiLib::lib('goal')->fetchGoal($object); 485 486 case 'template': 487 $info = TikiLib::lib('template')->get_template($object); 488 return ['title' => $info['name']]; 489 } 490 return (['error' => 'true']); 491 } 492 493 function set_data($objectType, $object, $data) 494 { 495 switch ($objectType) { 496 case 'wiki': 497 case 'wiki page': 498 global $user; 499 $tikilib = TikiLib::lib('tiki'); 500 $tikilib->update_page($object, $data, tra('section edit'), $user, $tikilib->get_ip_address()); 501 break; 502 } 503 } 504 505 function delete_object($type, $itemId) 506 { 507 $query = 'delete from `tiki_objects` where `itemId`=? and `type`=?'; 508 $this->query($query, [$itemId, $type]); 509 } 510 511 function delete_object_via_objectid($objectId) 512 { 513 $query = 'delete from `tiki_objects` where `objectId`=?'; 514 $this->query($query, [(int) $objectId]); 515 } 516 517 function get_object($type, $itemId) 518 { 519 $query = 'select * from `tiki_objects` where `itemId`=? and `type`=?'; 520 $result = $this->query($query, [$itemId, $type]); 521 return $result->fetchRow(); 522 } 523 524 function get_object_via_objectid($objectId) 525 { 526 $query = 'select * from `tiki_objects` where `objectId`=?'; 527 $result = $this->query($query, [(int) $objectId]); 528 return $result->fetchRow(); 529 } 530 531 /** 532 * @param string $type 533 * @param $id 534 * @param string $format - trackeritem format coming from ItemLink field or null by default 535 * @return void|string 536 */ 537 function get_title($type, $id, $format = null) 538 { 539 $detail = ''; 540 switch ($type) { 541 case 'trackeritemfield': 542 $type = 'trackeritem'; 543 $ids = explode(':', $id); 544 $id = (int)$ids[0]; 545 $fieldId = (int)$ids[1]; 546 $trackerlib = TikiLib::lib('trk'); 547 $info = $trackerlib->get_field_info($fieldId); 548 $extra = $info['name']; 549 case 'trackeritem': 550 if ($format) { 551 $lib = TikiLib::lib('unifiedsearch'); 552 $query = $lib->buildQuery([ 553 'object_type' => 'trackeritem', 554 'object_id' => $id 555 ]); 556 $result = $query->search($lib->getIndex()); 557 $result->applyTransform(function ($item) use ($format) { 558 return preg_replace_callback('/\{(\w+)\}/', function ($matches) use ($item, $format) { 559 $key = $matches[1]; 560 if (isset($item[$key])) { 561 return $item[$key]; 562 } elseif (! $format || $format == '{title}') { 563 return tr('empty'); 564 } else { 565 return ''; 566 } 567 }, $format); 568 }); 569 $titles = $result->getArrayCopy(); 570 $title = array_shift($titles); 571 } else { 572 $title = TikiLib::lib('trk')->get_isMain_value(null, $id); 573 } 574 if (empty($title)) { 575 $title = "$type:$id"; 576 } 577 if (isset($extra) && $extra) { 578 $title .= ' (' . $extra . ')'; 579 } 580 return $title; 581 case 'category': 582 return TikiLib::lib('categ')->get_category_name($id); 583 case 'file': 584 return TikiLib::lib('filegal')->get_file_label($id); 585 case 'topic': 586 $meta = TikiLib::lib('art')->get_topic($id); 587 return $meta['name']; 588 case 'group': 589 return $id; 590 case 'user': 591 if (is_int($id)) { 592 $id = TikiLib::lib('tiki')->get_user_login($id); 593 } 594 return TikiLib::lib('user')->clean_user($id); 595 case 'calendar': 596 $info = TikiLib::lib('calendar')->get_calendar($id); 597 return $info['name']; 598 case 'calendar event': 599 $info = TikiLib::lib('calendar')->get_item($id); 600 return $info['name']; 601 } 602 603 $title = $this->table('tiki_objects')->fetchOne( 604 'name', 605 [ 606 'type' => $type, 607 'itemId' => $id, 608 ] 609 ); 610 611 if ($title) { 612 return $title; 613 } 614 615 $info = $this->get_info($type, $id); 616 617 if (isset($info['title'])) { 618 return $info['title']; 619 } 620 621 if (isset($info['name'])) { 622 return $info['name']; 623 } 624 } 625 626 /** 627 * Gets a wiki parsed content for an object. This is used in case an object can have wiki parsed 628 * content that generates relations (ex: Plugin Include). 629 * 630 * This content can be used to find elements, but displaying to user might not be a good idea, since 631 * text from different fields can be concatenated. 632 * 633 * @param string $type 634 * @param $id 635 * @return void|string 636 */ 637 function get_wiki_content($type, $objectId) 638 { 639 if (substr($type, -7) == 'comment') { 640 $comment_info = TikiLib::lib('comments')->get_comment((int)$objectId); 641 return $comment_info['data']; 642 } 643 644 switch ($type) { 645 case 'wiki': 646 $type = 'wiki page'; 647 case 'wiki page': 648 $info = $this->get_page_info($objectId); 649 return $info['data']; 650 case 'forum post': 651 $comment_info = TikiLib::lib('comments')->get_comment((int)$objectId); 652 return $comment_info['data']; 653 case 'article': 654 $info = TikiLib::lib('art')->get_article((int)$objectId); 655 return $info['heading'] . "\n" . $info['body']; 656 case 'tracker': 657 $tracker_info = TikiLib::lib('trk')->get_tracker((int)$objectId); 658 return $tracker_info['description']; 659 case 'trackerfield': 660 $field_info = TikiLib::lib('trk')->get_field_info((int)$objectId); 661 return $field_info['description']; 662 case 'trackeritemfield': 663 $objectId = explode(':', $objectId); 664 $itemId = (int)$objectId[0]; 665 $fieldId = (int)$objectId[1]; 666 $trackerlib = TikiLib::lib('trk'); 667 $item_info = $trackerlib->get_tracker_item($itemId); 668 return $item_info[$fieldId]; 669 } 670 } 671 672 /** 673 * @param string $type 674 * @return string 675 */ 676 function get_verbose_type($type) 677 { 678 if (substr($type, -7) == 'comment') { 679 $isComment = true; 680 $type = substr($type, 0, strlen($type) - 8); 681 } else { 682 $isComment = false; 683 } 684 685 switch ($type) { 686 case 'trackeritem': 687 $type = 'tracker item'; 688 break; 689 case 'trackeritemfield': 690 $type = 'tracker item field'; 691 break; 692 case 'trackerfield': 693 $type = 'tracker field'; 694 break; 695 case 'wiki': 696 $type = 'wiki page'; 697 break; 698 } 699 700 if ($isComment) { 701 $type .= " comment"; 702 } 703 704 return tra(ucwords($type)); 705 } 706 707 /** 708 * Returns a hash indicating which permission is needed for viewing an object of desired type. 709 * 710 * @param boolean $comment - indicate if returned permission must be comment-related, e.g. 711 * am I allowed to see comments on a tracker item if I have or don't have tiki_p_tracker_view_comments. 712 * This allows search index to properly update comment permissions not basing them on viewing 713 * parent tracker item or wiki page but the comment itself. 714 */ 715 static function map_object_type_to_permission($comment = false) 716 { 717 return [ 718 'wiki page' => $comment ? 'tiki_p_wiki_view_comments' : 'tiki_p_view', 719 'wiki' => $comment ? 'tiki_p_wiki_view_comments' : 'tiki_p_view', 720 'forum' => 'tiki_p_forum_read', 721 'forum post' => 'tiki_p_forum_read', 722 'image gallery' => 'tiki_p_view_image_gallery', 723 'file gallery' => 'tiki_p_view_file_gallery', 724 'tracker' => 'tiki_p_view_trackers', 725 'blog' => 'tiki_p_read_blog', 726 'quiz' => 'tiki_p_take_quiz', 727 'template' => 'tiki_p_use_content_templates', 728 729 // overhead - we are checking individual permission on types below, but they 730 // can't have individual permissions, although they can be categorized. 731 // should they have permissions too? 732 'poll' => 'tiki_p_vote_poll', 733 'survey' => 'tiki_p_take_survey', 734 'directory' => 'tiki_p_view_directory', 735 'faq' => 'tiki_p_view_faqs', 736 'sheet' => 'tiki_p_view_sheet', 737 738 // these ones are tricky, because permission type is for container, not object itself. 739 // I think we need to refactor permission schemes for them to be wysiwyca - lfagundes 740 // 741 // by now they're not showing, list_category_objects needs support for ignoring permissions 742 // for a type. 743 'blog post' => 'tiki_p_read_blog', 744 'article' => 'tiki_p_read_article', 745 'submission' => 'tiki_p_approve_submission', 746 'image' => 'tiki_p_view_image_gallery', 747 'calendar' => 'tiki_p_view_calendar', 748 'file' => 'tiki_p_download_files', 749 'trackeritem' => $comment ? 'tiki_p_tracker_view_comments' : 'tiki_p_view_trackers', 750 751 // newsletters can't be categorized, although there's some code in tiki-admin_newsletters.php 752 // 'newsletter' => ?, 753 // 'events' => ?, 754 ]; 755 } 756 757 function get_metadata($type, $object, & $classList) 758 { 759 $smarty = TikiLib::lib('smarty'); 760 $smarty->loadPlugin('smarty_modifier_escape'); 761 762 $escapedType = smarty_modifier_escape($type); 763 $escapedObject = smarty_modifier_escape($object); 764 $metadata = ' data-type="' . $escapedType . '" data-object="' . $escapedObject . '"'; 765 766 if ($coordinates = TikiLib::lib('geo')->get_coordinates($type, $object)) { 767 $classList[] = 'geolocated'; 768 $metadata .= " data-geo-lat=\"{$coordinates['lat']}\" data-geo-lon=\"{$coordinates['lon']}\""; 769 770 if (isset($coordinates['zoom'])) { 771 $metadata .= " data-geo-zoom=\"{$coordinates['zoom']}\""; 772 } 773 } 774 775 $attributelib = TikiLib::lib('attribute'); 776 $attributes = $attributelib->get_attributes($type, $object); 777 778 if (isset($attributes['tiki.icon.src'])) { 779 $escapedIcon = smarty_modifier_escape($attributes['tiki.icon.src']); 780 $metadata .= " data-icon-src=\"$escapedIcon\""; 781 } 782 783 return $metadata; 784 } 785 786 function get_typeItemsInfo($type) // Returns information on all items of an object type (eg: menu, article, etc) from tiki_objects table 787 { 788 //get objects 789 $queryObjectInfo = 'select * from `tiki_objects` where `type`=?'; 790 $resultObjectInfo = $this->fetchAll($queryObjectInfo, [$type]); 791 792 //get object attributes 793 foreach ($resultObjectInfo as &$tempInfo) { 794 $objectAttributes = TikiLib::lib('attribute')->get_attributes($tempInfo['type'], $tempInfo['objectId']); 795 $tempInfo = array_merge($tempInfo, $objectAttributes); 796 } 797 unset($tempInfo); 798 799 //return information 800 return $resultObjectInfo; 801 } 802 803 public function get_maintainers() // get all objects that have maintainers ??? GET_MAINTAINED_OBJECTS 804 { 805 $relationlib = TikiLib::lib('relation'); 806 return $relationlib->get_related_objects('tiki.object.maintainer'); 807 } 808 809 public function set_maintainers($objectId, array $maintainers, $type = 'wiki page') 810 { 811 $relationlib = TikiLib::lib('relation'); 812 813 foreach ($maintainers as $maintainer) { 814 $relationlib->add_relation('tiki.object.maintainer', $type, $objectId, 'user', $maintainer); 815 } 816 } 817 818 public function get_freshness($objectId, $type = 'wiki page') 819 { 820 if ($type === 'wiki page') { 821 $info = TikiLib::lib('tiki')->get_page_info($objectId, false); 822 if (isset($info)) { 823 $lastModif = $info['lastModif']; 824 $freshness = (int) ((time() - $lastModif) / self::SecondsPerDay); 825 return $freshness; 826 } 827 } else { 828 Feedback::error(tr('Object freshness not supported yet for object type %0', $type)); 829 } 830 831 return false; 832 } 833} 834