PageRenderTime 51ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/source/components/com_pfrepo/site/controllers/fileform.php

https://github.com/projectfork/Projectfork
PHP | 431 lines | 222 code | 83 blank | 126 comment | 54 complexity | 44880d337f59212972b3dcf6dad9419a MD5 | raw file
  1. <?php
  2. /**
  3. * @package pkg_projectfork
  4. * @subpackage com_pfrepo
  5. *
  6. * @author Tobias Kuhn (eaxs)
  7. * @copyright Copyright (C) 2006-2013 Tobias Kuhn. All rights reserved.
  8. * @license http://www.gnu.org/licenses/gpl.html GNU/GPL, see LICENSE.txt
  9. */
  10. defined('_JEXEC') or die();
  11. jimport('joomla.application.component.controllerform');
  12. /**
  13. * Projectfork File Form Controller
  14. *
  15. */
  16. class PFrepoControllerFileForm extends JControllerForm
  17. {
  18. /**
  19. * The default item view
  20. *
  21. * @var string
  22. */
  23. protected $view_item = 'fileform';
  24. /**
  25. * The default list view
  26. *
  27. * @var string
  28. */
  29. protected $view_list = 'repository';
  30. /**
  31. * Method to get a model object, loading it if required.
  32. *
  33. * @param string $name The model name. Optional.
  34. * @param string $prefix The class prefix. Optional.
  35. * @param array $config Configuration array for model. Optional.
  36. *
  37. * @return object The model.
  38. */
  39. public function &getModel($name = 'FileForm', $prefix = 'PFrepoModel', $config = array('ignore_request' => true))
  40. {
  41. $model = parent::getModel($name, $prefix, $config);
  42. return $model;
  43. }
  44. /**
  45. * Method to check if you can add a new record.
  46. *
  47. * @param array $data An array of input data.
  48. *
  49. * @return boolean
  50. */
  51. protected function allowAdd($data = array())
  52. {
  53. // Get form input
  54. $dir = isset($data['parent_id']) ? (int) $data['parent_id'] : JRequest::getUint('filter_parent_id');
  55. $user = JFactory::getUser();
  56. $asset = 'com_pfrepo.directory.' . $dir;
  57. $access = true;
  58. // Deny if no parent directory is given
  59. if (!$dir) {
  60. $this->setError(JText::_('COM_PROJECTFORK_WARNING_DIRECTORY_NOT_FOUND'));
  61. return false;
  62. }
  63. // Check if the user has viewing access when not a super admin
  64. if (!$user->authorise('core.admin')) {
  65. $db = JFactory::getDbo();
  66. $query = $db->getQuery(true);
  67. $query->select('access')
  68. ->from('#__pf_repo_dirs')
  69. ->where('id = ' . $dir);
  70. $db->setQuery($query);
  71. $lvl = $db->loadResult();
  72. $access = in_array($lvl, $user->getAuthorisedViewLevels());
  73. }
  74. return ($user->authorise('core.create', $asset) && $access);
  75. }
  76. /**
  77. * Method override to check if you can edit an existing record.
  78. *
  79. * @param array $data An array of input data.
  80. * @param string $key The name of the key for the primary key.
  81. *
  82. * @return boolean
  83. */
  84. protected function allowEdit($data = array(), $key = 'id')
  85. {
  86. // Get form input
  87. $id = (int) (isset($data[$key]) ? $data[$key] : 0);
  88. $user = JFactory::getUser();
  89. $uid = JFactory::getUser()->get('id');
  90. $asset = 'com_pfrepo.file.' . $id;
  91. $access = true;
  92. // Check if the user has viewing access when not a super admin
  93. if (!$user->authorise('core.admin')) {
  94. $db = JFactory::getDbo();
  95. $query = $db->getQuery(true);
  96. $query->select('access')
  97. ->from('#__pf_repo_files')
  98. ->where('id = ' . $id);
  99. $db->setQuery($query);
  100. $lvl = $db->loadResult();
  101. if (!in_array($lvl, $user->getAuthorisedViewLevels())) {
  102. return false;
  103. }
  104. }
  105. // Check general edit permission first.
  106. if ($user->authorise('core.edit', $asset)) {
  107. return true;
  108. }
  109. // Fallback on edit.own.
  110. // First test if the permission is available.
  111. if (!$user->authorise('core.edit.own', $asset)) {
  112. return false;
  113. }
  114. // Load the item
  115. $record = $this->getModel()->getItem($id);
  116. // Abort if not found
  117. if (empty($record)) return false;
  118. // Now test the owner is the user.
  119. $owner = (int) isset($data['created_by']) ? (int) $data['created_by'] : $record->created_by;
  120. // If the owner matches 'me' then do the test.
  121. return ($owner == $uid && $uid > 0);
  122. }
  123. /**
  124. * Method to save a record.
  125. *
  126. * @param string $key The name of the primary key of the URL variable.
  127. * @param string $urlVar The name of the URL variable if different from the primary key (sometimes required to avoid router collisions).
  128. *
  129. * @return boolean True if successful, false otherwise.
  130. */
  131. public function save($key = 'id', $urlVar = null)
  132. {
  133. // Check for request forgeries.
  134. JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN'));
  135. // Initialise variables.
  136. $model = $this->getModel();
  137. $data = JRequest::getVar('jform', array(), 'post', 'array');
  138. $file_form = JRequest::getVar('jform', '', 'files', 'array');
  139. $context = $this->option . ".edit." . $this->context;
  140. $layout = JRequest::getVar('layout');
  141. $user = JFactory::getUser();
  142. $files = array();
  143. if (empty($urlVar)) $urlVar = $key;
  144. // Setup redirect links
  145. $record_id = JRequest::getInt($urlVar);
  146. $link_base = 'index.php?option=' . $this->option . '&view=';
  147. $link_list = $link_base . $this->view_list . $this->getRedirectToListAppend();
  148. $link_item = $link_base . $this->view_item . $this->getRedirectToItemAppend($record_id, $urlVar);
  149. // Get project id from directory if missing
  150. if ((!isset($data['project_id']) || empty($data['project_id'])) && isset($data['dir_id'])) {
  151. $data['project_id'] = PFrepoHelper::getProjectFromDir($data['dir_id']);
  152. }
  153. // Check edit id
  154. if (!$this->checkEditId($context, $record_id)) {
  155. // Somehow the person just went to the form and tried to save it. We don't allow that.
  156. $this->setError(JText::sprintf('JLIB_APPLICATION_ERROR_UNHELD_ID', $record_id));
  157. $this->setMessage($this->getError(), 'error');
  158. $this->setRedirect(JRoute::_(($layout != 'modal' ? $link_item : $link_list), false));
  159. return false;
  160. }
  161. // Check general access
  162. if (!$user->authorise('core.create', 'com_pfrepo') || defined('PFDEMO')) {
  163. $this->setError(JText::_('COM_PROJECTFORK_WARNING_CREATE_FILE_DENIED'));
  164. $this->setMessage($this->getError(), 'error');
  165. $this->setRedirect(JRoute::_(($layout != 'modal' ? $link_item : $link_list), false));
  166. return false;
  167. }
  168. // Get file info
  169. $files = $this->getFormFiles($file_form);
  170. // Check for upload errors
  171. if (!$this->checkFileError($files, $record_id)) {
  172. $this->setRedirect(JRoute::_(($layout != 'modal' ? $link_item : $link_list), false));
  173. return false;
  174. }
  175. // Upload file if we have any
  176. if (count($files) && !empty($files[0]['tmp_name'])) {
  177. $file = $files[0];
  178. if ($record_id) {
  179. // File extension must be the same as the original
  180. if (!$this->checkFileExtension($record_id, $file['name'])) {
  181. $this->setError(JText::_('COM_PROJECTFORK_WARNING_FILE_UPLOAD_ERROR_10'));
  182. $this->setMessage($this->getError(), 'error');
  183. $this->setRedirect(JRoute::_(($layout != 'modal' ? $link_item : $link_list), false));
  184. return false;
  185. }
  186. }
  187. // Upload the file
  188. $result = $model->upload($file, $data['dir_id'], false, $record_id);
  189. if (is_array($result)) {
  190. $data['file'] = $result;
  191. }
  192. else {
  193. $error = $model->getError();
  194. $this->setError($error);
  195. $this->setMessage($error, 'error');
  196. $this->setRedirect(JRoute::_(($layout != 'modal' ? $link_item : $link_list), false));
  197. return false;
  198. }
  199. }
  200. // Inject file info into the form post data
  201. if (version_compare(JVERSION, '3.0.0', 'ge')) {
  202. $this->input->post->set('jform', $data);
  203. }
  204. else {
  205. JRequest::setVar('jform', $data, 'post');
  206. }
  207. // Store data
  208. return parent::save($key, $urlVar);
  209. }
  210. /**
  211. * Method the get the file info coming from a form
  212. *
  213. * @param array $data The form data
  214. *
  215. * @return array $files The file data
  216. */
  217. protected function getFormFiles($data)
  218. {
  219. $files = array();
  220. if (!is_array($data)) return $files;
  221. foreach($data AS $attr => $field)
  222. {
  223. $count = count($field);
  224. $i = 0;
  225. while($count > $i)
  226. {
  227. foreach($field AS $name => $value)
  228. {
  229. $files[$i][$attr] = $value;
  230. }
  231. $i++;
  232. }
  233. }
  234. return $files;
  235. }
  236. /**
  237. * Method to check for upload errors
  238. *
  239. * @param array $files The files to check
  240. * @param integer $record_id The file id
  241. *
  242. * @return boolean True if no error
  243. */
  244. protected function checkFileError(&$files, $record_id = 0)
  245. {
  246. foreach ($files AS &$file)
  247. {
  248. // Uploading a file is not required when updating an existing record
  249. if ($file['error'] == 4 && $record_id > 0) {
  250. $file['error'] = 0;
  251. }
  252. if ($file['error']) {
  253. $error = PFrepoHelper::getFileErrorMsg($file['error'], $file['name']);
  254. $this->setError($error);
  255. $this->setMessage($error, 'error');
  256. return false;
  257. }
  258. }
  259. return true;
  260. }
  261. /**
  262. * Method to check if the file extension is the same the original
  263. *
  264. * @param integer $id The file id
  265. * @param string $file The name of the file to upload
  266. *
  267. * @return boolean True if they are the same
  268. */
  269. protected function checkFileExtension($id, $file)
  270. {
  271. $db = JFactory::getDbo();
  272. $query = $db->getQuery(true);
  273. $query->select('file_extension')
  274. ->from('#__pf_repo_files')
  275. ->where('id = ' . (int) $id);
  276. $db->setQuery($query);
  277. $original_ext = $db->loadResult();
  278. return (JFile::getExt($file) == $original_ext);
  279. }
  280. /**
  281. * Gets the URL arguments to append to an item redirect.
  282. *
  283. * @param int $id The primary key id for the item.
  284. * @param string $url_var The name of the URL variable for the id.
  285. *
  286. * @return string The arguments to append to the redirect URL.
  287. */
  288. protected function getRedirectToItemAppend($id = null, $url_var = 'id')
  289. {
  290. // Need to override the parent method completely.
  291. $tmpl = JRequest::getCmd('tmpl');
  292. $layout = JRequest::getCmd('layout', 'edit');
  293. $item_id = JRequest::getUInt('Itemid');
  294. $project = JRequest::getUint('filter_project', 0);
  295. $parent = JRequest::getUint('filter_parent_id', 0);
  296. $return = $this->getReturnPage($parent, $project);
  297. $append = '';
  298. // Setup redirect info.
  299. if ($project) $append .= '&filter_project=' . $project;
  300. if ($parent) $append .= '&filter_parent_id=' . $parent;
  301. if ($id) $append .= '&' . $url_var . '=' . $id;
  302. if ($item_id) $append .= '&Itemid=' . $item_id;
  303. if ($layout) $append .= '&layout=' . $layout;
  304. if ($tmpl) $append .= '&tmpl=' . $tmpl;
  305. if ($return) $append .= '&return='.base64_encode($return);
  306. return $append;
  307. }
  308. /**
  309. * Gets the URL arguments to append to a list redirect.
  310. *
  311. * @return string The arguments to append to the redirect URL.
  312. */
  313. protected function getRedirectToListAppend()
  314. {
  315. $tmpl = JRequest::getCmd('tmpl');
  316. $project = JRequest::getUint('filter_project');
  317. $parent = JRequest::getUint('filter_parent_id');
  318. $func = JRequest::getCmd('function');
  319. $layout = JRequest::getCmd('layout');
  320. $append = '';
  321. // Setup redirect info.
  322. if ($project) $append .= '&filter_project=' . $project;
  323. if ($parent) $append .= '&filter_parent_id=' . $parent;
  324. if ($tmpl) $append .= '&tmpl=' . $tmpl;
  325. if ($layout) $append .= '&layout=' . $layout;
  326. if ($func) $append .= '&function=' . $func;
  327. return $append;
  328. }
  329. /**
  330. * Get the return URL.
  331. * If a "return" variable has been passed in the request
  332. *
  333. * @return string The return URL.
  334. */
  335. protected function getReturnPage($parent, $project = 0)
  336. {
  337. $return = JRequest::getVar('return', null, 'default', 'base64');
  338. $append = '';
  339. if ($project) $append .= '&filter_project=' . $project;
  340. if ($parent) $append .= '&filter_parent_id=' . $parent;
  341. if (empty($return) || !JUri::isInternal(base64_decode($return))) {
  342. return JRoute::_('index.php?option=com_pfrepo&view=' . $this->view_list . $append, false);
  343. }
  344. else {
  345. return base64_decode($return);
  346. }
  347. }
  348. }