| [ Index ] |
|
Code source de b2evolution 2.1.0-beta |
1 <?php 2 /** 3 * This file implements the Admin UI class. 4 * Admin skins should derive from this class and override {@link get_template()} 5 * for example. 6 * 7 * This file is part of the b2evolution/evocms project - {@link http://b2evolution.net/}. 8 * See also {@link http://sourceforge.net/projects/evocms/}. 9 * 10 * @copyright (c)2003-2007 by Francois PLANQUE - {@link http://fplanque.net/}. 11 * Parts of this file are copyright (c)2005 by Daniel HAHLER - {@link http://thequod.de/contact}. 12 * 13 * @license http://b2evolution.net/about/license.html GNU General Public License (GPL) 14 * 15 * {@internal Open Source relicensing agreement: 16 * Daniel HAHLER grants Francois PLANQUE the right to license 17 * Daniel HAHLER's contributions to this file and the b2evolution project 18 * under any OSI approved OSS license (http://www.opensource.org/licenses/). 19 * }} 20 * 21 * @package admin 22 * 23 * {@internal Below is a list of authors who have contributed to design/coding of this file: }} 24 * @author blueyed: Daniel HAHLER 25 * @author fplanque: Francois PLANQUE. 26 * 27 * @todo Refactor to allow easier contributions! (blueyed) 28 * 29 * @version $Id: _adminUI_general.class.php,v 1.72 2007/11/02 02:37:37 fplanque Exp $ 30 */ 31 if( !defined('EVO_MAIN_INIT') ) die( 'Please, do not access this page directly.' ); 32 33 34 load_funcs( '_core/ui/_uiwidget.class.php' ); 35 36 37 /** 38 * The general Admin UI class. It provides functions to handle the UI part of the 39 * Backoffice. 40 * 41 * Admin skins should derive from this class and override {@link get_template()} 42 * for example. 43 * 44 * @package admin 45 * @todo CODE DOCUMENTATION!!! 46 */ 47 class AdminUI_general extends Widget 48 { 49 /** 50 * Visual path seperator (used in html title, ..) 51 * 52 * @var string 53 */ 54 var $pathSeparator = ' › '; 55 56 /*-------------------------------------------------------------------*/ 57 /*- The members below should not get overridden in a derived class. -*/ 58 59 /** 60 * The menus. 61 * 62 * Use {@link add_menu_entries()} to add them here. 63 * 64 * @access protected 65 * @var array 66 */ 67 var $_menus = array(); 68 69 /** 70 * The path of the current selected menu entry. 71 * Array of strings. 72 * The top level entry is at position 0. Selected submenu entries follow. 73 * 74 * Use {@link get_path()} or {@link get_path_range()} to access it. 75 * Use {@link set_path()}, {@link append_path_level()} or {@link set_path_level()} to set it. 76 * 77 * @access protected 78 * @var array 79 */ 80 var $path = array(); 81 82 /** 83 * The properties of the path entries. 84 * Numbered Array of arrays. 85 * The top level entry is at position 0. Selected submenu entries follow. 86 * 87 * Use {@link get_prop_for_path()} or {@link get_properties_for_path()} to access it 88 * Use {@link set_path()}, {@link append_path_level()} or {@link set_path_level()} to set it. 89 * 90 * @access protected 91 * @var array 92 */ 93 var $pathProps = array(); 94 95 /** 96 * The explicit title for the page. 97 * @var string 98 */ 99 var $title; 100 101 /** 102 * The explicit title for the titlearea (<h1>). 103 * @var string 104 */ 105 var $title_titlearea; 106 var $title_titlearea_appendix = ''; 107 108 109 /** 110 * Constructor. 111 */ 112 function AdminUI_general() 113 { 114 global $mode; // TODO: make it a real property 115 global $htsrv_url, $baseurl; 116 117 $this->mode = $mode; 118 119 $this->init_templates(); 120 } 121 122 123 /** 124 * This function should init the templates - like adding Javascript through the {@link add_headline()} method. 125 */ 126 function init_templates() 127 { 128 } 129 130 131 /** 132 * Add menu entries to the list of entries for a given path. 133 * 134 * @param NULL|string|array The path to add the entries to. See {@link get_node_by_path()}. 135 * @param array Menu entries to add (key (string) => entry (array)). 136 * An entry can have the following keys: 137 * 'text': Text/Caption for this entry. 138 * 'href': The link for this entry. 139 * 'style': CSS style for this entry. 140 * 'onclick': onclick property for this entry. 141 * 'name': name attribute of the link/entry. 142 * 'entries': array of sub-entries 143 */ 144 function add_menu_entries( $path, $entries ) 145 { 146 // Get a reference to the node in the menu list. 147 $node = & $this->get_node_by_path( $path, true ); 148 149 /* 150 if( !is_array($node) ) 151 { 152 debug_die( 'add_menu_entries() with non-existing path!' ); 153 } 154 */ 155 156 foreach( $entries as $l_key => $l_menu_props ) 157 { 158 $node['entries'][$l_key] = $l_menu_props; 159 } 160 } 161 162 163 /** 164 * Add menu entries to the beginning of the list for given path. 165 * 166 * @param NULL|string|array The path to add the entries to. 167 * @param array Menu entries to add (key (string) => entry (array)). 168 * @uses add_menu_entries() 169 */ 170 function unshift_menu_entries( $path, $entries ) 171 { 172 // Get a reference to the node in the menu list. 173 $node = & $this->get_node_by_path( $path, true ); 174 175 $node['entries'] = array_reverse( $node['entries'] ); 176 177 $this->add_menu_entries( $path, $entries ); 178 179 $node['entries'] = array_reverse( $node['entries'] ); 180 } 181 182 183 /** 184 * Get the <title> of the page. 185 * 186 * This is either {@link $title} or will be constructed from title/text properties 187 * of the path entries. 188 * 189 * @param boolean If true, the fallback will be in reversed order 190 * @return string 191 */ 192 function get_title( $reversedDefault = false ) 193 { 194 if( isset($this->title) ) 195 { // Explicit title has been set: 196 return $this->title; 197 } 198 else 199 { // Fallback: implode title/text properties of the path 200 $titles = $this->get_properties_for_path( $this->path, array( 'title', 'text' ) ); 201 if( $reversedDefault ) 202 { // We have asked for reverse order of the path elements: 203 $titles = array_reverse($titles); 204 } 205 return implode( $this->pathSeparator, $titles ); 206 } 207 } 208 209 210 /** 211 * Get the title for the titlearea (<h1>). 212 * 213 * This is the current path in the site structure 214 * 215 * @return string 216 */ 217 function get_title_for_titlearea() 218 { 219 if( ! isset( $this->title_titlearea ) ) 220 { // Construct path: 221 $titles = array(); 222 foreach( $this->path as $i => $lPath ) 223 { 224 if( false !== ($title_text = $this->get_prop_for_path( $i, array( 'title', 'text' ) )) ) 225 { 226 $titles[] = '<a href="'.$this->get_prop_for_path( $i, array( 'href' ) ).'">'.$title_text.'</a>'; 227 } 228 } 229 230 $this->title_titlearea = implode( $this->pathSeparator, $titles ); 231 } 232 233 return $this->title_titlearea.$this->title_titlearea_appendix; 234 } 235 236 237 /** 238 * Append a string at the end of the existing titlearea. 239 * 240 * We actually keep the appended stuff separate from the main title, because the main title 241 * might in some occasions not be known immediately. 242 * 243 * @param string What to append to the titlearea 244 */ 245 function append_to_titlearea( $string ) 246 { 247 $this->title_titlearea_appendix .= $this->pathSeparator.$string; 248 } 249 250 251 /** 252 * Get the title for HTML <title> tag. 253 * 254 * If no explicit title has been specified, auto construct one from path. 255 * 256 * @return string 257 */ 258 function get_html_title() 259 { 260 global $app_shortname; 261 262 $r = $app_shortname.$this->pathSeparator; 263 264 if( $htmltitle = $this->get_prop_for_node( $this->path, array( 'htmltitle' ) ) ) 265 { // Explicit htmltitle set: 266 $r .= $htmltitle; 267 } 268 else 269 { // No explicit title set, construct Title from path 270 $r .= #preg_replace( '/:$/', '', 271 $this->get_title() 272 #) 273 ; 274 } 275 276 return $r; 277 } 278 279 280 /** 281 * Get a list of properties for a given path for a set of property names to check. 282 * The result is a list of properties for each node down the path. 283 * 284 * The property names must be given in $prop_by_ref, ordered by preference. 285 * 286 * @param string|array The path. See {@link get_node_by_path()}. 287 * @param array Alternative names of the property to receive (ordered by priority). 288 * @return array List of the properties. 289 */ 290 function get_properties_for_path( $path, $prop_by_pref ) 291 { 292 if( !is_array($path) ) 293 { 294 $path = array( $path ); 295 } 296 $r = array(); 297 298 $prevPath = array(); 299 foreach( $path as $i => $lPath ) 300 { 301 if( false !== ($prop = $this->get_prop_for_path( $i, $prop_by_pref )) ) 302 { 303 $r[] = $prop; 304 } 305 306 $prevPath[] = $lPath; 307 } 308 309 return $r; 310 } 311 312 313 /** 314 * Get a property of a node, given by path. 315 * 316 * @param string|array The path. See {@link get_node_by_path()}. 317 * @param array Alternative names of the property to receive (ordered by priority). 318 * @return mixed|false False if property is not set for the node, otherwise its value. 319 */ 320 function get_prop_for_node( $path, $prop_by_pref ) 321 { 322 $node = & $this->get_node_by_path( $path ); 323 324 foreach( $prop_by_pref as $lProp ) 325 { 326 if( isset($node[$lProp]) ) 327 { 328 return $node[$lProp]; 329 } 330 } 331 332 return false; 333 } 334 335 336 /** 337 * Get a property for a specific path entry. 338 * 339 * @param int The numeric index of the path entry to query (0 is first). 340 * @param array A list of properties to check, ordered by priority. 341 * @return mixed|false The first found property or false if it does not exist 342 */ 343 function get_prop_for_path( $depth, $prop_by_pref ) 344 { 345 if( $pathWithProps = $this->get_path( $depth, true ) ) 346 { 347 foreach( $prop_by_pref as $lProp ) 348 { 349 if( isset($pathWithProps['props'][$lProp]) ) 350 { 351 // echo "<br>path depth $depth property $lProp = ".$pathWithProps['props'][$lProp]; 352 return $pathWithProps['props'][$lProp]; 353 } 354 } 355 } 356 357 return false; 358 } 359 360 361 /** 362 * Get a menu, any level. 363 * 364 * @param NULL|string|array The path. See {@link get_node_by_path()}. 365 * @param string The template name, see {@link get_template()}. 366 */ 367 function get_html_menu( $path = NULL, $template = 'main' ) 368 { 369 /* debug: 370 $r = ' dispMenu-BEGIN '; 371 $r .= $this->get_html_menu_entries( $path, $template ); 372 $r .= ' dispMenu-END '; 373 return $r; 374 */ 375 return $this->get_html_menu_entries( $path, $template ); 376 } 377 378 379 /** 380 * Display doctype + <head>...</head> section 381 */ 382 function disp_html_head() 383 { 384 global $adminskins_path; 385 require $adminskins_path.'_html_header.inc.php'; 386 } 387 388 389 /** 390 * Dsiplay the top of the HTML <body>... 391 * 392 * Typically includes title, menu, messages, etc. 393 */ 394 function disp_body_top() 395 { 396 global $skins_path; 397 398 /** 399 * @var Hit 400 */ 401 global $Hit; 402 403 // #body_win and .body_firefox (for example) can be used to customize CSS per plaform/browser 404 echo '<body id="body_'.$Hit->agent_platform.'" class="body_'.$Hit->agent_name.'">'."\n"; 405 406 require $skins_path.'_toolbar.inc.php'; 407 408 echo $this->get_body_top(); 409 } 410 411 /** 412 * Display body bottom, debug info and close </html> 413 */ 414 function disp_global_footer() 415 { 416 global $adminskins_path; 417 418 require $adminskins_path.'_html_footer.inc.php'; 419 } 420 421 422 /** 423 * Display the start of a payload block 424 * 425 * Note: it is possible to display several payload blocks on a single page. 426 * The first block uses the "sub" template, the others "block". 427 * 428 * @see disp_payload_end() 429 * @todo check if the plugin event is appropriate. Maybe it should rather go as 'AdminAfterBodyTop' or sth like this. 430 */ 431 function disp_payload_begin() 432 { 433 global $Plugins; 434 435 if( empty($this->displayed_sub_begin) ) 436 { 437 $Plugins->trigger_event( 'AdminBeginPayload' ); 438 439 // Display submenu (this also opens a div class="panelblock" or class="panelblocktabs") 440 441 //echo ' disp_submenu-BEGIN '; 442 $path = array( $this->get_path(0) ); 443 $r = $this->get_html_menu( $path, 'sub' ); 444 445 echo $this->replace_vars( $r ); 446 //echo ' disp_submenu-END '; 447 448 $this->displayed_sub_begin = 1; 449 } 450 else 451 { 452 $template = $this->get_template( 'block' ); 453 454 echo $template['begin']; 455 } 456 457 } 458 459 460 /** 461 * Display the end of a payload block 462 * 463 * Note: it is possible to display several payload blocks on a single page. 464 * The first block uses the "sub" template, the others "block". 465 * @see disp_payload_begin() 466 */ 467 function disp_payload_end() 468 { 469 if( empty($this->displayed_sub_end) ) 470 { 471 $name = 'sub'; 472 $this->displayed_sub_end = 1; 473 } 474 else 475 { 476 $name = 'block'; 477 } 478 479 $template = $this->get_template( $name ); 480 481 echo $template['end']; 482 } 483 484 485 /** 486 * Display a view 487 * 488 * Note: doing the require inside of a function has the side effect of forcing the view 489 * to declare any global object it wants to use. This can be a little tedious but on the 490 * other hand it has the advantage of clearly showing what objects are used and makes it 491 * easier to audit the views in order to determine if they include more business logic 492 * than they ought to. 493 * 494 * @param string 495 * @param array params to be used in the view (optional) 496 */ 497 function disp_view( $view_name, $view_params = array() ) 498 { 499 global $inc_path; 500 501 // THESE ARE THE GLOBALS WE WANT TO MAKE AVAILABLE TO ALL VIEWS: 502 global $action; 503 global $ctrl; 504 505 global $DB; // Note: not sure it's agood idea to let the views hit on the db... 506 507 global $current_User; 508 509 510 require $inc_path.$view_name; 511 } 512 513 514 /** 515 * Returns the list of available Collections (aka Blogs) to work on. 516 * 517 * @todo Use BlogCache(?) 518 * @todo Use a template (i wanna make an UL/LI/A list structure in newer skins) 519 * 520 * @param string name of required permission needed to display the blog in the list 521 * @param string level of required permission needed to display the blog in the list 522 * @param string Url format string for elements, with %d for blog number. 523 * @param string Title for "all" button 524 * @param string URL for "all" button 525 * @param string onclick attribute format string, with %d for blog number. 526 * @param string name attribute for each button (%d for blog number) 527 * @return string HTML 528 */ 529 function get_html_collection_list( $permname = 'blog_ismember', $permlevel = 1, $url_format = '?blog=%d', 530 $all_title = NULL, $all_url = '', $onclick = NULL, $name = NULL ) 531 { 532 global $current_User, $blog; 533 534 $template = $this->get_template( 'CollectionList' ); 535 536 $r = $template['before']; 537 538 if( !is_null($all_title) ) 539 { // We want to add an "all" button 540 $r .= $template[ $blog == 0 ? 'beforeEachSel' : 'beforeEach' ]; 541 $r .= '<a href="'.$all_url 542 .'" class="'.( $blog == 0 ? 'CurrentBlog' : 'OtherBlog' ).'">' 543 .$all_title.'</a> '; 544 $r .= $template[ $blog == 0 ? 'afterEachSel' : 'afterEach' ]; 545 } 546 547 $BlogCache = & get_Cache( 'BlogCache' ); 548 549 $blog_array = $BlogCache->load_user_blogs( $permname, $permlevel ); 550 551 foreach( $blog_array as $l_blog_ID ) 552 { // Loop through all blogs that match the requested permission: 553 554 $l_Blog = & $BlogCache->get_by_ID( $l_blog_ID ); 555 556 $r .= $template[ $l_blog_ID == $blog ? 'beforeEachSel' : 'beforeEach' ]; 557 558 $r .= '<a href="'.sprintf( $url_format, $l_blog_ID ) 559 .'" class="'.( $l_blog_ID == $blog ? 'CurrentBlog' : 'OtherBlog' ).'"'; 560 561 if( !is_null($onclick) ) 562 { // We want to include an onclick attribute: 563 $r .= ' onclick="'.sprintf( $onclick, $l_blog_ID ).'"'; 564 } 565 566 if( !is_null($name) ) 567 { // We want to include a name attribute: 568 $r .= ' name="'.sprintf( $name, $l_blog_ID ).'"'; 569 } 570 571 $r .= '>'.$l_Blog->dget( 'shortname', 'htmlbody' ).'</a> '; 572 573 $r .= $template[ $l_blog_ID == $blog ? 'afterEachSel' : 'afterEach' ]; 574 } 575 576 $r .= $template['after']; 577 578 return $r; 579 } 580 581 582 /** 583 * Get the HTML for the menu entries of a specific path. 584 * 585 * @param NULL|string|array The path. See {@link get_node_by_path()}. 586 * @param string Template name, see {@link get_template()}. 587 * @param int Depth (recursion) 588 * @return string The HTML for the menu. 589 */ 590 function get_html_menu_entries( $path, $template, $depth = 0 ) 591 { 592 global $current_User; 593 594 $r = ''; 595 596 $templateForLevel = $this->get_template( $template, $depth ); 597 598 if( !( $menuEntries = $this->get_menu_entries($path) ) ) 599 { // No menu entries at this level 600 if( isset($templateForLevel['empty']) ) 601 { 602 $r .= $templateForLevel['empty']; 603 } 604 } 605 else 606 { // There are entries to display: 607 $r .= $templateForLevel['before']; 608 609 $selected = $this->get_selected($path); 610 611 foreach( $menuEntries as $loop_key => $loop_details ) 612 { 613 $anchor = '<a href="'; 614 615 if( isset( $loop_details['href'] ) ) 616 { 617 $anchor .= $loop_details['href']; 618 } 619 elseif( !empty($loop_details['href_eval']) ) 620 { // Useful for passing dynamic context vars (fp>> I AM using it) 621 $anchor .= eval( $loop_details['href_eval'] ); 622 } 623 else 624 { 625 $anchor .= regenerate_url( 'tab', 'tab='.$loop_key ); 626 } 627 $anchor .= '"'; 628 if( isset($loop_details['style']) ) 629 { 630 $anchor .= ' style="'.$loop_details['style'].'"'; 631 } 632 if( isset($loop_details['onclick']) ) 633 { 634 $anchor .= ' onclick="'.$loop_details['onclick'].'"'; 635 } 636 if( isset($loop_details['name']) ) 637 { 638 $anchor .= ' name="'.$loop_details['name'].'"'; 639 } 640 641 $anchor .= '>'.format_to_output( $loop_details['text'], 'htmlbody' )."</a>"; 642 643 if( $loop_key == $selected ) 644 { // Highlight selected entry 645 if( !empty( $templateForLevel['_props']['recurseSelected'] ) 646 && ( $recursePath = array_merge( $path, $loop_key ) ) 647 && ($this->get_menu_entries($recursePath) ) ) 648 { 649 $r .= isset($templateForLevel['beforeEachSelWithSub']) 650 ? $templateForLevel['beforeEachSelWithSub'] 651 : $templateForLevel['beforeEachSel']; 652 $r .= $anchor; 653 654 // Recurse: 655 $r .= $this->get_html_menu_entries( $recursePath, $template, $depth+1 ); 656 657 $r .= isset($templateForLevel['afterEachSelWithSub']) 658 ? $templateForLevel['afterEachSelWithSub'] 659 : $templateForLevel['afterEachSel']; 660 } 661 else 662 { 663 $r .= $templateForLevel['beforeEachSel']; 664 $r .= $anchor; 665 $r .= $templateForLevel['afterEachSel']; 666 } 667 } 668 else 669 { 670 $r .= $templateForLevel['beforeEach']; 671 $r .= $anchor; 672 $r .= $templateForLevel['afterEach']; 673 } 674 } 675 $r .= $templateForLevel['after']; 676 } 677 678 return $r; 679 } 680 681 682 /** 683 * Get menu entries for a given path. 684 * 685 * @param NULL|string|array The path. See {@link get_node_by_path()}. 686 * @return array The menu entries (may be empty). 687 */ 688 function get_menu_entries( $path ) 689 { 690 $node = & $this->get_node_by_path( $path ); 691 692 return isset( $node['entries'] ) ? $node['entries'] : array(); 693 } 694 695 696 /** 697 * Get the key of a selected entry for a path. 698 * 699 * @param NULL|string|array The path. See {@link get_node_by_path()}. 700 * @return string|false 701 */ 702 function get_selected( $path ) 703 { 704 $node = & $this->get_node_by_path($path); 705 706 if( isset($node['selected']) ) 707 { 708 return $node['selected']; 709 } 710 711 return false; 712 } 713 714 715 /** 716 * Get the reference of a node from the menu entries using a path. 717 * 718 * @param array|string|NULL The path. NULL means root, string means child of root, 719 * array means path below root. 720 * (eg <code>array('options', 'general')</code>). 721 * @param boolean Should the node be created if it does not exist already? 722 * @return array|false The node as array or false, if the path does not exist (and we do not $createIfNotExisting). 723 */ 724 function & get_node_by_path( $path, $createIfNotExisting = false ) 725 { 726 if( is_null($path) ) 727 { // root element 728 $path = array(); 729 } 730 elseif( ! is_array($path) ) 731 { 732 $path = array($path); 733 } 734 735 $node = & $this->_menus; 736 foreach( $path as $lStep ) 737 { 738 if( ! isset($node['entries'][$lStep]) ) 739 { 740 if( $createIfNotExisting ) 741 { 742 $node['entries'][$lStep] = array(); 743 } 744 else 745 { 746 $r = false; 747 return $r; 748 } 749 } 750 $node = & $node['entries'][$lStep]; 751 } 752 753 return $node; 754 } 755 756 757 /** 758 * Get a template by name and depth. 759 * 760 * Templates can handle multiple depth levels 761 * 762 * This is a method (and not a member array) to allow dynamic generation and T_() 763 * 764 * @param string Name of the template ('main', 'sub') 765 * @param integer Nesting level (start at 0) 766 * @return array Associative array which defines layout and optionally properties. 767 */ 768 function get_template( $name, $depth = 0 ) 769 { 770 switch( $name ) 771 { 772 case 'main': 773 switch( $depth ) 774 { 775 case 0: 776 // main level 777 global $app_shortname, $app_version; 778 779 return array( 780 'before' => '<div id="mainmenu"><ul>', 781 'after' => '</ul></div>', 782 'beforeEach' => '<li>', 783 'afterEach' => '</li>', 784 'beforeEachSel' => '<li class="current">', 785 'afterEachSel' => '</li>', 786 'beforeEachSelWithSub' => '<li class="parent">', 787 'afterEachSelWithSub' => '</li>', 788 '_props' => array( 789 /** 790 * @todo Move to new skin (recurse for subentries if an entry is selected) 791 'recurseSelected' => true, 792 */ 793 ), 794 ); 795 796 default: 797 // any sublevel 798 return array( 799 'before' => '<ul class="submenu">', 800 'after' => '</ul>', 801 'beforeEach' => '<li>', 802 'afterEach' => '</li>', 803 'beforeEachSel' => '<li class="current">', 804 'afterEachSel' => '</li>', 805 ); 806 } 807 808 break; 809 810 811 case 'sub': 812 // a payload block with embedded submenu 813 return array( 814 'before' => '<div class="pt">' 815 ."\n".'<ul class="hack">' 816 ."\n<li><!-- Yes, this empty UL is needed! It's a DOUBLE hack for correct CSS display --></li>" 817 // TODO: this hack MAY NOT be needed when not using pixels instead of decimal ems or exs in the CSS 818 ."\n</ul>" 819 ."\n".'<div class="panelblocktabs">' 820 ."\n".'<ul class="tabs">', 821 'after' => "</ul>\n" 822 .'<span style="float:right">$global_icons$</span>' 823 ."</div>\n</div>" 824 ."\n".'<div class="tabbedpanelblock">', 825 'empty' => '<div class="panelblock">', 826 'beforeEach' => '<li>', 827 'afterEach' => '</li>', 828 'beforeEachSel' => '<li class="current">', 829 'afterEachSel' => '</li>', 830 'end' => '</div>', // used to end payload block that opened submenu 831 ); 832 833 834 case 'block': 835 // an additional payload block, anywhere after the one with the submenu. Used by disp_payload_begin()/disp_payload_end() 836 return array( 837 'begin' => '<div class="panelblock">', 838 'end' => "\n</div>", 839 ); 840 841 842 case 'CollectionList': 843 // Template for a list of Collections (Blogs) 844 return array( 845 'before' => '<div id="coll_list"><ul>', 846 'after' => '</ul></div>', 847 'beforeEach' => '<li>', 848 'afterEach' => '</li>', 849 'beforeEachSel' => '<li class="current">', 850 'afterEachSel' => '</li>', 851 ); 852 853 854 case 'Results': 855 // Results list: 856 return array( 857 'page_url' => '', // All generated links will refer to the current page 858 'before' => '<div class="results">', 859 'header_start' => '<div class="results_nav">', 860 'header_text' => '<strong>'.T_('Pages').'</strong>: $prev$ $first$ $list_prev$ $list$ $list_next$ $last$ $next$', 861 'header_text_single' => '', 862 'header_end' => '</div>', 863 'list_start' => '<table class="grouped" cellspacing="0">'."\n\n", 864 'head_start' => "<thead>\n", 865 'head_title' => '<tr><th colspan="$nb_cols$" class="title"><span style="float:right">$global_icons$</span>$title$</th>' 866 ."\n</tr>\n", 867 'filters_start' => '<tr class="filters"><td colspan="$nb_cols$">', 868 'filters_end' => '</td></tr>', 869 'line_start_head' => '<tr>', // TODO: fusionner avec colhead_start_first; mettre a jour admin_UI_general; utiliser colspan="$headspan$" 870 'colhead_start' => '<th $class_attrib$>', 871 'colhead_start_first' => '<th class="firstcol $class$">', 872 'colhead_start_last' => '<th class="lastcol $class$">', 873 'colhead_end' => "</th>\n", 874 'sort_asc_off' => '<img src="../admin/img/grey_arrow_up.gif" alt="A" title="'.T_('Ascending order') 875 .'" height="12" width="11" />', 876 'sort_asc_on' => '<img src="../admin/img/black_arrow_up.gif" alt="A" title="'.T_('Ascending order') 877 .'" height="12" width="11" />', 878 'sort_desc_off' => '<img src="../admin/img/grey_arrow_down.gif" alt="D" title="'.T_('Descending order') 879 .'" height="12" width="11" />', 880 'sort_desc_on' => '<img src="../admin/img/black_arrow_down.gif" alt="D" title="'.T_('Descending order') 881 .'" height="12" width="11" />', 882 'basic_sort_off' => '', 883 'basic_sort_asc' => get_icon( 'ascending' ), 884 'basic_sort_desc' => get_icon( 'descending' ), 885 'head_end' => "</thead>\n\n", 886 'tfoot_start' => "<tfoot>\n", 887 'tfoot_end' => "</tfoot>\n\n", 888 'body_start' => "<tbody>\n", 889 'line_start' => '<tr class="even">'."\n", 890 'line_start_odd' => '<tr class="odd">'."\n", 891 'line_start_last' => '<tr class="even lastline">'."\n", 892 'line_start_odd_last' => '<tr class="odd lastline">'."\n", 893 'col_start' => '<td $class_attrib$>', 894 'col_start_first' => '<td class="firstcol $class$">', 895 'col_start_last' => '<td class="lastcol $class$">', 896 'col_end' => "</td>\n", 897 'line_end' => "</tr>\n\n", 898 'grp_line_start' => '<tr class="group">'."\n", 899 'grp_line_start_odd' => '<tr class="odd">'."\n", 900 'grp_line_start_last' => '<tr class="lastline">'."\n", 901 'grp_line_start_odd_last' => '<tr class="odd lastline">'."\n", 902 'grp_col_start' => '<td $class_attrib$ $colspan_attrib$>', 903 'grp_col_start_first' => '<td class="firstcol $class$" $colspan_attrib$>', 904 'grp_col_start_last' => '<td class="lastcol $class$" $colspan_attrib$>', 905 'grp_col_end' => "</td>\n", 906 'grp_line_end' => "</tr>\n\n", 907 'body_end' => "</tbody>\n\n", 908 'total_line_start' => '<tr class="total">'."\n", 909 'total_col_start' => '<td $class_attrib$>', 910 'total_col_start_first' => '<td class="firstcol $class$">', 911 'total_col_start_last' => '<td class="lastcol $class$">', 912 'total_col_end' => "</td>\n", 913 'total_line_end' => "</tr>\n\n", 914 'list_end' => "</table>\n\n", 915 'footer_start' => '<div class="results_nav">', 916 'footer_text' => '<strong>'.T_('Pages').'</strong>: $prev$ $first$ $list_prev$ $list$ $list_next$ $last$ $next$' 917 /* T_('Page $scroll_list$ out of $total_pages$ $prev$ | $next$<br />'. */ 918 /* '<strong>$total_pages$ Pages</strong> : $prev$ $list$ $next$' */ 919 /* .' <br />$first$ $list_prev$ $list$ $list_next$ $last$ :: $prev$ | $next$') */, 920 'footer_text_single' => '', 921 'footer_text_no_limit' => '', // Text if theres no LIMIT and therefor only one page anyway 922 'prev_text' => T_('Previous'), 923 'next_text' => T_('Next'), 924 'no_prev_text' => '', 925 'no_next_text' => '', 926 'list_prev_text' => T_('...'), 927 'list_next_text' => T_('...'), 928 'list_span' => 11, 929 'scroll_list_range' => 5, 930 'footer_end' => "</div>\n\n", 931 'no_results_start' => '<table class="grouped" cellspacing="0">'."\n\n" 932 .'<th class="title"><span style="float:right">$global_icons$</span>' 933 .'$title$</th></tr>'."\n" 934 .'<tr class="lastline"><td class="firstcol lastcol">', 935 'no_results_end' => '</td></tr>' 936 .'</table>'."\n\n", 937 'after' => '</div>', 938 'sort_type' => 'basic' 939 ); 940 941 case 'compact_form': 942 case 'Form': 943 // Default Form settings: 944 return array( 945 'layout' => 'fieldset', 946 'formstart' => '', 947 'title_fmt' => '<span style="float:right">$global_icons$</span><h2>$title$</h2>'."\n", 948 'no_title_fmt' => '<span style="float:right">$global_icons$</span>'."\n", 949 'fieldset_begin' => '<fieldset $fieldset_attribs$>'."\n" 950 .'<legend $title_attribs$>$fieldset_title$</legend>'."\n", 951 'fieldset_end' => '</fieldset>'."\n", 952 'fieldstart' => '<fieldset $ID$>'."\n", 953 'labelstart' => '<div class="label">', 954 'labelend' => "</div>\n", 955 'labelempty' => '<div class="label"></div>', // so that IE6 aligns DIV.input correcctly 956 'inputstart' => '<div class="input">', 957 'infostart' => '<div class="info">', 958 'inputend' => "</div>\n", 959 'fieldend' => "</fieldset>\n\n", 960 'buttonsstart' => '<fieldset><div class="input">', 961 'buttonsend' => "</div></fieldset>\n\n", 962 'formend' => '', 963 ); 964 965 case 'file_browser': 966 return array( 967 'block_start' => '<div class="block_item"> 968 <h3><span style="float:right">$global_icons$</span>$title$</h3>', 969 'block_end' => '</div>', 970 ); 971 972 case 'block_item': 973 return array( 974 'block_start' => '<div class="block_item"> 975 <h3><span style="float:right">$global_icons$</span>$title$</h3>', 976 'block_end' => '</div>', 977 ); 978 979 case 'side_item': 980 return array( 981 'block_start' => '<div class="browse_side_item"> 982 <h3><span style="float:right">$global_icons$</span>$title$</h3>', 983 'block_end' => '</div>', 984 ); 985 986 default: 987 debug_die( 'Unknown $name for AdminUI::get_template(): '.var_export($name, true) /* PHP 4.2 ! */ ); 988 } 989 } 990 991 992 /** 993 * 994 * @todo Move generation of blog list to this class! 995 * 996 * @return string 997 */ 998 function get_bloglist_buttons( $before = '', $after = '' ) 999 { 1000 global $blogListButtons; 1001 1002 if( !empty($blogListButtons) ) 1003 { 1004 return $before.$blogListButtons.$after; 1005 } 1006 } 1007 1008 1009 /** 1010 * Get a path key by numeric key. Starts with 0. 1011 * 1012 * @param integer The numeric index of the path (0 is first). 1013 * @param boolean Also return properties? 1014 * @return string|array|false (depends on $withProps) 1015 */ 1016 function get_path( $which, $withProps = false ) 1017 { 1018 if( $which === 'last' ) 1019 { 1020 $which = count($this->path)-1; 1021 } 1022 if( !isset($this->path[$which]) ) 1023 { 1024 return false; 1025 } 1026 1027 if( $withProps ) 1028 { 1029 return array( 1030 'path' => $this->path[$which], 1031 'props' => isset( $this->pathProps[$which] ) ? $this->pathProps[$which] : array(), 1032 ); 1033 } 1034 1035 return $this->path[$which]; 1036 } 1037 1038 1039 /** 1040 * Get tghe list of path keys in a given range. 1041 * 1042 * @param integer start index 1043 * @param integer|NULL end index (NULL means same as start index) 1044 * @return array List of path keys. 1045 */ 1046 function get_path_range( $start, $end = NULL ) 1047 { 1048 if( is_null($end) ) 1049 { 1050 $end = $start; 1051 } 1052 1053 $r = array(); 1054 for( $i = $start; $i <= $end; $i++ ) 1055 { 1056 $r[] = isset($this->path[$i]) ? $this->path[$i] : NULL; 1057 } 1058 1059 return $r; 1060 } 1061 1062 1063 /** 1064 * Set a specific path level (specific depth). 1065 * 1066 * First level is 0, then the first subpath/submenu is level 1, etc. 1067 * 1068 * E.g., if plugins.php gets called, there could be a call to 1069 * $AdminUI->set_path_level( 0, 'plugins' ), which selects this entry from the menu. 1070 * If a specific tab is called inside of plugins.php, there could be a call to 1071 * $AdminUI->set_path_level( 1, $tab ) 1072 * 1073 * Though, it is recommended to call the wrapper functions: 1074 * - {@link append_path_level()} 1075 * - {@link set_path()} 1076 * 1077 * This also marks the parent node as selected and checks for permissions. 1078 * 1079 * @param integer Path level to set (starts at 0) 1080 * @param array Either the key of the path or an array(keyname, propsArray). 1081 * @param array Properties for this path entry. 1082 * @return boolean DEPRECATED True if perm granted, false if not (and we're not exiting). 1083 */ 1084 function set_path_level( $level, $pathKey, $pathProps = array() ) 1085 { 1086 // Get the parent node (the level above this one): 1087 if( $level == 0 ) 1088 { // first level in menu-path: parent node is NULL 1089 $parentNode = & $this->get_node_by_path( NULL ); 1090 } 1091 else 1092 { // parent node is the trunk from root to previous level 1093 $parentNode = & $this->get_node_by_path( $this->get_path_range( 0, $level-1 ) ); 1094 } 1095 if( ! $parentNode ) 1096 { // parent node does not exist: 1097 return false; 1098 } 1099 1100 // Store the selected entry name in the parent node: 1101 $parentNode['selected'] = $pathKey; 1102 1103 $this->path[$level] = $pathKey; 1104 $this->pathProps[$level] = $pathProps; 1105 // FP> WHY ON EARTH would we want to do that? $this->pathProps[$level] = array_merge( $parentNode, $pathProps ); 1106 1107 // pre_dump( 'set_path_level: ', $level, $pathKey, $this->pathProps[$level] ); 1108 1109 return true; 1110 } 1111 1112 1113 /** 1114 * Append a selected menu entry to the current path of selected entries. 1115 * 1116 * @param string|array Either the key of the path or an array(keyname, propsArray). 1117 */ 1118 function append_path_level( $path, $pathProps = array() ) 1119 { 1120 $search_path = $this->path; 1121 $search_path[] = $path; 1122 // auto-detect path props from menu entries 1123 if( $node = & $this->get_node_by_path( $search_path ) ) 1124 { 1125 $pathProps = array_merge( $node, $pathProps ); 1126 } 1127 1128 // Set the path level right after the last existing one: 1129 return $this->set_path_level( count($this->path), $path, $pathProps ); 1130 } 1131 1132 1133 /** 1134 * Set the full selected path. 1135 * 1136 * For example, this selects the tab/submenu 'plugins' in the main menu 'options': 1137 * <code> 1138 * set_path( 'options', 'plugins' ); 1139 * </code> 1140 * 1141 * Use {@link append_path_level()} to append a single path element. 1142 * 1143 * This is an easy stub for {@link set_path_level()}. 1144 * 1145 * @param string|array,... VARIABLE NUMBER OF ARGUMENTS. Each is either the key of a path entry or an array(keyname, propsArray). 1146 */ 1147 function set_path( ) 1148 { 1149 $args = func_get_args(); 1150 1151 $i = 0; 1152 $prevPath = array(); // Remember the path we have walked through 1153 1154 // Loop though all path levels to set: 1155 foreach( $args as $arg ) 1156 { 1157 if( is_array($arg) ) 1158 { // Path name and properties given 1159 list( $pathName, $pathProps ) = $arg; 1160 } 1161 else 1162 { // Just the path name 1163 $pathName = $arg; 1164 $pathProps = array(); 1165 } 1166 1167 $this->init_menus(); 1168 1169 if( $node = & $this->get_node_by_path( array_merge( $prevPath, array($pathName) ) ) ) 1170 { // the node exists in the menu entries: merge the properties 1171 $pathProps = array_merge( $node, $pathProps ); 1172 } 1173 1174 if( ! $this->set_path_level( $i++, $pathName, $pathProps ) ) 1175 { 1176 return false; 1177 } 1178 1179 $prevPath[] = $pathName; 1180 } 1181 1182 return true; 1183 } 1184 1185 1186 /** 1187 * Init the menus. 1188 * 1189 * Do this as late as possible. Especially after determining the blog ID we work on. 1190 * This allows to check for proper permissions and build correct cross navigation links. 1191 */ 1192 function init_menus() 1193 { 1194 global $Plugins; 1195 global $blog, $loc_transinfo, $ctrl; 1196 global $Settings; 1197 /** 1198 * @var User 1199 */ 1200 global $current_User; 1201 global $Blog; 1202 1203 if( !empty($this->_menus) ) 1204 { // Already initialized! 1205 return; 1206 } 1207 1208 1209 $this->add_menu_entries( 1210 NULL, // root 1211 array( 1212 'dashboard' => array( 1213 'text' => T_('Dashboard'), 1214 'href' => 'admin.php?ctrl=dashboard&blog='.$blog, 1215 'style' => 'font-weight: bold;' 1216 ), 1217 1218 'items' => array( 1219 'text' => T_('Posts / Comments'), 1220 'href' => 'admin.php?ctrl=items&blog='.$blog.'&filter=restore', 1221 // Controller may add subtabs 1222 ), 1223 ) ); 1224 1225 1226 if( $Settings->get( 'fm_enabled' ) && $current_User->check_perm( 'files', 'view' ) ) 1227 { // FM enabled and permission to view files: 1228 $this->add_menu_entries( NULL, array( 1229 'files' => array( 1230 'text' => T_('Files'), 1231 'title' => T_('File management'), 1232 'href' => 'admin.php?ctrl=files', 1233 // Controller may add subtabs 1234 ), 1235 ) ); 1236 1237 } 1238 1239 1240 if( $current_User->check_perm( 'stats', 'list' ) ) 1241 { // Permission to view stats for user's blogs: 1242 if( $current_User->check_perm( 'stats', 'view' ) ) 1243 { // We have permission to view all stats, 1244 // we'll assume that we want to view th aggregate stats and not the current blog stats 1245 // fp> TODO: it might be useful to have a user pref for [View aggregate stats by default] vs [View current blog stats by default] 1246 $default = 'admin.php?ctrl=stats&blog=0'; 1247 } 1248 else 1249 { 1250 $default = 'admin.php?ctrl=stats'; 1251 } 1252 $this->add_menu_entries( 1253 NULL, // root 1254 array( 1255 'stats' => array( 1256 'text' => T_('Stats'), 1257 'href' => $default, 1258 'entries' => array( 1259 'summary' => array( 1260 'text' => T_('Hit summary'), 1261 'href' => 'admin.php?ctrl=stats&tab=summary&blog='.$blog ), 1262 'browserhits' => array( 1263 'text' => T_('Browser hits'), 1264 'href' => 'admin.php?ctrl=stats&tab=browserhits&blog='.$blog ), 1265 'refsearches' => array( 1266 'text' => T_('Search B-hits'), 1267 'href' => 'admin.php?ctrl=stats&tab=refsearches&blog='.$blog ), 1268 'referers' => array( 1269 'text' => T_('Referered B-hits'), 1270 'href' => 'admin.php?ctrl=stats&tab=referers&blog='.$blog ), 1271 'other' => array( 1272 'text' => T_('Direct B-hits'), 1273 'href' => 'admin.php?ctrl=stats&tab=other&blog='.$blog ), 1274 'robots' => array( 1275 'text' => T_('Robot hits'), 1276 'href' => 'admin.php?ctrl=stats&tab=robots&blog='.$blog ), 1277 'syndication' => array( 1278 'text' => T_('XML hits'), 1279 'href' => 'admin.php?ctrl=stats&tab=syndication&blog='.$blog ), 1280 'useragents' => array( 1281 'text' => T_('User agents'), 1282 'href' => 'admin.php?ctrl=stats&tab=useragents&blog='.$blog ), 1283 'domains' => array( 1284 'text' => T_('Referring domains'), 1285 'href' => 'admin.php?ctrl=stats&tab=domains&blog='.$blog ), 1286 ) 1287 ), 1288 ) ); 1289 } 1290 1291 if( $blog == 0 && $current_User->check_perm( 'stats', 'view' ) ) 1292 { // Viewing aggregate + Permission to view stats for ALL blogs: 1293 $this->add_menu_entries( 1294 'stats', 1295 array( 1296 'sessions' => array( 1297 'text' => T_('Sessions'), 1298 'href' => 'admin.php?ctrl=stats&tab=sessions&blog='.$blog ), 1299 ) 1300 ); 1301 } 1302 1303 1304 // BLOG SETTINGS: 1305 if( $ctrl == 'collections' ) 1306 { // We are viewing the blog list, nothing fancy involved: 1307 $this->add_menu_entries( 1308 NULL, // root 1309 array( 1310 'blogs' => array( 1311 'text' => T_('Blog settings'), 1312 'href' => 'admin.php?ctrl=collections', 1313 ), 1314 ) ); 1315 } 1316 else 1317 { // We're on any other page, we may have a direct destination 1318 // + we have subtabs (fp > maybe the subtabs should go into the controller as for _items ?) 1319 1320 // What perms do we have? 1321 $coll_settings_perm = $current_User->check_perm( 'blog_properties', 'any', false, $blog ); 1322 $coll_chapters_perm = $current_User->check_perm( 'blog_cats', '', false, $blog ); 1323 1324 // Determine default page based on permissions: 1325 if( $coll_settings_perm ) 1326 { // Default: show General Blog Settings 1327 $default_page = 'admin.php?ctrl=coll_settings&tab=general&blog='.$blog; 1328 } 1329 elseif( $coll_chapters_perm ) 1330 { // Default: show categories 1331 $default_page = 'admin.php?ctrl=chapters&blog='.$blog; 1332 } 1333 else 1334 { // Default: Show list of blogs 1335 $default_page = 'admin.php?ctrl=collections'; 1336 } 1337 1338 $this->add_menu_entries( 1339 NULL, // root 1340 array( 1341 'blogs' => array( 1342 'text' => T_('Blog settings'), 1343 'href' => $default_page, 1344 ), 1345 ) ); 1346 1347 if( $coll_settings_perm ) 1348 { 1349 $this->add_menu_entries( 'blogs', array( 1350 'general' => array( 1351 'text' => T_('General'), 1352 'href' => 'admin.php?ctrl=coll_settings&tab=general&blog='.$blog, ), 1353 'features' => array( 1354 'text' => T_('Features'), 1355 'href' => 'admin.php?ctrl=coll_settings&tab=features&blog='.$blog, ), 1356 'skin' => array( 1357 'text' => T_('Skin'), 1358 'href' => 'admin.php?ctrl=coll_settings&tab=skin&blog='.$blog, ), 1359 'widgets' => array( 1360 'text' => T_('Widgets'), 1361 'href' => 'admin.php?ctrl=widgets&blog='.$blog, ), 1362 ) ); 1363 } 1364 1365 if( $coll_chapters_perm ) 1366 { 1367 $this->add_menu_entries( 'blogs', array( 1368 'chapters' => array( 1369 'text' => T_('Categories'), 1370 'href' => 'admin.php?ctrl=chapters&blog='.$blog ), 1371 ) ); 1372 } 1373 1374 if( $coll_settings_perm ) 1375 { 1376 $this->add_menu_entries( 'blogs', array( 1377 'urls' => array( 1378 'text' => T_('URLs'), 1379 'href' => 'admin.php?ctrl=coll_settings&tab=urls&blog='.$blog, ), 1380 'seo' => array( 1381 'text' => T_('SEO'), 1382 'href' => 'admin.php?ctrl=coll_settings&tab=seo&blog='.$blog, ), 1383 'advanced' => array( 1384 'text' => T_('Advanced'), 1385 'href' => 'admin.php?ctrl=coll_settings&tab=advanced&blog='.$blog, ), 1386 ) ); 1387 1388 if( $Blog && $Blog->advanced_perms ) 1389 { 1390 $this->add_menu_entries( 'blogs', array( 1391 'perm' => array( 1392 'text' => T_('User perms'), // keep label short 1393 'href' => 'admin.php?ctrl=coll_settings&tab=perm&blog='.$blog, ), 1394 'permgroup' => array( 1395 'text' => T_('Group perms'), // keep label short 1396 'href' => 'admin.php?ctrl=coll_settings&tab=permgroup&blog='.$blog, ), 1397 ) ); 1398 } 1399 } 1400 } 1401 1402 1403 if( $current_User->check_perm( 'options', 'view' ) ) 1404 { // Permission to view settings: 1405 $this->add_menu_entries( NULL, array( 1406 'options' => array( 1407 'text' => T_('Global settings'), 1408 'href' => 'admin.php?ctrl=settings', 1409 'entries' => array( 1410 'general' => array( 1411 'text' => T_('General'), 1412 'href' => 'admin.php?ctrl=settings' ), 1413 'features' => array( 1414 'text' => T_('Features'), 1415 'href' => 'admin.php?ctrl=features' ), 1416 'skins' => array( 1417 'text' => T_('Skins install'), 1418 'href' => 'admin.php?ctrl=skins'), 1419 'plugins' => array( 1420 'text' => T_('Plugins install'), 1421 'href' => 'admin.php?ctrl=plugins'), 1422 'antispam' => array( 1423 'text' => T_('Antispam'), 1424 'href' => 'admin.php?ctrl=set_antispam'), 1425 'regional' => array( 1426 'text' => T_('Regional'), 1427 'href' => 'admin.php?ctrl=locales'.( (isset($loc_transinfo) && $loc_transinfo) ? '&loc_transinfo=1' : '' ) ), 1428 'files' => array( 1429 'text' => T_('Files'), 1430 'href' => 'admin.php?ctrl=fileset' ), 1431 'filetypes' => array( 1432 'text' => T_('File types'), 1433 'href' => 'admin.php?ctrl=filetypes' ), 1434 'types' => array( 1435 'text' => T_('Post types'), 1436 'title' => T_('Post types management'), 1437 'href' => 'admin.php?ctrl=itemtypes'), 1438 'statuses' => array( 1439 'text' => T_('Post statuses'), 1440 'title' => T_('Post statuses management'), 1441 'href' => 'admin.php?ctrl=itemstatuses'), 1442 ) 1443 ), 1444 ) ); 1445 } 1446 1447 1448 if( $current_User->check_perm( 'users', 'view' ) ) 1449 { // Permission to view users: 1450 $this->add_menu_entries( NULL, array( 1451 'users' => array( 1452 'text' => T_('Users'), 1453 'title' => T_('User management'), 1454 'href' => 'admin.php?ctrl=users', 1455 ), 1456 ) ); 1457 } 1458 else 1459 { // Only perm to view his own profile: 1460 $this->add_menu_entries( NULL, array( 1461 'users' => array( 1462 'text' => T_('My profile'), 1463 'title' => T_('User profile'), 1464 'href' => 'admin.php?ctrl=users', 1465 ), 1466 ) ); 1467 } 1468 1469 1470 if( $current_User->check_perm( 'options', 'view' ) ) 1471 { // Permission to view settings: 1472 // FP> This assumes that we don't let regular users access the tools, including plugin tools. 1473 $this->add_menu_entries( NULL, array( 1474 'tools' => array( 1475 'text' => T_('Tools'), 1476 'href' => 'admin.php?ctrl=crontab', 1477 'entries' => array( 1478 'cron' => array( 1479 'text' => T_('Scheduler'), 1480 'href' => 'admin.php?ctrl=crontab' ), 1481 'system' => array( 1482 'text' => T_('System'), 1483 'href' => 'admin.php?ctrl=system' ), 1484 ), 1485 ), 1486 ) ); 1487 1488 if( $current_User->check_perm( 'spamblacklist', 'view' ) ) 1489 { // Permission to view antispam: 1490 $this->add_menu_entries( 'tools', array( 1491 'antispam' => array( 1492 'text' => T_('Antispam'), 1493 'href' => 'admin.php?ctrl=antispam' ), 1494 ) ); 1495 } 1496 1497 $this->add_menu_entries( 'tools', array( 1498 '' => array( // fp> '' is dirty 1499 'text' => T_('Misc'), 1500 'href' => 'admin.php?ctrl=tools' ), 1501 ) ); 1502 } 1503 elseif( $current_User->check_perm( 'spamblacklist', 'view' ) ) 1504 { // Permission to view antispam but NOT tools: 1505 // Give it it's own tab: 1506 $this->add_menu_entries( NULL, array( 1507 'tools' => array( 1508 'text' => T_('Tools'), 1509 'href' => 'admin.php?ctrl=antispam', 1510 'entries' => array( 1511 'antispam' => array( 1512 'text' => T_('Antispam'), 1513 'href' => 'admin.php?ctrl=antispam' ), 1514 ), 1515 ), 1516 ) ); 1517 } 1518 1519 1520 /* 1521 $this->add_menu_entries( NULL, array( 1522 'adsense' => array( 1523 'text' => T_('AdSense'), 1524 'title' => T_('AdSense stats'), 1525 'href' => 'admin.php?ctrl=adsense', 1526 ), 1527 ) ); 1528 */ 1529 1530 // Call AdminAfterMenuInit to notify Plugins that the menu is initialized 1531 // E.g. the livehits_plugin and weather_plugin use it for adding a menu entry. 1532 $Plugins->trigger_event( 'AdminAfterMenuInit' ); 1533 } 1534 1535 1536 /** 1537 * Get the top of the HTML <body>. 1538 * 1539 * @return string 1540 */ 1541 function get_body_top() 1542 { 1543 return ''; 1544 } 1545 1546 1547 /** 1548 * Get the end of the HTML <body>. Close open divs, etc... 1549 * 1550 * @return string 1551 */ 1552 function get_body_bottom() 1553 { 1554 return ''; 1555 } 1556 1557 1558 /** 1559 * GLOBAL HEADER - APP TITLE, LOGOUT, ETC. 1560 * 1561 * @return string 1562 */ 1563 function get_page_head() 1564 { 1565 global $app_shortname, $app_version, $current_User, $htsrv_url_sensitive, $admin_url, $baseurl, $rsc_url; 1566 1567 $r = ' 1568 <div id="header"> 1569 <div id="headinfo"> 1570 <span id="headfunctions">' 1571 // Note: if we log in with another user, we may not have the perms to come back to the same place any more, thus: redirect to admin home. 1572 .'<a href="'.$htsrv_url_sensitive.'login.php?action=logout&redirect_to='.rawurlencode(url_rel_to_same_host($admin_url, $htsrv_url_sensitive)).'">'.T_('Logout').'</a> 1573 <img src="'.$rsc_url.'icons/close.gif" width="14" height="14" border="0" class="top" alt="" title="' 1574 .T_('Logout').'" /></a> 1575 </span> 1576 1577 '.$app_shortname.' v <strong>'.$app_version.'</strong> 1578 </div> 1579 1580 <h1>'.$this->get_title_for_titlearea().'</h1> 1581 </div> 1582 '; 1583 1584 return $r; 1585 } 1586 1587 1588 /** 1589 * Get the footer text 1590 */ 1591 function get_footer_contents() 1592 { 1593 global $app_footer_text, $copyright_text; 1594 1595 return '<div class="footer">'.$app_footer_text.' – '.$copyright_text."</div>\n\n"; 1596 } 1597 } 1598 1599 /* 1600 * $Log: _adminUI_general.class.php,v $ 1601 * Revision 1.72 2007/11/02 02:37:37 fplanque 1602 * refactored blog settings / UI 1603 * 1604 * Revision 1.71 2007/09/29 03:08:24 fplanque 1605 * a little cleanup of the form class, hopefully fixing the plugin screen 1606 * 1607 * Revision 1.70 2007/09/28 09:28:36 fplanque 1608 * per blog advanced SEO settings 1609 * 1610 * Revision 1.69 2007/09/26 21:53:23 fplanque 1611 * file manager / file linking enhancements 1612 * 1613 * Revision 1.68 2007/09/18 00:00:59 fplanque 1614 * firefox mac specific forms 1615 * 1616 * Revision 1.67 2007/09/17 01:36:39 fplanque 1617 * look 'ma: just spent 5 hours on a smooth sized footer logo :P 1618 * 1619 * Revision 1.66 2007/09/11 08:21:29 yabs 1620 * minor bug fix 1621 * 1622 * Revision 1.65 2007/09/05 00:06:03 fplanque 1623 * no message 1624 * 1625 * Revision 1.64 2007/09/03 16:44:28 fplanque 1626 * chicago admin skin 1627 * 1628 * Revision 1.63 2007/07/16 02:53:04 fplanque 1629 * checking in mods needed by the chicago adminskin, 1630 * so that incompatibilities with legacy & evo can be detected early. 1631 * 1632 * Revision 1.62 2007/07/09 23:03:04 fplanque 1633 * cleanup of admin skins; especially evo 1634 * 1635 * Revision 1.61 2007/07/09 21:24:11 fplanque 1636 * cleanup of admin page top 1637 * 1638 * Revision 1.60 2007/06/25 11:02:33 fplanque 1639 * MODULES (refactored MVC) 1640 * 1641 * Revision 1.59 2007/06/24 22:35:57 fplanque 1642 * cleanup 1643 * 1644 * Revision 1.58 2007/06/24 15:43:34 personman2 1645 * Reworking the process for a skin or plugin to add js and css files to a blog display. Removed the custom header for nifty_corners. 1646 * 1647 * Revision 1.57 2007/06/20 19:13:42 blueyed 1648 * fixed doc 1649 * 1650 * Revision 1.56 2007/06/20 19:13:13 blueyed 1651 * doc 1652 * 1653 * Revision 1.55 2007/06/19 22:36:39 blueyed 1654 * doc 1655 * 1656 * Revision 1.54 2007/06/18 21:13:10 fplanque 1657 * minor 1658 * 1659 * Revision 1.53 2007/06/14 18:39:04 blueyed 1660 * Fixed E_NOTICE if there is no Blog available 1661 * 1662 * Revision 1.52 2007/05/31 03:02:24 fplanque 1663 * Advanced perms now disabled by default (simpler interface). 1664 * Except when upgrading. 1665 * Enable advanced perms in blog settings -> features 1666 * 1667 * Revision 1.51 2007/05/29 01:17:19 fplanque 1668 * advanced admin blog settings are now restricted by a special permission 1669 * 1670 * Revision 1.50 2007/05/14 02:51:18 fplanque 1671 * cleanup. 1672 * 1673 * Revision 1.49 2007/05/09 01:00:25 fplanque 1674 * optimized querying for blog lists 1675 * 1676 * Revision 1.48 2007/05/07 18:59:47 fplanque 1677 * renamed skin .page.php files to .tpl.php 1678 * 1679 * Revision 1.47 2007/04/26 00:11:03 fplanque 1680 * (c) 2007 1681 * 1682 * Revision 1.46 2007/03/20 09:53:26 fplanque 1683 * Letting boggers view their own stats. 1684 * + Letthing admins view the aggregate by default. 1685 * 1686 * Revision 1.45 2007/03/07 04:52:00 fplanque 1687 * Check perms while building the menu: 1688 * so much easier and so much more flexible 1689 * 1690 * Revision 1.44 2007/03/07 02:37:15 fplanque 1691 * OMG I decided that pregenerating the menus was getting to much of a PITA! 1692 * It's a zillion problems with the permissions. 1693 * This will be simplified a lot. Enough of these crazy stuff. 1694 * 1695 * Revision 1.43 2007/03/04 20:14:16 fplanque 1696 * GMT date now in system checks 1697 * 1698 * Revision 1.42 2007/03/04 05:24:53 fplanque 1699 * some progress on the toolbar menu 1700 * 1701 * Revision 1.41 2007/01/14 22:06:48 fplanque 1702 * support for customized 'no results' messages 1703 * 1704 * Revision 1.40 2007/01/14 17:26:11 blueyed 1705 * Fixed wrong TR around whole HEAD contents 1706 * 1707 * Revision 1.39 2006/12/12 19:39:08 fplanque 1708 * enhanced file links / permissions 1709 * 1710 * Revision 1.38 2006/12/12 16:42:23 fplanque 1711 * border-collapse sucks (firefox) 1712 * 1713 * Revision 1.37 2006/12/12 02:53:57 fplanque 1714 * Activated new item/comments controllers + new editing navigation 1715 * Some things are unfinished yet. Other things may need more testing. 1716 * 1717 * Revision 1.36 2006/12/03 01:58:27 blueyed 1718 * Renamed $admin_path_seprator to $admin_path_separator and AdminUI_general::pathSeperator to AdminUI::pathSeparator 1719 * 1720 * Revision 1.35 2006/11/27 19:14:14 fplanque 1721 * i18n 1722 * 1723 * Revision 1.34 2006/10/23 22:19:03 blueyed 1724 * Fixed/unified encoding of redirect_to param. Use just rawurlencode() and no funky & replacements 1725 * 1726 * Revision 1.33 2006/10/15 21:30:47 blueyed 1727 * Use url_rel_to_same_host() for redirect_to params. 1728 */ 1729 ?>
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
| Généré le : Thu Nov 29 23:58:50 2007 | par Balluche grâce à PHPXref 0.7 |
|