PageRenderTime 134ms CodeModel.GetById 61ms app.highlight 59ms RepoModel.GetById 1ms app.codeStats 1ms

/lib/kernel.php

http://litepublisher.googlecode.com/
PHP | 2871 lines | 2363 code | 425 blank | 83 comment | 483 complexity | 2340aaf0d9b0079dad65f2ccba0647b9 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

   1<?php
   2/**
   3* Lite Publisher
   4* Copyright (C) 2010, 2011, 2012, 2013 Vladimir Yushko http://litepublisher.com/
   5* Dual licensed under the MIT (mit.txt)
   6* and GPL (gpl.txt) licenses.
   7**/
   8//db.class.php
   9class tdatabase {
  10  public $result;
  11  public $sql;
  12  public $dbname;
  13  public $table;
  14  public $prefix;
  15  public $history;
  16  public $mysqli;
  17  
  18  public static function i() {
  19    return getinstance(__class__);
  20  }
  21  
  22  public static function instance() {
  23    return getinstance(__class__);
  24  }
  25  
  26  public function __construct() {
  27    if (!isset(litepublisher::$options->dbconfig)) return false;
  28    $dbconfig = litepublisher::$options->dbconfig;
  29    $this->table = '';
  30    $this->dbname =  $dbconfig['dbname'];
  31    $this->prefix =  $dbconfig['prefix'];
  32    $this->sql = '';
  33    $this->history = array();
  34    
  35    $this->mysqli = new mysqli($dbconfig['host'], $dbconfig['login'], str_rot13(base64_decode($dbconfig['password'])),
  36    $dbconfig['dbname'], $dbconfig['port'] > 0 ?  $dbconfig['port'] : null);
  37    
  38    if (mysqli_connect_error()) {
  39      throw new Exception('Error connect to database');
  40    }
  41    
  42    $this->mysqli->set_charset('utf8');
  43    //$this->query('SET NAMES utf8');
  44    
  45    /* lost performance
  46    $timezone = date('Z') / 3600;
  47    if ($timezone > 0) $timezone = "+$timezone";
  48    $this->query("SET time_zone = '$timezone:00'");
  49    */
  50  }
  51  
  52  /*
  53  public function __destruct() {
  54    if (is_object($this)) {
  55      if (is_object($this->mysqli)) $this->mysqli->close();
  56      $this->mysqli = false;
  57    }
  58  }
  59  */
  60  
  61  public function __get ($name) {
  62    return $this->prefix . $name;
  63  }
  64  
  65  public function  exec($sql) {
  66    return $this->query($sql);
  67  }
  68  
  69  public function query($sql) {
  70    $this->sql = $sql;
  71    if (litepublisher::$debug) {
  72      $this->history[] = array(
  73      'sql' => $sql,
  74      'time' => 0
  75      );
  76      $microtime = microtime(true);
  77    }
  78    
  79    if (is_object($this->result)) $this->result->close();
  80    $this->result = $this->mysqli->query($sql);
  81    if (litepublisher::$debug) {
  82      $this->history[count($this->history) - 1]['time'] = microtime(true) - $microtime;
  83      if ($this->mysqli->warning_count && ($r = $this->mysqli->query('SHOW WARNINGS'))) {
  84        echo "<pre>\n";
  85        echo $sql, "\n";
  86        var_dump($r->fetch_assoc ());
  87        echo "</pre>\n";
  88      }
  89    }
  90    if ($this->result == false) {
  91      $this->doerror($this->mysqli->error);
  92    }
  93    return $this->result;
  94  }
  95  
  96  private function doerror($mesg) {
  97    if (litepublisher::$debug) {
  98      $log = "exception:\n$mesg\n$this->sql\n";
  99      try {
 100        throw new Exception();
 101      } catch (Exception $e) {
 102        $log .=str_replace(litepublisher::$paths->home, '', $e->getTraceAsString());
 103      }
 104      $man = tdbmanager::i();
 105      $log .= $man->performance();
 106      $log = str_replace("\n", "<br />\n", htmlspecialchars($log));
 107      die($log);
 108    } else {
 109      litepublisher::$options->trace($this->sql . "\n" . $mesg);
 110    }
 111  }
 112  
 113  public function quote($s) {
 114    return sprintf('\'%s\'', $this->mysqli->real_escape_string($s));
 115  }
 116  
 117  public function escape($s) {
 118    return $this->mysqli->real_escape_string($s);
 119  }
 120  
 121  public function settable($table) {
 122    $this->table = $table;
 123    return $this;
 124  }
 125  
 126  public function select($where) {
 127    if ($where != '') $where = 'where '. $where;
 128    return $this->query("SELECT * FROM $this->prefix$this->table $where");
 129  }
 130  
 131  public function idselect($where) {
 132    return $this->res2id($this->query("select id from $this->prefix$this->table where $where"));
 133  }
 134  
 135  public function selectassoc($sql) {
 136    return $this->query($sql)->fetch_assoc();
 137  }
 138  
 139  public function getassoc($where) {
 140    return $this->select($where)->fetch_assoc();
 141  }
 142  
 143  public function update($values, $where) {
 144    return $this->query("update $this->prefix$this->table set " . $values  ." where $where");
 145  }
 146  
 147  public function idupdate($id, $values) {
 148    return $this->update($values, "id = $id");
 149  }
 150  
 151  public function updateassoc(array $a) {
 152    $list = array();
 153    foreach ($a As $name => $value) {
 154      if ($name == 'id') continue;
 155      if (is_bool($value)) {
 156        $value =$value ? '1' : '0';
 157        $list[] = sprintf('%s = %s ', $name, $value);
 158        continue;
 159      }
 160      
 161      $list[] = sprintf('%s = %s', $name,  $this->quote($value));
 162    }
 163    
 164    return $this->update(implode(', ', $list), 'id = '. $a['id'] . ' limit 1');
 165  }
 166  
 167  public function insertrow($row) {
 168    return $this->query(sprintf('INSERT INTO %s%s %s', $this->prefix, $this->table, $row));
 169  }
 170  
 171  public function insertassoc(array $a) {
 172    unset($a['id']);
 173    return $this->add($a);
 174  }
 175  
 176  public function addupdate(array $a) {
 177    if ($this->idexists($a['id'])) {
 178      $this->updateassoc($a);
 179    } else {
 180      return $this->add($a);
 181    }
 182  }
 183  
 184  public function add(array $a) {
 185    $this->insertrow($this->assoctorow($a));
 186    if ($id = $this->mysqli->insert_id) return $id;
 187    $r = $this->query('select last_insert_id() from ' . $this->prefix . $this->table)->fetch_row();
 188    return (int) $r[0];
 189  }
 190  
 191  public function insert(array $a) {
 192    $this->insertrow($this->assoctorow($a));
 193  }
 194  
 195  public function assoctorow(array $a) {
 196    $vals = array();
 197    foreach( $a as $name => $val) {
 198      if (is_bool($val)) {
 199        $vals[] = $val ? '1' : '0';
 200      } else {
 201        $vals[] = $this->quote($val);
 202      }
 203    }
 204    return sprintf('(%s) values (%s)', implode(', ', array_keys($a)), implode(', ', $vals));
 205  }
 206  
 207  public function getcount($where = '') {
 208    $sql = "SELECT COUNT(*) as count FROM $this->prefix$this->table";
 209    if ($where != '') $sql .= ' where '. $where;
 210    if (($res = $this->query($sql)) && ($r = $res->fetch_assoc())) {
 211      return (int) $r['count'];
 212    }
 213    return false;
 214  }
 215  
 216  public function delete($where) {
 217    return $this->query("delete from $this->prefix$this->table where $where");
 218  }
 219  
 220  public function iddelete($id) {
 221    return $this->query("delete from $this->prefix$this->table where id = $id");
 222  }
 223  
 224  public function deleteitems(array $items) {
 225    return $this->delete('id in ('. implode(', ', $items) . ')');
 226  }
 227  
 228  public function idexists($id) {
 229    if ($r = $this->query("select id  from $this->prefix$this->table where id = $id limit 1")->fetch_assoc()) return true;
 230    return false;
 231  }
 232  
 233  public function  exists($where) {
 234    if ($this->query("select *  from $this->prefix$this->table where $where limit 1")->num_rows) return true;
 235    return false;
 236  }
 237  
 238  public function getlist(array $list) {
 239    return $this->res2assoc($this->select(sprintf('id in (%s)', implode(',', $list))));
 240  }
 241  
 242  public function getitems($where) {
 243    return $this->res2assoc($this->select($where));
 244  }
 245  
 246  public function getitem($id) {
 247    if ($r = $this->query("select * from $this->prefix$this->table where id = $id limit 1")) return $r->fetch_assoc();
 248    return false;
 249  }
 250  
 251  public function finditem($where) {
 252    return $this->query("select * from $this->prefix$this->table where $where limit 1")->fetch_assoc();
 253  }
 254  
 255  public function findid($where) {
 256    if($r = $this->query("select id from $this->prefix$this->table where $where limit 1")->fetch_assoc()) return $r['id'];
 257    return false;
 258  }
 259  
 260  public function getval($table, $id, $name) {
 261    if ($r = $this->query("select $name from $this->prefix$table where id = $id limit 1")->fetch_assoc()) return $r[$name];
 262    return false;
 263  }
 264  
 265  public function getvalue($id, $name) {
 266    if ($r = $this->query("select $name from $this->prefix$this->table where id = $id limit 1")->fetch_assoc()) return $r[$name];
 267    return false;
 268  }
 269  
 270  public function setvalue($id, $name, $value) {
 271    return $this->update("$name = " . $this->quote($value), "id = $id");
 272  }
 273  
 274  public function res2array($res) {
 275    $result = array();
 276    if (is_object($res)) {
 277      while ($row = $res->fetch_row()) {
 278        $result[] = $row;
 279      }
 280      return $result;
 281    }
 282  }
 283  
 284  public function res2id($res) {
 285    $result = array();
 286    if (is_object($res)) {
 287      while ($row = $res->fetch_row()) {
 288        $result[] = $row[0];
 289      }
 290    }
 291    return $result;
 292  }
 293  
 294  public function res2assoc($res) {
 295    $result = array();
 296    if (is_object($res)) {
 297      while ($r = $res->fetch_assoc()) {
 298        $result[] = $r;
 299      }
 300    }
 301    return $result;
 302  }
 303  
 304  public function res2items($res) {
 305    $result = array();
 306    if (is_object($res)) {
 307      while ($r = $res->fetch_assoc()) {
 308        $result[(int) $r['id']] = $r;
 309      }
 310    }
 311    return $result;
 312  }
 313  
 314  public function fetchassoc($res) {
 315    return is_object($res) ? $res->fetch_assoc() : false;
 316  }
 317  
 318  public function fetchnum($res) {
 319    return is_object($res) ? $res->fetch_row() : false;
 320  }
 321  
 322  public function countof($res) {
 323    return  is_object($res) ? $res->num_rows : 0;
 324  }
 325  
 326  public static function str2array($s) {
 327    $result = array();
 328    foreach (explode(',', $s) as $i => $value) {
 329      $v = (int) trim($value);
 330      if ($v== 0) continue;
 331      $result[] = $v;
 332    }
 333    return $result;
 334  }
 335  
 336}//class
 337
 338//data.class.php
 339class tdata {
 340  public $basename;
 341  public $cache;
 342  public $coclasses;
 343  public $coinstances;
 344  public $data;
 345  public $lockcount;
 346  public $table;
 347  
 348  public static function i() {
 349    return getinstance(get_called_class());
 350  }
 351  
 352  public static function instance() {
 353    return getinstance(get_called_class());
 354  }
 355  
 356  public function __construct() {
 357    $this->lockcount = 0;
 358    $this->cache= true;
 359    $this->data= array();
 360    $this->coinstances = array();
 361    $this->coclasses = array();
 362    $this->basename = substr(get_class($this), 1);
 363    $this->create();
 364  }
 365  
 366  protected function create() {
 367  }
 368  
 369  public function __get($name) {
 370    if (method_exists($this, $get = 'get' . $name))  {
 371      return $this->$get();
 372    } elseif (array_key_exists($name, $this->data)) {
 373      return $this->data[$name];
 374    } else {
 375      foreach ($this->coinstances as $coinstance) {
 376        if (isset($coinstance->$name)) return $coinstance->$name;
 377      }
 378      return    $this->error(sprintf('The requested property "%s" not found in class  %s', $name, get_class($this)));
 379    }
 380  }
 381  
 382  public function __set($name, $value) {
 383    if (method_exists($this, $set = 'set' . $name)) {
 384      $this->$set($value);
 385      return true;
 386    }
 387    
 388    if (key_exists($name, $this->data)) {
 389      $this->data[$name] = $value;
 390      return true;
 391    }
 392    
 393    foreach ($this->coinstances as $coinstance) {
 394      if (isset($coinstance->$name)) {
 395        $coinstance->$name = $value;
 396        return true;
 397      }
 398    }
 399    
 400    return false;
 401  }
 402  
 403  public  function __call($name, $params) {
 404    if (method_exists($this, strtolower($name))) {
 405      return call_user_func_array(array($this, strtolower($name)), $params);
 406    }
 407    
 408    foreach ($this->coinstances as $coinstance) {
 409      if (method_exists($coinstance, $name) || $coinstance->method_exists($name))
 410      return call_user_func_array(array($coinstance, $name), $params);
 411    }
 412    $this->error("The requested method $name not found in class " . get_class($this));
 413  }
 414  
 415  public function __isset($name) {
 416    if (array_key_exists($name, $this->data) || method_exists($this, "get$name") || method_exists($this, "Get$name")) return true;
 417    foreach ($this->coinstances as $coinstance) {
 418      if (isset($coinstance->$name)) return true;
 419    }
 420    return false;
 421  }
 422  
 423  public function method_exists($name) {
 424    return false;
 425  }
 426  
 427  public function error($Msg, $code = 0) {
 428    throw new Exception($Msg, $code);
 429  }
 430  
 431  public function getbasename() {
 432    return $this->basename;
 433  }
 434  
 435  public function install() {
 436    $this->externalchain('Install');
 437  }
 438  
 439  public function uninstall() {
 440    $this->externalchain('Uninstall');
 441  }
 442  
 443  public function validate($repair = false) {
 444    $this->externalchain('Validate', $repair);
 445  }
 446  
 447  protected function externalchain($func, $arg = null) {
 448    $parents = class_parents($this);
 449    array_splice($parents, 0, 0, get_class($this));
 450    foreach ($parents as $key => $class) {
 451      $this->externalfunc($class, $func, $arg);
 452    }
 453  }
 454  
 455  public function externalfunc($class, $func, $args) {
 456    if ($filename = litepublisher::$classes->getclassfilename($class, true)) {
 457      $externalname = basename($filename, '.php') . '.install.php';
 458      $dir = dirname($filename) . DIRECTORY_SEPARATOR;
 459      $file = $dir . 'install' . DIRECTORY_SEPARATOR . $externalname;
 460      if (!file_exists($file)) {
 461        $file =$dir .  $externalname;
 462        if (!file_exists($file)) return;
 463      }
 464      include_once($file);
 465      $fnc = $class . $func;
 466      if (function_exists($fnc)) {
 467        //$fnc($this, $arg);
 468        if (is_array($args)) {
 469          array_unshift($args, $this);
 470        } else {
 471          $args = array($this, $args);
 472        }
 473        return call_user_func_array($fnc, $args);
 474      }
 475    }
 476  }
 477  
 478  public function load() {
 479    //if ($this->dbversion == 'full') return $this->LoadFromDB();
 480    return tfilestorage::load($this);
 481  }
 482  
 483  public function save() {
 484    if ($this->lockcount) return;
 485    if ($this->dbversion) {
 486      $this->SaveToDB();
 487    } else {
 488      tfilestorage::save($this);
 489    }
 490  }
 491  
 492  public function savetostring() {
 493    return serialize($this->data);
 494  }
 495  
 496  public function loadfromstring($s) {
 497    try {
 498      if (!empty($s)) $this->data = unserialize($s) + $this->data;
 499      $this->afterload();
 500      return true;
 501    } catch (Exception $e) {
 502      echo 'Caught exception: '.  $e->getMessage() ;
 503      return false;
 504    }
 505  }
 506  
 507  public function afterload() {
 508    foreach ($this->coinstances as $coinstance) {
 509      if (method_exists($coinstance, 'afterload')) $coinstance->afterload();
 510    }
 511  }
 512  
 513  public function lock() {
 514    $this->lockcount++;
 515  }
 516  
 517  public function unlock() {
 518    if (--$this->lockcount <= 0) $this->save();
 519  }
 520  
 521  public function getlocked() {
 522    return $this->lockcount  > 0;
 523  }
 524  
 525  public function Getclass() {
 526    return get_class($this);
 527  }
 528  
 529  public function getdbversion() {
 530    return false; // dbversion == 'full';
 531  }
 532  
 533  public function getdb($table = '') {
 534    $table =$table != '' ? $table : $this->table;
 535    if ($table != '') litepublisher::$db->table = $table;
 536    return litepublisher::$db;
 537  }
 538  
 539  protected function SaveToDB() {
 540    $this->db->add($this->getbasename(), $this->savetostring());
 541  }
 542  
 543  protected function LoadFromDB() {
 544    if ($r = $this->db->select('basename = '. $this->getbasename() . "'")) {
 545      return $this->loadfromstring($r['data']);
 546    }
 547  }
 548  
 549  protected function getthistable() {
 550    return litepublisher::$db->prefix . $this->table;
 551  }
 552  
 553  public static function get_class_name($c) {
 554    return is_object($c) ? get_class($c) : trim($c);
 555  }
 556  
 557}//class
 558
 559class tfilestorage {
 560  public static $disabled;
 561  public static $memcache = false;
 562  
 563  public static function save(tdata $obj) {
 564    if (self::$disabled) return false;
 565    return self::savetofile(litepublisher::$paths->data .$obj->getbasename(), $obj->savetostring());
 566  }
 567  
 568  public static function load(tdata $obj) {
 569    if ($s = self::loadfile(litepublisher::$paths->data . $obj->getbasename() .'.php')) {
 570      return $obj->loadfromstring($s);
 571    }
 572    return false;
 573  }
 574  
 575  public static function loadfile($filename) {
 576    if (self::$memcache) {
 577      if ($s =  self::$memcache->get($filename)) return $s;
 578    }
 579    
 580    if (file_exists($filename)) {
 581      $s = self::uncomment_php(file_get_contents($filename));
 582      if (self::$memcache) self::$memcache->set($filename, $s, false, 3600);
 583      return $s;
 584    }
 585    return false;
 586  }
 587  
 588  public static function savetofile($base, $content) {
 589    if (self::$memcache) self::$memcache->set($base . '.php', $content, false, 3600);
 590    $tmp = $base .'.tmp.php';
 591    if(false === file_put_contents($tmp, self::comment_php($content))) {
 592      litepublisher::$options->trace(sprintf('Error write to file "%s"', $tmp));
 593      return false;
 594    }
 595    chmod($tmp, 0666);
 596    $filename = $base .'.php';
 597    if (file_exists($filename)) {
 598      $back = $base . '.bak.php';
 599      self::delete($back);
 600      rename($filename, $back);
 601    }
 602    if (!rename($tmp, $filename)) {
 603      litepublisher::$options->trace(sprintf('Error rename temp file "%s" to "%s"', $tmp, $filename));
 604      return false;
 605    }
 606    return true;
 607  }
 608  
 609  public static function delete($filename) {
 610    if (file_exists($filename)) {
 611      if (!unlink($filename)) {
 612        chmod($filename, 0666);
 613        unlink($filename);
 614      }
 615    }
 616    
 617    if (self::$memcache) self::$memcache->delete($filename);
 618  }
 619  
 620  public static function getfile($filename) {
 621    if (self::$memcache) {
 622      if ($s =  self::$memcache->get($filename)) return $s;
 623    }
 624    
 625    if (file_exists($filename)) {
 626      $s = file_get_contents($filename);
 627      if (self::$memcache) self::$memcache->set($filename, $s, false, 3600);
 628      return $s;
 629    }
 630    return false;
 631  }
 632  
 633  public static function setfile($filename, $content) {
 634    if (self::$memcache) self::$memcache->set($filename, $content, false, 3600);
 635    file_put_contents($filename, $content);
 636    @chmod($filename, 0666);
 637  }
 638  
 639  public static function savevar($filename, &$var) {
 640    return self::savetofile($filename, serialize($var));
 641  }
 642  
 643  public static function loadvar($filename, &$var) {
 644    if ($s = self::loadfile($filename . '.php')) {
 645      $var = unserialize($s);
 646      return true;
 647    }
 648    return false;
 649  }
 650  
 651  public static function comment_php($s) {
 652    return sprintf('<?php /* %s */ ?>', str_replace('*/', '**//*/', $s));
 653  }
 654  
 655  public static function uncomment_php($s) {
 656    return str_replace('**//*/', '*/', substr($s, 9, strlen($s) - 9 - 6));
 657  }
 658  
 659}//class
 660
 661class tstorage extends tfilestorage {
 662  public static $data;
 663  private static $modified;
 664  
 665  public static function save(tdata $obj) {
 666    self::$modified = true;
 667    $base = $obj->getbasename();
 668    if (!isset(self::$data[$base])) self::$data[$base] = &$obj->data;
 669    return true;
 670  }
 671  
 672  public static function load(tdata $obj) {
 673    $base = $obj->getbasename();
 674    if (isset(self::$data[$base])) {
 675      $obj->data = &self::$data[$base];
 676      $obj->afterload();
 677      return true;
 678    } else {
 679      self::$data[$base] = &$obj->data;
 680      return false;
 681    }
 682  }
 683  
 684  public static function savemodified() {
 685    if (self::$modified) {
 686      if (self::$disabled) return false;
 687      $lock = litepublisher::$paths->data .'storage.lok';
 688      if (($fh = @fopen($lock, 'w')) &&       flock($fh, LOCK_EX | LOCK_NB)) {
 689        self::savetofile(litepublisher::$paths->data .'storage', serialize(self::$data));
 690        flock($fh, LOCK_UN);
 691        fclose($fh);
 692        @chmod($lock, 0666);
 693      } else {
 694        tfiler::log('Storage locked, data not saved');
 695      }
 696      self::$modified = false;
 697      return true;
 698    }
 699    return false;
 700  }
 701  
 702  public static function loaddata() {
 703    self::$data = array();
 704    return self::loadvar(litepublisher::$paths->data . 'storage', self::$data);
 705  }
 706  
 707}//class
 708
 709class tarray2prop {
 710  public $array;
 711public function __construct(array $a = null) { $this->array = $a; }
 712public function __destruct() { unset($this->array); }
 713public function __get($name) { return $this->array[$name]; }
 714public function __set($name, $value) { $this->array[$name] = $value; }
 715public function __isset($name) { return array_key_exists($name, $this->array); }
 716public function __tostring() { return $this->array['']; }
 717}//class
 718
 719function sqldate($date = 0) {
 720  if ($date == 0) $date = time();
 721  return date('Y-m-d H:i:s', $date);
 722}
 723
 724function sqltime($date = 0) {
 725  if ($date == 0) return '0000-00-00 00:00:00';
 726  return date('Y-m-d H:i:s', $date);
 727}
 728
 729function dbquote($s) {
 730  return litepublisher::$db->quote($s);
 731}
 732
 733function md5uniq() {
 734  return basemd5(mt_rand() . litepublisher::$secret. microtime());
 735}
 736
 737function basemd5($s) {
 738  return trim(base64_encode(md5($s, true)), '=');
 739}
 740
 741function strbegin($s, $begin) {
 742  return strncmp($s, $begin, strlen($begin)) == 0;
 743}
 744
 745function strbegins() {
 746  $a = func_get_args();
 747  $s = array_shift($a);
 748  while ($begin = array_shift($a)) {
 749    if (strncmp($s, $begin, strlen($begin)) == 0) return true;
 750  }
 751  return false;
 752}
 753
 754function strend($s, $end) {
 755  return $end == substr($s, 0 - strlen($end));
 756}
 757
 758function strip_utf($s) {
 759  $utf = "\xEF\xBB\xBF";
 760  return strbegin($s, $utf) ? substr($s, strlen($utf)) : $s;
 761}
 762
 763function array_delete(array &$a, $i) {
 764  array_splice($a, $i, 1);
 765}
 766
 767function array_delete_value(array &$a, $value) {
 768  $i = array_search($value, $a);
 769  if ($i !== false)         array_splice($a, $i, 1);
 770}
 771
 772function array_clean(array &$items) {
 773  $items = array_unique($items);
 774  foreach (array(0, false, null, '') as $v) {
 775    $i = array_search($v, $items);
 776    if ($i !== false)         array_splice($items, $i, 1);
 777  }
 778}
 779
 780function array_insert(array &$a, $item, $index) {
 781  array_splice($a, $index, 0, array($item));
 782}
 783
 784function array_move(array &$a, $oldindex, $newindex) {
 785  //delete and insert
 786  if (($oldindex == $newindex) || !isset($a[$oldindex])) return false;
 787  $item = $a[$oldindex];
 788  array_splice($a, $oldindex, 1);
 789  array_splice($a, $newindex, 0, array($item));
 790}
 791
 792function strtoarray($s) {
 793  $a = explode("\n", trim($s));
 794  foreach ($a as $k => $v) $a[$k] = trim($v);
 795  return $a;
 796}
 797
 798function tojson($a) {
 799  if (defined('JSON_NUMERIC_CHECK')) {
 800    return json_encode($a, JSON_NUMERIC_CHECK | (defined('JSON_UNESCAPED_UNICODE') ? JSON_UNESCAPED_UNICODE : 0));
 801  }
 802  
 803  return json_encode($a);
 804}
 805
 806function jsonattr($a) {
 807  return str_replace('"', '&quot;', tojson($a));
 808}
 809
 810function toenum($v, array $a) {
 811  $v = trim($v);
 812  return in_array($v, $a) ? $v : $a[0];
 813}
 814
 815function dumpstr($s) {
 816  echo "<pre>\n", htmlspecialchars($s), "</pre>\n";
 817}
 818
 819function dumpvar($v) {
 820  echo "<pre>\n";
 821  var_dump($v);
 822  echo "</pre>\n";
 823}
 824
 825//events.class.php
 826class ECancelEvent extends Exception {
 827  public $result;
 828  
 829  public function __construct($message, $code = 0) {
 830    $this->result = $message;
 831    parent::__construct('', 0);
 832  }
 833}
 834
 835class tevents extends tdata {
 836  protected $events;
 837  protected $eventnames;
 838  protected $map;
 839  
 840  public function __construct() {
 841    $this->eventnames = array();
 842    $this->map = array();
 843    parent::__construct();
 844    $this->assignmap();
 845    $this->load();
 846  }
 847  
 848  public function __destruct() {
 849    unset($this->data, $this->events, $this->eventnames, $this->map);
 850  }
 851  
 852  protected function create() {
 853    $this->addmap('events', array());
 854    $this->addmap('coclasses', array());
 855  }
 856  
 857  public function assignmap() {
 858    foreach ($this->map as $propname => $key) {
 859      $this->$propname = &$this->data[$key];
 860    }
 861  }
 862  
 863  public function afterload() {
 864    $this->assignmap();
 865    foreach ($this->coclasses as $coclass) {
 866      $this->coinstances[] = getinstance($coclass);
 867    }
 868    parent::afterload();
 869  }
 870  
 871  protected function addmap($name, $value) {
 872    $this->map[$name] = $name;
 873    $this->data[$name] = $value;
 874    $this->$name = &$this->data[$name];
 875  }
 876  
 877  public function free() {
 878    unset(litepublisher::$classes->instances[get_class($this)]);
 879    foreach ($this->coinstances as $coinstance) $coinstance->free();
 880  }
 881  
 882  public function eventexists($name) {
 883    return in_array($name, $this->eventnames);
 884  }
 885  
 886  public function __get($name) {
 887    if (method_exists($this, $name)) return array('class' =>get_class($this), 'func' => $name);
 888    return parent::__get($name);
 889  }
 890  
 891  public function __set($name, $value) {
 892    if (parent::__set($name, $value)) return true;
 893    if (in_array($name, $this->eventnames)) {
 894      $this->addevent($name, $value['class'], $value['func']);
 895      return true;
 896    }
 897    $this->error("Unknown property $name in class ". get_class($this));
 898  }
 899  
 900  public function method_exists($name) {
 901    return in_array($name, $this->eventnames);
 902  }
 903  
 904  public  function __call($name, $params) {
 905    if (in_array($name, $this->eventnames)) return $this->callevent($name, $params);
 906    parent::__call($name, $params);
 907  }
 908  
 909  public function __isset($name) {
 910    if (parent::__isset($name)) return true;
 911    return in_array($name, $this->eventnames);
 912  }
 913  
 914  protected function addevents() {
 915    $a = func_get_args();
 916    array_splice($this->eventnames, count($this->eventnames), 0, $a);
 917  }
 918  
 919  private function get_events($name) {
 920    return isset($this->events[$name]) ? $this->events[$name] : false;
 921  }
 922  
 923  public function callevent($name, $params) {
 924    $result = '';
 925    if (    $list = $this->get_events($name)) {
 926      
 927      foreach ($list as $i => $item) {
 928        if (empty($item['class'])) {
 929          if (function_exists($item['func'])) {
 930            $call = $item['func'];
 931          } else {
 932            $this->delete_event_item($name, $i);
 933            continue;
 934          }
 935        } elseif (!class_exists($item['class'])) {
 936          $this->delete_event_item($name, $i);
 937          continue;
 938        } else {
 939          $obj = getinstance($item['class']);
 940          $call = array($obj, $item['func']);
 941        }
 942        try {
 943          $result = call_user_func_array($call, $params);
 944        } catch (ECancelEvent $e) {
 945          return $e->result;
 946        }
 947      }
 948    }
 949    
 950    return $result;
 951  }
 952  
 953  public static function cancelevent($result) {
 954    throw new ECancelEvent($result);
 955  }
 956  
 957  private function delete_event_item($name, $i) {
 958    array_splice($this->events[$name], $i, 1);
 959    if (count($this->events[$name]) == 0) unset($this->events[$name]);
 960    $this->save();
 961  }
 962  
 963  public function setevent($name, $params) {
 964    return $this->addevent($name, $params['class'], $params['func']);
 965  }
 966  
 967  public function addevent($name, $class, $func) {
 968    if (!in_array($name, $this->eventnames)) return $this->error(sprintf('No such %s event', $name ));
 969    if (empty($func)) return false;
 970    if (isset($this->events[$name])) {
 971      if ($list = $this->get_events($name)) {
 972        foreach ($list  as $event) {
 973          if (($event['class'] == $class) && ($event['func'] == $func)) return false;
 974        }
 975      }
 976    } else {
 977      $this->events[$name] =array();
 978    }
 979    
 980    $this->events[$name][] = array(
 981    'class' => $class,
 982    'func' => $func
 983    );
 984    $this->save();
 985  }
 986  
 987  public function delete_event_class($name, $class) {
 988    if (isset($this->events[$name])) {
 989      $list = &$this->events[$name];
 990      $deleted = false;
 991      for ($i = count($list) - 1; $i >= 0; $i--) {
 992        if ($list[$i]['class'] == $class) {
 993          array_splice($list, $i, 1);
 994          $deleted = true;
 995        }
 996      }
 997      if ($deleted) {
 998        if (count($list) == 0) unset($this->events[$name]);
 999        $this->save();
1000      }
1001      return $deleted;
1002    }
1003    return false;
1004  }
1005  
1006  public function unsubscribeclass($obj) {
1007    $this->unbind($obj);
1008  }
1009  
1010  public function unsubscribeclassname($class) {
1011    $this->unbind($class);
1012  }
1013  
1014  public function unbind($c) {
1015    $class = self::get_class_name($c);
1016    foreach ($this->events as $name => $events) {
1017      foreach ($events as $i => $item) {
1018        if ($item['class'] == $class) array_splice($this->events[$name], $i, 1);
1019      }
1020    }
1021    
1022    $this->save();
1023  }
1024  
1025  public function seteventorder($eventname, $c, $order) {
1026    if (!isset($this->events[$eventname])) return false;
1027    $events = &$this->events[$eventname];
1028    $class = self::get_class_name($c);
1029    $count = count($events);
1030    if (($order < 0) || ($order >= $count)) $order = $count - 1;
1031    foreach ($events as $i => $event) {
1032      if ($class == $event['class']) {
1033        if ($i == $order) return true;
1034        array_splice($events, $i, 1);
1035        array_splice($events, $order, 0, array(0 => $event));
1036        $this->save();
1037        return true;
1038      }
1039    }
1040  }
1041  
1042  private function indexofcoclass($class) {
1043    return array_search($class, $this->coclasses);
1044  }
1045  
1046  public function addcoclass($class) {
1047    if ($this->indexofcoclass($class) === false) {
1048      $this->coclasses[] = $class;
1049      $this->save();
1050      $this->coinstances = getinstance($class);
1051    }
1052  }
1053  
1054  public function deletecoclass($class) {
1055    $i = $this->indexofcoclass($class);
1056    if (is_int($i)) {
1057      array_splice($this->coclasses, $i, 1);
1058      $this->save();
1059    }
1060  }
1061  
1062}//class
1063
1064class tevents_storage extends tevents {
1065  
1066  public function load() {
1067    return tstorage::load($this);
1068  }
1069  
1070  public function save() {
1071    return tstorage::save($this);
1072  }
1073  
1074}//class
1075
1076class tcoevents extends tevents {
1077  private $owner;
1078  
1079  public function __construct() {
1080    parent::__construct();
1081    $a = func_get_args();
1082    $owner = array_shift ($a);
1083    $this->owner = $owner;
1084    if (!isset($owner->data['events'])) $owner->data['events'] = array();
1085    $this->events = &$owner->data['events'];
1086    array_splice($this->eventnames, count($this->eventnames), 0, $a);
1087  }
1088  
1089  public function __destruct() {
1090    parent::__destruct();
1091    unset($this->owner);
1092  }
1093  
1094public function assignmap() {}
1095protected function create() { }
1096public function load() {}
1097  public function afterload() {
1098    $this->events = &$this->owner->data['events'];
1099  }
1100  
1101  public function save() {
1102    return $this->owner->save();
1103  }
1104  
1105}//class
1106
1107//items.class.php
1108class titems extends tevents {
1109  public $items;
1110  protected $autoid;
1111  public $dbversion;
1112  
1113  protected function create() {
1114    parent::create();
1115    $this->addevents('added', 'deleted');
1116    if ($this->dbversion) {
1117      $this->items = array();
1118    } else {
1119      $this->addmap('items', array());
1120      $this->addmap('autoid', 0);
1121    }
1122  }
1123  
1124  public function load() {
1125    if ($this->dbversion) {
1126      return tstorage::load($this);
1127    } else {
1128      return parent::load();
1129    }
1130  }
1131  
1132  public function save() {
1133    if ($this->lockcount > 0) return;
1134    if ($this->dbversion) {
1135      return tstorage::save($this);
1136    } else {
1137      return parent::save();
1138    }
1139  }
1140  
1141  public function loadall() {
1142    if (!$this->dbversion)  return;
1143    return $this->select('', '');
1144  }
1145  
1146  public function loaditems(array $items) {
1147    if (!$this->dbversion) return;
1148    //exclude loaded items
1149    $items = array_diff($items, array_keys($this->items));
1150    if (count($items) == 0) return;
1151    $list = implode(',', $items);
1152    $this->select("$this->thistable.id in ($list)", '');
1153  }
1154  
1155  public function select($where, $limit) {
1156    if (!$this->dbversion) $this->error('Select method must be called ffrom database version');
1157    if ($where != '') $where = 'where '. $where;
1158    return $this->res2items($this->db->query("SELECT * FROM $this->thistable $where $limit"));
1159  }
1160  
1161  public function res2items($res) {
1162    if (!$res) return array();
1163    $result = array();
1164    $db = litepublisher::$db;
1165    while ($item = $db->fetchassoc($res)) {
1166      $id = $item['id'];
1167      $result[] = $id;
1168      $this->items[$id] = $item;
1169    }
1170    return $result;
1171  }
1172  
1173  public function getcount() {
1174    if ($this->dbversion) {
1175      return $this->db->getcount();
1176    } else {
1177      return count($this->items);
1178    }
1179  }
1180  
1181  public function getitem($id) {
1182    if (isset($this->items[$id])) return $this->items[$id];
1183    if ($this->dbversion) {
1184      if ($this->select("$this->thistable.id = $id", 'limit 1')) return $this->items[$id];
1185    }
1186    return $this->error(sprintf('Item %d not found in class %s', $id, get_class($this)));
1187  }
1188  
1189  public function getvalue($id, $name) {
1190    if ($this->dbversion && !isset($this->items[$id])) $this->items[$id] = $this->db->getitem($id);
1191    return $this->items[$id][$name];
1192  }
1193  
1194  public function setvalue($id, $name, $value) {
1195    $this->items[$id][$name] = $value;
1196    if ($this->dbversion) {
1197      $this->db->setvalue($id, $name, $value);
1198    }
1199  }
1200  
1201  public function itemexists($id) {
1202    if (isset($this->items[$id])) return true;
1203    if ($this->dbversion) {
1204      try {
1205        return $this->getitem($id);
1206      } catch (Exception $e) {
1207        return false;
1208      }
1209    }
1210    return false;
1211  }
1212  
1213  public function indexof($name, $value) {
1214    if ($this->dbversion){
1215      return $this->db->findid("$name = ". dbquote($value));
1216    }
1217    
1218    foreach ($this->items as $id => $item) {
1219      if ($item[$name] == $value) {
1220        return $id;
1221      }
1222    }
1223    return false;
1224  }
1225  
1226  public function additem(array $item) {
1227    $id = $this->dbversion ? $this->db->add($item) : ++$this->autoid;
1228    $item['id'] = $id;
1229    $this->items[$id] = $item;
1230    if (!$this->dbversion) $this->save();
1231    $this->added($id);
1232    return $id;
1233  }
1234  
1235  public function delete($id) {
1236    if ($this->dbversion) $this->db->delete("id = $id");
1237    if (isset($this->items[$id])) {
1238      unset($this->items[$id]);
1239      if (!$this->dbversion) $this->save();
1240      $this->deleted($id);
1241      return true;
1242    }
1243    return false;
1244  }
1245  
1246}//class
1247
1248class titems_storage extends titems {
1249  
1250  public function load() {
1251    return tstorage::load($this);
1252  }
1253  
1254  public function save() {
1255    return tstorage::save($this);
1256  }
1257  
1258}//class
1259
1260class tsingleitems extends titems {
1261  public static $instances;
1262  public $id;
1263  
1264  public static function singleinstance($class, $id = 0) {
1265    if (!isset(self::$instances)) self::$instances = array();
1266    if (isset(self::$instances[$class][$id]))     return self::$instances[$class][$id];
1267    $self = litepublisher::$classes->newinstance($class);
1268    self::$instances[$class][$id] = $self;
1269    $self->id = $id;
1270    $self->load();
1271    return $self;
1272  }
1273  
1274  public function load() {
1275    if (!isset($this->id)) return false;
1276    return parent::load();
1277  }
1278  
1279  public function free() {
1280    unset(self::$instances[get_class($this)][$this->id]);
1281  }
1282  
1283}//class
1284
1285//item.class.php
1286class titem extends tdata {
1287  public static $instances;
1288  //public $id;
1289  
1290  public static function iteminstance($class, $id = 0) {
1291    $name = call_user_func_array(array($class, 'getinstancename'), array());
1292    if (!isset(self::$instances)) self::$instances = array();
1293    if (isset(self::$instances[$name][$id]))     return self::$instances[$name][$id];
1294    $self = litepublisher::$classes->newitem($name, $class, $id);
1295    return $self->loaddata($id);
1296  }
1297  
1298  public function loaddata($id) {
1299    $this->data['id'] = $id;
1300    if ($id != 0) {
1301      if (!$this->load()) {
1302        $this->free();
1303        return false;
1304      }
1305      self::$instances[$this->instancename][$id] = $this;
1306    }
1307    return $this;
1308  }
1309  
1310  public function free() {
1311    unset(self::$instances[$this->getinstancename()][$this->id]);
1312  }
1313  
1314  public function __construct() {
1315    parent::__construct();
1316    $this->data['id'] = 0;
1317  }
1318  
1319  public function __destruct() {
1320    $this->free();
1321  }
1322  
1323  public function __set($name, $value) {
1324    if (parent::__set($name, $value)) return true;
1325    return  $this->Error("Field $name not exists in class " . get_class($this));
1326  }
1327  
1328  public function setid($id) {
1329    if ($id != $this->id) {
1330      $name = $this->instancename;
1331      if (!isset(self::$instances)) self::$instances = array();
1332      if (!isset(self::$instances[$name])) self::$instances[$name] = array();
1333      $a = &self::$instances[$this->instancename];
1334      if (isset(   $a[$this->id])) unset($a[$this->id]);
1335      if (isset($a[$id])) $a[$id] = 0;
1336      $a[$id] = $this;
1337      $this->data['id'] = $id;
1338    }
1339  }
1340  
1341  public function request($id) {
1342    if ($id != $this->id) {
1343      $this->setid($id);
1344      if (!$this->load()) return 404;
1345    }
1346  }
1347  
1348  public static function deletedir($dir) {
1349    if (!@file_exists($dir)) return false;
1350    tfiler::delete($dir, true, true);
1351    @rmdir($dir);
1352  }
1353  
1354}
1355
1356class titem_storage extends titem {
1357  
1358  public function getowner() {
1359    $this->error(sprintf('The "%s" no have owner', get_class($this)));
1360  }
1361  
1362  public function load() {
1363    $owner = $this->owner;
1364    if ($owner->itemexists($this->id)) {
1365      $this->data = &$owner->items[$this->id];
1366      return true;
1367    }
1368    return false;
1369  }
1370  
1371  public function save() {
1372    return $this->owner->save();
1373  }
1374  
1375}//class
1376
1377//classes.class.php
1378if (!function_exists( 'spl_autoload_register' ) ) {
1379  function __autoload($class) {
1380    litepublisher::$classes->_autoload($class);
1381  }
1382}
1383
1384class tclasses extends titems {
1385  public $classes;
1386  public $interfaces;
1387  public $remap;
1388  public $factories;
1389  public $instances;
1390  public $included_files;
1391  
1392  public static function i() {
1393    if (!isset(litepublisher::$classes)) {
1394      $class = __class__;
1395      litepublisher::$classes = new $class();
1396      litepublisher::$classes->instances[$class] = litepublisher::$classes;
1397    }
1398    return litepublisher::$classes;
1399  }
1400  
1401  public static function instance() {
1402    return self::i();
1403  }
1404  
1405  protected function create() {
1406    parent::create();
1407    $this->basename = 'classes';
1408    $this->dbversion = false;
1409    $this->addevents('onnewitem', 'gettemplatevar');
1410    $this->addmap('classes', array());
1411    $this->addmap('interfaces', array());
1412    $this->addmap('remap', array());
1413    $this->addmap('factories', array());
1414    $this->instances = array();
1415    if (function_exists('spl_autoload_register')) spl_autoload_register(array($this, '_autoload'));
1416    $this->data['memcache'] = false;
1417    $this->data['revision_memcache'] = 1;
1418    $this->included_files = array();
1419  }
1420  
1421  public function load() {
1422    return tstorage::load($this);
1423  }
1424  
1425  public function save() {
1426    return tstorage::save($this);
1427  }
1428  
1429  public function getinstance($class) {
1430    if (!class_exists($class)) {
1431      $this->error("Class $class not found");
1432    }
1433    if (!isset($this->instances[$class])) {
1434      $this->instances[$class] = $this->newinstance($class);
1435    }
1436    return $this->instances[$class];
1437  }
1438  
1439  public function newinstance($class) {
1440    if (!empty($this->remap[$class])) $class = $this->remap[$class];
1441    return new $class();
1442    /*
1443    if (preg_match('/^(tcomments|toptions|tsite|targs|ttheme)$/', $class)) return new $class();
1444    return new tdebugproxy(new $class());
1445    */
1446  }
1447  
1448  public function newitem($name, $class, $id) {
1449    if (!empty($this->remap[$class])) $class = $this->remap[$class];
1450    $this->callevent('onnewitem', array($name, &$class, $id));
1451    return new $class();
1452  }
1453  
1454  public function __get($name) {
1455    if (isset($this->classes[$name])) return $this->getinstance($this->classes[$name]);
1456    if (isset($this->items[$name])) return $this->getinstance($name);
1457    $class = 't' . $name;
1458    if (isset($this->items[$class])) return $this->getinstance($class);
1459    return parent::__get($name);
1460  }
1461  
1462  public function add($class, $filename, $path = '') {
1463    if (isset($this->items[$class]) &&
1464    ($this->items[$class][0] == $filename) && ($this->items[$class][1] == $path)) return false;
1465    
1466    $this->lock();
1467    $m = $this->memcache;
1468    $this->memcache = false;
1469    $this->items[$class] = array($filename, $path);
1470    $instance = $this->getinstance($class);
1471    if (method_exists($instance, 'install')) $instance->install();
1472    $this->memcache = $m;
1473    if ($m) $this->revision_memcache++;
1474    $this->unlock();
1475    $this->added($class);
1476    return true;
1477  }
1478  
1479  public function delete($class) {
1480    if (!isset($this->items[$class])) return false;
1481    
1482    $this->lock();
1483    $m = $this->memcache;
1484    $this->memcache = false;
1485    
1486    if (class_exists($class)) {
1487      $instance = $this->getinstance($class);
1488      if (method_exists($instance, 'uninstall')) $instance->uninstall();
1489    }
1490    
1491    unset($this->items[$class]);
1492    
1493    $this->memcache = $m;
1494    if ($m) $this->revision_memcache++;
1495    $this->unlock();
1496    $this->deleted($class);
1497  }
1498  
1499  public function reinstall($class) {
1500    if (isset($this->items[$class])) {
1501      $this->lock();
1502      $item = $this->items[$class];
1503      $this->delete($class);
1504      $this->add($class, $item[0], $item[1]);
1505      $this->unlock();
1506    }
1507  }
1508  
1509  public function _autoload($class) {
1510    if ($filename = $this->getclassfilename($class)) {
1511      $this->include_file($filename);
1512      $this->included_files[$class] = $filename;
1513    }
1514  }
1515  
1516  public function include_file($filename) {
1517    if (!tfilestorage::$memcache || litepublisher::$debug  || !$this->memcache) {
1518      if (file_exists($filename)) require_once($filename);
1519      return;
1520    }
1521    
1522    if (in_array($filename, $this->included_files)) return;
1523    
1524    if ($s =  tfilestorage::$memcache->get($filename)) {
1525      $i = strpos($s, ';');
1526      $revision = substr($s, 0, $i);
1527      if ($revision == $this->revision_memcache) {
1528        eval(substr($s, $i + 1));
1529        return;
1530      }
1531      tfilestorage::$memcache->delete($filename);
1532    }
1533    
1534    if (file_exists($filename)) {
1535      $s = file_get_contents($filename);
1536      eval('?>' . $s);
1537      //strip php tag and copyright in head
1538      if (strbegin($s, '<?php')) $s = substr($s, 5);
1539      if (strend($s, '?>')) $s = substr($s, 0, -2);
1540      $s = trim($s);
1541      if (strbegin($s, '/*')) $s = substr($s, strpos($s, '*/') + 2);
1542      $s = $this->revision_memcache . ';' . ltrim($s);
1543      tfilestorage::$memcache->set($filename, $s, false, 3600);
1544    }
1545  }
1546  
1547  public function getclassfilename($class, $debug = false) {
1548    if (isset($this->items[$class])) {
1549      $item = $this->items[$class];
1550      $filename = (litepublisher::$debug || $debug) && isset($item[2]) ? $item[2] : $item[0];
1551      if (Empty($item[1])) {
1552        return litepublisher::$paths->lib . $filename;
1553      }
1554      $filename = trim($item[1], DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . $filename;
1555      //if (file_exists($filename))  return $filename;
1556      //may be is subdir?
1557      if (file_exists(litepublisher::$paths->plugins . $filename)) return litepublisher::$paths->plugins . $filename;
1558      if (file_exists(litepublisher::$paths->themes . $filename)) return litepublisher::$paths->themes . $filename;
1559      if  (file_exists(litepublisher::$paths->home . $filename)) return  litepublisher::$paths->home . $filename;
1560    }
1561    if (isset($this->interfaces[$class])) return litepublisher::$paths->lib . $this->interfaces[$class];
1562    return false;
1563  }
1564  
1565  public function exists($class) {
1566    return isset($this->items[$class]);
1567  }
1568  
1569  public function getfactory($instance) {
1570    foreach ($this->factories as $classname => $factory) {
1571      if (@is_a($instance, $classname)) return $this->getinstance($factory);
1572    }
1573  }
1574  
1575  public function getresourcedir($c) {
1576    $class = self::get_class_name($c);
1577    if (isset($this->included_files[$class])) {
1578      $dir = dirname($this->included_files[$class]);
1579    } else {
1580      $dir = dirname($this->getclassfilename($class));
1581    }
1582    
1583    return $dir . '/resource/';
1584  }
1585  
1586}//class
1587
1588function getinstance($class) {
1589  return litepublisher::$classes->getinstance($class);
1590}
1591
1592//options.class.php
1593class toptions extends tevents_storage {
1594  public $groupnames;
1595  public $parentgroups;
1596  public $group;
1597  public $idgroups;
1598  protected $_user;
1599  protected $_admincookie;
1600  public $gmt;
1601  public $errorlog;
1602  
1603  public static function i() {
1604    return getinstance(__class__);
1605  }
1606  
1607  public static function instance() {
1608    return getinstance(__class__);
1609  }
1610  
1611  protected function create() {
1612    parent::create();
1613    $this->basename = 'options';
1614    $this->addevents('changed', 'perpagechanged', 'onsave');
1615    unset($this->cache);
1616    $this->gmt = 0;
1617    $this->errorlog = '';
1618    $this->group = '';
1619    $this->idgroups = array();
1620    $this->addmap('groupnames', array());
1621    $this->addmap('parentgroups', array());
1622  }
1623  
1624  public function afterload() {
1625    parent::afterload();
1626    date_default_timezone_set($this->timezone);
1627    $this->gmt = date('Z');
1628    if (!defined('dbversion')) define('dbversion', true);
1629  }
1630  
1631  public function savemodified() {
1632    $result = tstorage::savemodified();
1633    $this->onsave($result);
1634    return $result;
1635  }
1636  
1637  public function __set($name, $value) {
1638    if (in_array($name, $this->eventnames)) {
1639      $this->addevent($name, $value['class'], $value['func']);
1640      return true;
1641    }
1642    
1643    if (method_exists($this, $set = 'set' . $name)) {
1644      $this->$set($value);
1645      return true;
1646    }
1647    
1648    if (!array_key_exists($name, $this->data)  || ($this->data[$name] != $value)) {
1649      $this->data[$name] = $value;
1650      $this->save();
1651      $this->dochanged($name, $value);
1652    }
1653    return true;
1654  }
1655  
1656  private function dochanged($name, $value) {
1657    if ($name == 'perpage') {
1658      $this->perpagechanged();
1659      $urlmap = turlmap::i();
1660      $urlmap->clearcache();
1661    } elseif ($name == 'cache') {
1662      $urlmap = turlmap::i();
1663      $urlmap->clearcache();
1664    } else {
1665      $this->changed($name, $value);
1666    }
1667  }
1668  
1669  public function delete($name) {
1670    if (array_key_exists($name, $this->data)) {
1671      unset($this->data[$name]);
1672      $this->save();
1673    }
1674  }
1675  
1676  public function getadmincookie() {
1677    if (is_null($this->_admincookie)) {
1678      $this->_admincookie = $this->cookieenabled && isset($_COOKIE['litepubl_user_flag']) ? $this->user && in_array(1, $this->idgroups) : false;
1679    }
1680    return $this->_admincookie;
1681  }
1682  
1683  public function setadmincookie($val) {
1684    $this->_admincookie = $val;
1685  }
1686  
1687  public function getuser() {
1688    if (is_null($this->_user)) {
1689      $this->_user = $this->cookieenabled ? $this->authcookie() : false;
1690    }
1691    return $this->_user;
1692  }
1693  
1694  public function setuser($id) {
1695    $this->_user = $id;
1696  }
1697  
1698  public function authcookie() {
1699    $iduser = isset($_COOKIE['litepubl_user_id']) ? (int) $_COOKIE['litepubl_user_id'] : 0;
1700    $cookie = isset($_COOKIE['litepubl_user']) ? (string) $_COOKIE['litepubl_user'] : (isset($_COOKIE['admin']) ? (string) $_COOKIE['admin'] : '');
1701    
1702    if ($cookie == '') return false;
1703    $cookie = basemd5($cookie . litepublisher::$secret);
1704    if (    $cookie == basemd5( litepublisher::$secret)) return false;
1705    
1706    if ($iduser) {
1707      if (!$this->finduser($iduser, $cookie)) return false;
1708    } elseif ($iduser = $this->findcookie($cookie)) {
1709      //fix prev versions
1710      if ($iduser == 1) {
1711        $expired = $this->cookieexpired;
1712      } else {
1713        $item = tusers::i()->getitem($iduser);
1714        $expired = strtotime($item['expired']);
1715      }
1716      setcookie('litepubl_user_id', $iduser, $expired, litepublisher::$site->subdir . '/', false);
1717    } else {
1718      return false;
1719    }
1720    
1721    $this->_user = $iduser;
1722    $this->updategroup();
1723    return $iduser;
1724  }
1725  
1726  public function finduser($iduser, $cookie) {
1727    if ($iduser == 1) return $this->compare_cookie($cookie);
1728    if (!$this->usersenabled)  return false;
1729    
1730    $users = tusers::i();
1731    try {
1732      $item = $users->getitem($iduser);
1733    } catch (Exception $e) {
1734      return false;
1735    }
1736    
1737    if ('hold' == $item['status']) return false;
1738    return ($cookie == $item['cookie']) && (strtotime($item['expired']) > time());
1739  }
1740  
1741  public function findcookie($cookie) {
1742    if ($this->compare_cookie($cookie)) return 1;
1743    if (!$this->usersenabled)  return false;
1744    
1745    $users = tusers::i();
1746    if ($iduser = $users->findcookie($cookie)){
1747      $item = $users->getitem($iduser);
1748      if (strtotime($item['expired']) <= time()) return false;
1749      return (int) $iduser;
1750    }
1751    return false;
1752  }
1753  
1754  private function compare_cookie($cookie) {
1755    return !empty($this->cookie ) && ($this->cookie == $cookie) && ($this->cookieexpired > time());
1756  }
1757  
1758  public function auth($email, $password) {
1759    if ($email == '' && $password == '' && $this->cookieenabled) return $this->authcookie();
1760    if ($email == $this->email) {
1761      if ($this->data['password'] != basemd5("$email:$this->realm:$password"))  return false;
1762      $this->_user = 1;
1763    } elseif(!$this->usersenabled) {
1764      return false;
1765    } else {
1766      $users = tusers::i();
1767      if (!($this->_user = $users->auth($email, $password))) return false;
1768    }
1769    $this->updategroup();
1770    return true;
1771  }
1772  
1773  public function updategroup() {
1774    if ($this->_user == 1) {
1775      $this->group = 'admin';
1776      $this->idgroups = array(1);
1777    } else {
1778      $user = tusers::i()->getitem($this->_user);
1779      $this->idgroups = $user['idgroups'];
1780      $this->group = count($this->idgroups) ? tusergroups::i()->items[$this->idgroups[0]]['name'] : '';
1781    }
1782  }
1783  
1784  public function can_edit($idauthor) {
1785    return ($idauthor == $this->user) || ($this->group == 'admin') || ($this->group == 'editor');
1786  }
1787  
1788  public function getpassword() {
1789    if ($this->user <= 1) return $this->data['password'];
1790    $users = tusers::i();
1791    return $users->getvalue($this->user, 'password');
1792  }
1793  
1794  public function changepassword($newpassword) {
1795    $this->data['password'] = basemd5("$this->email:$this->realm:$newpassword");
1796    $this->save();
1797  }
1798  
1799  public function setdbpassword($password) {
1800    $this->data['dbconfig']['password'] = base64_encode(str_rot13 ($password));
1801    $this->save();
1802  }
1803  
1804  public function logout() {
1805    if ($this->cookieenabled) {
1806      $this->setcookies('', 0);
1807    } else {
1808      tauthdigest::i()->logout();
1809    }
1810  }
1811  
1812  public function setcookies($cookie, $expired) {
1813    setcookie('litepubl_user_id', $this->_user, $expired, litepublisher::$site->subdir . '/', false);
1814    setcookie('litepubl_user', $cookie, $expired, litepublisher::$site->subdir . '/', false);
1815    if ('admin' == $this->group) {
1816      setcookie('litepubl_user_flag', $cookie ? 'true' : '', $expired, litepublisher::$site->subdir . '/', false);
1817    } else {
1818      setcookie('litepubl_user_flag', '', time(), litepublisher::$site->subdir . '/', false);
1819    }
1820    if ($this->_user == 1) {
1821      $this->set_cookie($cookie);
1822      $this->cookieexpired = $expired;
1823    } else {
1824      tusers::i()->setcookie($this->_user, $cookie, $expired);
1825    }
1826  }
1827  
1828  public function Getinstalled() {
1829    return isset($this->data['email']);
1830  }
1831  
1832  public function settimezone($value) {
1833    if(!isset($this->data['timezone']) || ($this->timezone != $value)) {
1834      $this->data['timezone'] = $value;
1835      $this->save();
1836      date_default_timezone_set($this->timezone);
1837      $this->gmt = date('Z');
1838    }
1839  }
1840  
1841  public function set_cookie($cookie)

Large files files are truncated, but you can click here to view the full file