PageRenderTime 53ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 0ms

/framework/applications/noviusos_page/classes/model/page.model.php

https://github.com/jay3/core
PHP | 474 lines | 393 code | 42 blank | 39 comment | 23 complexity | 6d427619d3b435f24cc304aabb07cc36 MD5 | raw file
Possible License(s): LGPL-2.1
  1. <?php
  2. /**
  3. * NOVIUS OS - Web OS for digital communication
  4. *
  5. * @copyright 2011 Novius
  6. * @license GNU Affero General Public License v3 or (at your option) any later version
  7. * http://www.gnu.org/licenses/agpl-3.0.html
  8. * @link http://www.novius-os.org
  9. */
  10. namespace Nos\Page;
  11. class Model_Page extends \Nos\Orm\Model
  12. {
  13. protected static $_table_name = 'nos_page';
  14. protected static $_primary_key = array('page_id');
  15. protected static $_title_property = 'page_title';
  16. protected static $_properties = array(
  17. 'page_id' => array(
  18. 'default' => null,
  19. 'data_type' => 'int',
  20. 'null' => false,
  21. ),
  22. 'page_parent_id' => array(
  23. 'default' => null,
  24. 'data_type' => 'int',
  25. 'null' => true,
  26. 'convert_empty_to_null' => true,
  27. ),
  28. 'page_template' => array(
  29. 'default' => null,
  30. 'data_type' => 'varchar',
  31. 'null' => true,
  32. 'convert_empty_to_null' => true,
  33. ),
  34. 'page_level' => array(
  35. 'default' => 0,
  36. 'data_type' => 'tinyint',
  37. 'null' => false,
  38. ),
  39. 'page_title' => array(
  40. 'default' => '',
  41. 'data_type' => 'varchar',
  42. 'null' => false,
  43. ),
  44. 'page_context' => array(
  45. 'default' => null,
  46. 'data_type' => 'varchar',
  47. 'null' => false,
  48. ),
  49. 'page_context_common_id' => array(
  50. 'default' => null,
  51. 'data_type' => 'int',
  52. 'null' => false,
  53. ),
  54. 'page_context_is_main' => array(
  55. 'default' => 0,
  56. 'data_type' => 'tinyint',
  57. 'null' => false,
  58. ),
  59. 'page_menu_title' => array(
  60. 'default' => null,
  61. 'data_type' => 'varchar',
  62. 'null' => true,
  63. 'convert_empty_to_null' => true,
  64. ),
  65. 'page_meta_title' => array(
  66. 'default' => null,
  67. 'data_type' => 'varchar',
  68. 'null' => true,
  69. 'convert_empty_to_null' => true,
  70. ),
  71. 'page_sort' => array(
  72. 'default' => null,
  73. 'data_type' => 'float',
  74. 'null' => true,
  75. 'convert_empty_to_null' => true,
  76. ),
  77. 'page_menu' => array(
  78. 'default' => 0,
  79. 'data_type' => 'tinyint',
  80. 'null' => false,
  81. ),
  82. 'page_type' => array(
  83. 'default' => 0,
  84. 'data_type' => 'tinyint',
  85. 'null' => false,
  86. ),
  87. 'page_published' => array(
  88. 'default' => 0,
  89. 'data_type' => 'tinyint',
  90. 'null' => false,
  91. ),
  92. 'page_publication_start' => array(
  93. 'default' => null,
  94. 'data_type' => 'datetime',
  95. 'null' => true,
  96. 'convert_empty_to_null' => true,
  97. ),
  98. 'page_publication_end' => array(
  99. 'default' => null,
  100. 'data_type' => 'datetime',
  101. 'null' => true,
  102. 'convert_empty_to_null' => true,
  103. ),
  104. 'page_meta_noindex' => array(
  105. 'default' => 0,
  106. 'data_type' => 'tinyint unsigned',
  107. 'null' => false,
  108. ),
  109. 'page_lock' => array(
  110. 'default' => 0,
  111. 'data_type' => 'tinyint',
  112. 'null' => false,
  113. ),
  114. 'page_entrance' => array(
  115. 'default' => 0,
  116. 'data_type' => 'tinyint',
  117. 'null' => false,
  118. ),
  119. 'page_home' => array(
  120. 'default' => 0,
  121. 'data_type' => 'tinyint',
  122. 'null' => false,
  123. ),
  124. 'page_cache_duration' => array(
  125. 'default' => null,
  126. 'data_type' => 'int',
  127. 'null' => true,
  128. 'convert_empty_to_null' => true,
  129. ),
  130. 'page_virtual_name' => array(
  131. 'default' => null,
  132. 'data_type' => 'varchar',
  133. 'null' => true,
  134. 'convert_empty_to_null' => true,
  135. 'character_maximum_length' => 100,
  136. ),
  137. 'page_virtual_url' => array(
  138. 'default' => null,
  139. 'data_type' => 'varchar',
  140. 'null' => true,
  141. 'convert_empty_to_null' => true,
  142. ),
  143. 'page_external_link' => array(
  144. 'default' => null,
  145. 'data_type' => 'varchar',
  146. 'null' => true,
  147. 'convert_empty_to_null' => true,
  148. ),
  149. 'page_external_link_type' => array(
  150. 'default' => null,
  151. 'data_type' => 'tinyint',
  152. 'null' => true,
  153. 'convert_empty_to_null' => true,
  154. ),
  155. 'page_created_at' => array(
  156. 'data_type' => 'timestamp',
  157. 'null' => false,
  158. ),
  159. 'page_updated_at' => array(
  160. 'data_type' => 'timestamp',
  161. 'null' => false,
  162. ),
  163. 'page_meta_description' => array(
  164. 'default' => null,
  165. 'data_type' => 'text',
  166. 'null' => true,
  167. 'convert_empty_to_null' => true,
  168. ),
  169. 'page_meta_keywords' => array(
  170. 'default' => null,
  171. 'data_type' => 'text',
  172. 'null' => true,
  173. 'convert_empty_to_null' => true,
  174. ),
  175. 'page_created_by_id' => array(
  176. 'default' => null,
  177. 'data_type' => 'int unsigned',
  178. 'null' => true,
  179. 'convert_empty_to_null' => true,
  180. ),
  181. 'page_updated_by_id' => array(
  182. 'default' => null,
  183. 'data_type' => 'int unsigned',
  184. 'null' => true,
  185. 'convert_empty_to_null' => true,
  186. ),
  187. );
  188. protected static $_has_one = array();
  189. protected static $_many_many = array();
  190. protected static $_has_many = array(
  191. 'children' => array(
  192. 'key_from' => 'page_id',
  193. 'model_to' => '\Nos\Page\Model_Page',
  194. 'key_to' => 'page_parent_id',
  195. 'cascade_save' => false,
  196. 'cascade_delete' => false,
  197. ),
  198. );
  199. protected static $_belongs_to = array(
  200. 'parent' => array(
  201. 'key_from' => 'page_parent_id',
  202. 'model_to' => '\Nos\Page\Model_Page',
  203. 'key_to' => 'page_id',
  204. 'cascade_save' => false,
  205. 'cascade_delete' => false,
  206. ),
  207. );
  208. protected static $_observers = array(
  209. 'Orm\\Observer_Self',
  210. 'Orm\Observer_CreatedAt' => array(
  211. 'mysql_timestamp' => true,
  212. 'property'=>'page_created_at'
  213. ),
  214. 'Orm\Observer_UpdatedAt' => array(
  215. 'mysql_timestamp' => true,
  216. 'property'=>'page_updated_at'
  217. ),
  218. );
  219. protected static $_behaviours = array(
  220. 'Nos\Orm_Behaviour_Twinnable' => array(
  221. 'context_property' => 'page_context',
  222. 'common_id_property' => 'page_context_common_id',
  223. 'is_main_property' => 'page_context_is_main',
  224. ),
  225. 'Nos\Orm_Behaviour_Tree' => array(
  226. 'parent_relation' => 'parent',
  227. 'children_relation' => 'children',
  228. 'level_property' => 'page_level',
  229. ),
  230. 'Nos\Orm_Behaviour_Virtualpath' => array(
  231. 'virtual_name_property' => 'page_virtual_name',
  232. 'virtual_path_property' => 'page_virtual_url',
  233. 'extension_property' => '.html',
  234. ),
  235. 'Nos\Orm_Behaviour_Sortable' => array(
  236. 'sort_property' => 'page_sort',
  237. ),
  238. 'Nos\Orm_Behaviour_Publishable' => array(
  239. 'publication_state_property' => 'page_published',
  240. 'publication_start_property' => 'page_publication_start',
  241. 'publication_end_property' => 'page_publication_end',
  242. // Permissions to deny publication is in the config file
  243. ),
  244. 'Nos\Orm_Behaviour_Author' => array(
  245. 'created_by_property' => 'page_created_by_id',
  246. 'updated_by_property' => 'page_updated_by_id',
  247. ),
  248. );
  249. protected $_page_id_for_delete = null;
  250. const TYPE_CLASSIC = 0;
  251. const TYPE_EXTERNAL_LINK = 3;
  252. const EXTERNAL_TARGET_NEW = 0;
  253. const EXTERNAL_TARGET_SAME = 2;
  254. const LOCK_UNLOCKED = 0;
  255. const LOCK_DELETION = 1;
  256. public static function find($id = null, array $options = array())
  257. {
  258. if (array_key_exists('order_by', $options)) {
  259. isset($options['order_by']['page_sort']) or $options['order_by']['page_sort'] = 'ASC';
  260. }
  261. return parent::find($id, $options);
  262. }
  263. /**
  264. * @deprecated Use htmlAnchor() method instead
  265. */
  266. public function link()
  267. {
  268. \Log::deprecated('->link() is deprecated, use ->htmlAnchor() instead.', 'Chiba.2');
  269. $attr = array(
  270. 'href' => \Nos\Tools_Url::encodePath($this->url()),
  271. );
  272. if ($this->page_type == self::TYPE_EXTERNAL_LINK) {
  273. if ($this->page_external_link_type == self::EXTERNAL_TARGET_NEW) {
  274. $attr['target'] = '_blank';
  275. }
  276. }
  277. return array_to_attr($attr);
  278. }
  279. /**
  280. * Returns an HTML anchor tag with, by default, page URL in href and page title in text.
  281. *
  282. * If key 'href' is set in $attributes parameter :
  283. * - if is a string, used for href attribute
  284. * - if is an array, used as argument of ->url() method
  285. *
  286. * If key 'text' is set in $attributes parameter, its value replace page title
  287. *
  288. * @param array $attributes Array of attributes to be applied to the anchor tag.
  289. * @return string
  290. */
  291. public function htmlAnchor(array $attributes = array())
  292. {
  293. $text = \Arr::get($attributes, 'text', e($this->page_title));
  294. \Arr::delete($attributes, 'text');
  295. $href = \Arr::get($attributes, 'href', $this->url());
  296. if (is_array($href)) {
  297. $href = $this->url($href);
  298. }
  299. $href = \Nos\Tools_Url::encodePath($href);
  300. \Arr::delete($attributes, 'href');
  301. if ($this->page_type == self::TYPE_EXTERNAL_LINK &&
  302. $this->page_external_link_type == self::EXTERNAL_TARGET_NEW &&
  303. empty($attributes['target'])) {
  304. $attributes['target'] = '_blank';
  305. }
  306. return \Html::anchor($href, $text, $attributes);
  307. }
  308. /**
  309. *
  310. * @param array params
  311. * @return string the href of the page (external link or virtual URL)
  312. */
  313. public function url($params = array())
  314. {
  315. if ($this->page_type == self::TYPE_EXTERNAL_LINK) {
  316. $page_external_link = $this->page_external_link;
  317. if (empty($page_external_link) && !$this->is_main_context()) {
  318. $page_external_link = $this->find_main_context()->page_external_link;
  319. }
  320. return $page_external_link;
  321. }
  322. $url = \Nos\Tools_Url::context($this->page_context);
  323. if (!($this->page_entrance)) {
  324. $url .= $this->virtual_path();
  325. }
  326. if (!empty($params['preview'])) {
  327. $url .= '?_preview=1';
  328. }
  329. return $url;
  330. }
  331. /**
  332. * Delete the cache for this page
  333. */
  334. public function delete_cache()
  335. {
  336. if ($this->page_type == self::TYPE_EXTERNAL_LINK) {
  337. return;
  338. }
  339. $url = $this->page_entrance ? '' : ltrim($this->virtual_path(), '/');
  340. $contexts = \Nos\Tools_Context::contexts();
  341. foreach ($contexts[$this->page_context] as $context_url) {
  342. $cache = \Nos\FrontCache::forge(\Nos\FrontCache::getPathFromUrl($context_url, $url));
  343. $cache->delete();
  344. }
  345. if ($this->page_menu || $this->is_changed('page_menu')) {
  346. static::delete_cache_context($this->page_context);
  347. }
  348. }
  349. /**
  350. * Delete the cache for this context
  351. *
  352. * @param $context string Context to delete (e.g. 'main::en_GB')
  353. */
  354. public static function delete_cache_context($context)
  355. {
  356. $contexts = \Nos\Tools_Context::contexts();
  357. foreach ($contexts[$context] as $context_url) {
  358. $host = parse_url($context_url, PHP_URL_HOST);
  359. $path = trim(parse_url($context_url, PHP_URL_PATH), '/');
  360. \Nos\FrontCache::deleteDir('pages'.DS.$host.DS.$path);
  361. }
  362. }
  363. public function _event_after_save()
  364. {
  365. \Nos\Config_Data::load('enhancers');
  366. $content = '';
  367. foreach ($this->wysiwygs as $text) {
  368. $content .= $text;
  369. }
  370. static::_remove_url_enhanced($this->page_id);
  371. static::_remove_page_enhanced($this->page_id);
  372. $page = $this;
  373. \Nos\Nos::parse_enhancers(
  374. $content,
  375. function ($enhancer, $data_config, $tag) use ($page) {
  376. $config = \Nos\Config_Data::get('enhancers.'.$enhancer, false);
  377. if ($config && !empty($config['urlEnhancer'])) {
  378. $url_enhanced = \Nos\Config_Data::get('url_enhanced', array());
  379. $url = $page->page_entrance ? '' : $page->virtual_path(true);
  380. $url_enhanced[$page->page_id] = array(
  381. 'url' => $url,
  382. 'context' => $page->page_context,
  383. );
  384. \Nos\Config_Data::save('url_enhanced', $url_enhanced);
  385. $page_enhanced = \Nos\Config_Data::get('page_enhanced', array());
  386. $page_enhanced[$enhancer][$page->page_id] = array(
  387. // (array) json_decode(strtr($data_config, array('&quot;' => '"',))) doesn't
  388. // recursively transform an object to an array
  389. 'config' => json_decode(strtr($data_config, array('&quot;' => '"',)), true),
  390. 'context' => $page->page_context,
  391. 'published' => $page->planificationStatus() == 2 ? array(
  392. 'start' => $page->publicationStart(),
  393. 'end' => $page->publicationEnd(),
  394. ) : $page->published(),
  395. );
  396. \Nos\Config_Data::save('page_enhanced', $page_enhanced);
  397. }
  398. }
  399. );
  400. $this->delete_cache();
  401. }
  402. public function _event_before_delete()
  403. {
  404. $this->_page_id_for_delete = $this->page_id;
  405. }
  406. public function _event_after_delete()
  407. {
  408. static::_remove_url_enhanced($this->_page_id_for_delete);
  409. static::_remove_page_enhanced($this->_page_id_for_delete);
  410. $this->delete_cache();
  411. $this->_page_id_for_delete = null;
  412. }
  413. protected static function _remove_url_enhanced($id)
  414. {
  415. $url_enhanced = \Nos\Config_Data::get('url_enhanced', array());
  416. if (isset($url_enhanced[$id])) {
  417. unset($url_enhanced[$id]);
  418. }
  419. \Nos\Config_Data::save('url_enhanced', $url_enhanced);
  420. }
  421. protected static function _remove_page_enhanced($id)
  422. {
  423. $page_enhanced = \Nos\Config_Data::get('page_enhanced', array());
  424. $enhancers = array_filter($page_enhanced, function ($val) use ($id) {
  425. return isset($val[$id]);
  426. });
  427. foreach ($enhancers as $enhancer => $array) {
  428. unset($page_enhanced[$enhancer][$id]);
  429. }
  430. \Nos\Config_Data::save('page_enhanced', $page_enhanced);
  431. }
  432. }