[ Index ] |
|
Code source de b2evolution 2.1.0-beta |
1 <?php 2 /** 3 * This file implements the Log class, which logs notes and errors. 4 * 5 * It additionally provides the class Log_noop that implements the same (used) methods, but as 6 * no-operation functions. This is useful to create a more resource friendly object when 7 * you don't need it (think Debuglog). 8 * 9 * This file is part of the evoCore framework - {@link http://evocore.net/} 10 * See also {@link http://sourceforge.net/projects/evocms/}. 11 * 12 * @copyright (c)2003-2007 by Francois PLANQUE - {@link http://fplanque.net/} 13 * Parts of this file are copyright (c)2004-2006 by Daniel HAHLER - {@link http://thequod.de/contact}. 14 * 15 * {@internal License choice 16 * - If you have received this file as part of a package, please find the license.txt file in 17 * the same folder or the closest folder above for complete license terms. 18 * - If you have received this file individually (e-g: from http://evocms.cvs.sourceforge.net/) 19 * then you must choose one of the following licenses before using the file: 20 * - GNU General Public License 2 (GPL) - http://www.opensource.org/licenses/gpl-license.php 21 * - Mozilla Public License 1.1 (MPL) - http://www.opensource.org/licenses/mozilla1.1.php 22 * }} 23 * 24 * {@internal Open Source relicensing agreement: 25 * Daniel HAHLER grants Francois PLANQUE the right to license 26 * Daniel HAHLER's contributions to this file and the b2evolution project 27 * under any OSI approved OSS license (http://www.opensource.org/licenses/). 28 * }} 29 * 30 * @package evocore 31 * 32 * @author blueyed: Daniel HAHLER 33 * @author fplanque: Francois PLANQUE 34 * 35 * @version $Id: _log.class.php,v 1.2 2007/09/23 18:55:17 fplanque Exp $ }}} 36 * 37 */ 38 if( !defined('EVO_MAIN_INIT') ) die( 'Please, do not access this page directly.' ); 39 40 41 /** 42 * Log class. Logs notes and errors. 43 * 44 * Messages can be logged into different categories (aka levels) 45 * Examples: 'note', 'error'. Note: 'all' is reserved to display all categories together. 46 * Messages can later be displayed grouped by category/level. 47 * 48 * @package evocore 49 */ 50 class Log 51 { 52 /** 53 * The stored messages (by category). 54 * array of arrays 55 * 56 * @var array 57 */ 58 var $messages = array(); 59 60 /** 61 * Default category for messages. 62 * @var string 63 */ 64 var $defaultcategory = 'error'; 65 66 /** 67 * string or array to display before messages 68 * @var mixed 69 */ 70 var $head = ''; 71 72 /** 73 * to display after messages 74 * @var string 75 */ 76 var $foot = ''; 77 78 /** 79 * Cache for {@link Log::count()} 80 * @var array 81 */ 82 var $_count = array(); 83 84 85 /** 86 * Constructor. 87 * 88 * @param string sets default category 89 */ 90 function Log( $category = 'error' ) 91 { 92 $this->defaultcategory = $category; 93 94 // create the array for this category 95 $this->messages[$category] = array(); 96 } 97 98 99 /** 100 * Clears the Log (all or specified category). 101 * 102 * @param string category, use 'all' to unset all categories 103 */ 104 function clear( $category = NULL ) 105 { 106 if( $category == 'all' ) 107 { 108 $this->messages = array(); 109 $this->_count = array(); 110 } 111 else 112 { 113 if( $category === NULL ) 114 { 115 $category = $this->defaultcategory; 116 } 117 unset( $this->messages[ $category ] ); 118 unset( $this->_count[$category] ); 119 unset( $this->_count['all'] ); 120 } 121 } 122 123 124 /** 125 * Add a message to the Log. 126 * 127 * @param string the message 128 * @param string|array the category, default is to use the object's default category. 129 * Can also be an array of categories to add the same message to. 130 * @param boolean Dump (output) this directly? 131 */ 132 function add( $message, $category = NULL ) 133 { 134 if( $category === NULL ) 135 { // By default, we use the default category: 136 $category = $this->defaultcategory; 137 } 138 139 if( is_array($category) ) 140 { 141 foreach( $category as $l_cat ) 142 { 143 $this->add( $message, $l_cat, false ); 144 } 145 } 146 else 147 { 148 $this->messages[$category][] = $message; 149 150 if( empty($this->_count[$category]) ) 151 { 152 $this->_count[$category] = 0; 153 } 154 $this->_count[$category]++; 155 } 156 } 157 158 159 /** 160 * Add an array of messages. 161 * 162 * @param array Array of messages where the keys are the categories and hold an array of messages. 163 */ 164 function add_messages( $messages ) 165 { 166 foreach( $messages as $l_cat => $l_messages ) 167 { 168 foreach( $l_messages as $l_message ) 169 { 170 $this->add( $l_message, $l_cat ); 171 } 172 } 173 } 174 175 176 /** 177 * Get head/foot for a specific category, designed for internal use of {@link display()} 178 * 179 * @static 180 * @access private 181 * 182 * @param mixed head or foot (array [ category => head/foot, category => 'string', 'template', 183 * or string [for container only]) 184 * @param string the category (or container) 185 * @param string template, where the head/foot gets used (%s) 186 */ 187 function get_head_foot( $headfoot, $category, $template = NULL ) 188 { 189 if( is_string($headfoot) && $category == 'container' ) 190 { // container head or foot 191 $r = $headfoot; 192 } 193 elseif( is_array($headfoot) ) 194 { // head or foot for categories 195 if( isset($headfoot[$category]) ) 196 { 197 $r = $headfoot[$category]; 198 } 199 elseif( isset($headfoot['all']) && $category != 'container' ) 200 { // use 'all' info, except if for container 201 $r = $headfoot['all']; 202 } 203 else 204 { 205 return false; 206 } 207 208 if( is_array($r) ) 209 { 210 if( isset($r['template']) ) 211 { 212 $template = $r['template']; 213 } 214 $r = $r['string']; 215 } 216 217 // Replace '%s' with category: 218 $r = str_replace( '%s', $category, $r ); 219 } 220 221 if( empty($r) ) 222 { 223 return false; 224 } 225 226 if( !empty($template) ) 227 { 228 $r = sprintf( $template, $r ); 229 } 230 231 return $r; 232 } 233 234 235 /** 236 * Wrapper to display messages as simple paragraphs. 237 * 238 * @param mixed the category of messages, see {@link display()}. NULL for default category. 239 * @param mixed the outer div, see {@link display()} 240 * @param mixed the css class for inner paragraphs 241 */ 242 function display_paragraphs( $category = 'all', $outerdivclass = 'panelinfo', $cssclass = NULL ) 243 { 244 if( is_null($cssclass) ) 245 { 246 $cssclass = array( 'all' => array( 'divClass' => false ) ); 247 } 248 return $this->display( '', '', true, $category, $cssclass, 'p', $outerdivclass ); 249 } 250 251 252 /** 253 * TEMPLATE TAG 254 * 255 * The purpose here is to have a tag which is simple yet flexible. 256 * the display function is WAAAY too bloated. 257 * 258 * @todo optimize 259 * 260 * @param string HTML to display before the log when there is something to display 261 * @param string HTML to display after the log when there is something to display 262 * @param boolean Skip if previewing? 263 * QUESTION: dh> This appears to not display e.g. errors which got inserted?!! 264 */ 265 function disp( $before = '<div class="action_messages">', $after = '</div>', $skip_if_preview = true ) 266 { 267 if( count($this->messages) ) 268 { 269 global $preview; 270 if( $preview ) 271 { 272 return; 273 } 274 275 $disp = $this->display( NULL, NULL, false, 'all', NULL, NULL, NULL ); 276 277 if( !empty( $disp ) ) 278 { 279 echo $before.$disp.$after; 280 } 281 } 282 } 283 284 285 /** 286 * Display messages of the Log object. 287 * 288 * - You can either output/get the messages of a category (string), 289 * all categories ('all') or category groups (array of strings) (defaults to 'all'). 290 * - Head/Foot will be displayed on top/bottom of the messages. You can pass 291 * an array as head/foot with the category as key and this will be displayed 292 * on top of the category's messages. 293 * - You can choose from various styles for message groups ('ul', 'p', 'br') 294 * and set a css class for it (by default 'log_'.$category gets used). 295 * - You can suppress the outer div or set a css class for it (defaults to 296 * 'log_container'). 297 * 298 * @todo Make this simple! 299 * start by getting rid of the $category selection and the special cases for 'all'. If you don't want to display ALL messages, 300 * then you should not log them in the same Log object and you should instantiate separate logs instead. 301 * 302 * @param string|NULL Header/title, might be array ( category => msg ), 303 * 'container' is then top. NULL for object's default ({@link Log::$head}. 304 * @param string|NULL Footer, might be array ( category => msg ), 'container' is then bottom. 305 * NULL for object's default ({@link Log::$foot}. 306 * @param boolean to display or return (default: display) 307 * @param mixed the category of messages to use (category, 'all', list of categories (array) 308 * or NULL for {@link $defaultcategory}). 309 * @param string the CSS class of the messages div tag (default: 'log_'.$category) 310 * @param string the style to use, 'ul', 'p', 'br' 311 * (default: 'br' for single message, 'ul' for more) 312 * @param mixed the outer div, may be false 313 * @return boolean false, if no messages; else true (and outputs if $display) 314 */ 315 function display( $head = NULL, $foot = NULL, $display = true, $category = 'all', $cssclass = NULL, $style = NULL, $outerdivclass = 'log_container' ) 316 { 317 if( is_null( $head ) ) 318 { // Use object default: 319 $head = isset( $this->head ) ? $this->head : ''; 320 } 321 if( is_null( $foot ) ) 322 { // Use object default: 323 $foot = isset( $this->foot ) ? $this->foot : ''; 324 } 325 if( is_null( $category ) ) 326 { 327 $category = isset( $this, $this->defaultcategory ) ? $this->defaultcategory : 'error'; 328 } 329 330 if( !$this->count( $category ) ) 331 { // no messages 332 return false; 333 } 334 else 335 { 336 $messages = $this->get_messages( $category ); 337 } 338 339 if( !is_array($cssclass) ) 340 { 341 $cssclass = array( 'all' => array( 'class' => is_null($cssclass) ? NULL : $cssclass, 'divClass' => true ) ); 342 } 343 elseif( !isset($cssclass['all']) ) 344 { 345 $cssclass['all'] = array( 'class' => NULL, 'divClass' => true ); 346 } 347 348 349 $disp = ''; 350 351 if( $outerdivclass ) 352 { 353 $disp .= "\n<div class=\"$outerdivclass\">"; 354 } 355 356 $disp .= Log::get_head_foot( $head, 'container', '<h2>%s</h2>' ); 357 358 359 foreach( $messages as $lcategory => $lmessages ) 360 { 361 $lcssclass = isset($cssclass[$lcategory]) ? $cssclass[$lcategory] : $cssclass['all']; 362 if( !isset($lcssclass['class']) || is_null($lcssclass['class']) ) 363 { 364 $lcssclass['class'] = 'log_'.$lcategory; 365 } 366 if( !isset($lcssclass['divClass']) || is_null($lcssclass['divClass']) || $lcssclass['divClass'] === true ) 367 { 368 $lcssclass['divClass'] = $lcssclass['class']; 369 } 370 371 372 $disp .= "\n"; 373 if( $lcssclass['divClass'] ) 374 { 375 $disp .= "\t<div class=\"{$lcssclass['divClass']}\">"; 376 } 377 378 $disp .= Log::get_head_foot( $head, $lcategory, '<h3>%s</h3>' ); 379 380 if( $style == NULL ) 381 { // 'br' for a single message, 'ul' for more 382 $style = count($lmessages) == 1 ? 'br' : 'ul'; 383 } 384 385 // implode messages 386 if( $style == 'ul' ) 387 { 388 $disp .= "\t<ul".( $lcssclass['class'] ? " class=\"{$lcssclass['class']}\"" : '' ).'>' 389 .'<li class="clear">' // "clear" to fix Konqueror (http://bugs.kde.org/show_bug.cgi?id=117509) 390 .implode( "</li>\n<li>", $lmessages )."</li></ul>\n"; 391 } 392 elseif( $style == 'p' ) 393 { 394 $disp .= "\t<p".( $lcssclass['class'] ? " class=\"{$lcssclass['class']}\"" : '' ).'>' 395 .implode( "</p>\n<p class=\"{$lcssclass['class']}\">", $lmessages )."</p>\n"; 396 } 397 else 398 { 399 $disp .= "\t".implode( "\n<br />\t", $lmessages ); 400 } 401 $disp .= Log::get_head_foot( $foot, $lcategory, "\n<p>%s</p>" ); 402 if( $lcssclass['divClass'] ) 403 { 404 $disp .= "\t</div>\n"; 405 } 406 } 407 408 $disp .= Log::get_head_foot( $foot, 'container', "\n<p>%s</p>" ); 409 410 if( $outerdivclass ) 411 { 412 $disp .= "</div>\n"; 413 } 414 415 if( $display ) 416 { 417 echo $disp; 418 return true; 419 } 420 421 return $disp; 422 } 423 424 425 /** 426 * Concatenates messages of a given category to a string 427 * 428 * @param string prefix of the string 429 * @param string suffic of the string 430 * @param string the category 431 * @return string the messages, imploded. Tags stripped. 432 */ 433 function get_string( $head = '', $foot = '', $category = NULL, $implodeBy = ', ' ) 434 { 435 if( !$this->count( $category ) ) 436 { 437 return false; 438 } 439 440 $r = ''; 441 if( '' != $head ) 442 { 443 $r .= $head.' '; 444 } 445 $r .= implode( $implodeBy, $this->get_messages( $category, true ) ); 446 if( '' != $foot ) 447 { 448 $r .= ' '.$foot; 449 } 450 451 return strip_tags( $r ); 452 } 453 454 455 /** 456 * Counts messages of a given category 457 * 458 * @todo this seems a bit weird (not really relying on the cache ($_count) and unsetting 'all') -> write testcases to safely be able to change it. 459 * @param string|array the category, NULL=default, 'all' = all 460 * @return number of messages 461 */ 462 function count( $category = NULL ) 463 { 464 if( is_null($category) ) 465 { // use default category: 466 $category = $this->defaultcategory; 467 } 468 469 if( is_string($category) ) 470 { 471 if( empty( $this->_count[$category] ) ) 472 { 473 $this->_count[$category] = count( $this->get_messages( $category, true ) ); 474 } 475 if( $category != 'all' ) 476 { 477 unset($this->_count['all']); 478 } 479 return $this->_count[$category]; 480 } 481 482 return count( $this->get_messages( $category, true ) ); 483 } 484 485 486 /** 487 * Returns array of messages of a single category or group of categories. 488 * 489 * If the category is an array, those categories will be used (where 'all' will 490 * be translated with the not already processed categories). 491 * <code>get_messages( array('error', 'note', 'all') )</code> would return 492 * 'errors', 'notes' and the remaining messages, in that order. 493 * 494 * @param string|array the category, NULL=default, 'all' = all 495 * @param boolean if true will use subarrays for each category 496 * @return array the messages, one or two dimensions (depends on second param) 497 */ 498 function get_messages( $category = NULL, $singleDimension = false ) 499 { 500 $messages = array(); 501 502 if( is_null($category) ) 503 { 504 $category = $this->defaultcategory; 505 } 506 507 if( $category == 'all' ) 508 { 509 $category = array_keys( $this->messages ); 510 sort($category); 511 } 512 elseif( !is_array($category) ) 513 { 514 $category = array( $category ); 515 } 516 517 $categoriesDone = array(); 518 519 while( $lcategory = array_shift( $category ) ) 520 { 521 if( $lcategory == 'all' ) 522 { // Put those categories in queue, which have not been processed already 523 $category = array_merge( array_diff( array_keys( $this->messages ), $categoriesDone ), $category ); 524 sort($category); 525 continue; 526 } 527 if( in_array( $lcategory, $categoriesDone ) ) 528 { 529 continue; 530 } 531 $categoriesDone[] = $lcategory; 532 533 534 if( !isset($this->messages[$lcategory][0]) ) 535 { // no messages 536 continue; 537 } 538 539 if( $singleDimension ) 540 { 541 $messages = array_merge( $messages, $this->messages[$lcategory] ); 542 } 543 else 544 { 545 $messages[$lcategory] = $this->messages[$lcategory]; 546 } 547 } 548 return $messages; 549 } 550 551 } 552 553 554 /** 555 * This is a no-operation implementation of {@link Log}. 556 * 557 * It just implements the used methods {@link get()} and {@link display()}. 558 * 559 * @package evocore 560 */ 561 class Log_noop { 562 /** 563 * This is a no-operation method. 564 */ 565 function add() 566 { 567 } 568 569 /** 570 * This is a no-operation method. 571 */ 572 function add_messages() 573 { 574 } 575 576 577 /** 578 * This is a no-operation method. 579 */ 580 function clear() 581 { 582 } 583 584 585 /** 586 * This is a no-operation method. 587 */ 588 function count() 589 { 590 } 591 592 593 /** 594 * This is a no-operation method. 595 */ 596 function disp() 597 { 598 } 599 600 601 /** 602 * This is a no-operation method. 603 */ 604 function display() 605 { 606 } 607 608 609 /** 610 * This is a no-operation method. 611 */ 612 function display_paragraphs() 613 { 614 } 615 616 617 /** 618 * This is a no-operation method. 619 */ 620 function get_messages() 621 { 622 return array(); 623 } 624 625 626 /** 627 * This is a no-operation method. 628 */ 629 function get_string() 630 { 631 return ''; 632 } 633 } 634 635 /* 636 * $Log: _log.class.php,v $ 637 * Revision 1.2 2007/09/23 18:55:17 fplanque 638 * attempting to debloat. The Log class is insane. 639 * 640 * Revision 1.1 2007/06/25 10:58:55 fplanque 641 * MODULES (refactored MVC) 642 * 643 * Revision 1.19 2007/06/19 23:22:28 blueyed 644 * doc fixes 645 * 646 * Revision 1.18 2007/06/16 19:20:38 blueyed 647 * doc/question 648 * 649 * Revision 1.17 2007/05/07 18:03:28 fplanque 650 * cleaned up skin code a little 651 * 652 * Revision 1.16 2007/04/26 00:11:08 fplanque 653 * (c) 2007 654 * 655 * Revision 1.15 2007/01/13 22:28:12 fplanque 656 * doc 657 * 658 * Revision 1.14 2006/12/07 23:13:13 fplanque 659 * @var needs to have only one argument: the variable type 660 * Otherwise, I can't code! 661 * 662 * Revision 1.13 2006/11/30 00:28:13 blueyed 663 * Interface fixes for Log_noop 664 * 665 * Revision 1.12 2006/11/24 18:27:27 blueyed 666 * Fixed link to b2evo CVS browsing interface in file docblocks 667 */ 668 ?>
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 |
![]() |