PageRenderTime 25ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/reason_4.0/lib/core/classes/url/page.php

https://github.com/luthercollege/reason_package
PHP | 359 lines | 217 code | 16 blank | 126 comment | 35 complexity | e48072d114a3732600ee1a6afab81e63 MD5 | raw file
  1. <?php
  2. /**
  3. * Reason Page URL class
  4. *
  5. * @package reason
  6. * @subpackage classes
  7. * @author Nathan White
  8. */
  9. /**
  10. * Include dependencies
  11. */
  12. include_once('reason_header.php');
  13. reason_include_once('classes/url/abstract.php');
  14. include_once(CARL_UTIL_INC . 'basic/url_funcs.php');
  15. /**
  16. * Reason Page URL
  17. *
  18. * A class to simplify getting correct URLs for reason pages, and help deprecate all the crazy URL functions.
  19. *
  20. * This class only cares about page id. Even if the site id is available we don't care. This is done because
  21. * ultimately ownership is going to be directly on the entity and will not require a lookup. By only dealing
  22. * with page_id we keep the API for the class simple. It is best to always just use get_url, which makes a
  23. * "best guess" about protocol.
  24. *
  25. * Basic Usage:
  26. *
  27. * <code>
  28. * $reason_page_url = new reasonPageURL();
  29. * $reason_page_url->set_id(3347);
  30. * $url = $reason_page_url->get_url();
  31. * </code>
  32. *
  33. * Advanced Usage:
  34. *
  35. * There are some optimizations that can be applied for advanced users. Most notably, if you have a minisite page
  36. * or a set of minisite pages already, you can provide them to the reasonPageURL class. If those entities have values
  37. * for parent_id and/or owner_id preset, those values will be used for further optimization. See methods:
  38. *
  39. * - provide_page_entity
  40. * - provide_page_entities
  41. *
  42. * One instance of this class can and should be used for repeated operations - just change the page_id.
  43. *
  44. * One bit of oddness is how to handle pages that aren't really pages, but just containers for URLs. What we do
  45. * is to just return the value in the url field if it is populated regardless of what get_url method is called.
  46. *
  47. * @todo modify page tree stuff to use this class
  48. * @todo make sure ports are properly handled
  49. *
  50. * @author Nathan White
  51. */
  52. class reasonPageURL extends reasonURL
  53. {
  54. /**
  55. * Returns an absolute url with our best guess at the appropriate protocol
  56. *
  57. * @return string absolute url with a "smart" protocol choice
  58. */
  59. function get_url()
  60. {
  61. return (on_secure_page()) ? $this->get_url_most_secure() : $this->get_url_http();
  62. }
  63. /**
  64. * @return string absolute url with the https protocol
  65. */
  66. function get_url_https()
  67. {
  68. $page_id = $this->get_id();
  69. $page =& $this->get_page($page_id);
  70. if ($page && $page->get_value('url')) return $page->get_value('url');
  71. return ($page) ? 'https://' . $page->get_value('domain') . $page->get_value('relative_url') : NULL;
  72. }
  73. /**
  74. * @return string absolute url with the http protocol
  75. */
  76. function get_url_http()
  77. {
  78. $page_id = $this->get_id();
  79. $page =& $this->get_page($page_id);
  80. if ($page && $page->get_value('url')) return $page->get_value('url');
  81. return ($page) ? 'http://' . $page->get_value('domain') . $page->get_value('relative_url') : NULL;
  82. }
  83. /**
  84. * @return string absolute url with the most secure protocol supported by the domain
  85. */
  86. function get_url_most_secure()
  87. {
  88. $page_id = $this->get_id();
  89. $page =& $this->get_page($page_id);
  90. if ($page)
  91. {
  92. if ($page->get_value('url')) return $page->get_value('url');
  93. if (isset($GLOBALS['_reason_domain_settings'][$page->get_value('domain')]['HTTPS_AVAILABLE'])) $secure = $GLOBALS['_reason_domain_settings'][$page->get_value('domain')]['HTTPS_AVAILABLE'];
  94. elseif (isset($GLOBALS['_default_domain_settings']['HTTPS_AVAILABLE'])) $secure = $GLOBALS['_default_domain_settings']['HTTPS_AVAILABLE'];
  95. else $secure = ($page->get_value('domain') == REASON_HOST) ? HTTPS_AVAILABLE : false;
  96. return ($secure) ? $this->get_url_https() : $this->get_url_http();
  97. }
  98. else return NULL;
  99. }
  100. /**
  101. * @return string relative url from the document root
  102. */
  103. function get_relative_url()
  104. {
  105. $page_id = $this->get_id();
  106. $page =& $this->get_page($page_id);
  107. if ($page && $page->get_value('url')) return $page->get_value('url');
  108. return ($page) ? $page->get_value('relative_url') : NULL;
  109. }
  110. /**
  111. * You can provide entities to the class in order to speed things up.
  112. *
  113. * @param object minisite_page entity
  114. * @return void
  115. */
  116. function provide_page_entity(&$page)
  117. {
  118. $page_entities =& $this->_get_page_entities();
  119. if (!isset($page_entities[$page->id()])) $page_entities[$page->id()] = $page;
  120. }
  121. /**
  122. * You can provide entities to the class in order to speed things up - this should rarely be necessary but might help in cases
  123. * where large batches of pages are selected with a single entity selector, and you want to get urls for those entities.
  124. *
  125. * @param array of minisite_page entity objects
  126. * @return void
  127. */
  128. function provide_page_entities(&$pages)
  129. {
  130. $page_entities =& $this->_get_page_entities();
  131. $page_entities = $pages;
  132. }
  133. /**
  134. * Grab the page entity with URL information (builds it if necessary)
  135. *
  136. * @param int page_id
  137. * @return object page entity with URL information
  138. */
  139. function &get_page($page_id)
  140. {
  141. static $pages;
  142. if (!isset($pages[$page_id]) || !$this->use_static_cache())
  143. {
  144. $pages[$page_id] = $this->_build_page($page_id);
  145. }
  146. $page =& $pages[$page_id];
  147. return $page;
  148. }
  149. /**
  150. * We use a DBSelector to construct a super basic query to quickly get the parent.
  151. *
  152. * This method probably ought to be a method directly on minisite page entities ... but alas we aren't there yet.
  153. * For efficiency sake, we could eliminate this if the parent was stored on the page entity and not across a relationship
  154. *
  155. * @access private
  156. * @param object minisite_page entity
  157. * @return int parent entity id for a minisite page
  158. */
  159. function _get_parent_id(&$page)
  160. {
  161. if (!$page->has_value('parent_id'))
  162. {
  163. $d = new DBselector();
  164. $d->add_table( 'r', 'relationship' );
  165. $d->add_field( 'r', 'entity_b', 'parent_id' );
  166. $d->add_relation( 'r.type = ' . relationship_id_of('minisite_page_parent'));
  167. $d->add_relation( 'r.entity_a = ' . $page->id() );
  168. $d->set_num(1);
  169. $result = db_query( $d->get_query() , 'Error getting parent ID.' );
  170. if( $row = mysql_fetch_assoc($result))
  171. {
  172. $page->set_value('parent_id', $row['parent_id']);
  173. }
  174. else
  175. {
  176. $page->set_value('parent_id', false);
  177. }
  178. }
  179. return $page->get_value('parent_id');
  180. }
  181. /**
  182. * We use a DBSelector to construct a super basic query to quickly get the owner id.
  183. *
  184. * This method probably ought to be a method directly on minisite page entities ... but alas we aren't there yet.
  185. * For efficiency sake, we could eliminate this if the owner was stored on the page entity and not across a relationship
  186. *
  187. * @access private
  188. * @param object minisite_page entity
  189. * @return int owner id for a minisite page
  190. */
  191. function _get_owner_id(&$page)
  192. {
  193. if (!$page->has_value('owner_id'))
  194. {
  195. $d = new DBselector();
  196. $d->add_table( 'r', 'relationship' );
  197. $d->add_field( 'r', 'entity_a', 'owner_id' );
  198. $d->add_relation( 'r.type = ' . get_owns_relationship_id(id_of('minisite_page')));
  199. $d->add_relation( 'r.entity_b = ' . $page->id() );
  200. $d->set_num(1);
  201. $result = db_query( $d->get_query() , 'Error getting owner ID.' );
  202. if( $row = mysql_fetch_assoc($result))
  203. {
  204. $page->set_value('owner_id', $row['owner_id']);
  205. }
  206. else
  207. {
  208. $page->set_value('owner_id', false);
  209. }
  210. }
  211. return $page->get_value('owner_id');
  212. }
  213. /**
  214. * Build a page entity with some custom values
  215. *
  216. * - relative_url
  217. * - domain
  218. * - parent_id
  219. * - owner_id
  220. *
  221. * @access private
  222. * @return object augmented page entity
  223. */
  224. function _build_page($page_id)
  225. {
  226. $page =& $this->_get_page_entity($page_id);
  227. if ($page && !$page->get_value('url')) // lets populate our custom values
  228. {
  229. if ($parent_id = $this->_get_parent_id($page)) // this populates parent_id on the entity
  230. {
  231. if ($parent_id == $page_id) // if i'm my own parent i am a root and my relative_url is the site_url
  232. {
  233. if ($site_id = $this->_get_owner_id($page)) // this populates owner_id on the entity
  234. {
  235. $site =& $this->_get_site_entity($site_id);
  236. if ($site)
  237. {
  238. $domain = ($site->has_value('domain') && $site->get_value('domain')) ? $site->get_value('domain') : REASON_HOST;
  239. $page->set_value('relative_url', str_replace("//", "/", $site->get_value('base_url')));
  240. $page->set_value('domain', $domain);
  241. }
  242. else
  243. {
  244. trigger_error('a live owner site (should have id ' . $site_id . ') could not be found for page_id ' . $page_id);
  245. return false;
  246. }
  247. }
  248. else
  249. {
  250. trigger_error('an owner site could not be found for page_id ' . $page_id);
  251. return false;
  252. }
  253. }
  254. else
  255. {
  256. $parent =& $this->get_page($parent_id);
  257. if ($parent)
  258. {
  259. $parent_path = $parent->get_value('relative_url');
  260. $page_path = $parent_path . $page->get_value('url_fragment') . '/';
  261. $page->set_value('relative_url', str_replace("//", "/", $page_path));
  262. $page->set_value('domain', $parent->get_value('domain'));
  263. }
  264. else
  265. {
  266. trigger_error('a live parent entity (should have id ' . $parent_id . ') could not be found for page_id ' . $page_id);
  267. return false;
  268. }
  269. }
  270. }
  271. else
  272. {
  273. trigger_error('a parent page could not be found for page id ' . $page_id);
  274. return false;
  275. }
  276. }
  277. elseif ($page && $page->get_value('url'))
  278. {
  279. $page->set_value('relative_url', '');
  280. $page->set_value('domain', '');
  281. }
  282. else
  283. {
  284. trigger_error('a live page with id ' . $page_id . ' could not be found in the reason database.');
  285. return false;
  286. }
  287. return $page;
  288. }
  289. /**
  290. * @access private
  291. */
  292. function &_get_page_entity($page_id)
  293. {
  294. $page_entities =& $this->_get_page_entities();
  295. if (!isset($page_entities[$page_id]) || !$this->use_static_cache())
  296. {
  297. $es = new entity_selector();
  298. $es->limit_tables(array('page_node', 'url'));
  299. $es->add_type(id_of('minisite_page'));
  300. $es->add_relation("entity.id = " . $page_id);
  301. $es->set_num(1);
  302. $result = $es->run_one();
  303. $page_entities[$page_id] = ($result) ? reset($result) : false;
  304. }
  305. return $page_entities[$page_id];
  306. }
  307. /**
  308. * @access private
  309. */
  310. function &_get_page_entities()
  311. {
  312. static $entities;
  313. if (!isset($entities)) $entities = array();
  314. return $entities;
  315. }
  316. /**
  317. * @access private
  318. */
  319. function &_get_site_entity($site_id)
  320. {
  321. $site_entities =& $this->_get_site_entities();
  322. if (!isset($site_entities[$site_id]) || !$this->use_static_cache())
  323. {
  324. $es = new entity_selector();
  325. $es->limit_tables('site');
  326. $es->add_type(id_of('site'));
  327. $es->add_relation("entity.id = " . $site_id);
  328. $es->set_num(1);
  329. $result = $es->run_one();
  330. $site_entities[$site_id] = ($result) ? reset($result) : false;
  331. }
  332. return $site_entities[$site_id];
  333. }
  334. /**
  335. * @access private
  336. */
  337. function &_get_site_entities()
  338. {
  339. static $entities;
  340. if (!isset($entities)) $entities = array();
  341. return $entities;
  342. }
  343. }