Source for file viewfile.act.php

Documentation is available at viewfile.act.php

  1. <?php
  2.  
  3. /**
  4. * @package polyphony.repository
  5. *
  6. * @copyright Copyright &copy; 2005, Middlebury College
  7. * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License (GPL)
  8. *
  9. * @version $Id: viewfile.act.php,v 1.14 2007/09/19 14:04:56 adamfranco Exp $
  10. */
  11.  
  12. require_once(POLYPHONY."/main/library/AbstractActions/ForceAuthAction.class.php");
  13.  
  14. /**
  15. * Display the file in the specified record.
  16. *
  17. * @since 11/11/04
  18. * @author Ryan Richards
  19. * @author Adam Franco
  20. *
  21. * @package polyphony.repository
  22. *
  23. * @copyright Copyright &copy; 2005, Middlebury College
  24. * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License (GPL)
  25. *
  26. * @version $Id: viewfile.act.php,v 1.14 2007/09/19 14:04:56 adamfranco Exp $
  27. */
  28. class viewfileAction
  29. extends ForceAuthAction
  30. {
  31. /**
  32. * Check Authorizations
  33. *
  34. * @return boolean
  35. * @access public
  36. * @since 4/26/05
  37. */
  38. function isExecutionAuthorized () {
  39. $harmoni = Harmoni::instance();
  40. $idManager = Services::getService("Id");
  41. $authZManager = Services::getService("AuthorizationManager");
  42. $harmoni->request->startNamespace("polyphony-repository");
  43. $assetId =$idManager->getId(RequestContext::value("asset_id"));
  44. $harmoni->request->endNamespace();
  45. return $authZManager->isUserAuthorized(
  46. $idManager->getId("edu.middlebury.authorization.view"),
  47. $assetId);
  48. }
  49. /**
  50. * Return a junk image that says you can't view the file
  51. *
  52. * @since 12/22/05
  53. */
  54. function getUnauthorizedMessage() {
  55. header("Content-Type: image/gif");
  56. header('Content-Disposition: filename="english.gif"');
  57. print file_get_contents(POLYPHONY.'/docs/images/unauthorized/english.gif');
  58. exit;
  59. }
  60. /**
  61. * Answer the HTTP Authentication 'Relm' to present to the user for authentication.
  62. *
  63. * @return mixed string or null
  64. * @access public
  65. * @since 8/7/06
  66. */
  67. function getRelm () {
  68. return 'Concerto'; // Override for custom relm.
  69. }
  70. /**
  71. * Answer the cancel function for this action, to use if the user hits
  72. * the 'cancel' button in the http authentication dialog.
  73. *
  74. * @return mixed string or null
  75. * @access public
  76. * @since 8/7/06
  77. */
  78. function getCancelFunction () {
  79. return 'viewfileAction::getUnauthorizedMessage();';
  80. }
  81. /**
  82. * Build the content for this action
  83. *
  84. * @return void
  85. * @access public
  86. * @since 4/26/05
  87. */
  88. function execute () {
  89. if (!$this->isAuthorizedToExecute())
  90. $this->getUnauthorizedMessage();
  91. $defaultTextDomain = textdomain("polyphony");
  92. $harmoni = Harmoni::instance();
  93. $idManager = Services::getService("Id");
  94. $repositoryManager = Services::getService("Repository");
  95. $harmoni->request->startNamespace("polyphony-repository");
  96. $repositoryId =$idManager->getId(RequestContext::value("repository_id"));
  97. $assetId =$idManager->getId(RequestContext::value("asset_id"));
  98. $recordId =$idManager->getId(RequestContext::value("record_id"));
  99. $size = RequestContext::value("size");
  100. $websafe = RequestContext::value("websafe");
  101. // See if we are passed a size
  102. if (is_numeric($size))
  103. $size = intval($size);
  104. else
  105. $size = FALSE;
  106. if ($websafe)
  107. $websafe = TRUE;
  108. else
  109. $websafe = FALSE;
  110.  
  111. // Get the requested record.
  112. $repository =$repositoryManager->getRepository($repositoryId);
  113. $asset =$repository->getAsset($assetId);
  114. $record =$asset->getRecord($recordId);
  115. // Make sure that the structure is the right one.
  116. $structure =$record->getRecordStructure();
  117. $remoteFileId =$idManager->getId('REMOTE_FILE');
  118. $fileId =$idManager->getId('FILE');
  119. if ($remoteFileId->isEqual($structure->getId())) {
  120. $urlParts =$record->getPartsByPartStructure(
  121. $idManager->getId("FILE_URL"));
  122. $urlPart =$urlParts->next();
  123. header("Location: ".$urlPart->getValue());
  124. } else if (!$fileId->isEqual($structure->getId())) {
  125. print "The requested record is not of the FILE structure, and therefore cannot be displayed.";
  126. } else {
  127. // Get the parts for the record.
  128. $partIterator =$record->getParts();
  129. $parts = array();
  130. while($partIterator->hasNext()) {
  131. $part =$partIterator->next();
  132. $partStructure =$part->getPartStructure();
  133. $partStructureId =$partStructure->getId();
  134. $parts[$partStructureId->getIdString()] =$part;
  135. }
  136. $imgProcessor = Services::getService("ImageProcessor");
  137. // If we want to (and can) resize the file, do so
  138. if (($size || $websafe)
  139. && $imgProcessor->isFormatSupported($parts['MIME_TYPE']->getValue()))
  140. {
  141. $imageCache = new RepositoryImageCache($record->getId(), $size, $websafe, $parts);
  142. header("Content-Type: ".$imageCache->getCachedMimeType());
  143. header('Content-Disposition: attachment; filename="'.
  144. $imageCache->getCachedFileName().'"');
  145. print $imageCache->getCachedImageData();
  146. }
  147. // Otherwise, just send the original file
  148. else {
  149. header("Content-Type: ".$parts['MIME_TYPE']->getValue());
  150. $filename = $parts['FILE_NAME']->getValue();
  151. if (!ereg("[^\\w]", $filename)) {
  152. $mime = Services::getService("MIME");
  153. $extension = $mime->getExtensionForMIMEType($parts['MIME_TYPE']->getValue());
  154. $filename = _("Untitled").".".$extension;
  155. }
  156. header('Content-Disposition: attachment; filename="'.$filename.'"');
  157. print $parts['FILE_DATA']->getValue();
  158. }
  159. }
  160. $harmoni->request->endNamespace();
  161. textdomain($defaultTextDomain);
  162. exit;
  163. }
  164. }
  165.  
  166.  
  167. /**
  168. * This cache management class is something of a hack, especially in how it
  169. * gets the database index from the repository manager. It should be reworked
  170. * to make use of its own configuration and not reference the repository tables,
  171. * though this would require the addition of a modification time part to the
  172. * FILE RecordStructure as well.
  173. *
  174. * @since 2/13/06
  175. * @package polyphony.repository
  176. *
  177. * @copyright Copyright &copy; 2005, Middlebury College
  178. * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License (GPL)
  179. *
  180. * @version $Id: viewfile.act.php,v 1.14 2007/09/19 14:04:56 adamfranco Exp $
  181. */
  182. class RepositoryImageCache {
  183. /**
  184. * Constructor
  185. *
  186. * @param object Id $id
  187. * @param integer $size
  188. * @param boolean $websafe
  189. * @param ref array $parts
  190. * @return object
  191. * @access public
  192. * @since 2/13/06
  193. */
  194. function RepositoryImageCache ( $id, $size, $websafe, $parts ) {
  195. $this->_id =$id;
  196. $this->_size = intval($size);
  197. $this->_websafe = $websafe;
  198. $this->_parts =$parts;
  199. }
  200. /**
  201. * Awswer the cached data (updating the cache if necessary).
  202. *
  203. * @return string
  204. * @access public
  205. * @since 2/13/06
  206. */
  207. function getCachedImageData () {
  208. if (!$this->isCacheUpToDate())
  209. $this->writeCache();
  210. return $this->readCache();
  211. }
  212. /**
  213. * Awswer the cached data mime-type.
  214. *
  215. * @return string
  216. * @access public
  217. * @since 2/13/06
  218. */
  219. function getCachedMimeType () {
  220. if (!$this->isCacheUpToDate())
  221. $this->writeCache();
  222. return $this->_mimeType;
  223. }
  224. /**
  225. * Answer the filename of the cached image
  226. *
  227. * @return string
  228. * @access public
  229. * @since 2/13/06
  230. */
  231. function getCachedFileName () {
  232. $mime = Services::getService("MIME");
  233. $extension = $mime->getExtensionForMIMEType($this->getCachedMimeType());
  234. if (eregi("^.+\.".$extension."$", $this->_parts['FILE_NAME']->getValue())) {
  235. return $this->_parts['FILE_NAME']->getValue();
  236. } else if (ereg("^[^\\w]+$", $this->_parts['FILE_NAME']->getValue())) {
  237. return $this->_parts['FILE_NAME']->getValue().".".$extension;
  238. } else {
  239. return _("Untitled").".".$extension;
  240. }
  241. }
  242. /**
  243. * Answer true if the cache is up to date.
  244. *
  245. * @return boolean
  246. * @access public
  247. * @since 2/13/06
  248. */
  249. function isCacheUpToDate () {
  250. $dbc = Services::getService('DatabaseManager');
  251. $query = new SelectQuery;
  252. $query->addColumn('dr_mime_type.type', 'mime_type');
  253. $query->addTable('dr_file');
  254. $query->addTable('dr_resized_cache', LEFT_JOIN, 'dr_file.id = dr_resized_cache.FK_file');
  255. $query->addTable('dr_mime_type', LEFT_JOIN, 'dr_resized_cache.FK_mime_type = dr_mime_type.id');
  256. $query->addWhere("dr_file.id = '".addslashes($this->_id->getIdString())."'");
  257. $query->addWhere("dr_file.mod_time < dr_resized_cache.cache_time");
  258. $query->addWhere("dr_resized_cache.size = '".addslashes($this->_size)."'");
  259. $query->addWhere("dr_resized_cache.websafe = ".(($this->_websafe)?'1':'0'));
  260. $result =$dbc->query($query, $this->getDBIndex());
  261. if ($result->getNumberOfRows() > 0) {
  262. $this->_mimeType = $result->field('mime_type');
  263. $result->free();
  264. return true;
  265. } else {
  266. $this->_mimeType = null;
  267. $result->free();
  268. return false;
  269. }
  270. }
  271. /**
  272. * Answer the cached data
  273. *
  274. * @return string
  275. * @access public
  276. * @since 2/13/06
  277. */
  278. function readCache () {
  279. $dbc = Services::getService('DatabaseManager');
  280. $query = new SelectQuery;
  281. $query->addColumn('data');
  282. $query->addTable('dr_resized_cache');
  283. $query->addWhere("dr_resized_cache.FK_file = '".addslashes($this->_id->getIdString())."'");
  284. $query->addWhere("dr_resized_cache.size = '".addslashes($this->_size)."'");
  285. $query->addWhere("dr_resized_cache.websafe = ".(($this->_websafe)?'1':'0'));
  286. $result =$dbc->query($query, $this->getDBIndex());
  287. $data = $result->field('data');
  288. $result->free();
  289. return $data;
  290. }
  291. /**
  292. * Write the cache
  293. *
  294. * @return void
  295. * @access public
  296. * @since 2/13/06
  297. */
  298. function writeCache () {
  299. $dbc = Services::getService('DatabaseManager');
  300. $query = new DeleteQuery;
  301. $query->setTable('dr_resized_cache');
  302. $query->addWhere("dr_resized_cache.FK_file = '".addslashes($this->_id->getIdString())."'");
  303. $query->addWhere("dr_resized_cache.size = '".addslashes($this->_size)."'");
  304. $query->addWhere("dr_resized_cache.websafe = ".(($this->_websafe)?'1':'0'));
  305. $dbc->query($query, $this->getDBIndex());
  306. $query = new InsertQuery;
  307. $query->setTable('dr_resized_cache');
  308. $query->setColumns(array( 'FK_file',
  309. 'size',
  310. 'websafe',
  311. 'cache_time',
  312. 'FK_mime_type',
  313. 'data'));
  314. $values = array();
  315. $values[] = "'".addslashes($this->_id->getIdString())."'";
  316. $values[] = "'".addslashes($this->_size)."'";
  317. $values[] = (($this->_websafe)?'1':'0');
  318. $values[] = "NOW()";
  319. $imgProcessor = Services::getService("ImageProcessor");
  320. if ($this->_websafe) {
  321. $this->_mimeType = $imgProcessor->getWebsafeFormat(
  322. $this->_parts['MIME_TYPE']->getValue());
  323. $values[] = $this->getMimeKey();
  324. $values[] = "'".addslashes(
  325. $imgProcessor->getWebsafeData(
  326. $this->_parts['MIME_TYPE']->getValue(),
  327. $this->_size,
  328. $this->_parts['FILE_DATA']->getValue()))."'";
  329. } else {
  330. $this->_mimeType = $imgProcessor->getResizedFormat(
  331. $this->_parts['MIME_TYPE']->getValue());
  332. $values[] = $this->getMimeKey();
  333. $values[] = "'".addslashes(
  334. $imgProcessor->getResizedData(
  335. $this->_parts['MIME_TYPE']->getValue(),
  336. $this->_size,
  337. $this->_parts['FILE_DATA']->getValue()))."'";
  338. }
  339. $query->addRowOfValues($values);
  340. $dbc->query($query, $this->getDBIndex());
  341. }
  342. /**
  343. * Answer the db index to use
  344. *
  345. * @return integer
  346. * @access public
  347. * @since 2/13/06
  348. */
  349. function getDBIndex () {
  350. $repositoryManager = Services::getService('Repository');
  351. $configuration =$repositoryManager->_configuration;
  352. return $configuration->getProperty('database_index');
  353. }
  354. /**
  355. * Answer the mime type key
  356. *
  357. * @param string $mimeType
  358. * @return integer
  359. * @access public
  360. * @since 2/13/06
  361. */
  362. function getMimeKey () {
  363. // If we have a key, make sure it exists.
  364. if ($this->_mimeType && $this->_mimeType != "NULL") {
  365. $dbc = Services::getService('DatabaseManager');
  366. // Check to see if the type is in the database
  367. $query = new SelectQuery;
  368. $query->addTable("dr_mime_type");
  369. $query->addColumn("id");
  370. $query->addWhere("type = '".$this->_mimeType."'");
  371. $result =$dbc->query($query, $this->getDBIndex());
  372. // If it doesn't exist, insert it.
  373. if (!$result->getNumberOfRows()) {
  374. $query = new InsertQuery;
  375. $query->setTable("dr_mime_type");
  376. $query->setAutoIncrementColumn("id", "dr_mime_type_id_seq");
  377. $query->setColumns(array("type"));
  378. $query->setValues(array("'".addslashes($this->_mimeType)."'"));
  379. $result2 =$dbc->query($query, $this->getDBIndex());
  380. $mimeId = "'".$result2->getLastAutoIncrementValue()."'";
  381. } else {
  382. $mimeId = "'".$result->field("id")."'";
  383. }
  384. $result->free();
  385. }
  386. // If we don't have an Id, set the key to NULL.
  387. else {
  388. $mimeId = "NULL";
  389. }
  390. return $mimeId;
  391. }
  392. }
  393.  
  394. ?>

Documentation generated on Wed, 19 Sep 2007 10:27:46 -0400 by phpDocumentor 1.3.0RC3