PageRenderTime 81ms CodeModel.GetById 16ms 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
Possible License(s): AGPL-1.0, GPL-3.0
  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
  9. class tdatabase {
  10. public $result;
  11. public $sql;
  12. public $dbname;
  13. public $table;
  14. public $prefix;
  15. public $history;
  16. public $mysqli;
  17. public static function i() {
  18. return getinstance(__class__);
  19. }
  20. public static function instance() {
  21. return getinstance(__class__);
  22. }
  23. public function __construct() {
  24. if (!isset(litepublisher::$options->dbconfig)) return false;
  25. $dbconfig = litepublisher::$options->dbconfig;
  26. $this->table = '';
  27. $this->dbname = $dbconfig['dbname'];
  28. $this->prefix = $dbconfig['prefix'];
  29. $this->sql = '';
  30. $this->history = array();
  31. $this->mysqli = new mysqli($dbconfig['host'], $dbconfig['login'], str_rot13(base64_decode($dbconfig['password'])),
  32. $dbconfig['dbname'], $dbconfig['port'] > 0 ? $dbconfig['port'] : null);
  33. if (mysqli_connect_error()) {
  34. throw new Exception('Error connect to database');
  35. }
  36. $this->mysqli->set_charset('utf8');
  37. //$this->query('SET NAMES utf8');
  38. /* lost performance
  39. $timezone = date('Z') / 3600;
  40. if ($timezone > 0) $timezone = "+$timezone";
  41. $this->query("SET time_zone = '$timezone:00'");
  42. */
  43. }
  44. /*
  45. public function __destruct() {
  46. if (is_object($this)) {
  47. if (is_object($this->mysqli)) $this->mysqli->close();
  48. $this->mysqli = false;
  49. }
  50. }
  51. */
  52. public function __get ($name) {
  53. return $this->prefix . $name;
  54. }
  55. public function exec($sql) {
  56. return $this->query($sql);
  57. }
  58. public function query($sql) {
  59. $this->sql = $sql;
  60. if (litepublisher::$debug) {
  61. $this->history[] = array(
  62. 'sql' => $sql,
  63. 'time' => 0
  64. );
  65. $microtime = microtime(true);
  66. }
  67. if (is_object($this->result)) $this->result->close();
  68. $this->result = $this->mysqli->query($sql);
  69. if (litepublisher::$debug) {
  70. $this->history[count($this->history) - 1]['time'] = microtime(true) - $microtime;
  71. if ($this->mysqli->warning_count && ($r = $this->mysqli->query('SHOW WARNINGS'))) {
  72. echo "<pre>\n";
  73. echo $sql, "\n";
  74. var_dump($r->fetch_assoc ());
  75. echo "</pre>\n";
  76. }
  77. }
  78. if ($this->result == false) {
  79. $this->doerror($this->mysqli->error);
  80. }
  81. return $this->result;
  82. }
  83. private function doerror($mesg) {
  84. if (litepublisher::$debug) {
  85. $log = "exception:\n$mesg\n$this->sql\n";
  86. try {
  87. throw new Exception();
  88. } catch (Exception $e) {
  89. $log .=str_replace(litepublisher::$paths->home, '', $e->getTraceAsString());
  90. }
  91. $man = tdbmanager::i();
  92. $log .= $man->performance();
  93. $log = str_replace("\n", "<br />\n", htmlspecialchars($log));
  94. die($log);
  95. } else {
  96. litepublisher::$options->trace($this->sql . "\n" . $mesg);
  97. }
  98. }
  99. public function quote($s) {
  100. return sprintf('\'%s\'', $this->mysqli->real_escape_string($s));
  101. }
  102. public function escape($s) {
  103. return $this->mysqli->real_escape_string($s);
  104. }
  105. public function settable($table) {
  106. $this->table = $table;
  107. return $this;
  108. }
  109. public function select($where) {
  110. if ($where != '') $where = 'where '. $where;
  111. return $this->query("SELECT * FROM $this->prefix$this->table $where");
  112. }
  113. public function idselect($where) {
  114. return $this->res2id($this->query("select id from $this->prefix$this->table where $where"));
  115. }
  116. public function selectassoc($sql) {
  117. return $this->query($sql)->fetch_assoc();
  118. }
  119. public function getassoc($where) {
  120. return $this->select($where)->fetch_assoc();
  121. }
  122. public function update($values, $where) {
  123. return $this->query("update $this->prefix$this->table set " . $values ." where $where");
  124. }
  125. public function idupdate($id, $values) {
  126. return $this->update($values, "id = $id");
  127. }
  128. public function updateassoc(array $a) {
  129. $list = array();
  130. foreach ($a As $name => $value) {
  131. if ($name == 'id') continue;
  132. if (is_bool($value)) {
  133. $value =$value ? '1' : '0';
  134. $list[] = sprintf('%s = %s ', $name, $value);
  135. continue;
  136. }
  137. $list[] = sprintf('%s = %s', $name, $this->quote($value));
  138. }
  139. return $this->update(implode(', ', $list), 'id = '. $a['id'] . ' limit 1');
  140. }
  141. public function insertrow($row) {
  142. return $this->query(sprintf('INSERT INTO %s%s %s', $this->prefix, $this->table, $row));
  143. }
  144. public function insertassoc(array $a) {
  145. unset($a['id']);
  146. return $this->add($a);
  147. }
  148. public function addupdate(array $a) {
  149. if ($this->idexists($a['id'])) {
  150. $this->updateassoc($a);
  151. } else {
  152. return $this->add($a);
  153. }
  154. }
  155. public function add(array $a) {
  156. $this->insertrow($this->assoctorow($a));
  157. if ($id = $this->mysqli->insert_id) return $id;
  158. $r = $this->query('select last_insert_id() from ' . $this->prefix . $this->table)->fetch_row();
  159. return (int) $r[0];
  160. }
  161. public function insert(array $a) {
  162. $this->insertrow($this->assoctorow($a));
  163. }
  164. public function assoctorow(array $a) {
  165. $vals = array();
  166. foreach( $a as $name => $val) {
  167. if (is_bool($val)) {
  168. $vals[] = $val ? '1' : '0';
  169. } else {
  170. $vals[] = $this->quote($val);
  171. }
  172. }
  173. return sprintf('(%s) values (%s)', implode(', ', array_keys($a)), implode(', ', $vals));
  174. }
  175. public function getcount($where = '') {
  176. $sql = "SELECT COUNT(*) as count FROM $this->prefix$this->table";
  177. if ($where != '') $sql .= ' where '. $where;
  178. if (($res = $this->query($sql)) && ($r = $res->fetch_assoc())) {
  179. return (int) $r['count'];
  180. }
  181. return false;
  182. }
  183. public function delete($where) {
  184. return $this->query("delete from $this->prefix$this->table where $where");
  185. }
  186. public function iddelete($id) {
  187. return $this->query("delete from $this->prefix$this->table where id = $id");
  188. }
  189. public function deleteitems(array $items) {
  190. return $this->delete('id in ('. implode(', ', $items) . ')');
  191. }
  192. public function idexists($id) {
  193. if ($r = $this->query("select id from $this->prefix$this->table where id = $id limit 1")->fetch_assoc()) return true;
  194. return false;
  195. }
  196. public function exists($where) {
  197. if ($this->query("select * from $this->prefix$this->table where $where limit 1")->num_rows) return true;
  198. return false;
  199. }
  200. public function getlist(array $list) {
  201. return $this->res2assoc($this->select(sprintf('id in (%s)', implode(',', $list))));
  202. }
  203. public function getitems($where) {
  204. return $this->res2assoc($this->select($where));
  205. }
  206. public function getitem($id) {
  207. if ($r = $this->query("select * from $this->prefix$this->table where id = $id limit 1")) return $r->fetch_assoc();
  208. return false;
  209. }
  210. public function finditem($where) {
  211. return $this->query("select * from $this->prefix$this->table where $where limit 1")->fetch_assoc();
  212. }
  213. public function findid($where) {
  214. if($r = $this->query("select id from $this->prefix$this->table where $where limit 1")->fetch_assoc()) return $r['id'];
  215. return false;
  216. }
  217. public function getval($table, $id, $name) {
  218. if ($r = $this->query("select $name from $this->prefix$table where id = $id limit 1")->fetch_assoc()) return $r[$name];
  219. return false;
  220. }
  221. public function getvalue($id, $name) {
  222. if ($r = $this->query("select $name from $this->prefix$this->table where id = $id limit 1")->fetch_assoc()) return $r[$name];
  223. return false;
  224. }
  225. public function setvalue($id, $name, $value) {
  226. return $this->update("$name = " . $this->quote($value), "id = $id");
  227. }
  228. public function res2array($res) {
  229. $result = array();
  230. if (is_object($res)) {
  231. while ($row = $res->fetch_row()) {
  232. $result[] = $row;
  233. }
  234. return $result;
  235. }
  236. }
  237. public function res2id($res) {
  238. $result = array();
  239. if (is_object($res)) {
  240. while ($row = $res->fetch_row()) {
  241. $result[] = $row[0];
  242. }
  243. }
  244. return $result;
  245. }
  246. public function res2assoc($res) {
  247. $result = array();
  248. if (is_object($res)) {
  249. while ($r = $res->fetch_assoc()) {
  250. $result[] = $r;
  251. }
  252. }
  253. return $result;
  254. }
  255. public function res2items($res) {
  256. $result = array();
  257. if (is_object($res)) {
  258. while ($r = $res->fetch_assoc()) {
  259. $result[(int) $r['id']] = $r;
  260. }
  261. }
  262. return $result;
  263. }
  264. public function fetchassoc($res) {
  265. return is_object($res) ? $res->fetch_assoc() : false;
  266. }
  267. public function fetchnum($res) {
  268. return is_object($res) ? $res->fetch_row() : false;
  269. }
  270. public function countof($res) {
  271. return is_object($res) ? $res->num_rows : 0;
  272. }
  273. public static function str2array($s) {
  274. $result = array();
  275. foreach (explode(',', $s) as $i => $value) {
  276. $v = (int) trim($value);
  277. if ($v== 0) continue;
  278. $result[] = $v;
  279. }
  280. return $result;
  281. }
  282. }//class
  283. //data.class.php
  284. class tdata {
  285. public $basename;
  286. public $cache;
  287. public $coclasses;
  288. public $coinstances;
  289. public $data;
  290. public $lockcount;
  291. public $table;
  292. public static function i() {
  293. return getinstance(get_called_class());
  294. }
  295. public static function instance() {
  296. return getinstance(get_called_class());
  297. }
  298. public function __construct() {
  299. $this->lockcount = 0;
  300. $this->cache= true;
  301. $this->data= array();
  302. $this->coinstances = array();
  303. $this->coclasses = array();
  304. $this->basename = substr(get_class($this), 1);
  305. $this->create();
  306. }
  307. protected function create() {
  308. }
  309. public function __get($name) {
  310. if (method_exists($this, $get = 'get' . $name)) {
  311. return $this->$get();
  312. } elseif (array_key_exists($name, $this->data)) {
  313. return $this->data[$name];
  314. } else {
  315. foreach ($this->coinstances as $coinstance) {
  316. if (isset($coinstance->$name)) return $coinstance->$name;
  317. }
  318. return $this->error(sprintf('The requested property "%s" not found in class %s', $name, get_class($this)));
  319. }
  320. }
  321. public function __set($name, $value) {
  322. if (method_exists($this, $set = 'set' . $name)) {
  323. $this->$set($value);
  324. return true;
  325. }
  326. if (key_exists($name, $this->data)) {
  327. $this->data[$name] = $value;
  328. return true;
  329. }
  330. foreach ($this->coinstances as $coinstance) {
  331. if (isset($coinstance->$name)) {
  332. $coinstance->$name = $value;
  333. return true;
  334. }
  335. }
  336. return false;
  337. }
  338. public function __call($name, $params) {
  339. if (method_exists($this, strtolower($name))) {
  340. return call_user_func_array(array($this, strtolower($name)), $params);
  341. }
  342. foreach ($this->coinstances as $coinstance) {
  343. if (method_exists($coinstance, $name) || $coinstance->method_exists($name))
  344. return call_user_func_array(array($coinstance, $name), $params);
  345. }
  346. $this->error("The requested method $name not found in class " . get_class($this));
  347. }
  348. public function __isset($name) {
  349. if (array_key_exists($name, $this->data) || method_exists($this, "get$name") || method_exists($this, "Get$name")) return true;
  350. foreach ($this->coinstances as $coinstance) {
  351. if (isset($coinstance->$name)) return true;
  352. }
  353. return false;
  354. }
  355. public function method_exists($name) {
  356. return false;
  357. }
  358. public function error($Msg, $code = 0) {
  359. throw new Exception($Msg, $code);
  360. }
  361. public function getbasename() {
  362. return $this->basename;
  363. }
  364. public function install() {
  365. $this->externalchain('Install');
  366. }
  367. public function uninstall() {
  368. $this->externalchain('Uninstall');
  369. }
  370. public function validate($repair = false) {
  371. $this->externalchain('Validate', $repair);
  372. }
  373. protected function externalchain($func, $arg = null) {
  374. $parents = class_parents($this);
  375. array_splice($parents, 0, 0, get_class($this));
  376. foreach ($parents as $key => $class) {
  377. $this->externalfunc($class, $func, $arg);
  378. }
  379. }
  380. public function externalfunc($class, $func, $args) {
  381. if ($filename = litepublisher::$classes->getclassfilename($class, true)) {
  382. $externalname = basename($filename, '.php') . '.install.php';
  383. $dir = dirname($filename) . DIRECTORY_SEPARATOR;
  384. $file = $dir . 'install' . DIRECTORY_SEPARATOR . $externalname;
  385. if (!file_exists($file)) {
  386. $file =$dir . $externalname;
  387. if (!file_exists($file)) return;
  388. }
  389. include_once($file);
  390. $fnc = $class . $func;
  391. if (function_exists($fnc)) {
  392. //$fnc($this, $arg);
  393. if (is_array($args)) {
  394. array_unshift($args, $this);
  395. } else {
  396. $args = array($this, $args);
  397. }
  398. return call_user_func_array($fnc, $args);
  399. }
  400. }
  401. }
  402. public function load() {
  403. //if ($this->dbversion == 'full') return $this->LoadFromDB();
  404. return tfilestorage::load($this);
  405. }
  406. public function save() {
  407. if ($this->lockcount) return;
  408. if ($this->dbversion) {
  409. $this->SaveToDB();
  410. } else {
  411. tfilestorage::save($this);
  412. }
  413. }
  414. public function savetostring() {
  415. return serialize($this->data);
  416. }
  417. public function loadfromstring($s) {
  418. try {
  419. if (!empty($s)) $this->data = unserialize($s) + $this->data;
  420. $this->afterload();
  421. return true;
  422. } catch (Exception $e) {
  423. echo 'Caught exception: '. $e->getMessage() ;
  424. return false;
  425. }
  426. }
  427. public function afterload() {
  428. foreach ($this->coinstances as $coinstance) {
  429. if (method_exists($coinstance, 'afterload')) $coinstance->afterload();
  430. }
  431. }
  432. public function lock() {
  433. $this->lockcount++;
  434. }
  435. public function unlock() {
  436. if (--$this->lockcount <= 0) $this->save();
  437. }
  438. public function getlocked() {
  439. return $this->lockcount > 0;
  440. }
  441. public function Getclass() {
  442. return get_class($this);
  443. }
  444. public function getdbversion() {
  445. return false; // dbversion == 'full';
  446. }
  447. public function getdb($table = '') {
  448. $table =$table != '' ? $table : $this->table;
  449. if ($table != '') litepublisher::$db->table = $table;
  450. return litepublisher::$db;
  451. }
  452. protected function SaveToDB() {
  453. $this->db->add($this->getbasename(), $this->savetostring());
  454. }
  455. protected function LoadFromDB() {
  456. if ($r = $this->db->select('basename = '. $this->getbasename() . "'")) {
  457. return $this->loadfromstring($r['data']);
  458. }
  459. }
  460. protected function getthistable() {
  461. return litepublisher::$db->prefix . $this->table;
  462. }
  463. public static function get_class_name($c) {
  464. return is_object($c) ? get_class($c) : trim($c);
  465. }
  466. }//class
  467. class tfilestorage {
  468. public static $disabled;
  469. public static $memcache = false;
  470. public static function save(tdata $obj) {
  471. if (self::$disabled) return false;
  472. return self::savetofile(litepublisher::$paths->data .$obj->getbasename(), $obj->savetostring());
  473. }
  474. public static function load(tdata $obj) {
  475. if ($s = self::loadfile(litepublisher::$paths->data . $obj->getbasename() .'.php')) {
  476. return $obj->loadfromstring($s);
  477. }
  478. return false;
  479. }
  480. public static function loadfile($filename) {
  481. if (self::$memcache) {
  482. if ($s = self::$memcache->get($filename)) return $s;
  483. }
  484. if (file_exists($filename)) {
  485. $s = self::uncomment_php(file_get_contents($filename));
  486. if (self::$memcache) self::$memcache->set($filename, $s, false, 3600);
  487. return $s;
  488. }
  489. return false;
  490. }
  491. public static function savetofile($base, $content) {
  492. if (self::$memcache) self::$memcache->set($base . '.php', $content, false, 3600);
  493. $tmp = $base .'.tmp.php';
  494. if(false === file_put_contents($tmp, self::comment_php($content))) {
  495. litepublisher::$options->trace(sprintf('Error write to file "%s"', $tmp));
  496. return false;
  497. }
  498. chmod($tmp, 0666);
  499. $filename = $base .'.php';
  500. if (file_exists($filename)) {
  501. $back = $base . '.bak.php';
  502. self::delete($back);
  503. rename($filename, $back);
  504. }
  505. if (!rename($tmp, $filename)) {
  506. litepublisher::$options->trace(sprintf('Error rename temp file "%s" to "%s"', $tmp, $filename));
  507. return false;
  508. }
  509. return true;
  510. }
  511. public static function delete($filename) {
  512. if (file_exists($filename)) {
  513. if (!unlink($filename)) {
  514. chmod($filename, 0666);
  515. unlink($filename);
  516. }
  517. }
  518. if (self::$memcache) self::$memcache->delete($filename);
  519. }
  520. public static function getfile($filename) {
  521. if (self::$memcache) {
  522. if ($s = self::$memcache->get($filename)) return $s;
  523. }
  524. if (file_exists($filename)) {
  525. $s = file_get_contents($filename);
  526. if (self::$memcache) self::$memcache->set($filename, $s, false, 3600);
  527. return $s;
  528. }
  529. return false;
  530. }
  531. public static function setfile($filename, $content) {
  532. if (self::$memcache) self::$memcache->set($filename, $content, false, 3600);
  533. file_put_contents($filename, $content);
  534. @chmod($filename, 0666);
  535. }
  536. public static function savevar($filename, &$var) {
  537. return self::savetofile($filename, serialize($var));
  538. }
  539. public static function loadvar($filename, &$var) {
  540. if ($s = self::loadfile($filename . '.php')) {
  541. $var = unserialize($s);
  542. return true;
  543. }
  544. return false;
  545. }
  546. public static function comment_php($s) {
  547. return sprintf('<?php /* %s */ ?>', str_replace('*/', '**//*/', $s));
  548. }
  549. public static function uncomment_php($s) {
  550. return str_replace('**//*/', '*/', substr($s, 9, strlen($s) - 9 - 6));
  551. }
  552. }//class
  553. class tstorage extends tfilestorage {
  554. public static $data;
  555. private static $modified;
  556. public static function save(tdata $obj) {
  557. self::$modified = true;
  558. $base = $obj->getbasename();
  559. if (!isset(self::$data[$base])) self::$data[$base] = &$obj->data;
  560. return true;
  561. }
  562. public static function load(tdata $obj) {
  563. $base = $obj->getbasename();
  564. if (isset(self::$data[$base])) {
  565. $obj->data = &self::$data[$base];
  566. $obj->afterload();
  567. return true;
  568. } else {
  569. self::$data[$base] = &$obj->data;
  570. return false;
  571. }
  572. }
  573. public static function savemodified() {
  574. if (self::$modified) {
  575. if (self::$disabled) return false;
  576. $lock = litepublisher::$paths->data .'storage.lok';
  577. if (($fh = @fopen($lock, 'w')) && flock($fh, LOCK_EX | LOCK_NB)) {
  578. self::savetofile(litepublisher::$paths->data .'storage', serialize(self::$data));
  579. flock($fh, LOCK_UN);
  580. fclose($fh);
  581. @chmod($lock, 0666);
  582. } else {
  583. tfiler::log('Storage locked, data not saved');
  584. }
  585. self::$modified = false;
  586. return true;
  587. }
  588. return false;
  589. }
  590. public static function loaddata() {
  591. self::$data = array();
  592. return self::loadvar(litepublisher::$paths->data . 'storage', self::$data);
  593. }
  594. }//class
  595. class tarray2prop {
  596. public $array;
  597. public function __construct(array $a = null) { $this->array = $a; }
  598. public function __destruct() { unset($this->array); }
  599. public function __get($name) { return $this->array[$name]; }
  600. public function __set($name, $value) { $this->array[$name] = $value; }
  601. public function __isset($name) { return array_key_exists($name, $this->array); }
  602. public function __tostring() { return $this->array['']; }
  603. }//class
  604. function sqldate($date = 0) {
  605. if ($date == 0) $date = time();
  606. return date('Y-m-d H:i:s', $date);
  607. }
  608. function sqltime($date = 0) {
  609. if ($date == 0) return '0000-00-00 00:00:00';
  610. return date('Y-m-d H:i:s', $date);
  611. }
  612. function dbquote($s) {
  613. return litepublisher::$db->quote($s);
  614. }
  615. function md5uniq() {
  616. return basemd5(mt_rand() . litepublisher::$secret. microtime());
  617. }
  618. function basemd5($s) {
  619. return trim(base64_encode(md5($s, true)), '=');
  620. }
  621. function strbegin($s, $begin) {
  622. return strncmp($s, $begin, strlen($begin)) == 0;
  623. }
  624. function strbegins() {
  625. $a = func_get_args();
  626. $s = array_shift($a);
  627. while ($begin = array_shift($a)) {
  628. if (strncmp($s, $begin, strlen($begin)) == 0) return true;
  629. }
  630. return false;
  631. }
  632. function strend($s, $end) {
  633. return $end == substr($s, 0 - strlen($end));
  634. }
  635. function strip_utf($s) {
  636. $utf = "\xEF\xBB\xBF";
  637. return strbegin($s, $utf) ? substr($s, strlen($utf)) : $s;
  638. }
  639. function array_delete(array &$a, $i) {
  640. array_splice($a, $i, 1);
  641. }
  642. function array_delete_value(array &$a, $value) {
  643. $i = array_search($value, $a);
  644. if ($i !== false) array_splice($a, $i, 1);
  645. }
  646. function array_clean(array &$items) {
  647. $items = array_unique($items);
  648. foreach (array(0, false, null, '') as $v) {
  649. $i = array_search($v, $items);
  650. if ($i !== false) array_splice($items, $i, 1);
  651. }
  652. }
  653. function array_insert(array &$a, $item, $index) {
  654. array_splice($a, $index, 0, array($item));
  655. }
  656. function array_move(array &$a, $oldindex, $newindex) {
  657. //delete and insert
  658. if (($oldindex == $newindex) || !isset($a[$oldindex])) return false;
  659. $item = $a[$oldindex];
  660. array_splice($a, $oldindex, 1);
  661. array_splice($a, $newindex, 0, array($item));
  662. }
  663. function strtoarray($s) {
  664. $a = explode("\n", trim($s));
  665. foreach ($a as $k => $v) $a[$k] = trim($v);
  666. return $a;
  667. }
  668. function tojson($a) {
  669. if (defined('JSON_NUMERIC_CHECK')) {
  670. return json_encode($a, JSON_NUMERIC_CHECK | (defined('JSON_UNESCAPED_UNICODE') ? JSON_UNESCAPED_UNICODE : 0));
  671. }
  672. return json_encode($a);
  673. }
  674. function jsonattr($a) {
  675. return str_replace('"', '&quot;', tojson($a));
  676. }
  677. function toenum($v, array $a) {
  678. $v = trim($v);
  679. return in_array($v, $a) ? $v : $a[0];
  680. }
  681. function dumpstr($s) {
  682. echo "<pre>\n", htmlspecialchars($s), "</pre>\n";
  683. }
  684. function dumpvar($v) {
  685. echo "<pre>\n";
  686. var_dump($v);
  687. echo "</pre>\n";
  688. }
  689. //events.class.php
  690. class ECancelEvent extends Exception {
  691. public $result;
  692. public function __construct($message, $code = 0) {
  693. $this->result = $message;
  694. parent::__construct('', 0);
  695. }
  696. }
  697. class tevents extends tdata {
  698. protected $events;
  699. protected $eventnames;
  700. protected $map;
  701. public function __construct() {
  702. $this->eventnames = array();
  703. $this->map = array();
  704. parent::__construct();
  705. $this->assignmap();
  706. $this->load();
  707. }
  708. public function __destruct() {
  709. unset($this->data, $this->events, $this->eventnames, $this->map);
  710. }
  711. protected function create() {
  712. $this->addmap('events', array());
  713. $this->addmap('coclasses', array());
  714. }
  715. public function assignmap() {
  716. foreach ($this->map as $propname => $key) {
  717. $this->$propname = &$this->data[$key];
  718. }
  719. }
  720. public function afterload() {
  721. $this->assignmap();
  722. foreach ($this->coclasses as $coclass) {
  723. $this->coinstances[] = getinstance($coclass);
  724. }
  725. parent::afterload();
  726. }
  727. protected function addmap($name, $value) {
  728. $this->map[$name] = $name;
  729. $this->data[$name] = $value;
  730. $this->$name = &$this->data[$name];
  731. }
  732. public function free() {
  733. unset(litepublisher::$classes->instances[get_class($this)]);
  734. foreach ($this->coinstances as $coinstance) $coinstance->free();
  735. }
  736. public function eventexists($name) {
  737. return in_array($name, $this->eventnames);
  738. }
  739. public function __get($name) {
  740. if (method_exists($this, $name)) return array('class' =>get_class($this), 'func' => $name);
  741. return parent::__get($name);
  742. }
  743. public function __set($name, $value) {
  744. if (parent::__set($name, $value)) return true;
  745. if (in_array($name, $this->eventnames)) {
  746. $this->addevent($name, $value['class'], $value['func']);
  747. return true;
  748. }
  749. $this->error("Unknown property $name in class ". get_class($this));
  750. }
  751. public function method_exists($name) {
  752. return in_array($name, $this->eventnames);
  753. }
  754. public function __call($name, $params) {
  755. if (in_array($name, $this->eventnames)) return $this->callevent($name, $params);
  756. parent::__call($name, $params);
  757. }
  758. public function __isset($name) {
  759. if (parent::__isset($name)) return true;
  760. return in_array($name, $this->eventnames);
  761. }
  762. protected function addevents() {
  763. $a = func_get_args();
  764. array_splice($this->eventnames, count($this->eventnames), 0, $a);
  765. }
  766. private function get_events($name) {
  767. return isset($this->events[$name]) ? $this->events[$name] : false;
  768. }
  769. public function callevent($name, $params) {
  770. $result = '';
  771. if ( $list = $this->get_events($name)) {
  772. foreach ($list as $i => $item) {
  773. if (empty($item['class'])) {
  774. if (function_exists($item['func'])) {
  775. $call = $item['func'];
  776. } else {
  777. $this->delete_event_item($name, $i);
  778. continue;
  779. }
  780. } elseif (!class_exists($item['class'])) {
  781. $this->delete_event_item($name, $i);
  782. continue;
  783. } else {
  784. $obj = getinstance($item['class']);
  785. $call = array($obj, $item['func']);
  786. }
  787. try {
  788. $result = call_user_func_array($call, $params);
  789. } catch (ECancelEvent $e) {
  790. return $e->result;
  791. }
  792. }
  793. }
  794. return $result;
  795. }
  796. public static function cancelevent($result) {
  797. throw new ECancelEvent($result);
  798. }
  799. private function delete_event_item($name, $i) {
  800. array_splice($this->events[$name], $i, 1);
  801. if (count($this->events[$name]) == 0) unset($this->events[$name]);
  802. $this->save();
  803. }
  804. public function setevent($name, $params) {
  805. return $this->addevent($name, $params['class'], $params['func']);
  806. }
  807. public function addevent($name, $class, $func) {
  808. if (!in_array($name, $this->eventnames)) return $this->error(sprintf('No such %s event', $name ));
  809. if (empty($func)) return false;
  810. if (isset($this->events[$name])) {
  811. if ($list = $this->get_events($name)) {
  812. foreach ($list as $event) {
  813. if (($event['class'] == $class) && ($event['func'] == $func)) return false;
  814. }
  815. }
  816. } else {
  817. $this->events[$name] =array();
  818. }
  819. $this->events[$name][] = array(
  820. 'class' => $class,
  821. 'func' => $func
  822. );
  823. $this->save();
  824. }
  825. public function delete_event_class($name, $class) {
  826. if (isset($this->events[$name])) {
  827. $list = &$this->events[$name];
  828. $deleted = false;
  829. for ($i = count($list) - 1; $i >= 0; $i--) {
  830. if ($list[$i]['class'] == $class) {
  831. array_splice($list, $i, 1);
  832. $deleted = true;
  833. }
  834. }
  835. if ($deleted) {
  836. if (count($list) == 0) unset($this->events[$name]);
  837. $this->save();
  838. }
  839. return $deleted;
  840. }
  841. return false;
  842. }
  843. public function unsubscribeclass($obj) {
  844. $this->unbind($obj);
  845. }
  846. public function unsubscribeclassname($class) {
  847. $this->unbind($class);
  848. }
  849. public function unbind($c) {
  850. $class = self::get_class_name($c);
  851. foreach ($this->events as $name => $events) {
  852. foreach ($events as $i => $item) {
  853. if ($item['class'] == $class) array_splice($this->events[$name], $i, 1);
  854. }
  855. }
  856. $this->save();
  857. }
  858. public function seteventorder($eventname, $c, $order) {
  859. if (!isset($this->events[$eventname])) return false;
  860. $events = &$this->events[$eventname];
  861. $class = self::get_class_name($c);
  862. $count = count($events);
  863. if (($order < 0) || ($order >= $count)) $order = $count - 1;
  864. foreach ($events as $i => $event) {
  865. if ($class == $event['class']) {
  866. if ($i == $order) return true;
  867. array_splice($events, $i, 1);
  868. array_splice($events, $order, 0, array(0 => $event));
  869. $this->save();
  870. return true;
  871. }
  872. }
  873. }
  874. private function indexofcoclass($class) {
  875. return array_search($class, $this->coclasses);
  876. }
  877. public function addcoclass($class) {
  878. if ($this->indexofcoclass($class) === false) {
  879. $this->coclasses[] = $class;
  880. $this->save();
  881. $this->coinstances = getinstance($class);
  882. }
  883. }
  884. public function deletecoclass($class) {
  885. $i = $this->indexofcoclass($class);
  886. if (is_int($i)) {
  887. array_splice($this->coclasses, $i, 1);
  888. $this->save();
  889. }
  890. }
  891. }//class
  892. class tevents_storage extends tevents {
  893. public function load() {
  894. return tstorage::load($this);
  895. }
  896. public function save() {
  897. return tstorage::save($this);
  898. }
  899. }//class
  900. class tcoevents extends tevents {
  901. private $owner;
  902. public function __construct() {
  903. parent::__construct();
  904. $a = func_get_args();
  905. $owner = array_shift ($a);
  906. $this->owner = $owner;
  907. if (!isset($owner->data['events'])) $owner->data['events'] = array();
  908. $this->events = &$owner->data['events'];
  909. array_splice($this->eventnames, count($this->eventnames), 0, $a);
  910. }
  911. public function __destruct() {
  912. parent::__destruct();
  913. unset($this->owner);
  914. }
  915. public function assignmap() {}
  916. protected function create() { }
  917. public function load() {}
  918. public function afterload() {
  919. $this->events = &$this->owner->data['events'];
  920. }
  921. public function save() {
  922. return $this->owner->save();
  923. }
  924. }//class
  925. //items.class.php
  926. class titems extends tevents {
  927. public $items;
  928. protected $autoid;
  929. public $dbversion;
  930. protected function create() {
  931. parent::create();
  932. $this->addevents('added', 'deleted');
  933. if ($this->dbversion) {
  934. $this->items = array();
  935. } else {
  936. $this->addmap('items', array());
  937. $this->addmap('autoid', 0);
  938. }
  939. }
  940. public function load() {
  941. if ($this->dbversion) {
  942. return tstorage::load($this);
  943. } else {
  944. return parent::load();
  945. }
  946. }
  947. public function save() {
  948. if ($this->lockcount > 0) return;
  949. if ($this->dbversion) {
  950. return tstorage::save($this);
  951. } else {
  952. return parent::save();
  953. }
  954. }
  955. public function loadall() {
  956. if (!$this->dbversion) return;
  957. return $this->select('', '');
  958. }
  959. public function loaditems(array $items) {
  960. if (!$this->dbversion) return;
  961. //exclude loaded items
  962. $items = array_diff($items, array_keys($this->items));
  963. if (count($items) == 0) return;
  964. $list = implode(',', $items);
  965. $this->select("$this->thistable.id in ($list)", '');
  966. }
  967. public function select($where, $limit) {
  968. if (!$this->dbversion) $this->error('Select method must be called ffrom database version');
  969. if ($where != '') $where = 'where '. $where;
  970. return $this->res2items($this->db->query("SELECT * FROM $this->thistable $where $limit"));
  971. }
  972. public function res2items($res) {
  973. if (!$res) return array();
  974. $result = array();
  975. $db = litepublisher::$db;
  976. while ($item = $db->fetchassoc($res)) {
  977. $id = $item['id'];
  978. $result[] = $id;
  979. $this->items[$id] = $item;
  980. }
  981. return $result;
  982. }
  983. public function getcount() {
  984. if ($this->dbversion) {
  985. return $this->db->getcount();
  986. } else {
  987. return count($this->items);
  988. }
  989. }
  990. public function getitem($id) {
  991. if (isset($this->items[$id])) return $this->items[$id];
  992. if ($this->dbversion) {
  993. if ($this->select("$this->thistable.id = $id", 'limit 1')) return $this->items[$id];
  994. }
  995. return $this->error(sprintf('Item %d not found in class %s', $id, get_class($this)));
  996. }
  997. public function getvalue($id, $name) {
  998. if ($this->dbversion && !isset($this->items[$id])) $this->items[$id] = $this->db->getitem($id);
  999. return $this->items[$id][$name];
  1000. }
  1001. public function setvalue($id, $name, $value) {
  1002. $this->items[$id][$name] = $value;
  1003. if ($this->dbversion) {
  1004. $this->db->setvalue($id, $name, $value);
  1005. }
  1006. }
  1007. public function itemexists($id) {
  1008. if (isset($this->items[$id])) return true;
  1009. if ($this->dbversion) {
  1010. try {
  1011. return $this->getitem($id);
  1012. } catch (Exception $e) {
  1013. return false;
  1014. }
  1015. }
  1016. return false;
  1017. }
  1018. public function indexof($name, $value) {
  1019. if ($this->dbversion){
  1020. return $this->db->findid("$name = ". dbquote($value));
  1021. }
  1022. foreach ($this->items as $id => $item) {
  1023. if ($item[$name] == $value) {
  1024. return $id;
  1025. }
  1026. }
  1027. return false;
  1028. }
  1029. public function additem(array $item) {
  1030. $id = $this->dbversion ? $this->db->add($item) : ++$this->autoid;
  1031. $item['id'] = $id;
  1032. $this->items[$id] = $item;
  1033. if (!$this->dbversion) $this->save();
  1034. $this->added($id);
  1035. return $id;
  1036. }
  1037. public function delete($id) {
  1038. if ($this->dbversion) $this->db->delete("id = $id");
  1039. if (isset($this->items[$id])) {
  1040. unset($this->items[$id]);
  1041. if (!$this->dbversion) $this->save();
  1042. $this->deleted($id);
  1043. return true;
  1044. }
  1045. return false;
  1046. }
  1047. }//class
  1048. class titems_storage extends titems {
  1049. public function load() {
  1050. return tstorage::load($this);
  1051. }
  1052. public function save() {
  1053. return tstorage::save($this);
  1054. }
  1055. }//class
  1056. class tsingleitems extends titems {
  1057. public static $instances;
  1058. public $id;
  1059. public static function singleinstance($class, $id = 0) {
  1060. if (!isset(self::$instances)) self::$instances = array();
  1061. if (isset(self::$instances[$class][$id])) return self::$instances[$class][$id];
  1062. $self = litepublisher::$classes->newinstance($class);
  1063. self::$instances[$class][$id] = $self;
  1064. $self->id = $id;
  1065. $self->load();
  1066. return $self;
  1067. }
  1068. public function load() {
  1069. if (!isset($this->id)) return false;
  1070. return parent::load();
  1071. }
  1072. public function free() {
  1073. unset(self::$instances[get_class($this)][$this->id]);
  1074. }
  1075. }//class
  1076. //item.class.php
  1077. class titem extends tdata {
  1078. public static $instances;
  1079. //public $id;
  1080. public static function iteminstance($class, $id = 0) {
  1081. $name = call_user_func_array(array($class, 'getinstancename'), array());
  1082. if (!isset(self::$instances)) self::$instances = array();
  1083. if (isset(self::$instances[$name][$id])) return self::$instances[$name][$id];
  1084. $self = litepublisher::$classes->newitem($name, $class, $id);
  1085. return $self->loaddata($id);
  1086. }
  1087. public function loaddata($id) {
  1088. $this->data['id'] = $id;
  1089. if ($id != 0) {
  1090. if (!$this->load()) {
  1091. $this->free();
  1092. return false;
  1093. }
  1094. self::$instances[$this->instancename][$id] = $this;
  1095. }
  1096. return $this;
  1097. }
  1098. public function free() {
  1099. unset(self::$instances[$this->getinstancename()][$this->id]);
  1100. }
  1101. public function __construct() {
  1102. parent::__construct();
  1103. $this->data['id'] = 0;
  1104. }
  1105. public function __destruct() {
  1106. $this->free();
  1107. }
  1108. public function __set($name, $value) {
  1109. if (parent::__set($name, $value)) return true;
  1110. return $this->Error("Field $name not exists in class " . get_class($this));
  1111. }
  1112. public function setid($id) {
  1113. if ($id != $this->id) {
  1114. $name = $this->instancename;
  1115. if (!isset(self::$instances)) self::$instances = array();
  1116. if (!isset(self::$instances[$name])) self::$instances[$name] = array();
  1117. $a = &self::$instances[$this->instancename];
  1118. if (isset( $a[$this->id])) unset($a[$this->id]);
  1119. if (isset($a[$id])) $a[$id] = 0;
  1120. $a[$id] = $this;
  1121. $this->data['id'] = $id;
  1122. }
  1123. }
  1124. public function request($id) {
  1125. if ($id != $this->id) {
  1126. $this->setid($id);
  1127. if (!$this->load()) return 404;
  1128. }
  1129. }
  1130. public static function deletedir($dir) {
  1131. if (!@file_exists($dir)) return false;
  1132. tfiler::delete($dir, true, true);
  1133. @rmdir($dir);
  1134. }
  1135. }
  1136. class titem_storage extends titem {
  1137. public function getowner() {
  1138. $this->error(sprintf('The "%s" no have owner', get_class($this)));
  1139. }
  1140. public function load() {
  1141. $owner = $this->owner;
  1142. if ($owner->itemexists($this->id)) {
  1143. $this->data = &$owner->items[$this->id];
  1144. return true;
  1145. }
  1146. return false;
  1147. }
  1148. public function save() {
  1149. return $this->owner->save();
  1150. }
  1151. }//class
  1152. //classes.class.php
  1153. if (!function_exists( 'spl_autoload_register' ) ) {
  1154. function __autoload($class) {
  1155. litepublisher::$classes->_autoload($class);
  1156. }
  1157. }
  1158. class tclasses extends titems {
  1159. public $classes;
  1160. public $interfaces;
  1161. public $remap;
  1162. public $factories;
  1163. public $instances;
  1164. public $included_files;
  1165. public static function i() {
  1166. if (!isset(litepublisher::$classes)) {
  1167. $class = __class__;
  1168. litepublisher::$classes = new $class();
  1169. litepublisher::$classes->instances[$class] = litepublisher::$classes;
  1170. }
  1171. return litepublisher::$classes;
  1172. }
  1173. public static function instance() {
  1174. return self::i();
  1175. }
  1176. protected function create() {
  1177. parent::create();
  1178. $this->basename = 'classes';
  1179. $this->dbversion = false;
  1180. $this->addevents('onnewitem', 'gettemplatevar');
  1181. $this->addmap('classes', array());
  1182. $this->addmap('interfaces', array());
  1183. $this->addmap('remap', array());
  1184. $this->addmap('factories', array());
  1185. $this->instances = array();
  1186. if (function_exists('spl_autoload_register')) spl_autoload_register(array($this, '_autoload'));
  1187. $this->data['memcache'] = false;
  1188. $this->data['revision_memcache'] = 1;
  1189. $this->included_files = array();
  1190. }
  1191. public function load() {
  1192. return tstorage::load($this);
  1193. }
  1194. public function save() {
  1195. return tstorage::save($this);
  1196. }
  1197. public function getinstance($class) {
  1198. if (!class_exists($class)) {
  1199. $this->error("Class $class not found");
  1200. }
  1201. if (!isset($this->instances[$class])) {
  1202. $this->instances[$class] = $this->newinstance($class);
  1203. }
  1204. return $this->instances[$class];
  1205. }
  1206. public function newinstance($class) {
  1207. if (!empty($this->remap[$class])) $class = $this->remap[$class];
  1208. return new $class();
  1209. /*
  1210. if (preg_match('/^(tcomments|toptions|tsite|targs|ttheme)$/', $class)) return new $class();
  1211. return new tdebugproxy(new $class());
  1212. */
  1213. }
  1214. public function newitem($name, $class, $id) {
  1215. if (!empty($this->remap[$class])) $class = $this->remap[$class];
  1216. $this->callevent('onnewitem', array($name, &$class, $id));
  1217. return new $class();
  1218. }
  1219. public function __get($name) {
  1220. if (isset($this->classes[$name])) return $this->getinstance($this->classes[$name]);
  1221. if (isset($this->items[$name])) return $this->getinstance($name);
  1222. $class = 't' . $name;
  1223. if (isset($this->items[$class])) return $this->getinstance($class);
  1224. return parent::__get($name);
  1225. }
  1226. public function add($class, $filename, $path = '') {
  1227. if (isset($this->items[$class]) &&
  1228. ($this->items[$class][0] == $filename) && ($this->items[$class][1] == $path)) return false;
  1229. $this->lock();
  1230. $m = $this->memcache;
  1231. $this->memcache = false;
  1232. $this->items[$class] = array($filename, $path);
  1233. $instance = $this->getinstance($class);
  1234. if (method_exists($instance, 'install')) $instance->install();
  1235. $this->memcache = $m;
  1236. if ($m) $this->revision_memcache++;
  1237. $this->unlock();
  1238. $this->added($class);
  1239. return true;
  1240. }
  1241. public function delete($class) {
  1242. if (!isset($this->items[$class])) return false;
  1243. $this->lock();
  1244. $m = $this->memcache;
  1245. $this->memcache = false;
  1246. if (class_exists($class)) {
  1247. $instance = $this->getinstance($class);
  1248. if (method_exists($instance, 'uninstall')) $instance->uninstall();
  1249. }
  1250. unset($this->items[$class]);
  1251. $this->memcache = $m;
  1252. if ($m) $this->revision_memcache++;
  1253. $this->unlock();
  1254. $this->deleted($class);
  1255. }
  1256. public function reinstall($class) {
  1257. if (isset($this->items[$class])) {
  1258. $this->lock();
  1259. $item = $this->items[$class];
  1260. $this->delete($class);
  1261. $this->add($class, $item[0], $item[1]);
  1262. $this->unlock();
  1263. }
  1264. }
  1265. public function _autoload($class) {
  1266. if ($filename = $this->getclassfilename($class)) {
  1267. $this->include_file($filename);
  1268. $this->included_files[$class] = $filename;
  1269. }
  1270. }
  1271. public function include_file($filename) {
  1272. if (!tfilestorage::$memcache || litepublisher::$debug || !$this->memcache) {
  1273. if (file_exists($filename)) require_once($filename);
  1274. return;
  1275. }
  1276. if (in_array($filename, $this->included_files)) return;
  1277. if ($s = tfilestorage::$memcache->get($filename)) {
  1278. $i = strpos($s, ';');
  1279. $revision = substr($s, 0, $i);
  1280. if ($revision == $this->revision_memcache) {
  1281. eval(substr($s, $i + 1));
  1282. return;
  1283. }
  1284. tfilestorage::$memcache->delete($filename);
  1285. }
  1286. if (file_exists($filename)) {
  1287. $s = file_get_contents($filename);
  1288. eval('?>' . $s);
  1289. //strip php tag and copyright in head
  1290. if (strbegin($s, '<?php')) $s = substr($s, 5);
  1291. if (strend($s, '?>')) $s = substr($s, 0, -2);
  1292. $s = trim($s);
  1293. if (strbegin($s, '/*')) $s = substr($s, strpos($s, '*/') + 2);
  1294. $s = $this->revision_memcache . ';' . ltrim($s);
  1295. tfilestorage::$memcache->set($filename, $s, false, 3600);
  1296. }
  1297. }
  1298. public function getclassfilename($class, $debug = false) {
  1299. if (isset($this->items[$class])) {
  1300. $item = $this->items[$class];
  1301. $filename = (litepublisher::$debug || $debug) && isset($item[2]) ? $item[2] : $item[0];
  1302. if (Empty($item[1])) {
  1303. return litepublisher::$paths->lib . $filename;
  1304. }
  1305. $filename = trim($item[1], DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . $filename;
  1306. //if (file_exists($filename)) return $filename;
  1307. //may be is subdir?
  1308. if (file_exists(litepublisher::$paths->plugins . $filename)) return litepublisher::$paths->plugins . $filename;
  1309. if (file_exists(litepublisher::$paths->themes . $filename)) return litepublisher::$paths->themes . $filename;
  1310. if (file_exists(litepublisher::$paths->home . $filename)) return litepublisher::$paths->home . $filename;
  1311. }
  1312. if (isset($this->interfaces[$class])) return litepublisher::$paths->lib . $this->interfaces[$class];
  1313. return false;
  1314. }
  1315. public function exists($class) {
  1316. return isset($this->items[$class]);
  1317. }
  1318. public function getfactory($instance) {
  1319. foreach ($this->factories as $classname => $factory) {
  1320. if (@is_a($instance, $classname)) return $this->getinstance($factory);
  1321. }
  1322. }
  1323. public function getresourcedir($c) {
  1324. $class = self::get_class_name($c);
  1325. if (isset($this->included_files[$class])) {
  1326. $dir = dirname($this->included_files[$class]);
  1327. } else {
  1328. $dir = dirname($this->getclassfilename($class));
  1329. }
  1330. return $dir . '/resource/';
  1331. }
  1332. }//class
  1333. function getinstance($class) {
  1334. return litepublisher::$classes->getinstance($class);
  1335. }
  1336. //options.class.php
  1337. class toptions extends tevents_storage {
  1338. public $groupnames;
  1339. public $parentgroups;
  1340. public $group;
  1341. public $idgroups;
  1342. protected $_user;
  1343. protected $_admincookie;
  1344. public $gmt;
  1345. public $errorlog;
  1346. public static function i() {
  1347. return getinstance(__class__);
  1348. }
  1349. public static function instance() {
  1350. return getinstance(__class__);
  1351. }
  1352. protected function create() {
  1353. parent::create();
  1354. $this->basename = 'options';
  1355. $this->addevents('changed', 'perpagechanged', 'onsave');
  1356. unset($this->cache);
  1357. $this->gmt = 0;
  1358. $this->errorlog = '';
  1359. $this->group = '';
  1360. $this->idgroups = array();
  1361. $this->addmap('groupnames', array());
  1362. $this->addmap('parentgroups', array());
  1363. }
  1364. public function afterload() {
  1365. parent::afterload();
  1366. date_default_timezone_set($this->timezone);
  1367. $this->gmt = date('Z');
  1368. if (!defined('dbversion')) define('dbversion', true);
  1369. }
  1370. public function savemodified() {
  1371. $result = tstorage::savemodified();
  1372. $this->onsave($result);
  1373. return $result;
  1374. }
  1375. public function __set($name, $value) {
  1376. if (in_array($name, $this->eventnames)) {
  1377. $this->addevent($name, $value['class'], $value['func']);
  1378. return true;
  1379. }
  1380. if (method_exists($this, $set = 'set' . $name)) {
  1381. $this->$set($value);
  1382. return true;
  1383. }
  1384. if (!array_key_exists($name, $this->data) || ($this->data[$name] != $value)) {
  1385. $this->data[$name] = $value;
  1386. $this->save();
  1387. $this->dochanged($name, $value);
  1388. }
  1389. return true;
  1390. }
  1391. private function dochanged($name, $value) {
  1392. if ($name == 'perpage') {
  1393. $this->perpagechanged();
  1394. $urlmap = turlmap::i();
  1395. $urlmap->clearcache();
  1396. } elseif ($name == 'cache') {
  1397. $urlmap = turlmap::i();
  1398. $urlmap->clearcache();
  1399. } else {
  1400. $this->changed($name, $value);
  1401. }
  1402. }
  1403. public function delete($name) {
  1404. if (array_key_exists($name, $this->data)) {
  1405. unset($this->data[$name]);
  1406. $this->save();
  1407. }
  1408. }
  1409. public function getadmincookie() {
  1410. if (is_null($this->_admincookie)) {
  1411. $this->_admincookie = $this->cookieenabled && isset($_COOKIE['litepubl_user_flag']) ? $this->user && in_array(1, $this->idgroups) : false;
  1412. }
  1413. return $this->_admincookie;
  1414. }
  1415. public function setadmincookie($val) {
  1416. $this->_admincookie = $val;
  1417. }
  1418. public function getuser() {
  1419. if (is_null($this->_user)) {
  1420. $this->_user = $this->cookieenabled ? $this->authcookie() : false;
  1421. }
  1422. return $this->_user;
  1423. }
  1424. public function setuser($id) {
  1425. $this->_user = $id;
  1426. }
  1427. public function authcookie() {
  1428. $iduser = isset($_COOKIE['litepubl_user_id']) ? (int) $_COOKIE['litepubl_user_id'] : 0;
  1429. $cookie = isset($_COOKIE['litepubl_user']) ? (string) $_COOKIE['litepubl_user'] : (isset($_COOKIE['admin']) ? (string) $_COOKIE['admin'] : '');
  1430. if ($cookie == '') return false;
  1431. $cookie = basemd5($cookie . litepublisher::$secret);
  1432. if ( $cookie == basemd5( litepublisher::$secret)) return false;
  1433. if ($iduser) {
  1434. if (!$this->finduser($iduser, $cookie)) return false;
  1435. } elseif ($iduser = $this->findcookie($cookie)) {
  1436. //fix prev versions
  1437. if ($iduser == 1) {
  1438. $expired = $this->cookieexpired;
  1439. } else {
  1440. $item = tusers::i()->getitem($iduser);
  1441. $expired = strtotime($item['expired']);
  1442. }
  1443. setcookie('litepubl_user_id', $iduser, $expired, litepublisher::$site->subdir . '/', false);
  1444. } else {
  1445. return false;
  1446. }
  1447. $this->_user = $iduser;
  1448. $this->updategroup();
  1449. return $iduser;
  1450. }
  1451. public function finduser($iduser, $cookie) {
  1452. if ($iduser == 1) return $this->compare_cookie($cookie);
  1453. if (!$this->usersenabled) return false;
  1454. $users = tusers::i();
  1455. try {
  1456. $item = $users->getitem($iduser);
  1457. } catch (Exception $e) {
  1458. return false;
  1459. }
  1460. if ('hold' == $item['status']) return false;
  1461. return ($cookie == $item['cookie']) && (strtotime($item['expired']) > time());
  1462. }
  1463. public function findcookie($cookie) {
  1464. if ($this->compare_cookie($cookie)) return 1;
  1465. if (!$this->usersenabled) return false;
  1466. $users = tusers::i();
  1467. if ($iduser = $users->findcookie($cookie)){
  1468. $item = $users->getitem($iduser);
  1469. if (strtotime($item['expired']) <= time()) return false;
  1470. return (int) $iduser;
  1471. }
  1472. return false;
  1473. }
  1474. private function compare_cookie($cookie) {
  1475. return !empty($this->cookie ) && ($this->cookie == $cookie) && ($this->cookieexpired > time());
  1476. }
  1477. public function auth($email, $password) {
  1478. if ($email == '' && $password == '' && $this->cookieenabled) return $this->authcookie();
  1479. if ($email == $this->email) {
  1480. if ($this->data['password'] != basemd5("$email:$this->realm:$password")) return false;
  1481. $this->_user = 1;
  1482. } elseif(!$this->usersenabled) {
  1483. return false;
  1484. } else {
  1485. $users = tusers::i();
  1486. if (!($this->_user = $users->auth($email, $password))) return false;
  1487. }
  1488. $this->updategroup();
  1489. return true;
  1490. }
  1491. public function updategroup() {
  1492. if ($this->_user == 1) {
  1493. $this->group = 'admin';
  1494. $this->idgroups = array(1);
  1495. } else {
  1496. $user = tusers::i()->getitem($this->_user);
  1497. $this->idgroups = $user['idgroups'];
  1498. $this->group = count($this->idgroups) ? tusergroups::i()->items[$this->idgroups[0]]['name'] : '';
  1499. }
  1500. }
  1501. public function can_edit($idauthor) {
  1502. return ($idauthor == $this->user) || ($this->group == 'admin') || ($this->group == 'editor');
  1503. }
  1504. public function getpassword() {
  1505. if ($this->user <= 1) return $this->data['password'];
  1506. $users = tusers::i();
  1507. return $users->getvalue($this->user, 'password');
  1508. }
  1509. public function changepassword($newpassword) {
  1510. $this->data['password'] = basemd5("$this->email:$this->realm:$newpassword");
  1511. $this->save();
  1512. }
  1513. public function setdbpassword($password) {
  1514. $this->data['dbconfig']['password'] = base64_encode(str_rot13 ($password));
  1515. $this->save();
  1516. }
  1517. public function logout() {
  1518. if ($this->cookieenabled) {
  1519. $this->setcookies('', 0);
  1520. } else {
  1521. tauthdigest::i()->logout();
  1522. }
  1523. }
  1524. public function setcookies($cookie, $expired) {
  1525. setcookie('litepubl_user_id', $this->_user, $expired, litepublisher::$site->subdir . '/', false);
  1526. setcookie('litepubl_user', $cookie, $expired, litepublisher::$site->subdir . '/', false);
  1527. if ('admin' == $this->group) {
  1528. setcookie('litepubl_user_flag', $cookie ? 'true' : '', $expired, litepublisher::$site->subdir . '/', false);
  1529. } else {
  1530. setcookie('litepubl_user_flag', '', time(), litepublisher::$site->subdir . '/', false);
  1531. }
  1532. if ($this->_user == 1) {
  1533. $this->set_cookie($cookie);
  1534. $this->cookieexpired = $expired;
  1535. } else {
  1536. tusers::i()->setcookie($this->_user, $cookie, $expired);
  1537. }
  1538. }
  1539. public function Getinstalled() {
  1540. return isset($this->data['email']);
  1541. }
  1542. public function settimezone($value) {
  1543. if(!isset($this->data['timezone']) || ($this->timezone != $value)) {
  1544. $this->data['timezone'] = $value;
  1545. $this->save();
  1546. date_default_timezone_set($this->timezone);
  1547. $this->gmt = date('Z');
  1548. }
  1549. }
  1550. public function set_cookie($cookie) {
  1551. if ($cookie != '') $cookie = basemd5((string) $cookie . litepublisher::$secret);
  1552. $this->data['cookie'] = $cookie;
  1553. $this->save();
  1554. }
  1555. public function ingroup($groupname) {
  1556. //admin has all rights
  1557. if ($this->user == 1) return true;
  1558. if (in_array($this->groupnames['admin'], $this->idgroups)) return true;
  1559. if (!$groupname) return true;
  1560. $groupname = trim($groupname);
  1561. if ($groupname == 'admin') return false;
  1562. if (!isset($this->groupnames[$groupname])) $this->error(sprintf('The "%s" group not found', $groupname));
  1563. $idgroup = $this->groupnames[$groupname];
  1564. return in_array($idgroup, $this->idgroups);
  1565. }
  1566. public function ingroups(array $idgroups) {
  1567. if ($this->ingroup('admin')) return true;
  1568. return count(array_intersect($this->idgroups, $idgroups));
  1569. }
  1570. public function hasgroup($groupname) {
  1571. if ($this->ingroup($groupname)) return true;
  1572. // if group is children of user groups
  1573. $idgroup = $this->groupnames[$groupname];
  1574. if (!isset($this->parentgroups[$idgroup])) return false;
  1575. return count(array_intersect($this->idgroups, $this->parentgroups[$idgroup]));
  1576. }
  1577. public function handexception($e) {
  1578. /*
  1579. echo "<pre>\n";
  1580. $debug = debug_backtrace();
  1581. foreach ($debug as $error) {
  1582. echo $error['function'] ;
  1583. echo "\n";
  1584. }
  1585. //array_shift($debug);
  1586. echo "</pre>\n";
  1587. */
  1588. $trace =str_replace(litepublisher::$paths->home, '', $e->getTraceAsString());
  1589. $message = "Caught exception:\n" . $e->getMessage();
  1590. $log = $message . "\n" . $trace;
  1591. $this->errorlog .= str_replace("\n", "<br />\n", htmlspecialchars($log));
  1592. tfiler::log($log, 'exceptions.log');
  1593. if (!(litepublisher::$debug || $this->echoexception || $this->admincookie || litepublisher::$urlmap->adminpanel)) {
  1594. tfiler::log($log, 'exceptionsmail.log');
  1595. }
  1596. }
  1597. public function trace($msg) {
  1598. try {
  1599. throw new Exception($msg);
  1600. } catch (Exception $e) {
  1601. $this->handexception($e);
  1602. }
  1603. }
  1604. public function showerrors() {
  1605. if (!empty($this->errorlog) && (litepublisher::$debug || $this->echoexception || $this->admincookie || litepublisher::$urlmap->adminpanel)) {
  1606. echo $this->errorlog;
  1607. }
  1608. }
  1609. }//class
  1610. //site.class.php
  1611. class tsite extends tevents_storage {
  1612. private $users;
  1613. public static function i() {
  1614. return getinstance(__class__);
  1615. }
  1616. public static function instance() {
  1617. return getinstance(__class__);
  1618. }
  1619. protected function create() {
  1620. parent::create();
  1621. $this->basename = 'site';
  1622. }
  1623. public function __set($name, $value) {
  1624. if ($name == 'url') return $this->seturl($value);
  1625. if (in_array($name, $this->eventnames)) {
  1626. $this->addevent($name, $value['class'], $value['func']);
  1627. } elseif (!array_key_exists($name, $this->data) || ($this->data[$name] != $value)) {
  1628. $this->data[$name] = $value;
  1629. $this->save();
  1630. }
  1631. return true;
  1632. }
  1633. public function geturl() {
  1634. if ($this->fixedurl) return $this->data['url'];
  1635. return 'http://'. litepublisher::$domain;
  1636. }
  1637. public function getfiles() {
  1638. if ($this->fixedurl) return $this->data['files'];
  1639. return 'http://'. litepublisher::$domain;
  1640. }
  1641. public function seturl($url) {
  1642. $url = rtrim($url, '/');
  1643. $this->data['url'] = $url;
  1644. $this->data['files'] = $url;
  1645. $this->subdir = '';
  1646. if ($i = strpos($url, '/', 10)) {
  1647. $this->subdir = substr($url, $i);
  1648. }
  1649. $this->save();
  1650. }
  1651. public function getversion() {
  1652. return litepublisher::$options->data['version'];
  1653. }
  1654. public function getlanguage() {
  1655. return litepublisher::$options->data['language'];
  1656. }
  1657. public function getdomain() {
  1658. return litepublisher::$domain;
  1659. }
  1660. public function getuserlink() {
  1661. if ($id = litepublisher::$options->user) {
  1662. if (!isset($this->users)) $this->users = array();
  1663. if (isset($this->users[$id])) return $this->users[$id];
  1664. $item = tusers::i()->getitem($id);
  1665. if ($item['website']) {
  1666. $result = sprintf('<a href="%s">%s</a>', $item['website'], $item['name']);
  1667. } else {
  1668. $page = $this->getdb('userpage')->getitem($id);
  1669. if(intval($page['idurl'])) {
  1670. $result = sprintf('<a href="%s%s">%s</a>', $this->url, litepublisher::$urlmap->getvalue($page['idurl'], 'url'), $item['name']);
  1671. } else {
  1672. $result = $item['name'];
  1673. }
  1674. }
  1675. $this->users[$id] = $result;
  1676. return $result;
  1677. }
  1678. return '';
  1679. }
  1680. }//class
  1681. //urlmap.class.php
  1682. class turlmap extends titems {
  1683. public $host;
  1684. public $url;
  1685. public $page;
  1686. public $uripath;
  1687. public $itemrequested;
  1688. public $context;
  1689. public $cache_enabled;
  1690. public $argtree;
  1691. public $is404;
  1692. public $isredir;
  1693. public $adminpanel;
  1694. public $mobile;
  1695. protected $close_events;
  1696. public static function i() {
  1697. return getinstance(__class__);
  1698. }
  1699. public static function instance() {
  1700. return getinstance(__class__);
  1701. }
  1702. public function __construct() {
  1703. parent::__construct();
  1704. if (tfilestorage::$memcache) {
  1705. $this->cache = new tlitememcache($this);
  1706. } else {
  1707. $this->cache = new tfilecache();
  1708. }
  1709. }
  1710. protected function create() {
  1711. $this->dbversion = true;
  1712. parent::create();
  1713. $this->table = 'urlmap';
  1714. $this->basename = 'urlmap';
  1715. $this->addevents('beforerequest', 'afterrequest', 'onclearcache');
  1716. $this->data['revision'] = 0;
  1717. $this->data['disabledcron'] = false;
  1718. $this->data['redirdom'] = false;
  1719. $this->is404 = false;
  1720. $this->isredir = false;
  1721. $this->adminpanel = false;
  1722. $this->mobile= false;
  1723. $this->cache_enabled = litepublisher::$options->cache && !litepublisher::$options->admincookie;
  1724. $this->page = 1;
  1725. $this->close_events = array();
  1726. }
  1727. protected function prepareurl($host, $url) {
  1728. $this->host = $host;
  1729. $this->page = 1;
  1730. $this->uripath = array();
  1731. if (litepublisher::$site->q == '?') {
  1732. $this->url = substr($url, strlen(litepublisher::$site->subdir));
  1733. } else {
  1734. $this->url = $_GET['url'];
  1735. }
  1736. }
  1737. public function request($host, $url) {
  1738. $this->prepareurl($host, $url);
  1739. $this->adminpanel = strbegin($this->url, '/admin/') || ($this->url == '/admin');
  1740. if ($this->redirdom) {
  1741. $parsedurl = parse_url(litepublisher::$site->url . '/');
  1742. if ($host != strtolower($parsedurl['host'])) {
  1743. return $this->redir($url);
  1744. }
  1745. }
  1746. $this->beforerequest();
  1747. if (!litepublisher::$debug && litepublisher::$options->ob_cache) ob_start();
  1748. try {
  1749. $this->dorequest($this->url);
  1750. } catch (Exception $e) {
  1751. litepublisher::$options->handexception($e);
  1752. }
  1753. if (!litepublisher::$debug && litepublisher::$options->ob_cache) {
  1754. litepublisher::$options->showerrors();
  1755. litepublisher::$options->errorlog = '';
  1756. $afterclose = $this->isredir || count($this->close_events);
  1757. if ($afterclose) $this->close_connection();
  1758. while (@ob_end_flush ());
  1759. flush();
  1760. //prevent output while client connected
  1761. if ($afterclose) ob_start();
  1762. }
  1763. $this->afterrequest($this->url);
  1764. $this->close();
  1765. }
  1766. public function close_connection() {
  1767. ignore_user_abort(true);
  1768. //$len = $this->isredir ? 0 : ob_get_length();
  1769. $len = ob_get_length();
  1770. header('Connection: close');
  1771. header('Content-Length: ' . $len);
  1772. header('Content-Encoding: none');
  1773. //header('Accept-Ranges: bytes');
  1774. }
  1775. protected function dorequest($url) {
  1776. //echo "'$url'<br>";
  1777. $this->itemrequested = $this->finditem($url);
  1778. if ($this->isredir) return;
  1779. if ($this->itemrequested) {
  1780. return $this->printcontent($this->itemrequested);
  1781. } else {
  1782. $this->notfound404();
  1783. }
  1784. }
  1785. public function getidurl($id) {
  1786. if (!isset($this->items[$id])) {
  1787. $this->items[$id] = $this->db->getitem($id);
  1788. }
  1789. return $this->items[$id]['url'];
  1790. }
  1791. public function findurl($url) {
  1792. if ($result = $this->db->finditem('url = '. dbquote($url))) return $result;
  1793. return false;
  1794. }
  1795. public function urlexists($url) {
  1796. return $this->db->findid('url = '. dbquote($url));
  1797. }
  1798. private function query($url) {
  1799. if ($item = $this->db->getassoc('url = '. dbquote($url). ' limit 1')) {
  1800. $this->items[$item['id']] = $item;
  1801. return $item;
  1802. }
  1803. return false;
  1804. }
  1805. public function finditem($url) {
  1806. if ($result = $this->query($url)) return $result;
  1807. $srcurl = $url;
  1808. if ($i = strpos($url, '?')) $url = substr($url, 0, $i);
  1809. if ('//' == substr($url, -2)) $this->redir(rtrim($url, '/') . '/');
  1810. //extract page number
  1811. if (preg_match('/(.*?)\/page\/(\d*?)\/?$/', $url, $m)) {
  1812. if ('/' != substr($url, -1)) return $this->redir($url . '/');
  1813. $url = $m[1];
  1814. if ($url == '') $url = '/';
  1815. $this->page = max(1, abs((int) $m[2]));
  1816. }
  1817. if ($result = $this->query($url)) {
  1818. if (($this->page == 1) && ($result['type'] == 'normal') && ($srcurl != $result['url'])) return $this->redir($url);
  1819. return $result;
  1820. }
  1821. $url = $url != rtrim($url, '/') ? rtrim($url, '/') : $url . '/';
  1822. if ($result = $this->query($url)) {
  1823. if ($this->page > 1) return $result;
  1824. if ($result['type'] == 'normal') return $this->redir($url);
  1825. return $result;
  1826. }
  1827. $this->uripath = explode('/', trim($url, '/'));
  1828. //tree convert into argument
  1829. $url = trim($url, '/');
  1830. $j = -1;
  1831. while($i = strrpos($url, '/', $j)) {
  1832. if ($result = $this->query('/' . substr($url, 0, $i + 1))) {
  1833. if ($result['type'] != 'tree') return false;
  1834. $this->argtree = substr($url, $i +1);
  1835. return $result;
  1836. }
  1837. $j = - (strlen($url) - $i + 1);
  1838. }
  1839. return false;
  1840. }
  1841. private function getcachefile(array $item) {
  1842. switch ($item['type']) {
  1843. case 'normal':
  1844. return sprintf('%s-%d.php', $item['id'], $this->page);
  1845. case 'usernormal':
  1846. return sprintf('%s-page-%d-user-%d.php', $item['id'], $this->page, litepublisher::$options->user);
  1847. case 'userget':
  1848. return sprintf('%s-page-%d-user%d-get-%s.php', $item['id'], $this->page, litepublisher::$options->user, md5($_SERVER['REQUEST_URI']));
  1849. default: //get
  1850. return sprintf('%s-%d-%s.php', $item['id'], $this->page, md5($_SERVER['REQUEST_URI']));
  1851. }
  1852. }
  1853. private function include_file($fn) {
  1854. if (tfilestorage::$memcache) {
  1855. if ($s = $this->cache->get($fn)) {
  1856. eval('?>' . $s);
  1857. return true;
  1858. }
  1859. return false;
  1860. }
  1861. $filename = litepublisher::$paths->cache . $fn;
  1862. if (file_exists($filename) &&
  1863. ((filemtime ($filename) + litepublisher::$options->expiredcache - litepublisher::$options->filetime_offset) >= time())) {
  1864. include($filename);
  1865. return true;
  1866. }
  1867. return false;
  1868. }
  1869. private function printcontent(array $item) {
  1870. $options = litepublisher::$options;
  1871. if ($this->cache_enabled) {
  1872. if ($this->include_file($this->getcachefile($item))) return;
  1873. }
  1874. if (class_exists($item['class'])) {
  1875. return $this->GenerateHTML($item);
  1876. } else {
  1877. //$this->deleteclass($item['class']);
  1878. $this->notfound404();
  1879. }
  1880. }
  1881. public function getidcontext($id) {
  1882. $item = $this->getitem($id);
  1883. return $this->getcontext($item);
  1884. }
  1885. public function getcontext(array $item) {
  1886. $class = $item['class'];
  1887. $parents = class_parents($class);
  1888. if (in_array('titem', $parents)) {
  1889. return call_user_func_array(array($class, 'i'), array($item['arg']));
  1890. } else {
  1891. return getinstance($class);
  1892. }
  1893. }
  1894. protected function GenerateHTML(array $item) {
  1895. $context = $this->getcontext($item);
  1896. $this->context = $context;
  1897. //special handling for rss
  1898. if (method_exists($context, 'request') && ($s = $context->request($item['arg']))) {
  1899. switch ($s) {
  1900. case 404: return $this->notfound404();
  1901. case 403: return $this->forbidden();
  1902. }
  1903. } else {
  1904. if ($this->isredir) return;
  1905. $template = ttemplate::i();
  1906. $s = $template->request($context);
  1907. }
  1908. eval('?>'. $s);
  1909. if ($this->cache_enabled && $context->cache) {
  1910. $this->cache->set($this->getcachefile($item), $s);
  1911. }
  1912. }
  1913. public function notfound404() {
  1914. $redir = tredirector::i();
  1915. if ($url = $redir->get($this->url)) {
  1916. return $this->redir($url);
  1917. }
  1918. $this->is404 = true;
  1919. $this->printclasspage('tnotfound404');
  1920. }
  1921. private function printclasspage($classname) {
  1922. $cachefile = $classname . '.php';
  1923. if ($this->cache_enabled) {
  1924. if ($this->include_file($cachefile)) return;
  1925. }
  1926. $obj = getinstance($classname);
  1927. $Template = ttemplate::i();
  1928. $s = $Template->request($obj);
  1929. eval('?>'. $s);
  1930. if ($this->cache_enabled && $obj->cache) {
  1931. $this->cache->set($cachefile, $result);
  1932. }
  1933. }
  1934. public function forbidden() {
  1935. $this->is404 = true;
  1936. $this->printclasspage('tforbidden');
  1937. }
  1938. public function addget($url, $class) {
  1939. return $this->add($url, $class, null, 'get');
  1940. }
  1941. public function add($url, $class, $arg, $type = 'normal') {
  1942. if (empty($url)) $this->error('Empty url to add');
  1943. if (empty($class)) $this->error('Empty class name of adding url');
  1944. if (!in_array($type, array('normal','get','tree', 'usernormal', 'userget'))) $this->error(sprintf('Invalid url type %s', $type));
  1945. if ($item = $this->db->finditem('url = ' . dbquote($url))) $this->error(sprintf('Url "%s" already exists', $url));
  1946. $item= array(
  1947. 'url' => $url,
  1948. 'class' => $class,
  1949. 'arg' => (string) $arg,
  1950. 'type' => $type
  1951. );
  1952. $item['id'] = $this->db->add($item);
  1953. $this->items[$item['id']] = $item;
  1954. return $item['id'];
  1955. }
  1956. public function delete($url) {
  1957. $url = dbquote($url);
  1958. if ($id = $this->db->findid('url = ' . $url)) {
  1959. $this->db->iddelete($id);
  1960. } else {
  1961. return false;
  1962. }
  1963. $this->clearcache();
  1964. $this->deleted($id);
  1965. return true;
  1966. }
  1967. public function deleteclass($class) {
  1968. if ($items =
  1969. $this->db->getitems("class = '$class'")) {
  1970. $this->db->delete("class = '$class'");
  1971. foreach ($items as $item) $this->deleted($item['id']);
  1972. }
  1973. $this->clearcache();
  1974. }
  1975. public function deleteitem($id) {
  1976. if ($item = $this->db->getitem($id)) {
  1977. $this->db->iddelete($id);
  1978. $this->deleted($id);
  1979. }
  1980. $this->clearcache();
  1981. }
  1982. //for Archives
  1983. public function GetClassUrls($class) {
  1984. $res = $this->db->query("select url from $this->thistable where class = '$class'");
  1985. return $this->db->res2id($res);
  1986. }
  1987. public function clearcache() {
  1988. $this->cache->clear();
  1989. $this->onclearcache();
  1990. }
  1991. public function setexpired($id) {
  1992. if ($item = $this->getitem($id)) {
  1993. $cache = $this->cache;
  1994. $page = $this->page;
  1995. for ($i = 1; $i <= 10; $i++) {
  1996. $this->page = $i;
  1997. $cache->delete($this->getcachefile($item));
  1998. }
  1999. $this->page = $page;
  2000. }
  2001. }
  2002. public function setexpiredcurrent() {
  2003. $this->cache->delete($this->getcachefile($this->itemrequested));
  2004. }
  2005. public function expiredclass($class) {
  2006. $items = $this->db->getitems("class = '$class'");
  2007. if (count($items) == 0) return;
  2008. $cache = $this->cache;
  2009. $page = $this->page;
  2010. $this->page = 1;
  2011. foreach ($items as $item) {
  2012. $cache->delete($this->getcachefile($item));
  2013. }
  2014. $this->page = $page;
  2015. }
  2016. public function addredir($from, $to) {
  2017. if ($from == $to) return;
  2018. $Redir = tredirector::i();
  2019. $Redir->add($from, $to);
  2020. }
  2021. public static function unsub($obj) {
  2022. $self = self::i();
  2023. $self->lock();
  2024. $self->unbind($obj);
  2025. $self->deleteclass(get_class($obj));
  2026. $self->unlock();
  2027. }
  2028. public function setonclose(array $a) {
  2029. if (count($a) == 0) return;
  2030. $this->close_events[] = $a;
  2031. }
  2032. public function onclose() {
  2033. $this->setonclose(func_get_args());
  2034. }
  2035. private function call_close_events() {
  2036. foreach ($this->close_events as $a) {
  2037. try {
  2038. $c = array_shift($a);
  2039. if (!is_callable($c)) {
  2040. $c = array($c, array_shift($a));
  2041. }
  2042. call_user_func_array($c, $a);
  2043. } catch (Exception $e) {
  2044. litepublisher::$options->handexception($e);
  2045. }
  2046. }
  2047. $this->close_events = array();
  2048. }
  2049. protected function close() {
  2050. $this->call_close_events();
  2051. if ($this->disabledcron) return;
  2052. if (tfilestorage::$memcache) {
  2053. $memcache = tfilestorage::$memcache;
  2054. $k =litepublisher::$domain . ':lastpinged';
  2055. $lastpinged = $memcache->get($k);
  2056. if (!$lastpinged || (time() > $lastpinged + 3600)) {
  2057. $memcache->set($k, time(), false, 3600);
  2058. tcron::pingonshutdown();
  2059. }else {
  2060. $k =litepublisher::$domain . ':singlepinged';
  2061. $singlepinged = $memcache->get($k);
  2062. if ($singlepinged && (time() > $singlepinged + 300)) {
  2063. $memcache->delete($k);
  2064. tcron::pingonshutdown();
  2065. }
  2066. }
  2067. } elseif (time() > litepublisher::$options->crontime + 3600) {
  2068. litepublisher::$options->crontime = time();
  2069. tcron::pingonshutdown();
  2070. }
  2071. }
  2072. public function redir($url, $status = 301) {
  2073. litepublisher::$options->savemodified();
  2074. $this->isredir = true;
  2075. switch ($status) {
  2076. case 301:
  2077. header('HTTP/1.1 301 Moved Permanently', true, 301);
  2078. break;
  2079. case 302:
  2080. header('HTTP/1.1 302 Found', true, 302);
  2081. break;
  2082. case 307:
  2083. header('HTTP/1.1 307 Temporary Redirect', true, 307);
  2084. break;
  2085. }
  2086. if (!strbegin($url, 'http://') && !strbegin($url, 'https://')) $url = litepublisher::$site->url . $url;
  2087. header('Location: ' . $url);
  2088. }
  2089. public function seturlvalue($url, $name, $value) {
  2090. if ($id = $this->urlexists($url)) {
  2091. $this->setvalue($id, $name, $value);
  2092. }
  2093. }
  2094. public function setidurl($id, $url) {
  2095. $this->db->setvalue($id, 'url', $url);
  2096. if (isset($this->items[$id])) $this->items[$id]['url'] = $url;
  2097. }
  2098. public function getnextpage() {
  2099. $url = $this->itemrequested['url'];
  2100. return litepublisher::$site->url . rtrim($url, '/') . '/page/' . ($this->page + 1) . '/';
  2101. }
  2102. public function getprevpage() {
  2103. $url = $this->itemrequested['url'];
  2104. if ($this->page <= 2) return url;
  2105. return litepublisher::$site->url . rtrim($url, '/') . '/page/' . ($this->page - 1) . '/';
  2106. }
  2107. public static function htmlheader($cache) {
  2108. return sprintf('<?php turlmap::sendheader(%s); ?>', $cache ? 'true' : 'false');
  2109. }
  2110. public static function nocache() {
  2111. Header( 'Cache-Control: no-cache, must-revalidate');
  2112. Header( 'Pragma: no-cache');
  2113. }
  2114. public static function sendheader($cache) {
  2115. if (!$cache) self::nocache();
  2116. header('Content-Type: text/html; charset=utf-8');
  2117. header('Last-Modified: ' . date('r'));
  2118. header('X-Pingback: ' . litepublisher::$site->url . '/rpc.xml');
  2119. }
  2120. public static function sendxml() {
  2121. header('Content-Type: text/xml; charset=utf-8');
  2122. header('Last-Modified: ' . date('r'));
  2123. header('X-Pingback: ' . litepublisher::$site->url . '/rpc.xml');
  2124. echo '<?xml version="1.0" encoding="utf-8" ?>';
  2125. }
  2126. }//class
  2127. class tlitememcache {
  2128. public $revision;
  2129. public $prefix;
  2130. public function __construct($urlmap) {
  2131. $this->revision = &$urlmap->data['revision'];
  2132. $this->prefix = litepublisher::$domain . ':cache:';
  2133. }
  2134. public function clear() {
  2135. $this->revision++;
  2136. litepublisher::$urlmap->save();
  2137. }
  2138. public function set($filename, $data) {
  2139. tfilestorage::$memcache->set($this->prefix . $filename,
  2140. serialize(array(
  2141. 'revision' => $this->revision,
  2142. 'time' => time(),
  2143. 'data' => $data
  2144. )), false, 3600);
  2145. }
  2146. public function get($filename) {
  2147. if ($s = tfilestorage::$memcache->get($this->prefix . $filename)) {
  2148. $a = unserialize($s);
  2149. if ($a['revision'] == $this->revision) {
  2150. return $a['data'];
  2151. } else {
  2152. tfilestorage::$memcache->delete($this->prefix . $filename);
  2153. }
  2154. }
  2155. return false;
  2156. }
  2157. public function delete($filename) {
  2158. tfilestorage::$memcache->delete($this->prefix . $filename);
  2159. }
  2160. public function exists($filename) {
  2161. return !!tfilestorage::$memcache->get($this->prefix . $filename);
  2162. }
  2163. }//class
  2164. class tfilecache {
  2165. public function clear() {
  2166. $path = litepublisher::$paths->cache;
  2167. if ( $h = @opendir($path)) {
  2168. while(FALSE !== ($filename = @readdir($h))) {
  2169. if (($filename == '.') || ($filename == '..') || ($filename == '.svn')) continue;
  2170. $file = $path. $filename;
  2171. if (is_dir($file)) {
  2172. tfiler::delete($file . DIRECTORY_SEPARATOR, true, true);
  2173. } else {
  2174. unlink($file);
  2175. }
  2176. }
  2177. closedir($h);
  2178. }
  2179. }
  2180. public function set($filename, $data) {
  2181. $fn = litepublisher::$paths->cache . $filename;
  2182. if (!is_string($data)) $data = serialize($data);
  2183. file_put_contents($fn, $data);
  2184. @chmod($fn, 0666);
  2185. }
  2186. public function get($filename) {
  2187. $fn = litepublisher::$paths->cache . $filename;
  2188. if (file_exists($fn)) return file_get_contents($fn);
  2189. return false;
  2190. }
  2191. public function delete($filename) {
  2192. $fn = litepublisher::$paths->cache . $filename;
  2193. if (file_exists($fn)) unlink($fn);
  2194. }
  2195. public function exists($filename) {
  2196. return file_exists(litepublisher::$paths->cache . $filename);
  2197. }
  2198. }//class
  2199. //interfaces.php
  2200. interface itemplate {
  2201. public function request($arg);
  2202. public function gettitle();
  2203. public function getkeywords();
  2204. public function getdescription();
  2205. public function gethead();
  2206. public function getcont();
  2207. public function getidview();
  2208. public function setidview($id);
  2209. }
  2210. interface iwidgets {
  2211. public function getwidgets(array &$items, $sidebar);
  2212. public function getsidebar(&$content, $sidebar);
  2213. }
  2214. interface iadmin {
  2215. public function getcontent();
  2216. public function processform();
  2217. }
  2218. interface iposts {
  2219. public function add(tpost $post);
  2220. public function edit(tpost $post);
  2221. public function delete($id);
  2222. }
  2223. interface imenu {
  2224. public function getcurrent();
  2225. }
  2226. //plugin.class.php
  2227. class tplugin extends tevents {
  2228. protected function create() {
  2229. parent::create();
  2230. $this->basename= 'plugins' .DIRECTORY_SEPARATOR . strtolower(get_class($this));
  2231. }
  2232. }
  2233. //users.class.php
  2234. class tusers extends titems {
  2235. public $grouptable;
  2236. public static function i() {
  2237. return getinstance(__class__);
  2238. }
  2239. protected function create() {
  2240. $this->dbversion = true;
  2241. parent::create();
  2242. $this->basename = 'users';
  2243. $this->table = 'users';
  2244. $this->grouptable = 'usergroup';
  2245. $this->addevents('beforedelete');
  2246. }
  2247. public function res2items($res) {
  2248. if (!$res) return array();
  2249. $result = array();
  2250. $db = litepublisher::$db;
  2251. while ($item = $db->fetchassoc($res)) {
  2252. $id = (int) $item['id'];
  2253. $item['idgroups'] = tdatabase::str2array($item['idgroups']);
  2254. $result[] = $id;
  2255. $this->items[$id] = $item;
  2256. }
  2257. return $result;
  2258. }
  2259. /*
  2260. public function getitem($id) {
  2261. if ($id == 1) return array(
  2262. 'email' =>litepublisher::$options->email,
  2263. 'name' => litepublisher::$site->author,
  2264. 'website' => litepublisher::$site->url . '/',
  2265. 'password' => litepublisher::$options->password,
  2266. 'cookie' => litepublisher::$options->cookie,
  2267. 'expired' => sqldate(litepublisher::$options->cookieexpired ),
  2268. 'status' => 'approved',
  2269. 'idgroups' => array(1)
  2270. );
  2271. return parent::getitem($id);
  2272. }
  2273. */
  2274. public function add(array $values) {
  2275. return tusersman::i()->add($values);
  2276. }
  2277. public function edit($id, array $values) {
  2278. return tusersman::i()->edit($id, $values);
  2279. }
  2280. public function setgroups($id, array $idgroups) {
  2281. $idgroups = array_unique($idgroups);
  2282. array_delete_value($idgroups, '');
  2283. array_delete_value($idgroups, false);
  2284. array_delete_value($idgroups, null);
  2285. $this->items[$id]['idgroups'] = $idgroups;
  2286. $db = $this->getdb($this->grouptable);
  2287. $db->delete("iduser = $id");
  2288. foreach ($idgroups as $idgroup) {
  2289. $db->add(array(
  2290. 'iduser' => $id,
  2291. 'idgroup' => $idgroup
  2292. ));
  2293. }
  2294. }
  2295. public function delete($id) {
  2296. if ($id == 1) return;
  2297. $this->beforedelete($id);
  2298. $this->getdb($this->grouptable)->delete('iduser = ' .(int)$id);
  2299. tuserpages::i()->delete($id);
  2300. $this->getdb('comments')->update("status = 'deleted'", "author = $id");
  2301. return parent::delete($id);
  2302. }
  2303. public function emailexists($email) {
  2304. if ($email == '') return false;
  2305. if ($email == litepublisher::$options->email) return 1;
  2306. return $this->db->findid('email = '. dbquote($email));
  2307. }
  2308. public function getpassword($id) {
  2309. return $id == 1 ? litepublisher::$options->password : $this->getvalue($id, 'password');
  2310. }
  2311. public function changepassword($id, $password) {
  2312. $item = $this->getitem($id);
  2313. $this->setvalue($id, 'password', basemd5(sprintf('%s:%s:%s', $item['email'], litepublisher::$options->realm, $password)));
  2314. }
  2315. public function approve($id) {
  2316. $this->setvalue($id, 'status', 'approved');
  2317. $pages = tuserpages::i();
  2318. if ($pages->createpage) $pages->addpage($id);
  2319. }
  2320. public function auth($email,$password) {
  2321. $password = basemd5(sprintf('%s:%s:%s', $email, litepublisher::$options->realm, $password));
  2322. $email = dbquote($email);
  2323. if (($a = $this->select("email = $email and password = '$password'", 'limit 1')) && (count($a) > 0)) {
  2324. $item = $this->getitem($a[0]);
  2325. if ($item['status'] == 'wait') $this->approve($item['id']);
  2326. return (int) $item['id'];
  2327. }
  2328. return false;
  2329. }
  2330. public function authcookie($cookie) {
  2331. $cookie = (string) $cookie;
  2332. if (empty($cookie)) return false;
  2333. $cookie = basemd5( $cookie . litepublisher::$secret);
  2334. if ($cookie == basemd5(litepublisher::$secret)) return false;
  2335. if ($id = $this->findcookie($cookie)) {
  2336. $item = $this->getitem($id);
  2337. if (strtotime($item['expired']) > time()) return $id;
  2338. }
  2339. return false;
  2340. }
  2341. public function findcookie($cookie) {
  2342. $cookie = dbquote($cookie);
  2343. if (($a = $this->select('cookie = ' . $cookie, 'limit 1')) && (count($a) > 0)) {
  2344. return (int) $a[0];
  2345. }
  2346. return false;
  2347. }
  2348. public function getgroupname($id) {
  2349. $item = $this->getitem($id);
  2350. $groups = tusergroups::i();
  2351. return $groups->items[$item['idgroups'][0]]['name'];
  2352. }
  2353. public function clearcookie($id) {
  2354. $this->setcookie($id, '', 0);
  2355. }
  2356. public function setcookie($id, $cookie, $expired) {
  2357. if ($cookie != '') $cookie = basemd5($cookie . litepublisher::$secret);
  2358. $expired = sqldate($expired);
  2359. if (isset($this->items[$id])) {
  2360. $this->items[$id]['cookie'] = $cookie;
  2361. $this->items[$id]['expired'] = $expired;
  2362. }
  2363. $this->db->updateassoc(array(
  2364. 'id' => $id,
  2365. 'cookie' => $cookie,
  2366. 'expired' => $expired
  2367. ));
  2368. }
  2369. }//class
  2370. //items.pull.class.php
  2371. class tpullitems extends tdata {
  2372. protected $perpull;
  2373. protected $pull;
  2374. protected $modified;
  2375. protected $ongetitem;
  2376. public static function i() {
  2377. return getinstance(__class__);
  2378. }
  2379. protected function create() {
  2380. parent::create();
  2381. $this->basename = 'pullitems';
  2382. $this->perpull = 20;
  2383. $this->pull = array();
  2384. $this->modified = array();
  2385. }
  2386. public function getitem($id) {
  2387. if (isset($this->ongetitem)) return call_user_func_array($this->ongetitem, array($id));
  2388. $this->error('Call abastract method getitem in class' . get_class($this));
  2389. }
  2390. public function getfilename($idpull) {
  2391. return $this->basename . '.pull.' . $idpull;
  2392. }
  2393. public function loadpull($idpull) {
  2394. if ($s = litepublisher::$urlmap->cache->get($this->getfilename($idpull))) {
  2395. $this->pull[$idpull] = unserialize($s);
  2396. } else {
  2397. $this->pull[$idpull] = array();
  2398. }
  2399. }
  2400. public function savepull($idpull) {
  2401. if (!isset($this->modified[$idpull])) {
  2402. litepublisher::$urlmap->onclose = array($this, 'savemodified', $idpull);
  2403. $this->modified[$idpull] = true;
  2404. }
  2405. }
  2406. public function savemodified($idpull) {
  2407. litepublisher::$urlmap->cache->set($this->getfilename($idpull), serialize($this->pull[$idpull]));
  2408. }
  2409. public function getidpull($id) {
  2410. $idpull = (int) floor ($id /$this->perpull);
  2411. if (!isset($this->pull[$idpull])) $this->loadpull($idpull);
  2412. return $idpull;
  2413. }
  2414. public function get($id) {
  2415. $idpull = $this->getidpull($id);
  2416. if (isset($this->pull[$idpull][$id])) return $this->pull[$idpull][$id];
  2417. $result = $this->getitem($id);
  2418. $this->pull[$idpull][$id] = $result;
  2419. $this->savepull($idpull);
  2420. return $result;
  2421. }
  2422. public function set($id, $item) {
  2423. $idpull = $this->getidpull($id);
  2424. $this->pull[$idpull][$id] = $item;
  2425. $this->savepull($idpull);
  2426. }
  2427. }//class
  2428. ?>