| [ Index ] |
|
Code source de GeekLog 1.4.1 |
1 <?php 2 3 /* Reminder: always indent with 4 spaces (no tabs). */ 4 // +---------------------------------------------------------------------------+ 5 // | Geeklog 1.4 | 6 // +---------------------------------------------------------------------------+ 7 // | lib-plugins.php | 8 // | | 9 // | This file implements plugin support in Geeklog. | 10 // +---------------------------------------------------------------------------+ 11 // | Copyright (C) 2000-2006 by the following authors: | 12 // | | 13 // | Authors: Tony Bibbs - tony AT tonybibbs DOT com | 14 // | Blaine Lang - blaine AT portalparts DOT com | 15 // | Dirk Haun - dirk AT haun-online DOT de | 16 // +---------------------------------------------------------------------------+ 17 // | | 18 // | This program is free software; you can redistribute it and/or | 19 // | modify it under the terms of the GNU General Public License | 20 // | as published by the Free Software Foundation; either version 2 | 21 // | of the License, or (at your option) any later version. | 22 // | | 23 // | This program is distributed in the hope that it will be useful, | 24 // | but WITHOUT ANY WARRANTY; without even the implied warranty of | 25 // | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 26 // | GNU General Public License for more details. | 27 // | | 28 // | You should have received a copy of the GNU General Public License | 29 // | along with this program; if not, write to the Free Software Foundation, | 30 // | Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | 31 // | | 32 // +---------------------------------------------------------------------------+ 33 // 34 // $Id: lib-plugins.php,v 1.113 2006/12/09 19:18:08 dhaun Exp $ 35 36 /** 37 * This is the plugin library for Geeklog. This is the API that plugins can 38 * implement to get tight integration with Geeklog. 39 * See each function for more details. 40 * 41 */ 42 43 if (strpos ($_SERVER['PHP_SELF'], 'lib-plugins.php') !== false) { 44 die ('This file can not be used on its own!'); 45 } 46 47 require_once($_CONF['path_system'] . 'classes/plugin.class.php'); 48 49 // buffer for function names for the center block API 50 $PLG_bufferCenterAPI = array (); 51 $PLG_buffered = false; 52 53 // buffer enabled plugins 54 $result = DB_query("SELECT pi_name FROM {$_TABLES['plugins']} WHERE pi_enabled = 1"); 55 $_PLUGINS = array(); 56 while ($A = DB_fetchArray($result)) { 57 $_PLUGINS[] = $A['pi_name']; 58 } 59 60 /** 61 * Calls a function for all enabled plugins 62 * 63 * @param string $function_name holds name of function to call 64 * 65 */ 66 function PLG_callFunctionForAllPlugins($function_name) 67 { 68 global $_PLUGINS; 69 70 foreach ($_PLUGINS as $pi_name) { 71 $function = $function_name . $pi_name; 72 if (function_exists($function)) { 73 $function(); 74 } 75 } 76 } 77 78 /** 79 * Calls a function for a single plugin 80 * 81 * This is a generic function used by some of the other API functions to 82 * call a function for a specific plugin and, optionally pass parameters. 83 * This function can handle up to 5 arguments and if more exist it will 84 * try to pass the entire args array to the function. 85 * 86 * @param string $function holds name of function to call 87 * @param array $args arguments to send to function 88 * @return mixed returns result of function call, otherwise false 89 * 90 */ 91 function PLG_callFunctionForOnePlugin($function, $args='') 92 { 93 if (function_exists($function)) { 94 if (empty ($args)) { 95 $args = array (); 96 } 97 98 // great, function exists, run it 99 switch (count($args)) { 100 case 0: 101 return $function(); 102 break; 103 case 1: 104 return $function($args[1]); 105 break; 106 case 2: 107 return $function($args[1], $args[2]); 108 break; 109 case 3: 110 return $function($args[1], $args[2], $args[3]); 111 break; 112 case 4: 113 return $function($args[1], $args[2], $args[3], $args[4]); 114 break; 115 case 5: 116 return $function($args[1], $args[2], $args[3], $args[4], $args[5]); 117 break; 118 case 6: 119 return $function($args[1], $args[2], $args[3], $args[4], $args[5], $args[6]); 120 break; 121 case 7: 122 return $function($args[1], $args[2], $args[3], $args[4], $args[5], $args[6], $args[7]); 123 break; 124 default: 125 return $function($args); 126 break; 127 } 128 } else { 129 return false; 130 } 131 } 132 133 /** 134 * Tells a plugin to install itself. NOTE: not currently used anymore 135 * 136 * @param string $type Plugin name 137 * @return boolean Returns true on success otherwise false 138 * 139 */ 140 function PLG_install($type) 141 { 142 return PLG_callFunctionForOnePlugin('plugin_install_' . $type); 143 } 144 145 /** 146 * Upgrades a plugin. Tells a plugin to upgrade itself. 147 * 148 * @param string $type Plugin name 149 * @return boolean Returns true on success otherwise false 150 * 151 */ 152 function PLG_upgrade($type) 153 { 154 return PLG_callFunctionForOnePlugin('plugin_upgrade_' . $type); 155 } 156 157 /** 158 * Calls the plugin function to return the current version of code. 159 * Used to indicate to admin if an update or upgrade is requied. 160 * 161 * @param string $type Plugin name 162 * @return boolean Returns true on success otherwise false 163 * 164 */ 165 function PLG_chkVersion($type) 166 { 167 return PLG_callFunctionForOnePlugin('plugin_chkVersion_' . $type); 168 } 169 170 /** 171 * Tells a plugin to uninstall itself. 172 * 173 * @param string $type Plugin to uninstall 174 * @return boolean Returns true on success otherwise false 175 * 176 */ 177 function PLG_uninstall ($type) 178 { 179 global $_PLUGINS, $_TABLES; 180 181 if (empty ($type)) { 182 return false; 183 } 184 185 $retval = PLG_callFunctionForOnePlugin ('plugin_uninstall_' . $type); 186 187 if ($retval === true) { 188 $plg = array_search ($type, $_PLUGINS); 189 if ($plg !== false) { 190 unset ($_PLUGINS[$plg]); 191 } 192 193 return true; 194 /** 195 } else if ($PLG_$type['auto_uninstall'] == true) 196 197 // removing tables 198 $i = count($PLG_$type['tables']); 199 for ($i=0; $i < count; $i++) { 200 COM_errorLog ('Dropping table' . $_PLG_$type['tables'][$i], 1); 201 DB_query ("DROP TABLE {$_TABLES[$_PLG_$type['tables'][$i]]}"); 202 COM_errorLog ('...success', 1); 203 } 204 205 // removing groups 206 $i = count($PLG_$type['groups']); 207 for ($i=0; $i < count; $i++) { 208 $grp_id = DB_getItem ($_TABLES['groups'], 'grp_id', 209 "grp_name = '{$_PLG_$type['groups'][$i]}'"); 210 if (!empty ($grp_id)) { 211 COM_errorLog ('Attempting to remove the {$_PLG_$type['groups'][$i]} group', 1); 212 DB_query ("DELETE FROM {$_TABLES['groups']} WHERE grp_id = $grp_id"); 213 COM_errorLog ('...success', 1); 214 COM_errorLog ('Attempting to {$_PLG_$type['groups'][$i]} group from all groups.', 1); 215 DB_query("DELETE FROM {$_TABLES['group_assignments']} WHERE ug_main_grp_id = $grp_id"); 216 COM_errorLog ('...success', 1); 217 } 218 } 219 220 // removing features 221 $i = count($PLG_$type['features']); 222 for ($i=0; $i < count; $i++) { 223 $access_id = DB_getItem ($_TABLES['features'], 'ft_id', 224 "ft_name = '{$_PLG_$type['features'][$i]}'"); 225 if (!empty ($acess_id)) { 226 COM_errorLog ('Attempting to remove {$_PLG_$type['features'][$i]} rights from all groups' ,1); 227 DB_query ("DELETE FROM {$_TABLES['access']} WHERE acc_ft_id = $edit_id"); 228 COM_errorLog ('...success', 1); 229 COM_errorLog ('Attempting to remove the {$_PLG_$type['features'][$i]} feature', 1); 230 DB_query ("DELETE FROM {$_TABLES['features']} WHERE ft_id = $edit_id"); 231 COM_errorLog ('...success', 1); 232 } 233 } 234 235 #uninstall feeds 236 $sql = "SELECT filename FROM {$_TABLES['syndication']} WHERE type = '$type';"; 237 $result = DB_query( $sql ); 238 $nrows = DB_numRows( $result ); 239 if ( $nrows > 0 ) { 240 COM_errorLog ('removing feed files', 1); 241 COM_errorLog ($nrows. ' files stored in table.', 1); 242 for ( $i = 0; $i < $nrows; $i++ ) { 243 $fcount = $i + 1; 244 $A = DB_fetchArray( $result ); 245 $fullpath = SYND_getFeedPath( $A[0] ); 246 if ( file_exists( $fullpath ) ) { 247 unlink ($fullpath); 248 COM_errorLog ("removed file $fcount of $nrows: $fullpath", 1); 249 } else { 250 COM_errorLog ("cannot remove file $fcount of $nrows, it does not exist! ($fullpath)", 1); 251 } 252 } 253 COM_errorLog ('...success', 1); 254 // Remove Links Feeds from syndiaction table 255 COM_errorLog ('removing links feeds from table', 1); 256 DB_query ("DELETE FROM {$_TABLES['syndication']} WHERE `type` = '$type'"); 257 COM_errorLog ('...success', 1); 258 } 259 260 // uninstall php-blocks 261 $i = count($PLG_$type['php_blocks']); 262 for ($i=0; $i < count; $i++) { 263 DB_delete ($_TABLES['blocks'], array ('type', 'phpblockfn'), 264 array ('phpblock', 'phpblock_{$_PLG_$type['php_blocks'][$i]}')); 265 } 266 267 // uninstall the plugin 268 COM_errorLog ('Attempting to unregister the $type plugin from Geeklog', 1); 269 DB_query ("DELETE FROM {$_TABLES['plugins']} WHERE pi_name = '$type'"); 270 COM_errorLog ('...success',1); 271 272 COM_errorLog ('Finished uninstalling the $type plugin.', 1); 273 **/ 274 } 275 276 return false; 277 } 278 279 /** 280 * Inform plugin that it is either being enabled or disabled. 281 * 282 * @param string $type Plugin name 283 * @param boolean $enable true if enabling, false if disabling 284 * @return boolean Returns true on success otherwise false 285 * 286 */ 287 function PLG_enableStateChange ($type, $enable) 288 { 289 global $_CONF, $_TABLES, $_DB_table_prefix; 290 291 $args[1] = $enable; 292 293 // IF we are enabling the plugin 294 // THEN we must include its functions.inc so we have access to the function 295 if ($enable) { 296 require_once ($_CONF['path'] . 'plugins/' . $type . '/functions.inc'); 297 } 298 299 return PLG_callFunctionForOnePlugin ('plugin_enablestatechange_' . $type, 300 $args); 301 } 302 303 /** 304 * Checks to see if user is a plugin moderator 305 * 306 * Geeklog is asking if the user is a moderator for any installed plugins. 307 * 308 * @return boolean True if current user is moderator of plugin otherwise false 309 * 310 */ 311 function PLG_isModerator() 312 { 313 return PLG_callFunctionForAllPlugins('plugin_ismoderator_'); 314 } 315 316 /** 317 * Gives plugins a chance to print their menu items in header 318 * 319 * Note that this is fairly unflexible. This simply loops through the plugins 320 * in the database in the order they were installed and get their menu items. 321 * If you want more flexibility in your menu then you should hard code the menu 322 * items in header.thtml for the theme(s) you are using. 323 * 324 * @return array Returns menu options for plugin 325 * 326 */ 327 function PLG_getMenuItems() 328 { 329 global $_PLUGINS; 330 331 $menu = array(); 332 foreach ($_PLUGINS as $pi_name) { 333 $function = 'plugin_getmenuitems_' . $pi_name; 334 if (function_exists($function)) { 335 $menuitems = $function(); 336 if (is_array ($menuitems)) { 337 $menu = array_merge ($menu, $menuitems); 338 } 339 } 340 } 341 342 return $menu; 343 } 344 345 /** 346 * Get view URL and name of unique identifier 347 * 348 * @author Vincent Furia <vinny01 AT users DOT sourceforge DOT net> 349 * @param string $type Plugin to delete comment 350 * @return array string of URL of view page, name of unique identifier 351 */ 352 function PLG_getCommentUrlId($type) 353 { 354 global $_CONF; 355 356 $ret = PLG_callFunctionForOnePlugin('plugin_getcommenturlid_' . $type); 357 if (empty($ret[0])) { 358 $ret[0] = $_CONF['site_url'] . "/$type/index.php"; 359 } 360 if (empty($ret[1])) { 361 $ret[1] = 'id'; 362 } 363 364 return $ret; 365 } 366 367 /** 368 * Plugin should delete a comment 369 * 370 * @author Vincent Furia <vinny01 AT users DOT sourceforge DOT net> 371 * @param string $type Plugin to delete comment 372 * @param int $cid Comment to be deleted 373 * @param string $id Item id to which $cid belongs 374 * @return mixed false for failure, HTML string (redirect?) for success 375 */ 376 function PLG_commentDelete($type, $cid, $id) 377 { 378 $args[1] = $cid; 379 $args[2] = $id; 380 381 return PLG_callFunctionForOnePlugin('plugin_deletecomment_' . $type, $args); 382 } 383 384 /** 385 * Plugin should save a comment 386 * 387 * @author Vincent Furia <vinny01 AT users DOT sourceforge DOT net> 388 * @param string $type Plugin to delete comment 389 * @param string $title comment title 390 * @param string $comment comment text 391 * @param string $id Item id to which $cid belongs 392 * @param int $pid comment parent 393 * @param string $postmode 'html' or 'text' 394 * @return mixed false for failure, HTML string (redirect?) for success 395 */ 396 function PLG_commentSave($type, $title, $comment, $id, $pid, $postmode) 397 { 398 $args[1] = $title; 399 $args[2] = $comment; 400 $args[3] = $id; 401 $args[4] = $pid; 402 $args[5] = $postmode; 403 404 return PLG_callFunctionForOnePlugin('plugin_savecomment_' . $type, $args); 405 } 406 407 /** 408 * Plugin should display [a] comment[s] 409 * 410 * @author Vincent Furia <vinny01 AT users DOT sourceforge DOT net> 411 * @param string $type Plugin to display comment 412 * @param string $id Unique idenifier for item comment belongs to 413 * @param int $cid Comment id to display (possibly including sub-comments) 414 * @param string $title Page/comment title 415 * @param string $order 'ASC' or 'DSC' or blank 416 * @param string $format 'threaded', 'nested', or 'flat' 417 * @param int $page Page number of comments to display 418 * @param boolean $view True to view comment (by cid), false to display (by $pid) 419 * @return mixed results of calling the plugin_displaycomment_ function 420 */ 421 function PLG_displayComment($type, $id, $cid, $title, $order, $format, $page, $view) 422 { 423 $args[1] = $id; 424 $args[2] = $cid; 425 $args[3] = $title; 426 $args[4] = $order; 427 $args[5] = $format; 428 $args[6] = $page; 429 $args[7] = $view; 430 431 return PLG_callFunctionForOnePlugin('plugin_displaycomment_' . $type, $args); 432 } 433 434 /** 435 * Allows plugins a chance to handle a comment before GL does. 436 437 * This is a first-come-first-serve affair so if a plugin returns an error, other 438 * plugins wishing to handle comment preprocessing won't get called 439 * 440 * @author Tony Bibbs <tony@geeklog.net> 441 * @access public 442 * @param integer $uid User ID 443 * @param string $title Comment title 444 * @param string $sid Story ID (not always a story, remember!) 445 * @param integer $pid Parent comment ID 446 * @param string $type Type of comment 447 * @param string $postmode HTML or text 448 * @return an error otherwise false if no errors were encountered 449 * 450 */ 451 function PLG_commentPreSave($uid, &$title, &$comment, $sid, $pid, $type, &$postmode) 452 { 453 global $_PLUGINS; 454 455 foreach ($_PLUGINS as $pi_name) { 456 $function = 'plugin_commentPreSave_' . $pi_name; 457 if (function_exists($function)) { 458 $someError = $function($uid, $title, $comment, $sid, $pid, $type, $postmode); 459 if ($someError) { 460 // Plugin doesn't want to save the comment 461 return $someError; 462 } 463 } 464 } 465 466 return false; 467 } 468 469 /** 470 * Allows plugins a chance to handle an item before GL does. Modeled 471 * after the PLG_commentPreSave() function. 472 * 473 * This is a first-come-first-serve affair so if a plugin returns an error, other 474 * plugins wishing to handle comment preprocessing won't get called 475 * 476 * @author Mark Evans <mevans@ecsnet.com> 477 * @access public 478 * @param string $type Type of item, i.e.; registration, contact ... 479 * @param string $content item specific content 480 * @return string empty is no error, error message if error was encountered 481 * 482 */ 483 function PLG_itemPreSave($type, $content) 484 { 485 global $_PLUGINS; 486 487 foreach ($_PLUGINS as $pi_name) { 488 $function = 'plugin_itemPreSave_' . $pi_name; 489 if (function_exists ($function)) { 490 $msgError = $function ($type, $content); 491 if (!empty ($msgError)) { 492 // Plugin doesn't want to save the item 493 return $msgError; 494 } 495 } 496 } 497 498 return ''; 499 } 500 501 /** 502 * The way this function works is very specific to how Geeklog shows its 503 * statistics. On stats.php, there is the top box which gives overall 504 * statistics for Geeklog and then there are blocks below it that give 505 * more specific statistics for various components of Geeklog. 506 * 507 * This plugin API function suffers from a variety of bugs and bad design 508 * decisions for which we have to provide backward compatibility, so please 509 * bear with us ... 510 * 511 * The only parameter to this function, $showsitestats, was documented as being 512 * 1 for the site stats and 0 for the plugin-specific stats. However, the latter 513 * was always called with a value of 2, so plugins only did a check for 1 and 514 * "else", which makes extensions somewhat tricky. 515 * Furthermore, due to the original templates for the site stats, it has 516 * become standard practice to hard-code a <table> in the plugins as the return 517 * value for $showsitestats == 1. This table, however, didn't align properly 518 * with the built-in site stats entries. 519 * 520 * Because of all this, the new mode, 3, works differently: 521 * - for $showsitestats == 3, we call a new plugin API function, 522 * plugin_statssummary_<plugin-name>, which is supposed to return the plugin's 523 * entry for the site stats in an array which stats.php will then properly 524 * format, alongside the entries for the built-in items. 525 * - for $showsitestats == 1, we only call those plugins that do NOT have a 526 * plugin_statssummary_<plugin-name> function, thus providing backward 527 * compatibility 528 * - for $showsitestats == 2, nothing has changed 529 * 530 * @param int $showsitestats value indicating type of stats to return 531 * @return mixed array (for mode 3) or string 532 * 533 */ 534 function PLG_getPluginStats ($showsitestats) 535 { 536 global $_PLUGINS; 537 538 if ($showsitestats == 3) { 539 $retval = array (); 540 } else { 541 $retval = ''; 542 } 543 544 foreach ($_PLUGINS as $pi_name) { 545 if ($showsitestats == 3) { 546 $function = 'plugin_statssummary_' . $pi_name; 547 if (function_exists ($function)) { 548 $summary = $function (); 549 if (is_array ($summary)) { 550 $retval[$pi_name] = $summary; 551 } 552 } 553 } else if ($showsitestats == 1) { 554 $function1 = 'plugin_showstats_' . $pi_name; 555 $function2 = 'plugin_statssummary_' . $pi_name; 556 if (!function_exists ($function2)) { 557 if (function_exists ($function1)) { 558 $retval .= $function1 ($showsitestats); 559 } 560 } 561 } else if ($showsitestats == 2) { 562 $function = 'plugin_showstats_' . $pi_name; 563 if (function_exists ($function)) { 564 $retval .= $function ($showsitestats); 565 } 566 } 567 } 568 569 return $retval; 570 } 571 572 /** 573 * This function gives each plugin the opportunity to put a value(s) in 574 * the 'Type' drop down box on the search.php page so that their plugin 575 * can be incorporated into searches. 576 * 577 * @return array String array of search types for plugin(s) 578 * 579 */ 580 function PLG_getSearchTypes() 581 { 582 global $_PLUGINS; 583 584 $types = array(); 585 $cur_types = array(); 586 587 foreach ($_PLUGINS as $pi_name) { 588 $function = 'plugin_searchtypes_' . $pi_name; 589 if (function_exists ($function)) { 590 $cur_types = $function (); 591 if (is_array ($cur_types) && (count ($cur_types) > 0)) { 592 $types = array_merge ($types, $cur_types); 593 } 594 } // no else because this is not a required API function 595 } 596 asort($types); 597 return $types; 598 } 599 600 /** 601 * Determines if a specific plugin supports Geeklog's 602 * expanded search results feature 603 * 604 * @author Tony Bibbs <tony AT geeklog DOT net> 605 * @access public 606 * @param string $type Plugin name 607 * @return boolean True if it is supported, otherwise false 608 * 609 * NOTE: This function is not currently used 610 * 611 */ 612 function PLG_supportsExpandedSearch($type) 613 { 614 $retval = ''; 615 $function = 'plugin_supportsexpandedsearch_' . $type; 616 if (function_exists($function)) { 617 $retval = $function(); 618 } 619 if (empty($retval) OR !is_bool($retval)) { 620 $retval = false; 621 } 622 623 return $retval; 624 } 625 626 /** 627 * This function gives each plugin the opportunity to do their search 628 * and return their results. Results comeback in an array of HTML 629 * formatted table rows that can be quickly printed by search.php 630 * 631 * @param string $query What the user searched for 632 * @param date $datestart beginning of date range to search for 633 * @param date $dateend ending date range to search for 634 * @param string $topic the topic the user searched within 635 * @param string $type Type of items they are searching, or 'all' 636 * @param int $author UID...only return results for this person 637 * @param string $keyType search key type: 'all', 'phrase', 'any' 638 * @param int $page page number of current search 639 * @param int $perpage number of results per page 640 * @return array Returns search results 641 * 642 */ 643 function PLG_doSearch($query, $datestart, $dateend, $topic, $type, $author, $keyType = 'all', $page = 1, $perpage = 10) 644 { 645 global $_PLUGINS; 646 647 $search_results = array(); 648 649 $nrows_plugins = 0; 650 $total_plugins = 0; 651 foreach ($_PLUGINS as $pi_name) { 652 $function = 'plugin_dopluginsearch_' . $pi_name; 653 if (function_exists($function)) { 654 $plugin_result = $function($query, $datestart, $dateend, $topic, $type, $author, $keyType, $page, $perpage); 655 $nrows_plugins = $nrows_plugins + $plugin_result->num_searchresults; 656 $total_plugins = $total_plugins + $plugin_result->num_itemssearched; 657 $search_results[] = $plugin_result; 658 } // no else because implementation of this API function not required 659 } 660 661 return array($nrows_plugins, $total_plugins, $search_results); 662 } 663 664 /** 665 * Asks each plugin to report any submissions they may have in their 666 * submission queue 667 * 668 * @return int Number of submissions in queue for plugins 669 * 670 */ 671 function PLG_getSubmissionCount() 672 { 673 global $_PLUGINS; 674 675 $num = 0; 676 foreach ($_PLUGINS as $pi_name) { 677 $function = 'plugin_submissioncount_' . $pi_name; 678 if (function_exists($function)) { 679 $num = $num + $function(); 680 } 681 } 682 683 return $num; 684 } 685 686 /** 687 * This function will get & check user or admin options from plugins and check 688 * required ones for availability. This function is called by several other 689 * functions and is not to be called from the plugin directly. The function which 690 * call this here follow below. 691 * 692 * NOTE for plugin developers: 693 * The plugin is responsible for its own security. 694 * This supports a plugin having either a single menuitem or multiple menuitems. 695 * The plugin has to provide an array for the menuitem of the format: 696 * array (menuitem_title, item_url, submission_count) 697 * or an array of arrays in case there are several entries: 698 * array ( 699 * array (menuitem1_title, item1_url, submission1_count), 700 * array (menuitem2_title, item2_url, submission2_count), 701 * array (menuitem3_title, item3_url, submission3_count)) 702 * Plugin function can return a single record array or multiple records 703 * 704 * 705 * @param array $var_names An array of the variables that are retrieved. 706 * This has to match the named array that is used 707 * in the function returning the values 708 * @param array $required_names An array of true/false-values, describing 709 * which of the above listed values is required 710 * to give a valid set of data. 711 * @param string $function_name A string that gives the name of the function 712 * at the plugin that will return the values. 713 * @return array Returns options to add to the given menu that is calling this 714 * 715 */ 716 function PLGINT_getOptionsforMenus($var_names, $required_names, $function_name) 717 { 718 global $_PLUGINS; 719 720 $plgresults = array (); 721 722 $counter = 0; 723 foreach ($_PLUGINS as $pi_name) { 724 $function = $function_name . $pi_name; 725 if (function_exists ($function)) { 726 $plg_array = $function(); 727 if (($plg_array !== false) && (count ($plg_array) > 0)) { 728 // Check if plugin is returning a single record array or multiple records 729 $entries = count ($plg_array[0]); 730 if ($entries == 0) { 731 $sets_array = array (); 732 } else if ($entries == 1) { 733 // Single record - so we need to prepare the sets_array; 734 $sets_array[0] = $plg_array; 735 } else { 736 // Multiple menuitem records - in required format 737 $sets_array = $plg_array; 738 } 739 foreach ($sets_array as $val) { 740 $plugin = new Plugin(); 741 $good_array = true; 742 for ($n = 0; $n < count($var_names); $n++) { 743 if (isset ($val[$n])) { 744 $plugin->$var_names[$n] = $val[$n]; 745 } else { 746 $plugin->$var_names[$n] = ''; 747 } 748 if (empty ($plugin->$var_names[$n]) && $required_names[$n]) { 749 $good_array = false; 750 } 751 } 752 $counter++; 753 if ($good_array) { 754 $plgresults[$counter] = $plugin; 755 } 756 } 757 } 758 } 759 } 760 761 return $plgresults; 762 } 763 764 /** 765 * This function shows the option for all plugins at the top of the 766 * command and control center. 767 * 768 * This supports that a plugin can have several lines in the CC menu. 769 * The plugin has to provide simply a set arrays with 3 variables in order to 770 * get n lines in the menu such as 771 * array( 772 * array("first line", "url1", "1"), 773 * array("second line", "url2", "44"), 774 * etc, etc) 775 * If there is only one item, a single array is enough: 776 * array("first line", "url1", "1") 777 * 778 * @return array Returns Command and Control options for moderation.php 779 * 780 */ 781 function PLG_getCCOptions() 782 { 783 $var_names = array('adminlabel', 'adminurl', 'plugin_image'); 784 $required_names = array(true, true, true); 785 $function_name = 'plugin_cclabel_'; 786 $plgresults = PLGINT_getOptionsforMenus($var_names, $required_names, $function_name); 787 788 return $plgresults; 789 } 790 791 /** 792 * This function will show any plugin adminstrative options in the 793 * admin functions block on every page (assuming the user is an admin 794 * and is logged in). 795 * 796 * NOTE: the plugin is responsible for its own security. 797 * This supports that a plugin can have several lines in the Admin menu. 798 * The plugin has to provide simply a set arrays with 3 variables in order to 799 * get n lines in the menu such as 800 * array( 801 * array("first line", "url1", "1"), 802 * array("second line", "url2", "44"),, 803 * etc, etc) 804 * If there is only one item, a single array is enough: 805 * array("first line", "url1", "1") 806 * 807 * @return array Returns options to put in admin menu 808 * 809 */ 810 function PLG_getAdminOptions() 811 { 812 $var_names = array('adminlabel', 'adminurl', 'numsubmissions'); 813 $required_names = array(true, true, false); 814 $function_name = 'plugin_getadminoption_'; 815 $plgresults = PLGINT_getOptionsforMenus($var_names, $required_names, $function_name); 816 817 return $plgresults; 818 } 819 820 /** 821 * This function will show any plugin user options in the 822 * user block on every page 823 * 824 * This supports that a plugin can have several lines in the User menu. 825 * The plugin has to provide simply a set of arrays with 3 variables in order to 826 * get n lines in the menu such as 827 * array( 828 * array("first line", "url1", "1"), 829 * array("second line", "url2", "44"), 830 * etc, etc) 831 * If there is only one item, a single array is enough: 832 * array("first line", "url1", "1") 833 * 834 * NOTE: the plugin is responsible for its own security. 835 * 836 * @return array Returns options to add to user menu 837 * 838 */ 839 function PLG_getUserOptions() 840 { 841 // I know this uses the adminlabel, adminurl but who cares? 842 $var_names = array('adminlabel', 'adminurl', 'numsubmissions'); 843 $required_names = array(true, true, false); 844 $function_name = 'plugin_getuseroption_'; 845 $plgresults = PLGINT_getOptionsforMenus($var_names, $required_names, $function_name); 846 847 return $plgresults; 848 } 849 850 /** 851 * This function is responsible for calling 852 * plugin_moderationapproves_<pluginname> which approves an item from the 853 * submission queue for a plugin. 854 * 855 * @param string $type Plugin name to do submission approval for 856 * @param string $id used to identify the record to approve 857 * @return boolean Returns true on success otherwise false 858 * 859 */ 860 function PLG_approveSubmission($type, $id) 861 { 862 $args[1] = $id; 863 864 return PLG_callFunctionForOnePlugin('plugin_moderationapprove_' . $type, $args); 865 } 866 867 /** 868 * This function is responsible for calling 869 * plugin_moderationdelete_<pluginname> which deletes an item from the 870 * submission queue for a plugin. 871 * 872 * @param string $type Plugin to do submission deletion for 873 * @param string $id used to identify the record for which to delete 874 * @return boolean Returns true on success otherwise false 875 * 876 */ 877 function PLG_deleteSubmission($type, $id) 878 { 879 $args[1] = $id; 880 881 return PLG_callFunctionForOnePlugin('plugin_moderationdelete_' . $type, $args); 882 } 883 884 /** 885 * This function calls the plugin_savesubmission_<pluginname> to save 886 * a user submission 887 * 888 * @param string $type Plugin to save submission for 889 * @param array $A holds plugin specific data to save 890 * @return boolean Returns true on success otherwise false 891 * 892 */ 893 function PLG_saveSubmission($type, $A) 894 { 895 $args[1] = $A; 896 897 return PLG_callFunctionForOnePlugin('plugin_savesubmission_' . $type, $args); 898 } 899 900 /** 901 * This function starts the chain of calls needed to show any submissions 902 * needing moderation for the plugins. 903 * 904 * @return string returns list of items needing moderation for plugins 905 * 906 */ 907 function PLG_showModerationList() 908 { 909 global $_PLUGINS; 910 911 $retval = ''; 912 913 foreach ($_PLUGINS as $pi_name) { 914 $retval .= itemlist($pi_name); 915 } 916 917 return $retval; 918 } 919 920 /** 921 * This function is responsible for setting the plugin-specific values 922 * needed by moderation.php to approve stuff. 923 * 924 * @param string $type Plugin to call function for 925 * @return string 926 * 927 */ 928 function PLG_getModerationValues($type) 929 { 930 return PLG_callFunctionForOnePlugin('plugin_moderationvalues_' . $type); 931 } 932 933 /** 934 * This function is resonsible for calling plugin_submit_<pluginname> so 935 * that the submission form for the plugin is displayed. 936 * 937 * @param string $type Plugin to show submission form for 938 * @return string HTML for submit form for plugin 939 * 940 */ 941 function PLG_showSubmitForm($type) 942 { 943 return PLG_callFunctionForOnePlugin('plugin_submit_' . $type); 944 } 945 946 /** 947 * This function will show the centerblock for any plugin 948 * It will be display before any news and after any defined staticpage content. 949 * The plugin is responsible to format the output correctly. 950 * 951 * @param where int 1 = top, 2 = after feat. story, 3 = bottom of page 952 * @param page int page number (1, ...) 953 * @param topic string topic ID or empty string == front page 954 * @return Formatted center block content 955 * 956 */ 957 function PLG_showCenterblock($where = 1, $page = 1, $topic = '') 958 { 959 global $PLG_bufferCenterAPI, $PLG_buffered, $_PLUGINS; 960 961 $retval = ''; 962 963 // buffer function names since we're coming back for them two more times 964 if (!$PLG_buffered) { 965 $PLG_bufferCenterAPI = array (); 966 foreach ($_PLUGINS as $pi_name) { 967 $function = 'plugin_centerblock_' . $pi_name; 968 if (function_exists ($function)) { 969 $PLG_bufferCenterAPI[$pi_name] = $function; 970 } 971 } 972 $PLG_buffered = true; 973 } 974 975 foreach ($PLG_bufferCenterAPI as $function) { 976 $retval .= $function ($where, $page, $topic); 977 978 if (($where == 0) && !empty ($retval)) { 979 break; 980 } 981 } 982 983 return $retval; 984 } 985 986 /** 987 * This function will inform all plugins when a new user account is created. 988 * 989 * @param int $uid user id of the new user account 990 * 991 */ 992 function PLG_createUser ($uid) 993 { 994 global $_PLUGINS; 995 996 foreach ($_PLUGINS as $pi_name) { 997 $function = 'plugin_user_create_' . $pi_name; 998 if (function_exists ($function)) { 999 $function ($uid); 1000 } 1001 } 1002 } 1003 1004 /** 1005 * This function will inform all plugins when a user account is deleted. 1006 * 1007 * @param int $uid user id of the deleted user account 1008 * 1009 */ 1010 function PLG_deleteUser ($uid) 1011 { 1012 global $_PLUGINS; 1013 1014 foreach ($_PLUGINS as $pi_name) { 1015 $function = 'plugin_user_delete_' . $pi_name; 1016 if (function_exists ($function)) { 1017 $function ($uid); 1018 } 1019 } 1020 } 1021 1022 /** 1023 * This function will inform all plugins when a user logs in 1024 * 1025 * Note: This function is NOT called when users are re-authenticated by their 1026 * long-term cookie. The global variable $_USER['auto_login'] will be set to 1027 * 'true' in that case, however. 1028 * 1029 * @param int $uid user id 1030 * 1031 */ 1032 function PLG_loginUser ($uid) 1033 { 1034 global $_PLUGINS; 1035 1036 foreach ($_PLUGINS as $pi_name) { 1037 $function = 'plugin_user_login_' . $pi_name; 1038 if (function_exists ($function)) { 1039 $function ($uid); 1040 } 1041 } 1042 } 1043 1044 /** 1045 * This function will inform all plugins when a user logs out. 1046 * Plugins should not rely on this ever being called, as the user may simply 1047 * close the browser instead of logging out. 1048 * 1049 * @param int $uid user id 1050 * 1051 */ 1052 function PLG_logoutUser ($uid) 1053 { 1054 global $_PLUGINS; 1055 1056 foreach ($_PLUGINS as $pi_name) { 1057 $function = 'plugin_user_logout_' . $pi_name; 1058 if (function_exists ($function)) { 1059 $function ($uid); 1060 } 1061 } 1062 } 1063 1064 /** 1065 * This functions is called to inform plugins when a user's information 1066 * (profile or preferences) has changed. 1067 * 1068 * @param int $uid User ID 1069 * 1070 */ 1071 function PLG_userInfoChanged ($uid) 1072 { 1073 global $_PLUGINS; 1074 1075 foreach ($_PLUGINS as $pi_name) { 1076 $function = 'plugin_user_changed_' . $pi_name; 1077 if (function_exists ($function)) { 1078 $function ($uid); 1079 } 1080 } 1081 } 1082 1083 /** 1084 * This functions is called to inform plugins when a group's information has 1085 * changed or a new group has been created. 1086 * 1087 * @param int $grp_id Group ID 1088 * @param string $mode type of change: 'new', 'edit', or 'delete' 1089 * 1090 */ 1091 function PLG_groupChanged ($grp_id, $mode) 1092 { 1093 global $_PLUGINS; 1094 1095 foreach ($_PLUGINS as $pi_name) { 1096 $function = 'plugin_group_changed_' . $pi_name; 1097 if (function_exists ($function)) { 1098 $function ($grp_id, $mode); 1099 } 1100 } 1101 } 1102 1103 /** 1104 * Geeklog is about to display the edit form for the user's profile. Plugins 1105 * now get a chance to add their own variables and input fields to the form. 1106 * 1107 * @param int $uid user id of the user profile to be edited 1108 * @param ref $template reference of the Template for the profile edit form 1109 * 1110 */ 1111 function PLG_profileVariablesEdit ($uid, &$template) 1112 { 1113 global $_PLUGINS; 1114 1115 foreach ($_PLUGINS as $pi_name) { 1116 $function = 'plugin_profilevariablesedit_' . $pi_name; 1117 if (function_exists($function)) { 1118 $function ($uid, $template); 1119 } 1120 } 1121 } 1122 1123 /** 1124 * Geeklog is about to display the edit form for the user's profile. Plugins 1125 * now get a chance to add their own blocks below the standard form. 1126 * 1127 * @param int $uid user id of the user profile to be edited 1128 * @return string HTML for additional block(s) 1129 * 1130 */ 1131 function PLG_profileBlocksEdit ($uid) 1132 { 1133 global $_PLUGINS; 1134 1135 $retval = ''; 1136 1137 foreach ($_PLUGINS as $pi_name) { 1138 $function = 'plugin_profileblocksedit_' . $pi_name; 1139 if (function_exists($function)) { 1140 $retval .= $function ($uid); 1141 } 1142 } 1143 1144 return $retval; 1145 } 1146 1147 /** 1148 * Geeklog is about to display the user's profile. Plugins now get a chance to 1149 * add their own variables to the profile. 1150 * 1151 * @param int $uid user id of the user profile to be edited 1152 * @param ref $template reference of the Template for the profile edit form 1153 * 1154 */ 1155 function PLG_profileVariablesDisplay ($uid, &$template) 1156 { 1157 global $_PLUGINS; 1158 1159 foreach ($_PLUGINS as $pi_name) { 1160 $function = 'plugin_profilevariablesdisplay_' . $pi_name; 1161 if (function_exists($function)) { 1162 $function ($uid, $template); 1163 } 1164 } 1165 } 1166 1167 /** 1168 * Geeklog is about to display the user's profile. Plugins now get a chance to 1169 * add their own blocks below the standard profile form. 1170 * 1171 * @param int $uid user id of the user profile to be edited 1172 * @return string HTML for additional block(s) 1173 * 1174 */ 1175 function PLG_profileBlocksDisplay ($uid) 1176 { 1177 global $_PLUGINS; 1178 1179 $retval = ''; 1180 1181 foreach ($_PLUGINS as $pi_name) { 1182 $function = 'plugin_profileblocksdisplay_' . $pi_name; 1183 if (function_exists($function)) { 1184 $retval .= $function ($uid); 1185 } 1186 } 1187 1188 return $retval; 1189 } 1190 1191 /** 1192 * The user wants to save changes to his/her profile. Any plugin that added its 1193 * own variables or blocks to the profile input form will now have to extract 1194 * its data and save it. 1195 * Plugins will have to refer to the global $_POST array to get the 1196 * actual data. 1197 * 1198 * @param string $plugin name of a specific plugin or empty (all plugins) 1199 * 1200 */ 1201 function PLG_profileExtrasSave ($plugin = '') 1202 { 1203 if (empty ($plugin)) { 1204 PLG_callFunctionForAllPlugins ('plugin_profileextrassave_'); 1205 } else { 1206 PLG_callFunctionForOnePlugin ('plugin_profileextrassave_' . $plugin); 1207 } 1208 } 1209 1210 /** 1211 * This function can be called to check if an plugin wants to set a template 1212 * variable 1213 * Example in COM_siteHeader, the API call is now added 1214 * A plugin can now check for templatename == 'header' and then set additional 1215 * template variables 1216 * 1217 * @param string $templatename Name of calling template - used as test in plugin function 1218 * @param ref $template reference for the Template 1219 * 1220 */ 1221 function PLG_templateSetVars ($templatename, &$template) 1222 { 1223 global $_PLUGINS; 1224 1225 if (function_exists ('CUSTOM_templateSetVars')) { 1226 CUSTOM_templatesetvars($templatename, $template); 1227 } 1228 1229 foreach ($_PLUGINS as $pi_name) { 1230 $function = 'plugin_templatesetvars_' . $pi_name; 1231 if (function_exists($function)) { 1232 $function ($templatename, $template); 1233 } 1234 } 1235 } 1236 1237 /** 1238 * This function is called from COM_siteHeader and will return additional header 1239 * information. This can be used for JavaScript functions required for the plugin 1240 * or extra Metatags 1241 * 1242 * @return string returns a concatenated string of all plugins extra header code 1243 */ 1244 function PLG_getHeaderCode() 1245 { 1246 global $_PLUGINS; 1247 1248 $headercode = ''; 1249 1250 foreach ($_PLUGINS as $pi_name) { 1251 $function = 'plugin_getheadercode_' . $pi_name; 1252 if (function_exists($function)) { 1253 $headercode .= $function(); 1254 } 1255 } 1256 1257 return $headercode; 1258 } 1259 1260 /** 1261 * Get a list of all currently supported autolink tags. 1262 * 1263 * Returns an associative array where $A['tag-name'] = 'plugin-name' 1264 * 1265 * @return array All currently supported autolink tags 1266 * 1267 */ 1268 function PLG_collectTags () 1269 { 1270 global $_CONF, $_PLUGINS; 1271 1272 if (isset ($_CONF['disable_autolinks']) && ($_CONF['disable_autolinks'] == 1)) { 1273 // autolinks are disabled - return an empty array 1274 return array (); 1275 } 1276 1277 // Determine which Core Modules and Plugins support AutoLinks 1278 // 'tag' => 'module' 1279 $autolinkModules = array ('story' => 'geeklog'); 1280 1281 foreach ($_PLUGINS as $pi_name) { 1282 $function = 'plugin_autotags_' . $pi_name; 1283 if (function_exists ($function)) { 1284 $autotag = $function ('tagname'); 1285 if (is_array ($autotag)) { 1286 foreach ($autotag as $tag) { 1287 $autolinkModules[$tag] = $pi_name; 1288 } 1289 } else { 1290 $autolinkModules[$autotag] = $pi_name; 1291 } 1292 } 1293 } 1294 1295 return $autolinkModules; 1296 } 1297 1298 /** 1299 * This function will allow plugins to support the use of custom autolinks 1300 * in other site content. Plugins can now use this API when saving content 1301 * and have the content checked for any autolinks before saving. 1302 * The autolink would be like: [story:20040101093000103 here] 1303 * 1304 * @param string $content Content that should be parsed for autolinks 1305 * @param string $plugin Optional if you only want to parse using a specific plugin 1306 * 1307 */ 1308 function PLG_replaceTags ($content, $plugin = '') 1309 { 1310 global $_CONF, $_TABLES, $LANG32; 1311 1312 if (isset ($_CONF['disable_autolinks']) && ($_CONF['disable_autolinks'] == 1)) { 1313 // autolinks are disabled - return $content unchanged 1314 return $content; 1315 } 1316 1317 $autolinkModules = PLG_collectTags (); 1318 1319 // For each supported module, scan the content looking for any AutoLink tags 1320 $tags = array (); 1321 foreach ($autolinkModules as $moduletag => $module) { 1322 $autotag_prefix = '['. $moduletag . ':'; 1323 $offset = 0; 1324 $prev_offset = 0; 1325 $contentlen = MBYTE_strlen ($content); 1326 while ($offset < $contentlen) { 1327 $start_pos = MBYTE_strpos (MBYTE_strtolower ($content), $autotag_prefix, 1328 $offset); 1329 if ($start_pos === false) { 1330 break; 1331 } else { 1332 $end_pos = MBYTE_strpos (MBYTE_strtolower ($content), ']', $start_pos); 1333 $next_tag = MBYTE_strpos (MBYTE_strtolower ($content), '[', $start_pos + 1); 1334 if (($end_pos > $start_pos) AND 1335 (($next_tag === false) OR ($end_pos < $next_tag))) { 1336 $taglength = $end_pos - $start_pos + 1; 1337 $tag = MBYTE_substr ($content, $start_pos, $taglength); 1338 $parms = explode (' ', $tag); 1339 1340 // Extra test to see if autotag was entered with a space 1341 // after the module name 1342 if (MBYTE_substr ($parms[0], -1) == ':') { 1343 $startpos = MBYTE_strlen ($parms[0]) + MBYTE_strlen ($parms[1]) + 2; 1344 $label = str_replace (']', '', MBYTE_substr ($tag, $startpos)); 1345 $tagid = $parms[1]; 1346 } else { 1347 $label = str_replace (']', '', 1348 MBYTE_substr ($tag, MBYTE_strlen ($parms[0]) + 1)); 1349 $parms = explode (':', $parms[0]); 1350 if (count ($parms) > 2) { 1351 // whoops, there was a ':' in the tag id ... 1352 array_shift ($parms); 1353 $tagid = implode (':', $parms); 1354 } else { 1355 $tagid = $parms[1]; 1356 } 1357 } 1358 1359 $newtag = array ( 1360 'module' => $module, 1361 'tag' => $moduletag, 1362 'tagstr' => $tag, 1363 'startpos' => $start_pos, 1364 'length' => $taglength, 1365 'parm1' => str_replace (']', '', $tagid), 1366 'parm2' => $label 1367 ); 1368 $tags[] = $newtag; 1369 } else { 1370 // Error: tags do not match - return with no changes 1371 return $content . $LANG32[32]; 1372 } 1373 $prev_offset = $offset; 1374 $offset = $end_pos; 1375 } 1376 } 1377 } 1378 1379 // If we have found 1 or more AutoLink tag 1380 if (count ($tags) > 0) { // Found the [tag] - Now process them all 1381 foreach ($tags as $autotag) { 1382 $function = 'plugin_autotags_' . $autotag['module']; 1383 if (($autotag['module'] == 'geeklog') AND 1384 (empty ($plugin) OR ($plugin == 'geeklog'))) { 1385 $url = ''; 1386 $linktext = $autotag['parm2']; 1387 if ($autotag['tag'] == 'story') { 1388 $autotag['parm1'] = COM_applyFilter ($autotag['parm1']); 1389 $url = COM_buildUrl ($_CONF['site_url'] 1390 . '/article.php?story=' . $autotag['parm1']); 1391 if (empty ($linktext)) { 1392 $linktext = stripslashes (DB_getItem ($_TABLES['stories'], 'title', "sid = '{$autotag['parm1']}'")); 1393 } 1394 } 1395 1396 if (!empty ($url)) { 1397 $filelink = '<a href="' . $url . '">' . $linktext . '</a>'; 1398 $content = str_replace ($autotag['tagstr'], $filelink, 1399 $content); 1400 } 1401 } else if (function_exists ($function) AND 1402 (empty ($plugin) OR ($plugin == $autotag['module']))) { 1403 $content = $function ('parse', $content, $autotag); 1404 } 1405 } 1406 } 1407 1408 return $content; 1409 } 1410 1411 1412 /** 1413 * Prepare a list of all plugins that support feeds. To do this, we re-use 1414 * plugin_getfeednames_<plugin name> and only keep the names of those plugins 1415 * which support that function 1416 * 1417 * @return array array of plugin names (can be empty) 1418 * 1419 */ 1420 function PLG_supportingFeeds () 1421 { 1422 global $_PLUGINS; 1423 1424 $plugins = array (); 1425 1426 foreach ($_PLUGINS as $pi_name) { 1427 $function = 'plugin_getfeednames_' . $pi_name; 1428 if (function_exists ($function)) { 1429 $feeds = $function (); 1430 if (is_array ($feeds) && (sizeof ($feeds) > 0)) { 1431 $plugins[] = $pi_name; 1432 } 1433 } 1434 } 1435 1436 return $plugins; 1437 } 1438 1439 /** 1440 * Ask the plugin for a list of feeds it supports. The plugin is expected to 1441 * return an array of id/name pairs where 'id' is the plugin's internal id 1442 * for the feed and 'name' is what will be presented to the user. 1443 * 1444 * @param string plugin plugin name 1445 * @return array array of id/name pairs 1446 * 1447 */ 1448 function PLG_getFeedNames ($plugin) 1449 { 1450 global $_PLUGINS; 1451 1452 $feeds = array (); 1453 1454 if (in_array ($plugin, $_PLUGINS)) { 1455 $function = 'plugin_getfeednames_' . $plugin; 1456 if (function_exists ($function)) { 1457 $feeds = $function (); 1458 } 1459 } 1460 1461 return $feeds; 1462 } 1463 1464 /** 1465 * Get the content of a feed from the plugin. 1466 * The plugin is expected to return an array holding the content of the feed 1467 * and to fill in 'link' (some link that represents the same content on the 1468 * site as that in the feed) and 'update_data' (to be stored for later up-to-date 1469 * checks. 1470 * 1471 * @param string plugin plugin name 1472 * @param int feed feed id 1473 * @param string link link to content on the site 1474 * @param string update_data information for later up-to-date checks 1475 * @param string feedType The type of feed (RSS/Atom etc) 1476 * @param string feedVersion The version info of the feed. 1477 * @return array content of feed 1478 * 1479 */ 1480 function PLG_getFeedContent ($plugin, $feed, &$link, &$update_data, $feedType, $feedVersion) 1481 { 1482 global $_PLUGINS; 1483 1484 $content = array (); 1485 1486 if (in_array ($plugin, $_PLUGINS)) { 1487 $function = 'plugin_getfeedcontent_' . $plugin; 1488 if (function_exists ($function)) { 1489 $content = $function ($feed, $link, $update_data, $feedType, $feedVersion); 1490 } 1491 } 1492 1493 return $content; 1494 } 1495 1496 /** 1497 * Get extension tags for a feed. For example, some plugins may extened the 1498 * available elements for an RSS 2.0 feed for articles. For some reason. This 1499 * function allows that. 1500 * 1501 * @param string contentType Type of feed content, article or a plugin specific type 1502 * @param string contentID Unique identifier of content item to extend 1503 * @param string feedType Type of feed format (RSS/Atom/etc) 1504 * @param string feedVersion Type of feed version (RSS 1.0 etc) 1505 * @param string topic The topic for the feed. 1506 * @param string fid The ID of the feed being fethed. 1507 */ 1508 function PLG_getFeedElementExtensions($contentType, $contentID, $feedType, $feedVersion, $topic, $fid) 1509 { 1510 global $_PLUGINS; 1511 1512 $extensions = array(); 1513 foreach( $_PLUGINS as $plugin ) 1514 { 1515 $function = 'plugin_feedElementExtensions_'.$plugin; 1516 if (function_exists($function)) 1517 { 1518 $extensions = array_merge($extensions, $function($contentType, $contentID, $feedType, $feedVersion, $topic, $fid)); 1519 } 1520 } 1521 return $extensions; 1522 } 1523 1524 /** 1525 * Get namespaces extensions for a feed. If a plugin has added extended tags 1526 * to a feed, then it may also need to insert some extensions to the name 1527 * spaces. 1528 * @param string contentType Type of feed content, article or a plugin specific type 1529 * @param string feedType Type of feed format (RSS/Atom/etc) 1530 * @param string feedVersion Type of feed version (RSS 1.0 etc) 1531 * @param string topic The topic for the feed. 1532 * @param string fid The ID of the feed being fethed. 1533 */ 1534 function PLG_getFeedNSExtensions($contentType, $feedType, $feedVersion, $topic, $fid) 1535 { 1536 global $_PLUGINS; 1537 1538 $namespaces = array(); 1539 foreach( $_PLUGINS as $plugin ) 1540 { 1541 $function = 'plugin_feedNSExtensions_'.$plugin; 1542 if (function_exists($function)) 1543 { 1544 $namespaces = array_merge($namespaces, $function($contentType, $feedType, $feedVersion, $topic, $fid)); 1545 } 1546 } 1547 1548 return $namespaces; 1549 } 1550 1551 /** 1552 * Get meta tag extensions for a feed. Add extended tags to the meta 1553 * area of a feed. 1554 * @param string contentType Type of feed content, article or a plugin specific type 1555 * @param string feedType Type of feed format (RSS/Atom/etc) 1556 * @param string feedVersion Type of feed version (RSS 1.0 etc) 1557 * @param string topic The topic for the feed. 1558 * @param string fid The ID of the feed being fethed. 1559 */ 1560 function PLG_getFeedExtensionTags($contentType, $feedType, $feedVersion, $topic, $fid) 1561 { 1562 global $_PLUGINS; 1563 1564 $tags = array(); 1565 foreach( $_PLUGINS as $plugin ) 1566 { 1567 $function = 'plugin_feedExtensionTags_'.$plugin; 1568 if (function_exists($function)) 1569 { 1570 $tags = array_merge($tags, $function($contentType, $feedType, $feedVersion, $topic, $fid)); 1571 } 1572 } 1573 1574 return $tags; 1575 } 1576 1577 /** 1578 * The plugin is expected to check if the feed content needs to be updated. 1579 * This is called from COM_rdfUpToDateCheck() every time Geeklog's index.php 1580 * is displayed - it should try to be as efficient as possible ... 1581 * 1582 * @param string plugin plugin name 1583 * @param int feed feed id 1584 * @param string topic "topic" of the feed - plugin specific 1585 * @param string limit number of entries or number of hours 1586 * @param string updated_type (optional) type of feed to update 1587 * @param string updated_topic (optional) topic to update 1588 * @param string updated_id (optional) entry id to update 1589 * @return bool false = feed has to be updated, true = ok 1590 * 1591 * @note The presence of non-empty $updated_XXX parameters indicates that an 1592 * existing entry has been changed. The plugin may therefore apply a 1593 * different method to check if its feed has to be updated. 1594 * 1595 */ 1596 function PLG_feedUpdateCheck ($plugin, $feed, $topic, $update_data, $limit, $updated_type = '', $updated_topic = '', $updated_id = '') 1597 { 1598 global $_PLUGINS; 1599 1600 $is_current = true; 1601 1602 if (in_array ($plugin, $_PLUGINS)) { 1603 $function = 'plugin_feedupdatecheck_' . $plugin; 1604 if (function_exists ($function)) { 1605 $is_current = $function ($feed, $topic, $update_data, $limit, 1606 $updated_type, $updated_topic, $updated_id); 1607 } 1608 } 1609 1610 return $is_current; 1611 } 1612 1613 /** 1614 * Ask plugins if they want to add something to Geeklog's What's New block. 1615 * 1616 * @return array array($headlines[], $bylines[], $content[$entries[]]) 1617 * 1618 */ 1619 function PLG_getWhatsNew () 1620 { 1621 global $_PLUGINS; 1622 1623 $newheadlines = array (); 1624 $newbylines = array (); 1625 $newcontent = array (); 1626 1627 foreach ($_PLUGINS as $pi_name) { 1628 $fn_head = 'plugin_whatsnewsupported_' . $pi_name; 1629 if (function_exists ($fn_head)) { 1630 $supported = $fn_head (); 1631 if (is_array ($supported)) { 1632 list ($headline, $byline) = $supported; 1633 1634 $fn_new = 'plugin_getwhatsnew_' . $pi_name; 1635 if (function_exists ($fn_new)) { 1636 $whatsnew = $fn_new (); 1637 $newcontent[] = $whatsnew; 1638 $newheadlines[] = $headline; 1639 $newbylines[] = $byline; 1640 } 1641 } 1642 } 1643 } 1644 1645 return array ($newheadlines, $newbylines, $newcontent); 1646 } 1647 1648 /** 1649 * Allows plugins and Core GL Components to filter out spam. 1650 * 1651 * The Spam-X Plugin is now part of the Geeklog Distribution 1652 * This plugin API will call the main function in the Spam-X plugin 1653 * but can also be used to call other plugins or custom functions 1654 * if available for filtering spam or content. 1655 * 1656 * @param string $content Text to be filtered or checked for spam 1657 * @param integer $action what to do if spam found 1658 * @return integer > 0: spam detected, == 0: no spam detected 1659 * 1660 * The caller should check for return values > 0 in which case spam has been 1661 * detected and the poster should be told, either via 1662 * 1663 * echo COM_refresh ($_CONF['site_url'] . '/index.php?msg=' . $result 1664 * . '&plugin=spamx'); 1665 * 1666 * or by 1667 * 1668 * COM_displayMessageAndAbort ($result, 'spamx', 403, 'Forbidden'); 1669 * 1670 * Where the former will only display a "spam detected" message while the latter 1671 * will also send an HTTP status code 403 with the message. 1672 * 1673 */ 1674 function PLG_checkforSpam ($content, $action = -1) 1675 { 1676 global $_PLUGINS; 1677 1678 foreach ($_PLUGINS as $pi_name) { 1679 $function = 'plugin_checkforSpam_' . $pi_name; 1680 if (function_exists ($function)) { 1681 $result = $function ($content, $action); 1682 if ($result > 0) { // Plugin found a match for spam 1683 1684 $result = PLG_spamAction ($content, $action); 1685 1686 return $result; 1687 } 1688 } 1689 } 1690 1691 return 0; 1692 } 1693 1694 /** 1695 * Act on spam 1696 * 1697 * This is normally called from PLG_checkforSpam (see above) automatically when 1698 * spam has been detected. There may however be situations where spam has been 1699 * detected by some other means, in which case you may want to trigger the 1700 * spam action explicitly. 1701 * 1702 * @param string $content Text to be filtered or checked for spam 1703 * @param integer $action what to do if spam found 1704 * @return integer > 0: spam detected, == 0: no spam detected 1705 * 1706 */ 1707 function PLG_spamAction ($content, $action = -1) 1708 { 1709 global $_PLUGINS; 1710 1711 $result = 0; 1712 1713 foreach ($_PLUGINS as $pi_name) { 1714 $function = 'plugin_spamaction_' . $pi_name; 1715 if (function_exists ($function)) { 1716 $res = $function ($content, $action); 1717 $result = max ($result, $res); 1718 } 1719 } 1720 1721 return $result; 1722 } 1723 1724 /** 1725 * Ask plugin for information about one of its items 1726 * 1727 * @param string $type plugin type 1728 * @param string $id ID of an item under the plugin's control 1729 * @param string $what comma-separated list of item properties 1730 * @return mixed string or array of strings with the information 1731 * 1732 * Item properties that can be requested: 1733 * 'url' - URL of the item 1734 * 'title' - title of the item 1735 * 'excerpt' - short description of the item 1736 * 'description' - full description of the item 1737 * 1738 * 'excerpt' and 'description' may return the same value. Properties should be 1739 * returned in the order they are listed in $what. Properties that are not 1740 * available should return an empty string. 1741 * Return false for errors (e.g. access denied, item does not exist, etc.). 1742 * 1743 */ 1744 function PLG_getItemInfo ($type, $id, $what) 1745 { 1746 $args[1] = $id; 1747 $args[2] = $what; 1748 1749 $function = 'plugin_getiteminfo_' . $type; 1750 1751 return PLG_callFunctionForOnePlugin ($function, $args); 1752 } 1753 1754 /** 1755 * Geeklog is about to perform an operation on a trackback or pingback comment 1756 * to one of the items under the plugin's control and asks for the plugin's 1757 * permission to continue. 1758 * 1759 * Geeklog handles receiving and deleting trackback comments and pingbacks 1760 * for the plugin but since it doesn't know about the plugin's access control, 1761 * it has to ask the plugin to approve / reject such an operation. 1762 * 1763 * @param string $type plugin type 1764 * @param string $id an ID or URL, depending on the operation 1765 * @param string $operation operation to perform 1766 * 1767 * $operation can be one of the following: 1768 * 'acceptByID' - accept a trackback comment on item with ID $id 1769 * returns: true for accept, false for reject 1770 * 'acceptByURI' - accept a pingback comment on item at URL $id 1771 * returns: the item's ID for accept, false for reject 1772 * 'delete' - is the current user allowed to delete item with ID $id? 1773 * returns: true for accept, false for reject 1774 * 1775 */ 1776 function PLG_handlePingComment ($type, $id, $operation) 1777 { 1778 $args[1] = $id; 1779 $args[2] = $operation; 1780 1781 $function = 'plugin_handlepingoperation_' . $type; 1782 1783 return PLG_callFunctionForOnePlugin ($function, $args); 1784 } 1785 1786 1787 /** 1788 * Check if plugins have a scheduled task they want to run 1789 * The interval between runs is determined by $_CONF['cron_schedule_interval'] 1790 */ 1791 function PLG_runScheduledTask () 1792 { 1793 global $_PLUGINS; 1794 1795 if (function_exists ('CUSTOM_runScheduledTask')) { 1796 CUSTOM_runScheduledTask(); 1797 } 1798 foreach ($_PLUGINS as $pi_name) { 1799 $function = 'plugin_runScheduledTask_' . $pi_name; 1800 if (function_exists ($function)) { 1801 $function (); 1802 } 1803 } 1804 } 1805 1806 /** 1807 * "Generic" plugin API: Save item 1808 * 1809 * To be called (eventually) whenever Geeklog saves an item into the database. 1810 * Plugins can hook into this and modify the item (which is already in the 1811 * database but not visible on the site yet). 1812 * 1813 * Plugins can signal an error by returning an error message (otherwise, they 1814 * should return 'false' to signal "no errors"). In case of an error, all the 1815 * plugins called up to that point will be invoked through an "abort" call to 1816 * undo their changes. 1817 * 1818 * @param string $id unique ID of the item 1819 * @param string $type type of the item, e.g. 'article' 1820 * @returns mixed Boolean false for "no error", or an error msg text 1821 * 1822 */ 1823 function PLG_itemSaved ($id, $type) 1824 { 1825 global $_PLUGINS; 1826 1827 $error = false; 1828 1829 $plugins = count ($_PLUGINS); 1830 for ($save = 0; $save < $plugins; $save++) { 1831 $function = 'plugin_itemsaved_' . $_PLUGINS[$save]; 1832 if (function_exists ($function)) { 1833 $error = $function ($id, $type); 1834 if ($error !== false) { 1835 // plugin reported a problem - abort 1836 1837 for ($abort = 0; $abort < $save; $abort++) { 1838 $function = 'plugin_abortsave_' . $_PLUGINS[$abort]; 1839 if (function_exists ($function)) { 1840 $function ($id, $type); 1841 } 1842 } 1843 break; // out of for($save) loop 1844 } 1845 } 1846 } 1847 1848 return $error; 1849 } 1850 1851 /** 1852 * Gets Geeklog blocks from plugins 1853 * 1854 * Returns data for blocks on a given side and, potentially, for 1855 * a given topic. 1856 * 1857 * @param string $side Side to get blocks for (right or left for now) 1858 * @param string $topic Only get blocks for this topic 1859 * @return array of block data 1860 * 1861 */ 1862 function PLG_getBlocks( $side, $topic='') 1863 { 1864 global $_PLUGINS; 1865 1866 $ret = array(); 1867 foreach ($_PLUGINS as $pi_name) 1868 { 1869 $function = 'plugin_getBlocks_' . $pi_name; 1870 if (function_exists($function)) 1871 { 1872 $items = $function($side, $topic=''); 1873 if (is_array ($items)) 1874 { 1875 $ret = array_merge ($ret, $items); 1876 } 1877 } 1878 } 1879 1880 // future code to do a lib-custom function 1881 /* 1882 if (function_exists('CUSTOM_getBlocks')) { 1883 $cust_items .= CUSTOM_getBlocks($side, $topic=''); 1884 if (is_array ($cust_items)) { 1885 $ret = array_merge ($ret, $cust_items) 1886 } 1887 } 1888 */ 1889 1890 return $ret; 1891 } 1892 1893 /** 1894 * Get the URL of a plugin's icon 1895 * 1896 * @param string $type plugin name 1897 * @return string URL of the icon 1898 * 1899 */ 1900 function PLG_getIcon ($type) 1901 { 1902 global $_CONF; 1903 1904 $retval = ''; 1905 1906 // try the "geticon" function first 1907 $function = 'plugin_geticon_' . $type; 1908 if (function_exists ($function)) { 1909 $retval = $function (); 1910 } 1911 1912 // if that didn't work, try the "cclabel" function 1913 if (empty ($retval)) { 1914 $function = 'plugin_cclabel_' . $type; 1915 if (function_exists ($function)) { 1916 $cclabel = $function (); 1917 if (is_array ($cclabel)) { 1918 if (!empty ($cclabel[2])) { 1919 $retval = $cclabel[2]; 1920 } 1921 } 1922 } 1923 } 1924 1925 // lastly, search for the icon (assuming it's a GIF) 1926 if (empty ($retval)) { 1927 $icon = $_CONF['site_url'] . '/' . $type . '/images/' . $type . '.gif'; 1928 $fh = @fopen ($icon, 'r'); 1929 if ($fh === false) { 1930 $icon = $_CONF['site_admin_url'] . '/plugins/' . $type . '/images/' 1931 . $type . '.gif'; 1932 $fh = @fopen ($icon, 'r'); 1933 if ($fh === false) { 1934 // give up and us a generic icon 1935 $retval = $_CONF['site_url'] . '/images/icons/plugins.gif'; 1936 } else { 1937 $retval = $icon; 1938 fclose ($fh); 1939 } 1940 } else { 1941 $retval = $icon; 1942 fclose ($fh); 1943 } 1944 } 1945 1946 return $retval; 1947 } 1948 1949 ?>
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
| Généré le : Wed Nov 21 12:27:40 2007 | par Balluche grâce à PHPXref 0.7 |
|