/objects/pages/pages.inc.php

https://github.com/nDIGAH3CEYIiCsq/gold · PHP · 367 lines · 236 code · 60 blank · 71 comment · 26 complexity · 34d04d20dc81ff659177eac890c76297 MD5 · raw file

  1. <?php
  2. /**
  3. * Предоставляет функции работы со страницами в БД
  4. *
  5. * @uses DatabaseInterface
  6. * @uses ObjectCache
  7. * @uses ObjectLog
  8. * @uses Parsable
  9. *
  10. * @version 1.0.3
  11. */
  12. class ObjectPages extends Object implements DatabaseInterface
  13. {
  14. const CacheClass = "templates";
  15. private $cache = array();
  16. static public function get_queries()
  17. {
  18. return array(
  19. 'get' => "SELECT * FROM @ppages WHERE name = BINARY @s",
  20. 'get_all' => "SELECT * FROM @ppages WHERE name LIKE BINARY @s",
  21. 'get_in' => "SELECT * FROM @ppages WHERE name IN (BINARY @l)",
  22. 'add' => "INSERT INTO @ppages SET @a",
  23. 'replace' => "REPLACE @ppages SET @a",
  24. 'update' => "UPDATE @ppages SET @a WHERE name = BINARY @s",
  25. 'delete' => "DELETE FROM @ppages WHERE name IN (BINARY @l)",
  26. 'get_names' => "SELECT name FROM @ppages ORDER BY name ASC"
  27. );
  28. }
  29. /**
  30. * Возвращает данные страницы
  31. * @param $name String: Имя страницы
  32. * @retval Array Данные страницы
  33. */
  34. public function get($name)
  35. {
  36. $data = $this->get_template($name);
  37. if ($data === false)
  38. $this->Log->error("Page {$name} doesn't exists");
  39. return $data;
  40. }
  41. /**
  42. * Возвращает данные страницы без парсинга шаблона
  43. * @param $name String: Имя страницы
  44. * @retval Array Данные страницы
  45. */
  46. public function get_raw($name)
  47. {
  48. $data = $this->get_template_raw($name);
  49. if ($data === false)
  50. $this->Log->error("Page {$name} doesn't exists");
  51. return $data;
  52. }
  53. /**
  54. * Возвращает данные страниц по префиксу имени
  55. * @param $prefix String: Префикс имени
  56. * @retval Array Данные страниц
  57. */
  58. public function get_all($prefix)
  59. {
  60. if (is_array($prefix))
  61. return $this->DB->get_in($prefix);
  62. return $this->DB->get_all($prefix."%");
  63. }
  64. /**
  65. * Добавляет страницу
  66. * @param $data Array: Данные страницы
  67. */
  68. public function add($data)
  69. {
  70. $this->invalidate($data['name']);
  71. $this->unparse($data);
  72. $this->DB->add($data);
  73. }
  74. /**
  75. * Заменяет данные страницы
  76. * @param $data Array: Данные страницы
  77. */
  78. public function replace($data)
  79. {
  80. $this->invalidate($data['name']);
  81. $this->unparse($data);
  82. $this->DB->replace($data);
  83. }
  84. /**
  85. * Удаляет страницу по имени или массиву имён
  86. * @param $names Mixed: Имя страницы для удаления или массив имён
  87. */
  88. public function delete($names)
  89. {
  90. if (!is_array($names))
  91. $names = array($names);
  92. while (list(, $name) = each($names))
  93. $this->invalidate($name);
  94. $this->DB->delete($names);
  95. }
  96. /**
  97. * Обновляет данные страницы
  98. * @param $data Array: Данные страницы
  99. * @param $name String: Старое имя страницы
  100. */
  101. public function update($data, $name = null)
  102. {
  103. if ($name === null)
  104. $name = $data['name'];
  105. else
  106. $this->invalidate($data['name']);
  107. $this->invalidate($name);
  108. $this->unparse($data);
  109. $this->DB->update($data, $name);
  110. }
  111. /**
  112. * Переименовывает страницу
  113. * @param $old_name String: Старое имя
  114. * @param $new_name String: Новое имя
  115. */
  116. public function rename($old_name, $new_name)
  117. {
  118. if ($old_name == $new_name)
  119. return;
  120. $this->invalidate($old_name);
  121. $this->invalidate($new_name);
  122. $this->DB->update(array('name' => $new_name), $old_name);
  123. }
  124. /**
  125. * Проверяет существование страницы
  126. * @param $name String: Имя страницы
  127. * @retval true Страница существует
  128. * @retval false Страница не существует
  129. */
  130. public function exist($name)
  131. {
  132. return ($this->get_template($name) !== false);
  133. }
  134. /**
  135. * Проверяет существование страницы без парсинга шаблона
  136. * @param $name String: Имя страницы
  137. * @retval true Страница существует
  138. * @retval false Страница не существует
  139. */
  140. public function exist_raw($name)
  141. {
  142. return ($this->get_template_raw($name) !== false);
  143. }
  144. /**
  145. * Удаляет страницу из кэша
  146. * @param $name String: Имя страницы
  147. */
  148. public function invalidate($name)
  149. {
  150. $cache_key = $this->get_cache_key($name);
  151. unset($this->cache[$name]);
  152. $this->Cache->delete($cache_key, self::CacheClass);
  153. }
  154. /**
  155. * Возвращает список имён страниц
  156. * @retval Array Список имён
  157. */
  158. public function get_names()
  159. {
  160. $names = $this->Cache->get("names", self::CacheClass);
  161. if ($names !== false)
  162. return $names;
  163. $result = $this->DB->get_names();
  164. $names = array();
  165. while (($row = $result->fetch()))
  166. array_push($names, $row['name']);
  167. $this->Cache->set("names", self::CacheClass, $names);
  168. return $names;
  169. }
  170. /**
  171. * Обновляет список имён страниц
  172. * @param $added_pages Array: Добавляемые страницы
  173. * @param $deleted_pages Array: Удаляемые страницы
  174. */
  175. public function update_names($added_pages, $deleted_pages)
  176. {
  177. $names = $this->Cache->get("names", self::CacheClass);
  178. if ($names === false)
  179. return;
  180. $names = array_diff($names, $deleted_pages);
  181. $names = array_merge($names, $added_pages);
  182. $names = array_unique($names);
  183. sort($names);
  184. $this->Cache->set("names", self::CacheClass, $names);
  185. }
  186. /**
  187. * Выполняет парсинг данных страницы
  188. * @param $data Array: Данные страницы в исходном виде
  189. */
  190. public function parse(&$data)
  191. {
  192. if (!empty($data['params']))
  193. $data['params'] = unserialize($data['params']);
  194. else
  195. $data['params'] = array();
  196. }
  197. private function get_template($name)
  198. {
  199. if (isset($this->cache[$name]))
  200. return $this->cache[$name];
  201. $cache_key = $this->get_cache_key($name);
  202. $data = $this->Cache->get($cache_key, self::CacheClass);
  203. if ($data !== false)
  204. {
  205. if ($data === null)
  206. $data = false;
  207. $this->cache[$name] = $data;
  208. return $data;
  209. }
  210. $result = $this->DB->get($name);
  211. if (!$result->is_empty())
  212. $data = $result->fetch();
  213. if ($data !== false)
  214. {
  215. $this->extract($data);
  216. $this->cache[$name] = $data;
  217. }
  218. else
  219. {
  220. $data = null;
  221. $this->cache[$name] = false;
  222. }
  223. $this->Cache->set($cache_key, self::CacheClass, $data);
  224. if ($data === null)
  225. return false;
  226. return $data;
  227. }
  228. private function get_template_raw($name)
  229. {
  230. $result = $this->DB->get($name);
  231. if ($result->is_empty())
  232. return false;
  233. $data = $result->fetch();
  234. $this->parse($data);
  235. return $data;
  236. }
  237. private function extract(&$data)
  238. {
  239. $this->parse($data);
  240. $this->pack($data);
  241. }
  242. private function unparse(&$data)
  243. {
  244. $data['content'] = str_replace("\r", "", $data['content']);
  245. $params = &$data['params'];
  246. while (list($name, $content) = each($params))
  247. $params[$name] = str_replace("\r", "", $content);
  248. if (!empty($data['params']))
  249. $data['params'] = serialize($data['params']);
  250. else
  251. $data['params'] = "";
  252. }
  253. private function pack(&$data)
  254. {
  255. $data['content'] = new Parsable($data['content']);
  256. $this->apply_includes($data['content']);
  257. $params = &$data['params'];
  258. while (list($name, $content) = each($params))
  259. {
  260. $params[$name] = new Parsable($content);
  261. $this->apply_includes($params[$name]);
  262. }
  263. }
  264. private function get_cache_key($name)
  265. {
  266. return "page_".$name;
  267. }
  268. private function apply_includes(&$parsable)
  269. {
  270. $data = $parsable->get_data();
  271. $cnt = count($data);
  272. for ($i = 0; $i < $cnt; $i++)
  273. {
  274. $param = $data[$i];
  275. switch ($param['type'])
  276. {
  277. case "include":
  278. $value = $this->get($param['value']);
  279. $value_data = $value['content']->get_data();
  280. array_splice($data, $i, 1, $value_data);
  281. $new_cnt = count($value_data) - 1;
  282. $cnt += $new_cnt;
  283. $i += $new_cnt;
  284. break;
  285. case "param":
  286. if (!isset($param['options']))
  287. break;
  288. $this->parse_options($data[$i]['options']);
  289. break;
  290. }
  291. }
  292. $parsable->set_data($data);
  293. }
  294. private function parse_options(&$options)
  295. {
  296. reset($options);
  297. while (list($name, $data) = each($options))
  298. {
  299. if ($data === true)
  300. continue;
  301. $this->apply_includes($options[$name]);
  302. }
  303. }
  304. }
  305. ?>