1<?php 2/* 3 * e107 website system 4 * 5 * Copyright (C) 2008-2010 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 * e107 Preference Handler 10 * 11 * $URL$ 12 * $Id$ 13*/ 14 15if (!defined('e107_INIT')) { exit; } 16require_once(e_HANDLER.'model_class.php'); 17 18/** 19 * Base preference object - shouldn't be used direct, 20 * used internal by {@link e_plugin_pref} and {@link e_core_pref classes} 21 * 22 * @package e107 23 * @category e107_handlers 24 * @version $Id$ 25 * @author SecretR 26 * @copyright Copyright (c) 2009, e107 Inc. 27 */ 28class e_pref extends e_front_model 29{ 30 /** 31 * Preference ID - DB row value 32 * 33 * @var string 34 */ 35 protected $prefid; 36 37 /** 38 * Preference ID alias e.g. 'core' is an alias of prefid 'SitePrefs' 39 * Used in e.g. server cache file name 40 * 41 * @var string 42 */ 43 protected $alias; 44 45 /** 46 * Runtime cache, set on first data load 47 * 48 * @var string 49 */ 50 protected $pref_cache = ''; 51 52 /** 53 * Backward compatibility - serialized preferences 54 * Note: serialized preference storage is deprecated 55 * 56 * @var boolean 57 */ 58 protected $serial_bc = false; 59 60 /** 61 * If true, $prefid.'_Backup' row will be created/updated 62 * on every {@link save()} call 63 * 64 * @var boolean 65 */ 66 protected $set_backup = false; 67 68 /** 69 * Constructor 70 * 71 * @param string $prefid 72 * @param string $alias Used by cache file. 73 * @param array $data 74 * @param boolean $sanitize_data 75 */ 76 function __construct($prefid, $alias = '', $data = array(), $sanitize_data = true) 77 { 78 require_once(e_HANDLER.'cache_handler.php'); 79 80 $this->prefid = preg_replace('/[^\w\-]/', '', $prefid); 81 82 if(empty($alias)) 83 { 84 $alias = $prefid; 85 } 86 87 $this->alias = preg_replace('/[^\w\-]/', '', $alias); 88 89 $this->loadData($data, $sanitize_data); 90 } 91 92 /** 93 * Advanced getter - $pref_name could be path in format 'pref1/pref2/pref3' (multidimensional arrays support), 94 * alias of {@link e_model::getData()} 95 * If $pref_name is empty, all data array will be returned 96 * 97 * @param string $pref_name 98 * @param mixed $default 99 * @param integer $index 100 * @return mixed 101 */ 102 public function getPref($pref_name = '', $default = null, $index = null) 103 { 104 return $this->getData($pref_name, $default, $index); 105 } 106 107 /** 108 * Simple getter - $pref_name is not parsed (no multidimensional arrays support), alias of {@link e_model::get()} 109 * This is the prefered (performance wise) method when simple preference is retrieved 110 * 111 * @param string $pref_name 112 * @param mixed $default 113 * @return mixed 114 */ 115 public function get($pref_name, $default = null) 116 { 117 return parent::get((string) $pref_name, $default); 118 } 119 120 /** 121 * Advanced setter - $pref_name could be path in format 'pref1/pref2/pref3' (multidimensional arrays support) 122 * If $pref_name is array, it'll be merged with existing preference data, non existing preferences will be added as well 123 * 124 * @param string|array $pref_name 125 * @param mixed $value 126 * @return e_pref 127 */ 128 public function setPref($pref_name, $value = null) 129 { 130 global $pref; 131 //object reset not allowed, adding new pref is allowed 132 if(empty($pref_name)) 133 { 134 return $this; 135 } 136 137 //Merge only allowed 138 if(is_array($pref_name)) 139 { 140 $this->mergeData($pref_name, false, false, false); 141 return $this; 142 } 143 144 parent::setData($pref_name, $value, false); 145 146 //BC 147 if($this->alias === 'core') 148 { 149 $pref = $this->getData(); 150 } 151 return $this; 152 } 153 154 /** 155 * Reset preference object to given/empty state 156 * @param array $prefs 157 * @return $this 158 */ 159 public function reset($prefs = array()) 160 { 161 parent::setData(array()); 162 163 return $this; 164 } 165 166 /** 167 * Advanced setter - $pref_name could be path in format 'pref1/pref2/pref3' (multidimensional arrays support) 168 * Object data reseting is not allowed, adding new preferences is controlled by $strict parameter 169 * 170 * @param string|array $pref_name 171 * @param mixed $value 172 * @param boolean $strict true - update only, false - same as setPref() 173 * @return e_pref 174 */ 175 public function updatePref($pref_name, $value = null, $strict = false) 176 { 177 global $pref; 178 //object reset not allowed, adding new pref is not allowed 179 if(empty($pref_name)) 180 { 181 return $this; 182 } 183 184 //Merge only allowed 185 if(is_array($pref_name)) 186 { 187 $this->mergeData($pref_name, $strict, false, false); 188 return $this; 189 } 190 191 parent::setData($pref_name, $value, $strict); 192 193 //BC 194 if($this->alias === 'core') 195 { 196 $pref = $this->getData(); 197 } 198 return $this; 199 } 200 201 /** 202 * Simple setter - $pref_name is not parsed (no multidimensional arrays support) 203 * Adding new pref is allowed 204 * 205 * @param string $pref_name 206 * @param mixed $value 207 * @return e_pref 208 */ 209 public function set($pref_name, $value=null, $strict = false) 210 { 211 global $pref; 212 if(empty($pref_name) || !is_string($pref_name)) 213 { 214 return $this; 215 } 216 217 if(!isset($this->_data[$pref_name]) || $this->_data[$pref_name] != $value) $this->data_has_changed = true; 218 $this->_data[$pref_name] = $value; 219 220 //BC 221 if($this->alias === 'core') 222 { 223 $pref = $this->getData(); 224 } 225 return $this; 226 } 227 228 /** 229 * Simple setter - $pref_name is not parsed (no multidimensional arrays support) 230 * Non existing setting will be not created 231 * 232 * @param string $pref_name 233 * @param mixed $value 234 * @return e_pref 235 */ 236 public function update($pref_name, $value) 237 { 238 global $pref; 239 if(empty($pref_name) || !is_string($pref_name)) 240 { 241 return $this; 242 } 243 if(array_key_exists($pref_name, $this->_data)) 244 { 245 if($this->_data[$pref_name] != $value) $this->data_has_changed = true; 246 $this->_data[$pref_name] = $value; 247 } 248 249 //BC 250 if($this->alias === 'core') 251 { 252 $pref = $this->getData(); 253 } 254 return $this; 255 } 256 257 /** 258 * Add new (single) preference (ONLY if doesn't exist) 259 * No multidimensional arrays support 260 * 261 * @see addData() 262 * @param string $pref_name 263 * @param mixed $value 264 * @return e_pref 265 */ 266 public function add($pref_name, $value) 267 { 268 if(empty($pref_name) || !is_string($pref_name)) 269 { 270 return $this; 271 } 272 if(!isset($this->_data[$pref_name])) 273 { 274 $this->_data[$pref_name] = $value; 275 $this->data_has_changed = true; 276 } 277 278 //BC 279 if($this->alias === 'core') 280 { 281 $pref = $this->getData(); 282 } 283 return $this; 284 } 285 286 /** 287 * Add new preference or preference array (ONLY if it/they doesn't exist) 288 * $pref_name could be path in format 'pref1/pref2/pref3' 289 * 290 * @see addData() 291 * @param string|array $pref_name 292 * @param mixed $value 293 * @return e_pref 294 */ 295 public function addPref($pref_name, $value = null) 296 { 297 $this->addData($pref_name, $value); 298 return $this; 299 } 300 301 /** 302 * Remove single preference 303 * $pref_name is not parsed as a path 304 * 305 * @see e_model::remove() 306 * @param string $pref_name 307 * @return e_pref 308 */ 309 public function remove($pref_name) 310 { 311 global $pref; 312 parent::remove((string) $pref_name); 313 314 //BC 315 if($this->alias === 'core') 316 { 317 $pref = $this->getData(); 318 } 319 return $this; 320 } 321 322 /** 323 * Remove single preference (parse $pref_name) 324 * $pref_name could be path in format 'pref1/pref2/pref3' 325 * 326 * @see removeData() 327 * @param string $pref_name 328 * @return e_pref 329 */ 330 public function removePref($pref_name) 331 { 332 $this->removeData($pref_name); 333 return $this; 334 } 335 336 /** 337 * Disallow public use of e_model::addData() 338 * Disallow preference override 339 * 340 * @param string|array $pref_name 341 * @param mixed value 342 * @param boolean $strict 343 * @return $this|\e_model 344 */ 345 final public function addData($pref_name, $value = null, $override = true) 346 { 347 global $pref; 348 parent::addData($pref_name, $value, false); 349 //BC 350 if($this->alias === 'core') 351 { 352 $pref = $this->getData(); 353 } 354 return $this; 355 } 356 357 /** 358 * Disallow public use of e_model::setData() 359 * Only data merge possible 360 * 361 * @param string|array $pref_name 362 * @param mixed $value 363 * @return e_pref 364 */ 365 final public function setData($pref_name, $value = null, $strict = false) 366 { 367 global $pref; 368 if(empty($pref_name)) 369 { 370 return $this; 371 } 372 373 //Merge only allowed 374 if(is_array($pref_name)) 375 { 376 $this->mergeData($pref_name, false, false, false); 377 return $this; 378 } 379 380 parent::setData($pref_name, $value, false); 381 382 //BC 383 if($this->alias === 'core') 384 { 385 $pref = $this->getData(); 386 } 387 return $this; 388 } 389 390 /** 391 * Disallow public use of e_model::removeData() 392 * Object data reseting is not allowed 393 * 394 * @param string $pref_name 395 * @return e_pref 396 */ 397 final public function removeData($pref_name=null) 398 { 399 global $pref; 400 parent::removeData((string) $pref_name); 401 402 //BC 403 if($this->alias === 'core') 404 { 405 $pref = $this->getData(); 406 } 407 return $this; 408 } 409 410 /** 411 * Reset object data 412 * 413 * @param array $data 414 * @param boolean $sanitize 415 * @return e_pref 416 */ 417 public function loadData(array $data, $sanitize = true) 418 { 419 global $pref; 420 if(!empty($data)) 421 { 422 if($sanitize) 423 { 424 $data = e107::getParser()->toDB($data); 425 } 426 parent::setData($data, null, false); 427 $this->pref_cache = e107::getArrayStorage()->WriteArray($data, false); //runtime cache 428 //BC 429 if($this->alias === 'core') 430 { 431 $pref = $this->getData(); 432 } 433 } 434 return $this; 435 } 436 437 /** 438 * Load object data - public 439 * 440 * @see _load() 441 * @param boolean $force 442 * @return e_pref 443 */ 444 public function load($id=null, $force = false) 445 { 446 global $pref; 447 if($force || !$this->hasData()) 448 { 449 $this->data_has_changed = false; 450 $this->_load($force); 451 //BC 452 if($this->alias === 'core') 453 { 454 $pref = $this->getData(); 455 } 456 } 457 458 return $this; 459 } 460 461 /** 462 * Load object data 463 * 464 * @param boolean $force 465 * @return e_pref 466 */ 467 protected function _load($force = false) 468 { 469 $id = $this->prefid; 470 $data = $force ? false : $this->getPrefCache(true); 471 472 if(!empty($data)) 473 { 474 $this->pref_cache = e107::getArrayStorage()->WriteArray($data, false); //runtime cache 475 $this->loadData((array) $data, false); 476 return $this; 477 } 478 479 if (e107::getDb()->select('core', 'e107_value', "e107_name='{$id}'")) 480 { 481 $row = e107::getDb()->fetch(); 482 483 if($this->serial_bc) 484 { 485 $data = unserialize($row['e107_value']); 486 $row['e107_value'] = e107::getArrayStorage()->WriteArray($data, false); 487 } 488 else 489 { 490 $data = e107::unserialize($row['e107_value']); 491 } 492 493 $this->pref_cache = $row['e107_value']; //runtime cache 494 $this->setPrefCache($row['e107_value'], true); 495 } 496 497 if(empty($data)) 498 $data = array(); 499 500 $this->loadData($data, false); 501 return $this; 502 } 503 504 /** 505 * Save object data to DB 506 * 507 * @param boolean $from_post merge post data 508 * @param boolean $force 509 * @param mixed $session_messages null: normal messages displayed, true: session messages used, false: no messages displayed. 510 * @return boolean|integer 0 - no change, true - saved, false - error 511 */ 512 public function save($from_post = true, $force = false, $session_messages = null) 513 { 514 global $pref; 515 if(!$this->prefid) 516 { 517 return false; 518 } 519 520 e107::getMessage()->setUnique($this->prefid); // attempt to fix 521 522 if($from_post) 523 { 524 $this->mergePostedData(); //all posted data is sanitized and filtered vs preferences/_data_fields array 525 } 526 527 if($this->hasValidationError()) 528 { 529 return false; 530 } 531 532 if(!$this->data_has_changed && !$force) 533 { 534 if($session_messages !== false) 535 { 536 e107::getMessage()->addInfo(LAN_SETTINGS_NOT_SAVED_NO_CHANGES_MADE, $this->prefid, $session_messages)->moveStack($this->prefid); 537 } 538 539 return 0; 540 } 541 542 $log = e107::getAdminLog(); 543 $disallow_logs = $this->getParam('nologs', false); 544 545 //Save to DB 546 if(!$this->hasError()) 547 { 548 if($this->serial_bc) 549 { 550 $dbdata = serialize($this->getPref()); 551 } 552 else 553 { 554 $dbdata = $this->toString(false); 555 } 556 557 if(e107::getDb()->gen("REPLACE INTO `#core` (e107_name,e107_value) values ('{$this->prefid}', '".addslashes($dbdata)."') ")) 558 { 559 $this->data_has_changed = false; //reset status 560 561 if(!empty($this->pref_cache)) 562 { 563 $old = e107::unserialize($this->pref_cache); 564 if($this->serial_bc) 565 { 566 $dbdata = serialize($old); 567 } 568 else 569 { 570 $dbdata = $this->pref_cache; 571 } 572 573 // auto admin log 574 if(is_array($old) && !$disallow_logs) // fix install problems - no old prefs available 575 { 576 $new = $this->getPref(); 577 // $log->logArrayDiffs($new, $old, 'PREFS_02', false); 578 $log->addArray($new,$old); 579 unset($new, $old); 580 581 } 582 583 // Backup 584 if($this->set_backup === true && e107::getDb()->gen("REPLACE INTO `#core` (e107_name,e107_value) values ('".$this->prefid."_Backup', '".addslashes($dbdata)."') ")) 585 { 586 if(!$disallow_logs) $log->logMessage('Backup of <strong>'.$this->alias.' ('.$this->prefid.')</strong> successfully created.', E_MESSAGE_DEBUG, E_MESSAGE_SUCCESS, $session_messages); 587 e107::getCache()->clear_sys('Config_'.$this->alias.'_backup'); 588 if(deftrue('e_DEBUG')) 589 { 590 $backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS,2); 591 $log->logMessage(print_a($backtrace,true), E_MESSAGE_DEBUG); 592 } 593 } 594 595 } 596 597 $this->setPrefCache($this->toString(false), true); //reset pref cache - runtime & file 598 599 if($this->alias == 'search') // Quick Fix TODO Improve. 600 { 601 $logId = 'SEARCH_04'; 602 } 603 elseif($this->alias == 'notify') 604 { 605 $logId = 'NOTIFY_01'; 606 } 607 else 608 { 609 $logId = 'PREFS_01'; 610 } 611 612 // FIXME: Admin LAN dependency out of nowhere 613 e107::includeLan(e_LANGUAGEDIR . e_LANGUAGE . '/admin/lan_admin.php'); 614 615 $log->addSuccess(LAN_SETSAVED, ($session_messages === null || $session_messages === true)); 616 617 $uid = USERID; 618 619 if(empty($uid)) // Log extra details of any pref changes made by a non-user. 620 { 621 $log->addWarning(print_r(debug_backtrace(null,2), true), false); 622 } 623 624 $log->save($logId); 625 626 // if(!$disallow_logs) $log->logSuccess('Settings successfully saved.', true, $session_messages)->flushMessages($logId, E_LOG_INFORMATIVE, '', $this->prefid); 627 628 629 //BC 630 if($this->alias === 'core') 631 { 632 $pref = $this->getPref(); 633 } 634 e107::getMessage()->moveStack($this->prefid); 635 return true; 636 } 637 elseif(e107::getDb()->getLastErrorNumber()) 638 { 639 if(!$disallow_logs) 640 $log->logError('mySQL error #'.e107::getDb()->getLastErrorNumber().': '.e107::getDb()->getLastErrorText(), true, $session_messages) 641 ->logError('Settings not saved.', true, $session_messages) 642 ->flushMessages('PREFS_03', E_LOG_INFORMATIVE, '', $this->prefid); 643 644 e107::getMessage()->moveStack($this->prefid); 645 return false; 646 } 647 } 648 649 if($this->hasError()) 650 { 651 //add errors to the eMessage stack 652 //$this->setErrors(true, $session_messages); old - doesn't needed anymore 653 if(!$disallow_logs) 654 $log->logError('Settings not saved.', true, $session_messages) 655 ->flushMessages('LAN_FIXME', E_LOG_INFORMATIVE, '', $this->prefid); 656 657 e107::getMessage()->moveStack($this->prefid); 658 return false; 659 } 660 else 661 { 662 e107::getMessage()->addInfo(LAN_SETTINGS_NOT_SAVED_NO_CHANGES_MADE, $this->prefid, $session_messages); 663 if(!$disallow_logs) $log->flushMessages('LAN_FIXME', E_LOG_INFORMATIVE, '', $this->prefid); 664 e107::getMessage()->moveStack($this->prefid); 665 return 0; 666 } 667 } 668 669 /** 670 * Get cached data from server cache file 671 * 672 * @param boolean $toArray convert to array 673 * @return string|array|false 674 */ 675 protected function getPrefCache($toArray = true) 676 { 677 if(!$this->pref_cache) 678 { 679 $this->pref_cache = e107::getCache()->retrieve_sys('Config_'.$this->alias, 24 * 60, true); 680 } 681 682 return ($toArray && $this->pref_cache ? e107::unserialize($this->pref_cache) : $this->pref_cache); 683 } 684 685 /** 686 * Convert data to a string and store it to a server cache file 687 * If $cache_string is an array, it'll be converted to a string 688 * If $save is string, it'll be used for building the cache filename 689 * 690 * @param string|array $cache_string 691 * @param string|boolean $save write to a file 692 * @return e_pref 693 */ 694 protected function setPrefCache($cache_string, $save = false) 695 { 696 if(is_array($cache_string)) 697 { 698 $cache_string = e107::getArrayStorage()->WriteArray($cache_string, false); 699 } 700 if(is_bool($save)) 701 { 702 $this->pref_cache = $cache_string; 703 } 704 if($save) 705 { 706 e107::getCache()->set_sys('Config_'.($save !== true ? $save : $this->alias), $cache_string, true); 707 } 708 return $this; 709 } 710 711 /** 712 * Clear pref cache 713 * 714 * @param string $cache_name default to current alias 715 * @param boolean $runtime clear runtime cache as well ($this->pref_cache) 716 * @return e_pref 717 */ 718 public function clearPrefCache($cache_name = '', $runtime = true) 719 { 720 if($runtime) 721 { 722 $this->pref_cache = ''; 723 } 724 e107::getCache()->clear_sys('Config_'.(!empty($cache_name) ? $cache_name : $this->alias)); 725 return $this; 726 } 727 728 /** 729 * Validation 730 * 731 * @param array $data [optional] null to use Posted data 732 * @return boolean 733 */ 734 public function validate($data = null) 735 { 736 return parent::validate($data); 737 } 738 739 /** 740 * Set $set_backup option 741 * 742 * @param boolean $optval 743 * @return e_pref 744 * 745 */ 746 public function setOptionBackup($optval) 747 { 748 $this->set_backup = $optval; 749 return $this; 750 } 751 752 /** 753 * Set $serial_bc option 754 * 755 * @param boolean $optval 756 * @return e_pref 757 * 758 */ 759 public function setOptionSerialize($optval) 760 { 761 $this->serial_bc = $optval; 762 return $this; 763 } 764 765 /** 766 * Override 767 */ 768 public function delete($ids, $destroy = true, $session_messages = false) 769 { 770 } 771 772 /** 773 * Override 774 */ 775 protected function dbUpdate($force = false, $session_messages = false) 776 { 777 } 778} 779 780/** 781 * Handle core preferences 782 * 783 * @package e107 784 * @category e107_handlers 785 * @version 1.0 786 * @author SecretR 787 * @copyright Copyright (c) 2009, e107 Inc. 788 */ 789final class e_core_pref extends e_pref 790{ 791 /** 792 * Allowed core id array 793 * 794 * @var array 795 */ 796 public $aliases = array( 797 'core' => 'SitePrefs', 798 'core_backup' => 'SitePrefs_Backup', 799 'core_old' => 'pref', 800 'emote' => 'emote_default', //TODO include other emote packs of the user. 801 'menu' => 'menu_pref', 802 'search' => 'search_prefs', 803 'notify' => 'notify_prefs', 804 'history' => 'history_prefs', 805 ); 806 807 /** 808 * Backward compatibility - list of prefid's which operate wit serialized data 809 * 810 * @var array 811 */ 812 // protected $serial_bc_array = array('core_old', 'emote', 'menu', 'search'); 813 protected $serial_bc_array = array('core_old'); 814 815 /** 816 * Constructor 817 * 818 * @param string $alias 819 * @param boolean $load load DB data on startup 820 */ 821 function __construct($alias, $load = true) 822 { 823 824 825 $pref_alias = $alias; 826 827 if($alias == 'emote') 828 { 829 $pack = e107::pref('core','emotepack'); 830 $this->aliases['emote'] = 'emote_'.$pack; 831 } 832 833 $pref_id = $this->getConfigId($alias); 834 835 836 if(!$pref_id) 837 { 838 $pref_id = $pref_alias = ''; 839 trigger_error('Core config ID '.$alias.' not found!', E_USER_WARNING); 840 return; 841 } 842 843 if(in_array($pref_alias, $this->serial_bc_array)) 844 { 845 $this->setOptionSerialize(true); 846 } 847 848 if('core' === $pref_alias) 849 { 850 $this->setOptionBackup(true); 851 } 852 853 parent::__construct($pref_id, $pref_alias); 854 if($load && $pref_id) 855 { 856 $this->load(); 857 } 858 859 860 } 861 862 /** 863 * Get config ID 864 * Allowed values: key or value from $alias array 865 * If id not found this method returns false 866 * 867 * @param string $alias 868 * @return string 869 */ 870 public function getConfigId($alias) 871 { 872 $alias = trim($alias); 873 if(isset($this->aliases[$alias])) 874 { 875 return $this->aliases[$alias]; 876 } 877 return false; 878 } 879 880 /** 881 * Get config ID 882 * Allowed values: key or value from $alias array 883 * If id not found this method returns false 884 * 885 * @param string $prefid 886 * @return string 887 */ 888 public function getAlias($prefid) 889 { 890 $prefid = trim($prefid); 891 return array_search($prefid, $this->aliases); 892 } 893 894 895 /** 896 * Export data from core pref and remove if needed. Useful for core pref -> menu table parm migration. 897 * @param array $prefList key/value pairs. key = oldpref value = new pref key 898 * @param bool|false $remove 899 * @return array|false if no match found. 900 */ 901 public function migrateData($prefList=array(), $remove=false) 902 { 903 $data = self::getData(); 904 $array = array(); 905 $save = false; 906 907 if(empty($prefList)) 908 { 909 return false; 910 } 911 912 foreach($data as $k=>$v) 913 { 914 if(isset($prefList[$k])) 915 { 916 $key = $prefList[$k]; 917 $array[$key] = $v; 918 919 if($remove == true) 920 { 921 self::remove($k); 922 $save = true; 923 } 924 } 925 926 } 927 928 if(empty($array)) 929 { 930 return false; 931 } 932 933 if(!empty($save)) 934 { 935 self::save(false,true,false); 936 } 937 938 return $array; 939 940 } 941} 942 943/** 944 * Handle plugin preferences 945 * 946 * @package e107 947 * @category e107_handlers 948 * @version 1.0 949 * @author SecretR 950 * @copyright Copyright (c) 2009, e107 Inc. 951 */ 952class e_plugin_pref extends e_pref 953{ 954 /** 955 * Unique plugin name 956 * 957 * @var string 958 */ 959 protected $plugin_id; 960 961 /** 962 * Constructor 963 * Note: object data will be loaded only if the plugin is installed (no matter of the passed 964 * $load value) 965 * 966 * @param string $plugin_id unique plugin name 967 * @param string $multi_row additional field identifier appended to the $prefid 968 * @param boolean $load load on startup 969 */ 970 function __construct($plugin_id, $multi_row = '', $load = true) 971 { 972 $this->plugin_id = $plugin_id; 973 if($multi_row) 974 { 975 $plugin_id = $plugin_id.'_'.$multi_row; 976 } 977 parent::__construct('plugin_'.$plugin_id, "plugin_".$this->plugin_id); 978 if($load && e107::findPref('plug_installed/'.$this->plugin_id)) 979 { 980 $this->load(); 981 } 982 } 983 984 /** 985 * Retrive unique plugin name 986 * 987 * @return string 988 */ 989 public function getPluginId() 990 { 991 return $this->plugin_id; 992 } 993 994 /** 995 * Delete plugin preferences 996 * @see e107_handlers/e_pref#delete() 997 * @return boolean 998 */ 999 public function delete($ids, $destroy = true, $session_messages = false) 1000 { 1001 $ret = false; 1002 if($this->plugin_id) 1003 { 1004 $ret = e107::getDb($this->plugin_id)->delete('core', "e107_name='{$this->plugin_id}'"); 1005 $this->destroy(); 1006 } 1007 return $ret; 1008 } 1009} 1010 1011 1012/** 1013 * Handle plugin preferences 1014 * 1015 * @package e107 1016 * @category e107_handlers 1017 * @version 1.0 1018 * @author SecretR 1019 * @copyright Copyright (c) 2009, e107 Inc. 1020 */ 1021class e_theme_pref extends e_pref 1022{ 1023 /** 1024 * Unique plugin name 1025 * 1026 * @var string 1027 */ 1028 protected $theme_id; 1029 1030 /** 1031 * Constructor 1032 * Note: object data will be loaded only if the plugin is installed (no matter of the passed 1033 * $load value) 1034 * 1035 * @param string $theme_id unique plugin name 1036 * @param string $multi_row additional field identifier appended to the $prefid 1037 * @param boolean $load load on startup 1038 */ 1039 function __construct($theme_id, $multi_row = '', $load = true) 1040 { 1041 $this->theme_id = $theme_id; 1042 if($multi_row) 1043 { 1044 $theme_id = $theme_id.'_'.$multi_row; 1045 } 1046 parent::__construct('theme_'.$theme_id, "theme_".$this->theme_id); 1047 // if($load && e107::findPref('plug_installed/'.$this->theme_id)) 1048 { 1049 $this->load(); 1050 } 1051 } 1052 1053 /** 1054 * Retrive unique plugin name 1055 * 1056 * @return string 1057 */ 1058 public function getPluginId() 1059 { 1060 return $this->theme_id; 1061 } 1062 1063 /** 1064 * Delete plugin preferences 1065 * @see e107_handlers/e_pref#delete() 1066 * @return boolean 1067 */ 1068 public function delete($ids, $destroy = true, $session_messages = false) 1069 { 1070 $ret = false; 1071 if($this->theme_id) 1072 { 1073 $ret = e107::getDb($this->theme_id)->delete('core', "e107_name='{$this->theme_id}'"); 1074 $this->destroy(); 1075 } 1076 return $ret; 1077 } 1078} 1079 1080 1081 1082 1083 1084 1085 1086/** 1087 * DEPRECATED - see e107::getConfig(), e_core_pref and e_plugin_pref 1088 * 1089 */ 1090// 1091// Simple functionality: 1092// Grab all prefs once, in one DB query. Reuse them throughout the session. 1093// 1094// get/set methods serve/consume strings (with slashes taken care of) 1095// getArray/setArray methods serve/consume entire arrays (since most prefs are such!) 1096// 1097// NOTE: Use of this class is VALUABLE (efficient) yet not NECESSARY (i.e. the system 1098// will not break if it is ignored)... AS LONG AS there is no path consisting of: 1099// - modify pref value(s) IGNORING this class 1100// - retrieve pref value(s) USING this class 1101// (while processing a single web page) 1102// Just to be safe I have changed a number of menu_pref edits to use setArray(). 1103// 1104 1105class prefs 1106{ 1107 var $prefVals; 1108 var $prefArrays; 1109 1110 // Default prefs to load 1111 var $DefaultRows = "e107_name='e107' OR e107_name='menu_pref' OR e107_name='notify_prefs'"; 1112 1113 // Read prefs from DB - get as many rows as are required with a single query. 1114 // $RowList is an array of pref entries to retrieve. 1115 // If $use_default is TRUE, $RowList entries are added to the default array. Otherwise only $RowList is used. 1116 // Returns TRUE on success (measured as getting at least one row of data); false on error. 1117 // Any data read is buffered (in serialised form) here - retrieve using get() 1118 function ExtractPrefs($RowList = "", $use_default = FALSE) 1119 { 1120 global $sql; 1121 $Args = ''; 1122 if($use_default) 1123 { 1124 $Args = $this->DefaultRows; 1125 } 1126 if(is_array($RowList)) 1127 { 1128 foreach($RowList as $v) 1129 { 1130 $Args .= ($Args ? " OR e107_name='{$v}'" : "e107_name='{$v}'"); 1131 } 1132 } 1133 if (!$sql->select('core', '*', $Args, 'default')) 1134 { 1135 return FALSE; 1136 } 1137 while ($row = $sql->fetch()) 1138 { 1139 $this->prefVals['core'][$row['e107_name']] = $row['e107_value']; 1140 } 1141 return TRUE; 1142 } 1143 1144 1145 /** 1146 * Return current pref string $name from $table (only core for now) 1147 * 1148 * @param string $name -- name of pref row 1149 * @param string $table -- "core" 1150 * @return string pref value, slashes already stripped. FALSE on error 1151 * @access public 1152 */ 1153 function get($Name) 1154 { 1155 if(isset($this->prefVals['core'][$Name])) 1156 { 1157 if($this->prefVals['core'][$Name] != '### ROW CACHE FALSE ###') 1158 { 1159 return $this->prefVals['core'][$Name]; // Dava from cache 1160 } 1161 else 1162 { 1163 return false; 1164 } 1165 } 1166 1167 // Data not in cache - retrieve from DB 1168 $get_sql = new db; // required so sql loops don't break using $tp->toHTML(). 1169 if($get_sql->db_Select('core', '*', "`e107_name` = '{$Name}'", 'default')) 1170 { 1171 $row = $get_sql->db_Fetch(); 1172 $this->prefVals['core'][$Name] = $row['e107_value']; 1173 return $this->prefVals['core'][$Name]; 1174 } 1175 else 1176 { // Data not in DB - put a 'doesn't exist' entry in cache to save another DB access 1177 $this->prefVals['core'][$Name] = '### ROW CACHE FALSE ###'; 1178 return false; 1179 } 1180 } 1181 1182 /** 1183 * Return current array from pref string $name in $table (core only for now) 1184 * 1185 * @param string $name -- name of pref row 1186 * @param string $table -- "core" only now 1187 * @return array pref values 1188 * @access public 1189 */ 1190 // retrieve prefs as an array of values 1191 function getArray($name) 1192 { 1193 return e107::unserialize($this->get($name)); 1194 // return unserialize($this->get($name)); 1195 } 1196 1197 1198 /** 1199 * Update pref set and cache 1200 * 1201 * @param string val -- pre-serialized string 1202 * @param string $name -- name of pref row 1203 * @param string $table -- "core" or "user" 1204 * @global mixed $$name 1205 * @access public 1206 * 1207 * set("val") == 'core', 'pref' 1208 * set("val","rowname") == 'core', rowname 1209 * set("val","","user") == 'user', 'user_pref' for current user 1210 * set("val","","user",uid) == 'user', 'user_pref' for user uid 1211 * set("val","fieldname","user") == 'user', fieldname 1212 * 1213 */ 1214 function set($val, $name = "", $table = "core", $uid = USERID) { 1215 global $sql; 1216 if (!strlen($name)) { 1217 switch ($table) { 1218 case 'core': 1219 $name = "pref"; 1220 break; 1221 case 'user': 1222 $name = "user_pref"; 1223 break; 1224 } 1225 } 1226 $val = addslashes($val); 1227 1228 switch ($table ) { 1229 case 'core': 1230 if(!$sql->db_Update($table, "e107_value='$val' WHERE e107_name='$name'")) 1231 { 1232 $sql->db_Insert($table, "'{$name}', '{$val}'"); 1233 } 1234 $this->prefVals[$table][$name] = $val; 1235 unset($this->prefArrays[$table][$name]); 1236 break; 1237 case 'user': 1238 $sql->db_Update($table, "user_prefs='$val' WHERE user_id=$uid"); 1239 break; 1240 } 1241 } 1242 1243 1244 /** 1245 * Update pref set and cache 1246 * 1247 * - @param string $name -- name of pref row 1248 * - @param string $table -- "core" or "user" 1249 * - @global $$name 1250 * - @access public 1251 * 1252 * set() == core, pref 1253 * set("rowname") == core, rowname 1254 * set("","user") == user, user_pref for current user 1255 * set("","user",uid) == user, user_pref for user uid 1256 * set("fieldname","user") == user, fieldname 1257 * 1258 * all pref sets other than menu_pref get toDB() 1259 */ 1260 function setArray($name = '', $table = 'core', $uid = USERID) 1261 { 1262 $tp = e107::getParser(); 1263 1264 if (!strlen($name)) 1265 { 1266 switch ($table) 1267 { 1268 case 'core': 1269 $name = 'pref'; 1270 break; 1271 case 'user': 1272 $name = 'user_pref'; 1273 break; 1274 } 1275 } 1276 1277 global $$name; 1278 if ($name != 'menu_pref') 1279 { 1280 foreach($$name as $key => $prefvalue) 1281 { 1282 $$name[$key] = $tp->toDB($prefvalue); 1283 } 1284 } 1285 $tmp = e107::getArrayStorage()->WriteArray($$name, FALSE); // $this->set() adds slashes now 1286 // $tmp = serialize($$name); 1287 $this->set($tmp, $name, $table, $uid); 1288 } 1289} 1290 1291