PageRenderTime 33ms CodeModel.GetById 28ms RepoModel.GetById 0ms app.codeStats 0ms

/reason_4.0/lib/core/minisite_templates/modules/assets.php

https://github.com/luthercollege/reason_package
PHP | 431 lines | 314 code | 22 blank | 95 comment | 45 complexity | 619a27e4d1c876a1a6296b2f2b9221a4 MD5 | raw file
  1. <?php
  2. /**
  3. * @package reason
  4. * @subpackage minisite_modules
  5. */
  6. /**
  7. * Include base class & other dependencies
  8. */
  9. reason_include_once( 'minisite_templates/modules/default.php' );
  10. reason_include_once( 'function_libraries/asset_functions.php' );
  11. reason_include_once('classes/group_helper.php');
  12. /**
  13. * Register the class so the template can instantiate it
  14. */
  15. $GLOBALS[ '_module_class_names' ][ basename( __FILE__, '.php' ) ] = 'AssetsModule';
  16. /**
  17. * A minisite module to display assets (files) attached to the current page
  18. */
  19. class AssetsModule extends DefaultMinisiteModule
  20. {
  21. var $es;
  22. var $assets = array();
  23. var $assets_by_category = array();
  24. /**
  25. * Parameters that can be set up in the page type
  26. *
  27. * limit_by_page_categories is DEPRECATED. Use organize_by_page_categories instead.
  28. *
  29. * offer_merged_pdfs parameter requires pdflib to be installed.
  30. *
  31. * show_fields uses same values as the 2nd param of @see function make_assets_list_markup()
  32. */
  33. var $acceptable_params = array(
  34. 'show_fields'=>array(),
  35. 'date_format'=>'',
  36. 'limit_by_page_categories'=>false,
  37. 'organize_by_page_categories'=>false,
  38. 'order'=>'',
  39. 'offer_merged_pdfs'=>false,
  40. );
  41. var $cleanup_rules = array('asset_view'=>'turn_into_string');
  42. function init( $args = array() ) // {{{
  43. {
  44. if ($this->params['limit_by_page_categories'])
  45. {
  46. trigger_error('limit_by_page_categories is a deprecated parameter. Use organize_by_page_categories instead.' );
  47. $this->params['organize_by_page_categories'] = $this->params['limit_by_page_categories'];
  48. $this->params['limit_by_page_categories'] = false;
  49. }
  50. $this->site = new entity($this->site_id);
  51. $this->es = new entity_selector();
  52. $this->es->description = 'Selecting assets for this page';
  53. $this->es->set_env( 'site', $this->site_id);
  54. $this->es->add_type( id_of('asset') );
  55. $this->es->add_right_relationship( $this->page_id, relationship_id_of('page_to_asset') );
  56. if(!empty($this->params['order']))
  57. {
  58. $this->es->set_order( $this->params['order'] );
  59. }
  60. else
  61. {
  62. $this->es->add_rel_sort_field( $this->page_id, relationship_id_of('page_to_asset'));
  63. $this->es->set_order( 'rel_sort_order' );
  64. }
  65. if ($this->params['organize_by_page_categories']) $es_by_cat = carl_clone($this->es);
  66. $this->assets = $this->es->run_one();
  67. if ($this->assets)
  68. {
  69. if ($this->params['organize_by_page_categories'])
  70. {
  71. $es_by_cat->enable_multivalue_results();
  72. $es_by_cat->add_left_relationship_field('asset_to_category', 'entity', 'id', 'cat_id'); // grab category ids
  73. $result = $es_by_cat->run_one();
  74. if (!empty($result)) $this->assets_by_category =& $this->init_by_category($result);
  75. }
  76. }
  77. if($this->params['offer_merged_pdfs'] && !empty($this->request['asset_view']) && $this->request['asset_view'] == 'merged_pdf')
  78. {
  79. $this->_merge_and_send_pdfs( $this->_get_pdfs_to_merge() );
  80. }
  81. } // }}}
  82. /**
  83. * Grab categories and for each page category, build a reference to a subset of the page assets
  84. *
  85. * Takes an array in this form:
  86. *
  87. * <code>
  88. * array( $asset_id=>$asset, $asset_id=>$asset, ...);
  89. * </code>
  90. *
  91. * Returns an array in this form:
  92. *
  93. * <code>
  94. * array(
  95. * $category_id => array( $asset_id=>$asset, $asset_id=>$asset, ...),
  96. * $category_id => array( $asset_id=>$asset, $asset_id=>$asset, ...),
  97. * ...
  98. * );
  99. * </code>
  100. *
  101. * @param array $page_assets
  102. * @return array assets by category
  103. */
  104. function &init_by_category(&$page_assets)
  105. {
  106. $assets_by_category = false;
  107. $cat_es = new entity_selector($this->site_id);
  108. $cat_es->set_env( 'site', $this->site_id );
  109. $cat_es->add_type( id_of('category_type') );
  110. $cat_es->limit_tables('entity');
  111. $cat_es->limit_fields('entity.name');
  112. $cat_es->add_right_relationship( $this->page_id, relationship_id_of('page_to_category') );
  113. $cat_es->add_rel_sort_field( $this->page_id, relationship_id_of('page_to_category'));
  114. $cat_es->set_order( 'rel_sort_order' );
  115. $result = $cat_es->run_one();
  116. if ($result)
  117. {
  118. $asset_ids = array_keys($page_assets);
  119. $cat_ids = array_keys($result);
  120. foreach ($asset_ids as $asset_id)
  121. {
  122. $item =& $page_assets[$asset_id];
  123. $asset_cat_ids = (is_array($item->get_value('cat_id'))) ? $item->get_value('cat_id') : array($item->get_value('cat_id'));
  124. $cat_intersect = array_intersect($asset_cat_ids, $cat_ids);
  125. if (!empty($cat_intersect))
  126. {
  127. foreach ($cat_intersect as $cat_id)
  128. {
  129. $stack[$cat_id][$asset_id] =& $item;
  130. }
  131. unset ($this->assets[$asset_id]); // it is in at least one category - zap from main asset list
  132. }
  133. }
  134. foreach ($cat_ids as $cat_id)
  135. {
  136. if (isset($stack[$cat_id])) $assets_by_category[$cat_id] =& $stack[$cat_id];
  137. }
  138. }
  139. else
  140. {
  141. }
  142. return $assets_by_category;
  143. }
  144. /**
  145. * Merge and send a set of pdfs
  146. *
  147. * @access private
  148. */
  149. function _merge_and_send_pdfs($pdfs)
  150. {
  151. if(!empty($pdfs))
  152. {
  153. $username = reason_check_authentication();
  154. if(!$this->_has_access($pdfs, $username))
  155. {
  156. if(!empty($username))
  157. {
  158. $this->_display_403_page();
  159. die();
  160. }
  161. else
  162. {
  163. header('Location: '.REASON_LOGIN_URL.'?dest_page='.urlencode(get_current_url()));
  164. die();
  165. }
  166. }
  167. $pdf_files = array();
  168. $titles = array();
  169. foreach($pdfs as $pdf)
  170. {
  171. $file_location = reason_get_asset_filesystem_location($pdf);
  172. $pdf_files[] = $file_location;
  173. $titles[$file_location] = strip_tags($pdf->get_value('name'));
  174. }
  175. include_once(CARL_UTIL_INC.'pdf/pdf_utils.php');
  176. $merged = carl_merge_pdfs($pdf_files, $titles);
  177. if(empty($merged))
  178. {
  179. trigger_error('PDF merge failed');
  180. }
  181. else
  182. {
  183. if(carl_send_pdf($merged, $this->cur_page->get_value('url_fragment').'.pdf'))
  184. die();
  185. else
  186. trigger_error('Unable to send PDF');
  187. }
  188. }
  189. }
  190. /**
  191. * Display a 403 (access denied) page
  192. */
  193. function _display_403_page()
  194. {
  195. http_response_code(403);
  196. if(file_exists(WEB_PATH.ERROR_403_PATH) && is_readable(WEB_PATH.ERROR_403_PATH))
  197. {
  198. include(WEB_PATH.ERROR_403_PATH);
  199. }
  200. else
  201. {
  202. trigger_error('The file at ERROR_403_PATH ('.ERROR_403_PATH.') is not able to be included');
  203. echo '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><title>403: Forbidden</title></head><body><h1>403: Forbidden</h1><p>You do not have access to this resource.</p></body></html>';
  204. }
  205. }
  206. /**
  207. * Determine if a given user has access to all of a set of assets
  208. *
  209. * @param array $access
  210. * @param string $username
  211. * @return boolean
  212. */
  213. function _has_access($assets, $username)
  214. {
  215. if(!is_array($assets))
  216. $assets = array($assets->id()=>$assets);
  217. if(!empty($assets))
  218. {
  219. $es = new entity_selector();
  220. $es->add_right_relationship(array_keys($assets), relationship_id_of('asset_access_permissions_to_group'));
  221. $es->add_type(id_of('group_type'));
  222. $es->set_env('site',$this->site_id);
  223. $groups = $es->run_one();
  224. //pray($groups);
  225. //die();
  226. foreach($groups as $group_id=>$group)
  227. {
  228. $gh = new group_helper();
  229. $gh->set_group_by_entity($group);
  230. if(!$gh->has_authorization($username))
  231. return false;
  232. }
  233. }
  234. return true;
  235. }
  236. /**
  237. * Get the set of PDFs on the page that can be merged
  238. *
  239. * This function provides the pdfs in the same order that they are displayed on the page
  240. *
  241. * @return array $to_merge an array of PDF assets
  242. */
  243. function _get_pdfs_to_merge()
  244. {
  245. $to_merge = array();
  246. // pick out the pdfs & add to array
  247. foreach($this->assets as $asset)
  248. {
  249. if($asset->get_value('file_type') == 'pdf')
  250. $to_merge[$asset->id()] = $asset;
  251. }
  252. foreach($this->assets_by_category as $assets)
  253. {
  254. foreach($assets as $asset)
  255. {
  256. if($asset->get_value('file_type') == 'pdf')
  257. $to_merge[$asset->id()] = $asset;
  258. }
  259. }
  260. return $to_merge;
  261. }
  262. /**
  263. * Does the current page contail only assets of a given file type( e.g. pdf, txt, etc.)?
  264. * @param string $type
  265. * @return boolean
  266. */
  267. function _page_contains_entirely_single_file_type($type)
  268. {
  269. foreach($this->assets as $asset)
  270. {
  271. if($asset->get_value('file_type') != $type)
  272. return false;
  273. }
  274. foreach($this->assets_by_category as $assets)
  275. {
  276. foreach($assets as $asset)
  277. {
  278. if($asset->get_value('file_type') != $type)
  279. return false;
  280. }
  281. }
  282. return true;
  283. }
  284. /**
  285. * Does the module have any content to display?
  286. * @return boolean
  287. */
  288. function has_content() // {{{
  289. {
  290. if( $this->assets || $this->assets_by_category ) return true;
  291. else return false;
  292. } // }}}
  293. /**
  294. * Generate and output the XHTML content of the module
  295. */
  296. function run() // {{{
  297. {
  298. $markup = '';
  299. if ($this->assets) $markup .= $this->get_asset_markup($this->assets);
  300. if ($this->assets_by_category)
  301. {
  302. foreach ($this->assets_by_category as $category_id=>$assets)
  303. {
  304. $category = new entity( $category_id );
  305. $markup .= '<h4>' . $category->get_value('name') . '</h4>';
  306. $markup .= $this->get_asset_markup($assets);
  307. }
  308. }
  309. if(!empty($markup))
  310. {
  311. $class = ($this->assets_by_category) ? "assets assetsByCategory" : "assets";
  312. echo '<div class="'.$class.'">'."\n";
  313. echo '<h3>Related Documents</h3>'."\n";
  314. echo $this->_get_pdf_merge_markup();
  315. echo $markup;
  316. echo '</div>'."\n";
  317. }
  318. } // }}}
  319. function _get_pdf_merge_markup()
  320. {
  321. if($this->params['offer_merged_pdfs'] && count($this->_get_pdfs_to_merge()) > 1)
  322. {
  323. if($this->_page_contains_entirely_single_file_type('pdf'))
  324. {
  325. return '<div class="downloadMerged"><a href="?asset_view=merged_pdf">Download all documents as a single PDF</a></div>'."\n";
  326. }
  327. return '<div class="downloadMerged"><a href="?asset_view=merged_pdf">Download PDFs on this page as one file</a> <div class="note smallText">Note: only PDFs will be merged.</div></div>'."\n";
  328. }
  329. return '';
  330. }
  331. /**
  332. * Get the markup for a list of assets
  333. *
  334. * @param array $assets
  335. * @return string $markup
  336. */
  337. function get_asset_markup($assets)
  338. {
  339. if(!empty($this->params['show_fields']) && !empty($this->params['date_format']))
  340. {
  341. $markup = make_assets_list_markup( $assets, $this->site, $this->params['show_fields'], $this->params['date_format'] );
  342. }
  343. elseif(!empty($this->params['show_fields']))
  344. {
  345. $markup = make_assets_list_markup( $assets, $this->site, $this->params['show_fields'] );
  346. }
  347. elseif(!empty($this->params['date_format']))
  348. {
  349. trigger_error('assetsModule::run(): the show_fields parameter must be passed to the assetsModule for the date_format parameter to work');
  350. $markup = make_assets_list_markup( $assets, $this->site );
  351. }
  352. else
  353. {
  354. $markup = make_assets_list_markup( $assets, $this->site );
  355. }
  356. return $markup;
  357. }
  358. /**
  359. * When was the most recently edited asset last modified?
  360. *
  361. * @return string | boolean Either a mysql-formatted datetime or false if no assets on page
  362. */
  363. function last_modified()
  364. {
  365. if( $this->has_content() )
  366. {
  367. $temp = $this->es->get_max( 'last_modified' );
  368. return $temp->get_value( 'last_modified' );
  369. }
  370. else
  371. return false;
  372. }
  373. /**
  374. * Explain the function of the assets module in plain text.
  375. */
  376. function get_documentation()
  377. {
  378. return'<p>Displays assets (e.g. pdfs and other documents) attached to this page.</p>'."\n";
  379. foreach($this->params as $key=>$val)
  380. {
  381. switch($key)
  382. {
  383. case 'show_fields':
  384. echo '<p>For each asset, these fields will be shown: '.htmlspecialchars(implode(', ',$val), ENT_QUOTES).'</p>'."\n";
  385. break;
  386. case 'date_format':
  387. echo '<p>Dates will use this format: '.date($val).'</p>'."\n";
  388. break;
  389. case 'limit_by_page_categories':
  390. case 'organize_by_page_categories':
  391. if($val)
  392. echo '<p>Assets will be listed in groups based on the categories assigned to the page.</p>'."\n";
  393. else
  394. echo '<p>Assets will be listed in a single list (not grouped by categories)</p>'."\n";
  395. break;
  396. case 'order':
  397. echo '<p>Assets will be listed in the following order: '.htmlspecialchars($val, ENT_QUOTES).'.</p>'."\n";
  398. break;
  399. case 'offer_merged_pdfs':
  400. if(function_exists('PDF_new'))
  401. echo '<p>If the page contains only PDFs, a visitors will be able to download all files as a single PDF.</p>'."\n";
  402. else
  403. echo '<p>NOTE: It does not appear that the server is set up correctly to offer merged downloads. Please make sure pdflib is installed.</p>'."\n";
  404. break;
  405. }
  406. }
  407. }
  408. }
  409. ?>