1<?php 2/* 3 * e107 website system 4 * 5 * Copyright (C) 2008-2012 e107 Inc (e107.org) 6 * Released under the terms and conditions of the 7 * GNU General Public License (http://www.gnu.org/licenses/gpl.txt) 8 * 9 * Message Handler 10 * 11 * $URL$ 12 * $Id$ 13 * 14*/ 15 16if (!defined('e107_INIT')) { exit; } 17 18/* 19 * Type defines 20 */ 21define('E_MESSAGE_INFO', 'info'); 22define('E_MESSAGE_SUCCESS', 'success'); 23define('E_MESSAGE_WARNING', 'warning'); 24define('E_MESSAGE_ERROR', 'error'); 25define('E_MESSAGE_DEBUG', 'debug'); 26define('E_MESSAGE_NODISPLAY', 'nodisplay'); // Appears to be needed by update_routine 27 28//FIXME - language file! new? 29 30/** 31 * Handle system messages 32 * 33 * @package e107 34 * @subpackage e107_handlers 35 * @version $Id$ 36 * @author SecretR 37 * @copyright Copyright (C) 2008-2010 e107 Inc (e107.org) 38 */ 39class eMessage 40{ 41 /** 42 * Type defines 43 */ 44 const E_INFO = 'info'; 45 const E_SUCCESS = 'success'; 46 const E_WARNING = 'warning'; 47 const E_ERROR = 'error'; 48 const E_DEBUG = 'debug'; 49 const E_NODISPLAY = 'nodisplay'; 50 51 52 /** 53 * System Message Array 54 * in format [type][message_stack] = array(message[, ...]) 55 * 56 * @var array 57 */ 58 protected $_sysmsg = array(); 59 60 /** 61 * Session key for storing session messages 62 * 63 * @var string 64 */ 65 protected $_session_id; 66 67 /** 68 * @var e_core_session 69 */ 70 protected $_session_handler = null; 71 72 /** 73 * @var array 74 */ 75 protected $_unique = array(); 76 77 /** 78 * @var array 79 */ 80 static $_customTitle = array(); 81 82 /** 83 * Custom font-awesome icon 84 * @var array 85 */ 86 static $_customIcon = array(); 87 88 89 static $_close = array('info'=>true,'success'=>true,'warning'=>true,'error'=>true,'debug'=>true); 90 /** 91 * Singleton instance 92 * 93 * @var eMessage 94 */ 95 //protected static $_instance = null; 96 97 /** 98 * Constructor 99 * 100 * Use {@link getInstance()}, direct instantiating 101 * is not possible for signleton objects 102 * 103 * @return void 104 */ 105 public function __construct() 106 { 107 //if(!session_id()) session_start(); 108 109 // require_once(e_HANDLER.'e107_class.php'); 110 $this->_session_id = '_system_messages'; 111 112 $this->reset()->mergeWithSession(); 113 } 114 115 /** 116 * Cloning is not allowed 117 * 118 */ 119 // private function __clone() 120 // { 121 // } 122 123 /** 124 * Singleton is not required, we go for factory instead 125 * @return eMessage 126 */ 127 public static function getInstance() 128 { 129 // if(null == self::$_instance) 130 // { 131 // self::$_instance = new self(); 132 // } 133 return e107::getMessage(); 134 } 135 136 /** 137 * Set message session id 138 * @param string $name 139 * @return eMessage 140 */ 141 public function setSessionId($name = '') 142 { 143 $sid = $name.'_system_messages'; 144 if($this->_session_id != $sid) 145 { 146 if(session_id()) 147 { 148 $session = $this->getSessionHandler(); 149 $session->set($sid, $session->get($this->_session_id, true)); // move 150 if(!$session->has($sid)) $session->set($sid, array()); // be sure it's array 151 } 152 $this->_session_id = $sid; 153 } 154 return $this; 155 } 156 157 /** 158 * Get session handler 159 * @return e_core_session 160 */ 161 public function getSessionHandler() 162 { 163 if(null === $this->_session_handler) 164 { 165 $session = e107::getSession(); 166 if(!$session->has($this->_session_id)) $session->set($this->_session_id, array()); 167 $this->_session_handler = $session; 168 } 169 return $this->_session_handler; 170 } 171 172 173 /** 174 * Set unique message stacks 175 * @param string $mstack message stack which should have only unique message values 176 * @return eMessage 177 */ 178 public function setUnique($mstack='default') 179 { 180 if(!in_array($mstack, $this->_unique)) 181 { 182 $this->_unique[] = $mstack; 183 } 184 return $this; 185 } 186 187 188 /** 189 * Add message to a type stack and default message stack 190 * If $message is array, $message[0] will be the message stack and 191 * $message[1] the message itself 192 * 193 * @param string|array $message 194 * @param string $type 195 * @param boolean $session 196 * @return eMessage 197 */ 198 public function add($message, $type = eMessage::E_INFO, $session = false) 199 { 200 if(empty($message)) return $this; 201 202 $mstack = 'default'; 203 $msg = $message; 204 if(is_array($message)) 205 { 206 $mstack = $message[1]; 207 $msg = $message[0]; 208 } 209 if(empty($msg)) return $this; 210 211 if(!$session) 212 { 213 // unique messages only 214 if(in_array($mstack, $this->_unique) && isset($this->_sysmsg[$type][$mstack]) && in_array($msg, $this->_sysmsg[$type][$mstack])) return $this; 215 if($this->isType($type)) $this->_sysmsg[$type][$mstack][] = $msg; 216 return $this; 217 } 218 219 $this->addSession($message, $type); 220 return $this; 221 } 222 223 /** 224 * Alias of {@link add()}. 225 * Should be used for dealing with messages with custom message stacks. 226 * Supports message arrays. 227 * 228 * @param string|array $message message(s) 229 * @param string $mstack defaults to 'default' 230 * @param string $type [optional] 231 * @param boolean $session [optional] 232 * @return eMessage 233 */ 234 public function addStack($message, $mstack = 'default', $type = E_MESSAGE_INFO, $session = false) 235 { 236 if(!is_array($message)) 237 { 238 $message = array($message); 239 } 240 241 foreach ($message as $m) 242 { 243 $this->add(array($m, $mstack), $type, $session); 244 } 245 return $this; 246 } 247 248 /** 249 * Add success message 250 * 251 * @param string $message 252 * @param string $mstack message stack, default value is 'default' 253 * @param boolean $session 254 * @return eMessage 255 */ 256 public function addSuccess($message, $mstack = 'default', $session = false) 257 { 258 return $this->addStack($message, $mstack, E_MESSAGE_SUCCESS, $session); 259 } 260 261 /** 262 * Add error message 263 * 264 * @param string $message 265 * @param string $mstack message stack, default value is 'default' 266 * @param boolean $session 267 * @return eMessage 268 */ 269 public function addError($message, $mstack = 'default', $session = false) 270 { 271 return $this->addStack($message, $mstack, E_MESSAGE_ERROR, $session); 272 } 273 274 /** 275 * Add warning message 276 * 277 * @param string $message 278 * @param string $mstack message stack, default value is 'default' 279 * @param boolean $session 280 * @return eMessage 281 */ 282 public function addWarning($message, $mstack = 'default', $session = false) 283 { 284 return $this->addStack($message, $mstack, E_MESSAGE_WARNING, $session); 285 } 286 287 /** 288 * Add info message 289 * 290 * @param string $message 291 * @param string $mstack message stack, default value is 'default' 292 * @param boolean $session 293 * @return eMessage 294 */ 295 public function addInfo($message, $mstack = 'default', $session = false) 296 { 297 return $this->addStack($message, $mstack, E_MESSAGE_INFO, $session); 298 } 299 300 /** 301 * Add debug message 302 * 303 * @param string $message 304 * @param string $mstack message stack, default value is 'default' 305 * @param boolean $session 306 * @return eMessage 307 */ 308 public function addDebug($message, $mstack = 'default', $session = false) //TODO Add different types of DEBUG depending on the debug mode. 309 { 310 return $this->addStack($message, $mstack, E_MESSAGE_DEBUG, $session); 311 } 312 313 /** 314 * Add message to a _SESSION type stack 315 * If $message is array, $message[0] will be the message stack and 316 * $message[1] the message itself 317 * 318 * @param string|array $message 319 * @param string $type 320 * @return eMessage 321 */ 322 public function addSession($message, $type = E_MESSAGE_INFO) 323 { 324 if(empty($message) || !session_id()) return $this; 325 326 $mstack = 'default'; 327 if(is_array($message)) 328 { 329 $mstack = $message[1]; 330 $message = $message[0]; 331 } 332 $SESSION = $this->getSessionHandler()->get($this->_session_id); 333 334 if($this->isType($type)) 335 { 336 // unique messages only 337 if(in_array($mstack, $this->_unique) && in_array($message, $SESSION[$type][$mstack])) return $this; 338 339 $SESSION[$type][$mstack][] = $message; 340 $this->getSessionHandler()->set($this->_session_id, $SESSION); 341 } 342 return $this; 343 } 344 345 /** 346 * Alias of {@link addSession()}. 347 * Should be used for dealing with messages with custom message stacks. 348 * Supports message arrays. 349 * 350 * @param string|array $message message(s) 351 * @param string $mstack defaults to 'default' 352 * @param string $type [optional] 353 * @return eMessage 354 */ 355 public function addSessionStack($message, $mstack = 'default', $type = E_MESSAGE_INFO) 356 { 357 if(!is_array($message)) 358 { 359 $message = array($message); 360 } 361 foreach ($message as $m) 362 { 363 $this->addSession(array($m, $mstack), $type); 364 } 365 return $this; 366 } 367 368 /** 369 * Get type title (multi-language) 370 * 371 * @param string $type 372 * @param string $message_stack 373 * @return string title 374 */ 375 public static function getTitle($type, $message_stack = 'default') 376 { 377 if(!empty(self::$_customTitle[$type])) 378 { 379 return self::$_customTitle[$type]; 380 } 381 382 if($message_stack && $message_stack != 'default' && defined('EMESSLAN_TITLE_'.strtoupper($type.'_'.$message_stack))) 383 { 384 return constant('EMESSLAN_TITLE_'.strtoupper($type.'_'.$message_stack)); 385 } 386 return deftrue('EMESSLAN_TITLE_'.strtoupper($type), ''); 387 } 388 389 390 /** 391 * Set a custom title/caption (useful for front-end) 392 * 393 * @param string $title 394 * @param string $type E_MESSAGE_SUCCESS,E_MESSAGE_ERROR, E_MESSAGE_WARNING, E_MESSAGE_INFO 395 * @return $this 396 * @example e107::getMessage()->setTitle('Custom Title', E_MESSAGE_INFO); 397 */ 398 public function setTitle($title, $type) 399 { 400 $tp = e107::getParser(); 401 self::$_customTitle[$type] = $tp->toText($title); 402 403 return $this; 404 } 405 406 /** 407 * Set a custom icon (useful for front-end) 408 * 409 * @param string $fa FontAwesome reference. eg. fa-cog 410 * @param string $type E_MESSAGE_SUCCESS,E_MESSAGE_ERROR, E_MESSAGE_WARNING, E_MESSAGE_INFO 411 * @return $this 412 * @example e107::getMessage()->setIcon('fa-cog', E_MESSAGE_INFO); 413 */ 414 public function setIcon($fa, $type) 415 { 416 $tp = e107::getParser(); 417 self::$_customIcon[$type] = $tp->toText($fa); 418 419 return $this; 420 } 421 422 423 /** 424 * Enable the 'x' close functionality of an alert. 425 * 426 * @param boolean $toggle 427 * @param string $type E_MESSAGE_SUCCESS,E_MESSAGE_ERROR, E_MESSAGE_WARNING, E_MESSAGE_INFO 428 * @return $this 429 * @example e107::getMessage()->setClose(false, E_MESSAGE_INFO); 430 */ 431 public function setClose($toggle, $type) 432 { 433 self::$_close[$type] = $toggle; 434 return $this; 435 } 436 437 438 439 /** 440 * Message getter 441 * 442 * @param string $type valid type 443 * @param string $mstack message stack name 444 * @param bool $raw force array return 445 * @param bool $reset reset message type stack 446 * @return string|array message 447 */ 448 public function get($type, $mstack = 'default', $raw = false, $reset = true) 449 { 450 $message = isset($this->_sysmsg[$type][$mstack]) ? $this->_sysmsg[$type][$mstack] : ''; 451 if($reset) $this->reset($type, $mstack, false); 452 453 return (true === $raw ? $message : self::formatMessage($mstack, $type, $message)); 454 } 455 456 /** 457 * Get all messages for a stack 458 * 459 * @param string $mstack message stack name 460 * @param bool $raw force array return 461 * @param bool $reset reset message type stack 462 * @return array messages 463 */ 464 public function getAll($mstack = 'default', $raw = false, $reset = true) 465 { 466 $ret = array(); 467 foreach ($this->_get_types() as $type) 468 { 469 $message = $this->get($type, $mstack, $raw, $reset); 470 if(!empty($message)) 471 { 472 $ret[$type] = $message; 473 } 474 } 475 476 return $ret; 477 } 478 479 /** 480 * Session message getter 481 * 482 * @param string $type valid type 483 * @param string $mstack message stack 484 * @param bool $raw force array return 485 * @param bool $reset reset session message type stack 486 * @return string|array session message 487 */ 488 public function getSession($type, $mstack = 'default', $raw = false, $reset = true) 489 { 490 if(!session_id()) return null; 491 $SESSION = $this->getSessionHandler()->get($this->_session_id); 492 $message = isset($SESSION[$type][$mstack]) ? $SESSION[$type][$mstack] : ''; 493 if($reset) $this->resetSession($type, $mstack); 494 495 return (true === $raw ? $message : self::formatMessage($mstack, $type, $message)); 496 } 497 498 /** 499 * Get all session messages for a stack 500 * 501 * @param string $mstack message stack name 502 * @param bool $raw force array return 503 * @param bool $reset reset message type stack 504 * @return array session messages 505 */ 506 public function getAllSession($mstack = 'default', $raw = false, $reset = true) 507 { 508 if(!session_id()) return array(); 509 $ret = array(); 510 foreach ($this->_get_types() as $type) 511 { 512 $message = $this->getSession($type, $mstack, $raw, $reset); 513 if(!empty($message)) 514 { 515 $ret[$type] = $message; 516 } 517 } 518 519 return $ret; 520 } 521 522 /** 523 * Output all accumulated messages OR a specific type of messages. eg. 'info', 'warning', 'error', 'success' 524 * 525 * @param string $mstack message stack name 526 * @param bool|string $options - true : merge with session messages or enter a type 'info', 'warning', 'error', 'success' 527 * @param bool $reset reset all messages 528 * @param bool $raw force return type array 529 * @return array|string messages 530 */ 531 public function render($mstack = 'default', $options = false, $reset = true, $raw = false) 532 { 533 if($options === true ) 534 { 535 $this->mergeWithSession(true, $mstack); 536 } 537 $ret = array(); 538 539 $typesArray = (is_string($options) && in_array($options, $this->_get_types())) ? array($options) : $this->_get_types(); 540 541 foreach ($typesArray as $type) 542 { 543 if(E_MESSAGE_DEBUG === $type && (!deftrue('E107_DEBUG_LEVEL') || !ADMIN)) 544 { 545 continue; 546 } 547 $message = $this->get($type, $mstack, $raw); 548 549 if(!empty($message)) 550 { 551 $ret[$type] = $message; 552 } 553 } 554 555 if($reset) $this->reset(false, $mstack); 556 if(true === $raw || empty($ret)) return ($raw ? $ret : ''); 557 558 559 return " 560 <div class='s-message'> 561 ".implode("\n", $ret)." 562 </div> 563 "; 564 } 565 566 /** 567 * Create message block markup based on its type. 568 * 569 * @param string $mstack 570 * @param string $type 571 * @param array|string $message 572 * @return string 573 */ 574 public static function formatMessage($mstack, $type, $message) 575 { 576 $bstrap = array('info'=>'alert-info','error'=>'alert-error alert-danger','warning'=>'alert-warning','success'=>'alert-success','debug'=>'alert-warning'); 577 $bclass = vartrue($bstrap[$type]) ? " ".$bstrap[$type] : ""; 578 579 if (empty($message)) 580 { 581 return ''; 582 } 583 elseif (is_array($message)) 584 { 585 // XXX quick fix disabled because of various troubles - fix attempt made inside pref handler (the source of the problem) 586 // New feature added - setUnique($mstack) -> array_unique only for given message stacks 587 //$message = array_unique($message); // quick fix for duplicates. 588 $message = "<div class='s-message-item'>".implode("</div>\n<div class='s-message-item'>", $message)."</div>"; 589 } 590 591 $icon = !empty(self::$_customIcon[$type]) ? "s-message-empty fa fa-2x ".self::$_customIcon[$type] : "s-message-".$type; 592 593 594 $text = "<div class='s-message alert alert-block alert-dismissible fade in show {$type} {$bclass}' role='alert'>"; 595 $text .= (self::$_close[$type] === true) ? "<a class='close' data-dismiss='alert' aria-label='".LAN_CLOSE."'>×</a>" : ""; 596 $text .= "<i class='s-message-icon ".$icon."'></i> 597 <h4 class='s-message-title'>".self::getTitle($type, $mstack)."</h4> 598 <div class='s-message-body'> 599 {$message} 600 </div> 601 </div> 602 "; 603 604 605 return $text; 606 } 607 608 /** 609 * Reset message array 610 * 611 * @param mixed $type false for reset all or type string 612 * @param mixed $mstack false for reset all or stack name string 613 * @param boolean $session reset session messages as well 614 * @return eMessage 615 */ 616 public function reset($type = false, $mstack = false, $session = false) 617 { 618 if(false === $type) 619 { 620 if(false === $mstack) 621 { 622 $this->_sysmsg = $this->_type_map(); 623 } 624 elseif(is_array($this->_sysmsg)) 625 { 626 foreach ($this->_sysmsg as $t => $_mstack) 627 { 628 if(is_array($_mstack)) 629 { 630 unset($this->_sysmsg[$t][$mstack]); 631 } 632 } 633 } 634 } 635 elseif(isset($this->_sysmsg[$type])) 636 { 637 if(false === $mstack) 638 { 639 $this->_sysmsg[$type] = array(); 640 } 641 elseif(is_array($this->_sysmsg[$type])) 642 { 643 unset($this->_sysmsg[$type][$mstack]); 644 } 645 } 646 647 if($session) $this->resetSession($type, $mstack); 648 649 return $this; 650 } 651 652 /** 653 * Reset _SESSION message array 654 * 655 * @param mixed $type false for reset all, or valid type constant 656 * @param mixed $mstack false for reset all or stack name string 657 * @return eMessage 658 */ 659 public function resetSession($type = false, $mstack = false) 660 { 661 if(!session_id()) return $this; 662 $SESSION = $this->getSessionHandler()->get($this->_session_id); 663 if(false === $type) 664 { 665 if(false === $mstack) 666 { 667 $SESSION = $this->_type_map(); 668 } 669 elseif($SESSION) 670 { 671 foreach ($SESSION as $t => $_mstack) 672 { 673 if(is_array($_mstack)) 674 { 675 unset($SESSION[$t][$mstack]); 676 } 677 } 678 } 679 } 680 elseif(isset($SESSION[$type])) 681 { 682 if(false === $mstack) 683 { 684 $SESSION[$type] = array(); 685 } 686 elseif(is_array($SESSION[$type])) 687 { 688 unset($SESSION[$type][$mstack]); 689 } 690 } 691 $this->getSessionHandler()->set($this->_session_id, $SESSION); 692 return $this; 693 } 694 695 /** 696 * Merge _SESSION message array with the current messages 697 * 698 * @param boolean $reset 699 * @param boolean $mstack 700 * @return eMessage 701 */ 702 public function mergeWithSession($reset = true, $mstack = false) 703 { 704 // do nothing if there is still no session 705 if(!session_id()) return $this; 706 $SESSION = $this->getSessionHandler()->get($this->_session_id); 707 708 if(!empty($SESSION)) 709 { 710 foreach (array_keys($SESSION) as $type) 711 { 712 if(!$this->isType($type)) 713 { 714 unset($SESSION[$type]); 715 continue; 716 } 717 if(false === $mstack) 718 { 719 $this->_sysmsg[$type] = array_merge_recursive($this->_sysmsg[$type], $SESSION[$type]); 720 continue; 721 } 722 723 if(isset($SESSION[$type][$mstack])) 724 { 725 $this->_sysmsg[$type][$mstack] = $SESSION[$type][$mstack]; 726 } 727 } 728 $this->getSessionHandler()->set($this->_session_id, $SESSION); 729 } 730 if($reset) $this->resetSession(false, $mstack); 731 return $this; 732 } 733 734 /** 735 * Convert current messages to Session messages 736 * 737 * @param bool $mstack false - move all message stacks 738 * @param bool $message_type false - move all types 739 * @return eMessage 740 */ 741 public function moveToSession($mstack = false, $message_type = false) 742 { 743 // do nothing if there is still no session 744 if(!session_id()) return $this; 745 $SESSION = $this->getSessionHandler()->get($this->_session_id); 746 747 foreach (array_keys($this->_sysmsg) as $type) 748 { 749 if(!$this->isType($type) || ($message_type && $message_type !== $type)) 750 { 751 unset($this->_sysmsg[$type]); 752 continue; 753 } 754 if(false === $mstack) 755 { 756 $SESSION[$type] = array_merge_recursive($SESSION[$type], $this->_sysmsg[$type]); 757 continue; 758 } 759 760 if(isset($this->_sysmsg[$type][$mstack])) 761 { 762 $SESSION[$type][$mstack] = $this->_sysmsg[$type][$mstack]; 763 } 764 } 765 $this->getSessionHandler()->set($this->_session_id, $SESSION); 766 $this->reset($message_type, $mstack, false); 767 return $this; 768 } 769 770 /** 771 * Merge messages from source stack with destination stack 772 * and reset source stack 773 * 774 * @param string $from_stack source stack 775 * @param string $to_stack [optional] destination stack 776 * @param bool $type [optional] merge for a given type only 777 * @param bool $session [optional] merge session as well 778 * @return eMessage 779 */ 780 public function moveStack($from_stack, $to_stack = 'default', $type = false, $session = true) 781 { 782 if($from_stack == $to_stack) return $this; 783 foreach ($this->_sysmsg as $_type => $stacks) 784 { 785 if($type && $type !== $_type) 786 { 787 continue; 788 } 789 790 if(isset($stacks[$from_stack])) 791 { 792 if(!isset($this->_sysmsg[$_type][$to_stack])) 793 { 794 $this->_sysmsg[$_type][$to_stack] = array(); 795 } 796 if(in_array($from_stack, $this->_unique)) 797 { 798 // check the destination stack messages, remove duplicates 799 foreach ($this->_sysmsg[$_type][$from_stack] as $i => $_m) 800 { 801 if(in_array($_m, $this->_sysmsg[$_type][$to_stack])) unset($this->_sysmsg[$_type][$from_stack][$i]); 802 } 803 } 804 $this->_sysmsg[$_type][$to_stack] = array_merge($this->_sysmsg[$_type][$to_stack], $this->_sysmsg[$_type][$from_stack]); 805 unset($this->_sysmsg[$_type][$from_stack]); 806 } 807 } 808 809 if($session) $this->moveSessionStack($from_stack, $to_stack, $type); 810 811 return $this; 812 } 813 814 /** 815 * Merge session messages from source stack with destination stack 816 * and reset source stack 817 * 818 * @param string $from_stack source stack 819 * @param string $to_stack [optional] destination stack 820 * @param string|bool $type [optional] merge for a given type only 821 * @return eMessage 822 */ 823 public function moveSessionStack($from_stack, $to_stack = 'default', $type = false) 824 { 825 // do nothing if there is still no session 826 if(!session_id() || $from_stack == $to_stack) return $this; 827 $SESSION = $this->getSessionHandler()->get($this->_session_id); 828 829 foreach ($SESSION as $_type => $stacks) 830 { 831 if($type && $type !== $_type) 832 { 833 continue; 834 } 835 if(isset($stacks[$from_stack])) 836 { 837 if(!isset($SESSION[$_type][$to_stack])) 838 { 839 $SESSION[$_type][$to_stack] = array(); 840 } 841 $SESSION[$_type][$to_stack] = array_merge($SESSION[$_type][$to_stack], $this->_sysmsg[$_type][$from_stack]); 842 unset($SESSION[$_type][$from_stack]); 843 } 844 } 845 $this->getSessionHandler()->set($this->_session_id, $SESSION); 846 847 return $this; 848 } 849 850 /** 851 * Check passed type against the type map 852 * 853 * @param mixed $type 854 * @return boolean 855 */ 856 public function isType($type) 857 { 858 return (array_key_exists($type, $this->_type_map())); 859 } 860 861 /** 862 * Check for messages 863 * 864 * @param mixed $type 865 * @param string|bool $mstack 866 * @param boolean $session 867 * @return boolean 868 */ 869 public function hasMessage($type = false, $mstack = false, $session = true) 870 { 871 if(!$mstack) $mstack = 'default'; 872 873 if(false === $type) 874 { 875 foreach ($this->_get_types() as $_type) 876 { 877 if($this->get($_type, $mstack, true, false) || ($session && $this->getSession($_type, $mstack, true, false))) 878 { 879 return true; 880 } 881 } 882 } 883 return ($this->get($type, $mstack, true, false) || ($session && $this->getSession($type, $mstack, true, false))); 884 } 885 886 /** 887 * Balnk type array structure 888 * 889 * @return array type map 890 */ 891 protected function _type_map() 892 { 893 //show them in this order! 894 return array( 895 E_MESSAGE_ERROR => array(), 896 E_MESSAGE_WARNING => array(), 897 E_MESSAGE_SUCCESS => array(), 898 E_MESSAGE_INFO => array(), 899 E_MESSAGE_DEBUG => array() 900 ); 901 } 902 903 /** 904 * Get all valid message types 905 * 906 * @return array valid message types 907 */ 908 protected function _get_types() 909 { 910 return array_keys($this->_type_map()); 911 } 912 913 /** 914 * Proxy for undefined methods. It allows quick (less arguments) 915 * call to {@link addStack()}. 916 * Name of the method should equal to valid eMessage type - {@link _type_map()} 917 * 918 * Example: 919 * <code> 920 * e107::getMessage()->success('Success', false); 921 * //calls internal $this->addStack('Success', E_MESSAGE_SUCCESS, false); 922 * </code> 923 * @param string $method valid message type 924 * @param array $arguments array(0 => (string) message, [optional] 1 =>(boolean) session, [optional] 2=> message stack ) 925 * @return eMessage 926 * @throws Exception 927 */ 928 function __call($method, $arguments) { 929 if($this->isType($method)) 930 { 931 $this->addStack($arguments[0], vartrue($arguments[2], 'default'), $method, (isset($arguments[1]) && !empty($arguments[1]))); 932 return $this; 933 } 934 throw new Exception('Method eMessage::'.$method.' does not exist!');//FIXME - e107Exception handler 935 } 936 937 938 939 /** 940 * Automate DB system messages 941 * NOTE: default value of $output parameter will be changed to false (no output by default) in the future 942 * 943 * @param integer|bool $update return result of db::db_Query 944 * @param string $type update|insert|update 945 * @param string|bool $success forced success message 946 * @param string|bool $failed forced error message 947 * @param bool $output false suppress any function output 948 * @return integer|bool db::db_Query result 949 */ 950 // TODO - This function often needs to be available BEFORE header.php is loaded. 951 // It has been copied from admin_update() in e107_admin/header.php 952 953 public function addAuto($update, $type = 'update', $success = false, $failed = false, $output = false) 954 { 955 956 $sql = e107::getDb(); 957 958 if (($type == 'update' && $update) || ($type == 'insert' && $update !== false)) 959 { 960 $this->add(($success ? $success : ($type == 'update' ? LAN_UPDATED : LAN_CREATED)), E_MESSAGE_SUCCESS); 961 } 962 elseif ($type == 'delete' && $update) 963 { 964 $this->add(($success ? $success : LAN_DELETED), E_MESSAGE_SUCCESS); 965 } 966 elseif (!$sql->getLastErrorNumber()) 967 { 968 if ($type == 'update') 969 { 970 $this->add(LAN_NO_CHANGE.' '.LAN_TRY_AGAIN, E_MESSAGE_INFO); 971 } 972 elseif ($type == 'delete') 973 { 974 $this->add(LAN_DELETED_FAILED.' '.LAN_TRY_AGAIN, E_MESSAGE_INFO); 975 } 976 } 977 else 978 { 979 switch ($type) 980 { 981 case 'insert': 982 $msg = LAN_CREATED_FAILED; 983 break; 984 case 'delete': 985 $msg = LAN_DELETED_FAILED; 986 break; 987 default: 988 $msg = LAN_UPDATED_FAILED; 989 break; 990 } 991 992 $text = ($failed ? $failed : $msg." - ".LAN_TRY_AGAIN)."<br />".LAN_ERROR." ".$sql->getLastErrorNumber().": ".$sql->getLastErrorText(); 993 $this->add($text, E_MESSAGE_ERROR); 994 } 995 996 if ($output) echo $this->render(); 997 return $update; 998 } 999 1000 1001 1002} 1003 1004function show_emessage($mode, $message, $line = 0, $file = "") { 1005 global $tp; 1006 1007 // For critical errors where no theme is available. 1008 $errorHead = ' 1009 <!doctype html> 1010 <html lang="en"> 1011 <head> 1012 <meta charset="utf-8" /> 1013 <title>Error</title> 1014 <link rel="stylesheet" media="all" type="text/css" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" /> 1015 <link rel="stylesheet" media="all" type="text/css" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.4.0/css/font-awesome.min.css" /> 1016 <link rel="stylesheet" media="all" type="text/css" href="/e107_web/css/e107.css" /> 1017 </head> 1018 <body > 1019 <div class="container" style="margin-top:100px">'; 1020 1021 1022 $errorFoot = "</div></body></html>"; 1023 1024 1025 1026 if(is_numeric($message)) 1027 { 1028 if(!defined('e_LANGUAGE')) 1029 { 1030 define('e_LANGUAGE', 'English'); 1031 } 1032 1033 if(!defined('e_LANGUAGEDIR')) 1034 { 1035 define('e_LANGUAGEDIR','e107_languages/'); 1036 } 1037 1038 $path = e_LANGUAGEDIR.e_LANGUAGE."/lan_error.php"; 1039 1040 if(is_readable($path)) 1041 { 1042 include($path); 1043 } 1044 1045 // include_lan(e_LANGUAGEDIR.e_LANGUAGE."/lan_error.php"); 1046 global $mySQLdefaultdb; 1047 1048 $emessage[1] = "<b>".LAN_ERROR_25."</b>"; 1049 $emessage[2] = "<b>".LAN_ERROR_26."</b>"; 1050 $emessage[3] = "<b>".LAN_ERROR_27."</b>"; 1051 $emessage[4] = "<b>".LAN_ERROR_28."</b>"; 1052 $emessage[5] = LAN_ERROR_29; 1053 $emessage[6] = "<b>".LAN_ERROR_30."</b>"; 1054 $emessage[7] = "<b>".$tp->lanVars(LAN_ERROR_31, $mySQLdefaultdb)."</b>"; 1055 /*$emessage[8] = " 1056 <div style='text-align:center; font: 12px Verdana, Tahoma'><b>".LAN_ERROR_32." </b><br /><br /> 1057 ".chr(36)."ADMIN_DIRECTORY = \"e107_admin/\";<br /> 1058 ".chr(36)."FILES_DIRECTORY = \"e107_files/\";<br /> 1059 ".chr(36)."IMAGES_DIRECTORY = \"e107_images/\"; <br /> 1060 ".chr(36)."THEMES_DIRECTORY = \"e107_themes/\"; <br /> 1061 ".chr(36)."PLUGINS_DIRECTORY = \"e107_plugins/\"; <br /> 1062 ".chr(36)."HANDLERS_DIRECTORY = \"e107_handlers/\"; <br /> 1063 ".chr(36)."LANGUAGES_DIRECTORY = \"e107_languages/\"; <br /> 1064 ".chr(36)."HELP_DIRECTORY = \"e107_docs/help/\"; <br /> 1065 ".chr(36)."DOWNLOADS_DIRECTORY = \"e107_files/downloads/\";\n 1066 </div>";*/ 1067 //v2.x 1068 $emessage[8] = '<b>'.LAN_ERROR_32.' </b><br /><br /><pre> 1069$ADMIN_DIRECTORY = "e107_admin/"; 1070$IMAGES_DIRECTORY = "e107_images/"; 1071$THEMES_DIRECTORY = "e107_themes/"; 1072$PLUGINS_DIRECTORY = "e107_plugins/"; 1073$HANDLERS_DIRECTORY = "e107_handlers/"; 1074$LANGUAGES_DIRECTORY = "e107_languages/"; 1075$HELP_DIRECTORY = "e107_docs/help/"; 1076$MEDIA_DIRECTORY = "e107_media/"; 1077$SYSTEM_DIRECTORY = "e107_system/";</pre> 1078 1079 '; 1080 1081 } 1082 1083 1084 if (class_exists('e107table')) 1085 { 1086 $ns = new e107table; 1087 } 1088 1089 switch($mode) 1090 { 1091 case "CRITICAL_ERROR" : 1092 1093 $message = !empty($emessage[$message]) ? $emessage[$message] : $message; 1094 1095 //FIXME - this breaks class2 pref check!!! ? 1096 1097 if (is_readable(e_THEME.'error.html')) 1098 { 1099 require_once(e_THEME.'error.html'); 1100 exit; 1101 } 1102 1103 1104 if(defined('e_LOG_CRITICAL')) 1105 { 1106 $date = date('r'); 1107 @file_put_contents(e_LOG.'criticalError.log',$date."\t\t". strip_tags($message)."\n", FILE_APPEND); 1108 $message = LAN_ERROR_46; // "Check log for details"; 1109 $line = null; 1110 $file = null; 1111 } 1112 1113 1114 if(!defined('HEADERF')) 1115 { 1116 echo $errorHead; 1117 } 1118 1119 echo "<div class='alert alert-block alert-error alert-danger' style='font: 11px verdana, tahoma, arial, helvetica, sans-serif;'><h4>CRITICAL ERROR: </h4>"; 1120 echo (!empty($line)) ? "Line $line " : ""; 1121 echo (!empty($file)) ? $file : ""; 1122 echo "<div>".$message."</div>"; 1123 echo "</div>"; 1124 1125 if(!defined('FOOTERF')) 1126 { 1127 echo $errorFoot; 1128 } 1129 1130 break; 1131 1132 case "MESSAGE": 1133 if(strstr(e_SELF, "forum_post.php")) //FIXME Shouldn't be here. 1134 { 1135 return; 1136 } 1137 $ns->tablerender("", "<div class='alert alert-block' style='text-align:center'><b>{$message}</b></div>"); 1138 break; 1139 1140 case "ADMIN_MESSAGE": 1141 $ns->tablerender("Admin Message", "<div class='alert'><b>{$message}</b></div>"); 1142 break; 1143 1144 case "ALERT": 1145 $message = isset($emessage[$message]) ? $emessage[$message] : $message; 1146 echo "<noscript>$message</noscript><script type='text/javascript'>alert(\"".$tp->toJS($message)."\"); window.history.go(-1); </script>\n"; exit; 1147 break; 1148 1149 case "P_ALERT": 1150 echo "<script type='text/javascript'>alert(\"".$tp->toJS($message)."\"); </script>\n"; 1151 break; 1152 1153 case 'POPUP': 1154 1155 $mtext = "<html><head><title>Message</title><link rel=stylesheet href=" . THEME . "style.css></head><body style=padding-left:2px;padding-right:2px;padding:2px;padding-bottom:2px;margin:0px;align;center marginheight=0 marginleft=0 topmargin=0 leftmargin=0><table width=100% align=center style=width:100%;height:99%padding-bottom:2px class=bodytable height=99% ><tr><td width=100% style='text-align:center'><b>--- Message ---</b><br /><br />".$message."<br /><br /><form><input class=button type=submit onclick=self.close() value = ok /></form></td></tr></table></body></html> "; 1156 1157 echo " 1158 <script type='text/javascript'> 1159 winl=(screen.width-200)/2; 1160 wint = (screen.height-100)/2; 1161 winProp = 'width=200,height=100,left='+winl+',top='+wint+',scrollbars=no'; 1162 window.open('javascript:document.write(\"".$mtext."\");', \"message\", winProp); 1163 </script >"; 1164 1165 break; 1166 1167 } 1168} 1169 1170 1171