PageRenderTime 44ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/application/plugins/files/models/ProjectFileRevision.class.php

https://github.com/cj/Project-Pier
PHP | 498 lines | 210 code | 60 blank | 228 comment | 41 complexity | 33cacdff5660b9efc86d398374c0d7d7 MD5 | raw file
  1. <?php
  2. /**
  3. * ProjectFileRevision class
  4. * Generated on Tue, 04 Jul 2006 06:46:08 +0200 by DataObject generation tool
  5. *
  6. * @http://www.projectpier.org/
  7. */
  8. class ProjectFileRevision extends BaseProjectFileRevision {
  9. /**
  10. * Message comments are searchable
  11. *
  12. * @var boolean
  13. */
  14. protected $is_searchable = true;
  15. /**
  16. * Array of searchable columns
  17. *
  18. * @var array
  19. */
  20. protected $searchable_columns = array('comment', 'filecontent');
  21. /**
  22. * Parent file object
  23. *
  24. * @var ProjectFile
  25. */
  26. private $file;
  27. /**
  28. * Cached file type object
  29. *
  30. * @var FileType
  31. */
  32. private $file_type;
  33. /**
  34. * Cached show thumbnails configuration option
  35. *
  36. * @var String
  37. */
  38. private $show_thumbnail;
  39. /**
  40. * Construct file revision object
  41. *
  42. * @param void
  43. * @return ProjectFileRevision
  44. */
  45. function __construct() {
  46. $this->addProtectedAttribute('file_id', 'file_type_id', 'system_filename', 'thumb_filename', 'revision_number', 'type_string', 'filesize');
  47. parent::__construct();
  48. $this->show_thumbnail = (config_option('files_show_thumbnails', '1') == '1');
  49. } // __construct
  50. /**
  51. * Return parent file object
  52. *
  53. * @param void
  54. * @return ProjectFile
  55. */
  56. function getFile() {
  57. if (is_null($this->file)) {
  58. $this->file = ProjectFiles::findById($this->getFileId());
  59. } // if
  60. return $this->file;
  61. } // getFile
  62. /**
  63. * Return parent project
  64. *
  65. * @param void
  66. * @return Project
  67. */
  68. function getProject() {
  69. if (is_null($this->project)) {
  70. $file = $this->getFile();
  71. if ($file instanceof ProjectFile) {
  72. $this->project = $file->getProject();
  73. }
  74. } // if
  75. return $this->project;
  76. } // getProject
  77. /**
  78. * Return project ID
  79. *
  80. * @param void
  81. * @return integer
  82. */
  83. function getProjectId() {
  84. $project = $this->getProject();
  85. return $project instanceof Project ? $project->getId() : null;
  86. } // getProjectId
  87. /**
  88. * Return file type object
  89. *
  90. * @param void
  91. * @return FileType
  92. */
  93. function getFileType() {
  94. if (is_null($this->file_type)) {
  95. $this->file_type = FileTypes::findById($this->getFileTypeId());
  96. } // if
  97. return $this->file_type;
  98. } // getFileType
  99. /**
  100. * Return content of this file
  101. *
  102. * @param void
  103. * @return string
  104. */
  105. function getFilePath() {
  106. return FileRepository::getFilePath($this->getRepositoryId());
  107. } // getFileContent
  108. /**
  109. * Return value of 'filename' field
  110. *
  111. * @access public
  112. * @param void
  113. * @return string
  114. */
  115. function getFilename() {
  116. $filename = $this->getColumnValue('filename');
  117. if (!$filename) {
  118. $filename = $this->getFile()->getFilename();
  119. }
  120. return $filename;
  121. } // getFilename()
  122. /**
  123. * Return content of this file
  124. *
  125. * @param void
  126. * @return string
  127. */
  128. function getFileContent() {
  129. return FileRepository::getFileContent($this->getRepositoryId());
  130. } // getFileContent
  131. // ---------------------------------------------------
  132. // Utils
  133. // ---------------------------------------------------
  134. /**
  135. * This function will return content of specific searchable column. It uses inherited
  136. * behaviour for all columns except for `filecontent`. In case of this column function
  137. * will return file content if file type is marked as searchable (text documents, office
  138. * documents etc).
  139. *
  140. * @param string $column_name Column name
  141. * @return string
  142. */
  143. function getSearchableColumnContent($column_name) {
  144. if ($column_name == 'filecontent') {
  145. // Unknown type or type not searchable
  146. $file_type = $this->getFileType();
  147. if (!($file_type instanceof FileType) || !$file_type->getIsSearchable()) {
  148. return null;
  149. } // if
  150. $content = $this->getFileContent();
  151. if (strlen($content) <= MAX_SEARCHABLE_FILE_SIZE) {
  152. return $content;
  153. }
  154. } else {
  155. return parent::getSearchableColumnContent($column_name);
  156. } // if
  157. } // getSearchableColumnContent
  158. /**
  159. * Create image thumbnail. This function will return true on success, false otherwise
  160. *
  161. * @param void
  162. * @return boolean
  163. */
  164. protected function createThumb() {
  165. do {
  166. $source_file = CACHE_DIR . '/' . sha1(uniqid(rand(), true));
  167. } while (is_file($source_file));
  168. if (!file_put_contents($source_file, $this->getFileContent()) || !is_readable($source_file)) {
  169. return false;
  170. } // if
  171. do {
  172. $temp_file = CACHE_DIR . '/' . sha1(uniqid(rand(), true));
  173. } while (is_file($temp_file));
  174. try {
  175. Env::useLibrary('simplegd');
  176. $image = new SimpleGdImage($source_file);
  177. $thumb = $image->scale(100, 100, SimpleGdImage::BOUNDARY_DECREASE_ONLY, false);
  178. $thumb->saveAs($temp_file, IMAGETYPE_PNG);
  179. $public_filename = PublicFiles::addFile($temp_file, 'png');
  180. if ($public_filename) {
  181. $this->setThumbFilename($public_filename);
  182. $this->save();
  183. } // if
  184. $result = true;
  185. } catch(Exception $e) {
  186. $result = false;
  187. } // try
  188. @unlink($source_file);
  189. @unlink($temp_file);
  190. return $result;
  191. } // createThumb
  192. // ---------------------------------------------------
  193. // URLs
  194. // ---------------------------------------------------
  195. /**
  196. * Return revision details URL
  197. *
  198. * @param void
  199. * @return string
  200. */
  201. function getDetailsUrl() {
  202. $file = $this->getFile();
  203. return $file instanceof ProjectFile ? $file->getDetailsUrl() . '#revision' . $this->getId() : null;
  204. } // getDetailsUrl
  205. /**
  206. * Show download URL
  207. *
  208. * @param void
  209. * @return string
  210. */
  211. function getDownloadUrl() {
  212. return get_url('files', 'download_revision', array('id' => $this->getId(), 'active_project' => $this->getProjectId()));
  213. } // getDownloadUrl
  214. /**
  215. * Return edit revision URL
  216. *
  217. * @param void
  218. * @return string
  219. */
  220. function getEditUrl() {
  221. return get_url('files', 'edit_revision', array('id' => $this->getId(), 'active_project' => $this->getProjectId()));
  222. } // getEditUrl
  223. /**
  224. * Return delete revision URL
  225. *
  226. * @param void
  227. * @return string
  228. */
  229. function getDeleteUrl() {
  230. return get_url('files', 'delete_revision', array('id' => $this->getId(), 'active_project' => $this->getProjectId()));
  231. } // getDeleteUrl
  232. /**
  233. * Return thumb URL
  234. *
  235. * @param void
  236. * @return string
  237. */
  238. function getThumbUrl() {
  239. if ($this->getThumbFilename() == '') {
  240. $this->createThumb();
  241. } // if
  242. if (trim($this->getThumbFilename())) {
  243. return PublicFiles::getFileUrl($this->getThumbFilename());
  244. } else {
  245. return '';
  246. } // if
  247. } // getThumbUrl
  248. /**
  249. * Return URL of file type icon. If we are working with image file type this function
  250. * will return thumb URL if it success in creating it
  251. *
  252. * @param void
  253. * @return string
  254. */
  255. function getTypeIconUrl() {
  256. $file_type = $this->getFileType();
  257. if ($file_type instanceof FileType) {
  258. if ($this->show_thumbnail && $file_type->getIsImage()) {
  259. $thumb_url = $this->getThumbUrl();
  260. if (trim($thumb_url)) {
  261. return $thumb_url; // we have the thumb!
  262. } // if
  263. } // if
  264. } // if
  265. $icon_file = $file_type instanceof FileType ? $file_type->getIcon() : 'unknown.png';
  266. return get_image_url("filetypes/$icon_file");
  267. } // getTypeIconUrl
  268. // ---------------------------------------------------
  269. // Permissions
  270. // ---------------------------------------------------
  271. /**
  272. * Check CAN_MANAGE_DOCUMENS permission
  273. *
  274. * @access public
  275. * @param User $user
  276. * @return boolean
  277. */
  278. function canManage(User $user) {
  279. if (!$user->isProjectUser($this->getProject())) {
  280. return false;
  281. }
  282. return $user->getProjectPermission($this->getProject(), PermissionManager::CAN_MANAGE_FILES);
  283. } // canManage
  284. /**
  285. * Empty implementation of abstract method. Message determins if user have view access
  286. *
  287. * @param void
  288. * @return boolean
  289. */
  290. function canView(User $user) {
  291. //if (!$user->isProjectUser($this->getProject())) return false;
  292. if ($this->isPrivate() && !$user->isMemberOfOwnerCompany()) {
  293. return false;
  294. }
  295. return true;
  296. } // canView
  297. /**
  298. * Returns true if user can download this file
  299. *
  300. * @param User $user
  301. * @return boolean
  302. */
  303. function canDownload(User $user) {
  304. return $this->canView($user);
  305. } // canDownload
  306. /**
  307. * Empty implementation of abstract methods. Messages determine does user have
  308. * permissions to add comment
  309. *
  310. * @param void
  311. * @return null
  312. */
  313. function canAdd(User $user, Project $project) {
  314. return $user->isAdministrator() || ProjectFile::canUpload($user, $project);
  315. } // canAdd
  316. /**
  317. * Check if specific user can edit this file
  318. *
  319. * @access public
  320. * @param User $user
  321. * @return boolean
  322. */
  323. function canEdit(User $user) {
  324. if ($user->isAdministrator()) {
  325. return true; // give access to admin
  326. }
  327. if (!$this->canManage(logged_user())) {
  328. return false; // user don't have access to this project or can't manage files
  329. }
  330. return false;
  331. } // canEdit
  332. /**
  333. * Check if specific user can delete this comment
  334. *
  335. * @access public
  336. * @param User $user
  337. * @return boolean
  338. */
  339. function canDelete(User $user) {
  340. if ($user->isAdministrator()) {
  341. return true; // give access to admin
  342. }
  343. if (!$user->isProjectUser($this->getProject())) {
  344. return false;
  345. } // if
  346. $file = $this->getFile();
  347. if (!($file instanceof ProjectFile)) {
  348. return false;
  349. } // if
  350. if ($file->countRevisions() == 1) {
  351. return false; // this is the only file revision! it can't be deleted!
  352. } // if
  353. return false;
  354. } // canDelete
  355. // ---------------------------------------------------
  356. // System
  357. // ---------------------------------------------------
  358. /**
  359. * Validate before save. This one is used to keep the data in sync. Users
  360. * can't create revisions directly...
  361. *
  362. * @param array $errors
  363. * @return null
  364. */
  365. function validate(&$errors) {
  366. if (!$this->validatePresenceOf('file_id')) {
  367. $errors[] = lang('file revision file_id required');
  368. } // if
  369. if (!$this->validatePresenceOf('repository_id')) {
  370. $errors[] = lang('file revision filename required');
  371. } // if
  372. if (!$this->validatePresenceOf('type_string')) {
  373. $errors[] = lang('file revision type_string required');
  374. } // if
  375. } // validate
  376. /**
  377. * Delete from DB and from the disk
  378. *
  379. * @param void
  380. * @return boolean
  381. */
  382. function delete() {
  383. FileRepository::deleteFile($this->getRepositoryId());
  384. $this->deleteThumb(false);
  385. return parent::delete();
  386. } // delete
  387. /**
  388. * Delete thumb
  389. *
  390. * @param boolean $save
  391. * @return boolean
  392. */
  393. function deleteThumb($save = true) {
  394. $thumb_filename = $this->getThumbFilename();
  395. if ($thumb_filename) {
  396. $this->setThumbFilename('');
  397. PublicFiles::deleteFile($this->getThumbFilename());
  398. } // if
  399. if ($save) {
  400. return $this->save();
  401. } // if
  402. return true;
  403. } // deleteThumb
  404. // ---------------------------------------------------
  405. // ApplicationDataObject implementation
  406. // ---------------------------------------------------
  407. /**
  408. * Return object name
  409. *
  410. * @access public
  411. * @param void
  412. * @return string
  413. */
  414. function getObjectName() {
  415. $file = $this->getFile();
  416. return $file instanceof ProjectFile ? $file->getObjectName() . ' revision #' . $this->getRevisionNumber() : 'Unknown file revision';
  417. } // getObjectName
  418. /**
  419. * Return object type name
  420. *
  421. * @param void
  422. * @return string
  423. */
  424. function getObjectTypeName() {
  425. return lang('file revision');
  426. } // getObjectTypeName
  427. /**
  428. * Return object URl
  429. *
  430. * @access public
  431. * @param void
  432. * @return string
  433. */
  434. function getObjectUrl() {
  435. return $this->getDetailsurl();
  436. } // getObjectUrl
  437. } // ProjectFileRevision
  438. ?>