PageRenderTime 61ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/system/expressionengine/controllers/cp/content_files_modal.php

https://bitbucket.org/mbaily/tremain
PHP | 478 lines | 254 code | 80 blank | 144 comment | 24 complexity | ce0a564b1dbe700ab0f80b03f9c12941 MD5 | raw file
  1. <?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
  2. /**
  3. * ExpressionEngine - by EllisLab
  4. *
  5. * @package ExpressionEngine
  6. * @author EllisLab Dev Team
  7. * @copyright Copyright (c) 2003 - 2013, EllisLab, Inc.
  8. * @license http://ellislab.com/expressionengine/user-guide/license.html
  9. * @link http://ellislab.com
  10. * @since Version 2.0
  11. * @filesource
  12. */
  13. // ------------------------------------------------------------------------
  14. /**
  15. * ExpressionEngine CP Home Page Class
  16. *
  17. * @package ExpressionEngine
  18. * @subpackage Control Panel
  19. * @category Control Panel
  20. * @author EllisLab Dev Team
  21. * @link http://ellislab.com
  22. */
  23. class Content_files_modal extends CP_Controller {
  24. private $_upload_dirs = array();
  25. private $_base_url = '';
  26. public function __construct()
  27. {
  28. parent::__construct();
  29. // Permissions
  30. if ( ! $this->cp->allowed_group('can_access_content'))
  31. {
  32. show_error(lang('unauthorized_access'));
  33. }
  34. $this->load->library('filemanager');
  35. $this->load->model(array('file_model', 'file_upload_preferences_model'));
  36. // Get upload dirs
  37. $upload_dirs = $this->filemanager->fetch_upload_dirs();
  38. foreach ($upload_dirs as $row)
  39. {
  40. $this->_upload_dirs[$row['id']] = $row;
  41. }
  42. // Turn off the profiler, everything is in a modal
  43. $this->output->enable_profiler(FALSE);
  44. $this->_base_url = BASE.AMP.'C=content_files_modal';
  45. // Clear out the preloaded core javacript files
  46. $this->cp->requests = array();
  47. $this->cp->loaded = array();
  48. }
  49. // ------------------------------------------------------------------------
  50. /**
  51. * Shows the inner upload iframe, handles getting that view the data it needs
  52. */
  53. public function index()
  54. {
  55. $this->load->view('_shared/file_upload/index', $this->_vars_index());
  56. }
  57. // ------------------------------------------------------------------------
  58. /**
  59. * Upload file
  60. *
  61. * This method does a few things, but it's main goal is to facilitate working
  62. * with Filemanager to both upload and add the file to exp_files.
  63. *
  64. * 1. Verifies that you have access to upload
  65. * - Is this being accessed through a form?
  66. * - Was a upload directory specified?
  67. * - Does the user have access to the directory?
  68. * 2. Next, it calls Filemanager's upload_file
  69. * - That uploads the file and adds it to the database
  70. * 3. Then it generates a response based upon Filemanager's response:
  71. * - If there's an error, that's shown
  72. * - If there's an existing file with the same name, they have the option to rename
  73. * - If everything went according to plan, a success message is shown
  74. *
  75. * @return mixed View file based upon Filemanager's response: success, failure or rename
  76. */
  77. public function upload_file()
  78. {
  79. $this->output->enable_profiler(FALSE);
  80. // Handles situation where the file attempted to upload exceeds the max upload size so much
  81. // that it removes all headers in $_POST and $_FILES; we need to handle this before anything
  82. // else because everything below depends on $_POST
  83. if (empty($_POST)
  84. AND empty($_FILES)
  85. AND $this->input->server('REQUEST_METHOD') == 'POST'
  86. AND $this->input->server('CONTENT_LENGTH') > 0)
  87. {
  88. $this->lang->loadfile('upload');
  89. $vars = $this->_vars_index();
  90. $vars['error'] = lang('upload_file_exceeds_limit');
  91. return $this->load->view('_shared/file_upload/index', $vars);
  92. }
  93. // Make sure this is a valid form submit
  94. if (empty($_POST))
  95. {
  96. show_error(lang('unauthorized_access'));
  97. }
  98. // Do some basic permissions checking
  99. if ( ! ($file_dir = $this->input->get_post('upload_dir')))
  100. {
  101. show_error(lang('unauthorized_access'));
  102. }
  103. // Bail if they dont' have access to this upload location.
  104. if ( ! array_key_exists($file_dir, $this->_upload_dirs))
  105. {
  106. show_error(lang('unauthorized_access'));
  107. }
  108. $restrict_image = ($this->input->post('restrict_image')) ? TRUE : FALSE;
  109. // Both uploads the file and adds it to the database
  110. $upload_response = $this->filemanager->upload_file($file_dir, FALSE, $restrict_image);
  111. // Any errors from the Filemanager?
  112. if (isset($upload_response['error']))
  113. {
  114. $vars = $this->_vars_index();
  115. $vars['error'] = $upload_response['error'];
  116. return $this->load->view('_shared/file_upload/index', $vars);
  117. }
  118. // Check to see if the file needs to be renamed
  119. // It needs to be renamed if the current name differs from
  120. // the original AFTER clean_filename and upload library's prep done
  121. // but before duplicate checking
  122. $file = $this->_get_file($upload_response['file_id']);
  123. $file['modified_date'] = $this->localize->human_time($file['modified_date']);
  124. $original_name = $upload_response['orig_name'];
  125. $cleaned_name = basename($this->filemanager->clean_filename(
  126. $original_name,
  127. $file_dir
  128. ));
  129. if ($file['file_name'] != $original_name
  130. AND $file['file_name'] != $cleaned_name)
  131. {
  132. // At this point, orig_name contains the extension
  133. $vars = $this->_vars_rename($file, $original_name);
  134. return $this->load->view('_shared/file_upload/rename', $vars);
  135. }
  136. $vars = $this->_vars_success($file);
  137. return $this->load->view('_shared/file_upload/success', $vars);
  138. }
  139. // ------------------------------------------------------------------------
  140. /**
  141. * Attempts to rename the file, goes back to rename if it couldn't, sends
  142. * the user to success if everything went to plan.
  143. *
  144. * Called via content_files::upload_file if the file already exists
  145. */
  146. public function update_file()
  147. {
  148. $new_file_name = basename($this->filemanager->clean_filename(
  149. $this->input->post('new_file_name').'.'.$this->input->post('file_extension'),
  150. $this->input->post('directory_id')
  151. ));
  152. $new_file_base = substr($new_file_name, 0, -strlen('.'.$this->input->post('file_extension')));
  153. $temp_filename = basename($this->filemanager->clean_filename(
  154. $this->input->post('original_name'),
  155. $this->input->post('directory_id')
  156. ));
  157. // Attempt to replace the file
  158. $rename_file = $this->filemanager->rename_file(
  159. $this->input->post('file_id'),
  160. $new_file_name,
  161. $temp_filename
  162. );
  163. // Get the file data of the renamed file
  164. $file = $this->_get_file($rename_file['file_id']);
  165. // Humanize Unix timestamp
  166. $file['modified_date'] = $this->localize->human_time($file['modified_date']);
  167. // Views need to know if the file was replaced
  168. $file['replace'] = $rename_file['replace'];
  169. // If renaming the file was unsuccessful try again
  170. if ($rename_file['success'] === FALSE && $rename_file['error'] == 'retry')
  171. {
  172. // At this point, original_name no longer contains the file extension
  173. // so we need to add it for build_rename_vars
  174. $vars = $this->_vars_rename(
  175. $file,
  176. $this->input->post('original_name')
  177. );
  178. return $this->load->view('_shared/file_upload/rename', $vars);
  179. }
  180. // If the file was successfully replaced send them to the success page
  181. if ($rename_file['success'] === TRUE)
  182. {
  183. $vars = $this->_vars_success($file);
  184. return $this->load->view('_shared/file_upload/success', $vars);
  185. }
  186. // If it's a different type of error, show it
  187. else
  188. {
  189. return $this->load->view('_shared/file_upload/rename', $rename_file['error']);
  190. }
  191. }
  192. // ------------------------------------------------------------------------
  193. public function edit_file()
  194. {
  195. // Retrieve the file ID
  196. $file_id = $this->input->get_post('file_id');
  197. // Attempt to save the file
  198. $this->_save_file();
  199. // Retrieve the (possibly updated) file data
  200. $vars['file'] = $this->_get_file($file_id);
  201. // Create array of hidden inputs
  202. $vars['hidden'] = array(
  203. 'file_id' => $file_id,
  204. 'file_name' => $vars['file']['file_name'],
  205. 'upload_dir' => $vars['file']['upload_location_id']
  206. );
  207. // List out the tabs
  208. $vars['tabs'] = array('file_metadata');
  209. // Add image tools if we're dealing with an image
  210. if ($vars['file']['is_image'])
  211. {
  212. $this->javascript->set_global(array(
  213. 'filemanager' => array(
  214. 'image_height' => $vars['file']['dimensions'][0],
  215. 'image_width' => $vars['file']['dimensions'][1],
  216. 'resize_over_confirmation' => lang('resize_over_confirmation')
  217. ),
  218. ));
  219. array_push($vars['tabs'], 'image_tools');
  220. }
  221. // Create a list of metadata fields
  222. $vars['metadata_fields'] = array(
  223. 'title' => form_input('title', $vars['file']['title']),
  224. 'description' => form_textarea(array(
  225. 'name' => 'description',
  226. 'value' => $vars['file']['description'],
  227. 'rows' => 3
  228. )),
  229. 'credit' => form_input('credit', $vars['file']['credit']),
  230. 'location' => form_input('location', $vars['file']['location'])
  231. );
  232. // Load javascript libraries
  233. $this->cp->add_js_script(array(
  234. 'plugin' => 'ee_resize_scale',
  235. 'file' => 'files/edit_file'
  236. ));
  237. $this->javascript->compile();
  238. $this->load->view('_shared/file_upload/edit', $vars);
  239. }
  240. // ------------------------------------------------------------------------
  241. /**
  242. * Retrieves variables used on the index page of the modal since they are
  243. * used on failure as well as initial load
  244. *
  245. * @return array Associative array containing the upload directory dropdown
  246. * array, hidden variables for the form, and the ID of the selected
  247. * directory
  248. */
  249. private function _vars_index()
  250. {
  251. $selected_directory_id = ($this->input->get_post('directory_id')) ? $this->input->get_post('directory_id') : '';
  252. $directory_override = (in_array($this->input->get_post('restrict_directory'), array('true', 1))) ? $selected_directory_id : '';
  253. $restrict_image = (in_array($this->input->get_post('restrict_image'), array('true', 1))) ? TRUE : FALSE;
  254. return array(
  255. 'upload_directories' => $this->file_upload_preferences_model->get_dropdown_array(
  256. $this->session->userdata('group_id'),
  257. $directory_override
  258. ),
  259. 'hidden_vars' => array(
  260. 'restrict_image' => $restrict_image,
  261. 'directory_id' => $this->input->get_post('directory_id'),
  262. 'restrict_directory' => $this->input->get_post('restrict_directory')
  263. ),
  264. 'selected_directory_id' => $selected_directory_id
  265. );
  266. }
  267. // ------------------------------------------------------------------------
  268. /**
  269. * Creates an associative array the be passed as the variables for the
  270. * rename view
  271. *
  272. * @param array $file The associative array of the file, comes from _get_file
  273. * @param string $original_name The original name of the file that was uploaded
  274. * @return array Associative array containing file_json, file_extension,
  275. * original_name and an array of hidden variables
  276. */
  277. private function _vars_rename($file, $original_name)
  278. {
  279. // Check to see if they want to increment or replace
  280. $original_name = ($this->config->item('filename_increment') == 'y') ? $file['file_name'] : $original_name;
  281. // Explode the original name so we have something to work with if they
  282. // need to rename the file later
  283. $original_name = explode('.' , $original_name);
  284. $file_extension = array_pop($original_name);
  285. $original_name = implode('.', $original_name);
  286. return array(
  287. 'file_json' => json_encode($file),
  288. 'file_extension' => $file_extension,
  289. 'original_name' => $original_name,
  290. 'hidden' => array(
  291. 'file_id' => $file['file_id'],
  292. 'directory_id' => $file['upload_location_id'],
  293. 'file_extension' => $file_extension,
  294. 'original_name' => $original_name.'.'.$file_extension
  295. )
  296. );
  297. }
  298. // ------------------------------------------------------------------------
  299. /**
  300. * Creates an associative array for the success view
  301. *
  302. * @param array $file The associative array of the file, comes from _get_file
  303. * @return array Associative array containing file, file_id and file_json
  304. */
  305. private function _vars_success($file)
  306. {
  307. // Success only needs file, file_id, and file_json
  308. return array(
  309. 'file' => $file,
  310. 'file_id' => $file['file_id'],
  311. 'file_json' => json_encode($file)
  312. );
  313. }
  314. // ------------------------------------------------------------------------
  315. /**
  316. * Retrieves the file and sets up various data we need for the file uploader
  317. *
  318. * @param integer $file_id The ID of the file
  319. * @return array Associative array of the file
  320. */
  321. private function _get_file($file_id)
  322. {
  323. $file = $this->file_model->get_files_by_id($file_id)->row_array();
  324. // Set is_image
  325. $file['is_image'] = $this->filemanager->is_image($file['mime_type']);
  326. // Get thumbnail
  327. $thumb_info = $this->filemanager->get_thumb(
  328. $file['file_name'],
  329. $file['upload_location_id']
  330. );
  331. $file['thumb'] = $thumb_info['thumb'];
  332. // Copying file_name to name for addons
  333. $file['name'] = $file['file_name'];
  334. // Add dimensions if we're dealing with an image
  335. if ($file['is_image'])
  336. {
  337. $file['dimensions'] = explode(' ', $file['file_hw_original']);
  338. }
  339. // Change file size to human readable
  340. $this->load->helper('number');
  341. $file['file_size'] = byte_format($file['file_size']);
  342. // Blend in the upload directory preferences
  343. $file['upload_directory_prefs'] = $this->file_upload_preferences_model->get_file_upload_preferences(
  344. $this->session->userdata('group_id'),
  345. $file['upload_location_id']
  346. );
  347. return $file;
  348. }
  349. // ------------------------------------------------------------------------
  350. /**
  351. * Saves the file if we've submitted the edit form and validation passes
  352. */
  353. private function _save_file()
  354. {
  355. $this->load->library('form_validation');
  356. $this->form_validation->set_error_delimiters('<div class="notice">', '</div>');
  357. $this->form_validation->set_rules('title', 'lang:title', 'trim|required');
  358. // Save the file if title has been posted (success form doesn't have
  359. // title, so it wouldn't even bother saving data)
  360. if ($this->input->post('title') !== FALSE AND $this->form_validation->run())
  361. {
  362. $updated_data = array(
  363. 'file_id' => $this->input->post('file_id'),
  364. 'description' => $this->input->post('description', ''),
  365. 'credit' => $this->input->post('credit', ''),
  366. 'location' => $this->input->post('location', '')
  367. );
  368. // Only add title if it's not blank
  369. if (($title = $this->input->post('title', '')) != '')
  370. {
  371. $updated_data['title'] = $this->input->post('title');
  372. }
  373. $this->file_model->save_file($updated_data);
  374. // Check and see if we actually need to do image processing. Height
  375. // or width needs to be different from the default or rotate needs
  376. // to be set.
  377. $actions = array();
  378. if ($this->input->post('resize_height_default') !== $this->input->post('resize_height')
  379. OR $this->input->post('resize_width_default') !== $this->input->post('resize_width'))
  380. {
  381. // Resize MUST come first, the original values only make sense
  382. // in the context of resize first
  383. $actions[] = 'resize';
  384. }
  385. if ($this->input->post('rotate') !== FALSE)
  386. {
  387. $actions[] = 'rotate';
  388. }
  389. if (count($actions))
  390. {
  391. $_POST['action'] = $actions;
  392. $this->filemanager->_do_image_processing(FALSE);
  393. }
  394. }
  395. }
  396. }
  397. /* End File: content_files_modal.php */
  398. /* File Location: system/expressionengine/controllers/cp/content_files_modal.php */