PageRenderTime 26ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/ci_2.2.6_application/controllers/upload.php

https://github.com/dmcb/dmcb-cms
PHP | 361 lines | 297 code | 31 blank | 33 comment | 102 complexity | b49d6d2523cbbd31a079de72770b1e4d MD5 | raw file
  1. <?php
  2. /**
  3. * @package dmcb-cms
  4. * @author Derek McBurney
  5. * @copyright Copyright (c) 2011, Derek McBurney, derek@dmcbdesign.com
  6. * This code may not be used commercially without the expressed
  7. * written consent of Derek McBurney. Non-commercial use requires
  8. * attribution.
  9. * @link http://dmcbdesign.com
  10. */
  11. class Upload extends MY_Controller {
  12. function Upload()
  13. {
  14. parent::__construct();
  15. $this->load->model('files_model');
  16. }
  17. function file()
  18. {
  19. ini_set('post_max_size', '128M');
  20. ini_set('upload_max_filesize', '120M');
  21. ini_set('max_execution_time', '360');
  22. ini_set('max_input_time', '360');
  23. $attachedid = NULL;
  24. $attachedto = $this->uri->segment(3);
  25. $attachedto_object = NULL;
  26. $attachedname = "";
  27. for ($i=4; $i <= $this->uri->total_segments(); $i++)
  28. {
  29. $attachedname .= $this->uri->segment($i);
  30. if ($i != $this->uri->total_segments())
  31. {
  32. $attachedname .= '/';
  33. }
  34. }
  35. if ($attachedto == "user") // Uploading to a user profile, limit to images
  36. {
  37. $config['allowed_types'] = str_replace('*.', '', str_replace(';','|',$this->config->item('dmcb_profile_upload_types')));
  38. $config['max_size'] = $this->config->item('dmcb_profile_upload_size');
  39. $attachedto_object = instantiate_library('user', $attachedname, 'urlname');
  40. $attachedid = $attachedto_object->user['userid'];
  41. }
  42. else // Upload any kind of files for site, page and post uploads
  43. {
  44. $config['allowed_types'] = str_replace('*.', '', str_replace(';','|',$this->config->item('dmcb_site_upload_types')));
  45. $config['max_size'] = $this->config->item('dmcb_site_upload_size');
  46. // Uploads directly to the site don't need an attachedid, but if it's uploaded to a post or page, grab it
  47. if ($attachedto == "page")
  48. {
  49. $attachedto_object = instantiate_library('page', $attachedname, 'urlname');
  50. $attachedid = $attachedto_object->page['pageid'];
  51. }
  52. else if ($attachedto == "post")
  53. {
  54. $attachedto_object = instantiate_library('post', $attachedname, 'urlname');
  55. $attachedid = $attachedto_object->post['postid'];
  56. }
  57. }
  58. // If the upload is replacing a file, grab the fileid of the file to replace
  59. $replacefileid = NULL;
  60. if (isset($_POST['replace']))
  61. {
  62. $object = instantiate_library('file', $_POST['replace']);
  63. if (isset($object->file['fileid']))
  64. {
  65. // Confirm we are replacing a file on the same area (i.e. same post or page)
  66. if ($object->file['attachedto'] == $attachedto && $object->file['attachedid'] == $attachedid)
  67. {
  68. $replacefileid = $_POST['replace'];
  69. }
  70. }
  71. }
  72. // If the upload is going to a specific file type, specify it
  73. $filetypeid = NULL;
  74. if (isset($_POST['filetype']))
  75. {
  76. $filetypeid = $_POST['filetype'];
  77. }
  78. $config['upload_path'] = 'files_managed/'.$attachedto.'/'.str_replace('/', '+', $attachedname); // Upload to managed area first, sort it out later, also replace / with + for flat file structure
  79. $config['remove_spaces'] = true;
  80. $config['encrypt_name'] = false;
  81. $this->load->library('upload', $config);
  82. if (!file_exists($config['upload_path']))
  83. {
  84. mkdir($config['upload_path']);
  85. }
  86. // Set the return path and other specific options depending on where the upload is to
  87. if ($attachedto == "site")
  88. {
  89. $returnurl = "manage_content/attachments";
  90. }
  91. else if ($attachedto == "email")
  92. {
  93. $returnurl = "manage_users/email";
  94. }
  95. else if ($attachedto == "page")
  96. {
  97. $returnurl = $attachedname.'/attachments';
  98. }
  99. else if ($attachedto == "user")
  100. {
  101. $returnurl = "profile/".$attachedname.'/attachments';
  102. }
  103. else if ($attachedto == "post")
  104. {
  105. $returnurl = $attachedname.'/attachments';
  106. }
  107. else
  108. {
  109. $returnurl = $attachedto.'/'.$attachedid.'/attachments';
  110. }
  111. $uploadtype = "";
  112. $result = "";
  113. if (isset($_FILES["swfuploadfile"])) // Upload is a swfupload, and it's swfupload's first pass, so physically upload file
  114. {
  115. $uploadtype = "swfuploadupload";
  116. $result = $this->upload->do_upload('swfuploadfile');
  117. }
  118. else if (isset($_POST["hidFileID"]) && $_POST["hidFileID"] != "" ) // We are on swfupload's second pass, the upload has already been done
  119. {
  120. $uploadtype = "swfuploadparse";
  121. $result = TRUE;
  122. }
  123. else // Upload is a non swfupload, physically upload file
  124. {
  125. $uploadtype = "regular";
  126. $result = $this->upload->do_upload('Filedata');
  127. }
  128. if(!$result && $uploadtype == "regular") // A non swfupload fail
  129. {
  130. $this->_message(
  131. 'Manage uploads',
  132. $this->upload->display_errors('', '').' Click <a href="'.base_url().$returnurl.'">here</a> to return to editing.',
  133. 'Error'
  134. );
  135. }
  136. else if (!$result)
  137. {
  138. // User won't see this area since something did fail, but this was on swfupload's first pass, so swfupload will report the error
  139. }
  140. else // Upload was a success
  141. {
  142. if ($uploadtype == "swfuploadparse") // It's swfupload's second pass after the physical upload let's grab the filename from swfupload
  143. {
  144. $filename = $_POST["hidFileID"];
  145. }
  146. else // Otherwise, it's a regular upload or swfupload's first pass, and we will get the file name through CI
  147. {
  148. $filedata = $this->upload->data();
  149. $filename = $filedata['file_name'];
  150. }
  151. if ($uploadtype != "swfuploadupload") // We aren't on swfupload's first pass, so we are either on its second or a regular upload, so we will parse the file into the database and return to the user
  152. {
  153. // However, we will only parse the file if the user has an established session
  154. // We couldn't check earlier in this code for the session because when swfupload does it's first pass, it's through the flash/ajax applet, and that doesn't handle sessions and can't grab CI session
  155. /* Which means, now that we are back to the CI form submission, if there's no valid session here and they don't have attachments privilege,
  156. we will delete the file that was attempted to be uploaded and return an error */
  157. $allowed_to_upload = FALSE;
  158. $object = instantiate_library('user', $this->session->userdata('userid'));
  159. if (isset($object->user['userid']))
  160. {
  161. if ($attachedto == "page" && $this->acl->allow('page', 'attachments', FALSE, 'page', $attachedid))
  162. {
  163. $allowed_to_upload = TRUE;
  164. }
  165. else if ($attachedto == "post" && $this->acl->allow('post', 'attachments', FALSE, 'post', $attachedid))
  166. {
  167. // Grab post's parent so we can grab a template
  168. $attachedto_parent = instantiate_library('page', $attachedto_object->post['pageid']);
  169. if (isset($attachedto_parent->page['pageid']))
  170. {
  171. $attachedto_parent->initialize_page_tree();
  172. if (isset($attachedto_parent->page['post_templateid']))
  173. {
  174. $templateid = $attachedto_parent->page['post_templateid'];
  175. }
  176. else
  177. {
  178. $this->load->helper('template');
  179. $templateid = template_to_use('template', 'post', $attachedto_parent->page_tree);
  180. }
  181. $template = instantiate_library('template', $templateid);
  182. // Check if there's a template
  183. if (isset($template->template['templateid']))
  184. {
  185. // Grab template quotas
  186. $template->initialize_quotas();
  187. $quota_required = TRUE;
  188. $no_quota_in_use = TRUE;
  189. // Go through quotas determing which one the user is set to, if any
  190. foreach ($template->quotas as $filegroup)
  191. {
  192. $filegroup_editable = $this->acl->access($filegroup['protection'], $attachedto_parent, $attachedid);
  193. if ($filegroup_editable)
  194. {
  195. $no_quota_in_use = FALSE;
  196. }
  197. else if (!$filegroup_editable && $filegroup['other_roles_allowed'])
  198. {
  199. $quota_required = FALSE;
  200. }
  201. // If we are uploading to a specific file type, and that file type is permitted in this template, we must check if we reached the cap
  202. if ((!$quota_required || $filegroup_editable) && $filetypeid != NULL && isset($filegroup['filetypes'][$filetypeid]))
  203. {
  204. $attached = $this->files_model->get_attached('post', $attachedid, $filetypeid);
  205. if ($filegroup['filetypes'][$filetypeid]['cap'] != '*' && $attached->num_rows() >= $filegroup['filetypes'][$filetypeid]['cap'])
  206. {
  207. $failure_message = 'You cannot upload a '.strtolower($filegroup['filetypes'][$filetypeid]['name']).' file, the maximum allowed is '.$filegroup['filetypes'][$filetypeid]['cap'].'. '.
  208. '<a href="'.base_url().$returnurl.'">Please remove a file of this type first</a>.';
  209. }
  210. else
  211. {
  212. $allowed_to_upload = TRUE;
  213. }
  214. }
  215. }
  216. // If the user isn't assigned to a quota, or is assigned to one but not required to use it
  217. // And the file isn't a part of a quota but a regular file attachment, allow the upload
  218. if (!isset($failure_message) && $filetypeid == NULL && (!$quota_required || $no_quota_in_use))
  219. {
  220. $allowed_to_upload = TRUE;
  221. }
  222. }
  223. else // No template, which means they can upload
  224. {
  225. $allowed_to_upload = TRUE;
  226. }
  227. }
  228. else // No template, which means they can upload
  229. {
  230. $allowed_to_upload = TRUE;
  231. }
  232. }
  233. else if ($attachedto == "user" && $this->acl->allow('profile', 'add', FALSE, 'user', $attachedid))
  234. {
  235. $allowed_to_upload = TRUE;
  236. }
  237. else if ($attachedto == "email" && $this->acl->allow('site', 'manage_users', FALSE))
  238. {
  239. $allowed_to_upload = TRUE;
  240. }
  241. else if ($this->acl->allow('site', 'manage_content', FALSE))
  242. {
  243. $allowed_to_upload = TRUE;
  244. }
  245. }
  246. if ($allowed_to_upload)
  247. {
  248. if ($attachedto != "email") // But only parse file into the database when it's not an email attachment, which are temporary uploads
  249. {
  250. $this->_parsefile($config['upload_path'], $filename, $attachedto, $attachedid, $replacefileid, $filetypeid);
  251. }
  252. else // Add temporary upload information to mailing list session
  253. {
  254. // Preserve mailing user list session information
  255. $this->session->keep_flashdata('maillist');
  256. $this->session->keep_flashdata('sort');
  257. $this->session->keep_flashdata('page');
  258. $mailattachments = $this->session->flashdata('mailattachments');
  259. array_push($mailattachments, $filename);
  260. $this->session->set_flashdata('mailattachments', $mailattachments);
  261. }
  262. redirect($returnurl);
  263. }
  264. else
  265. {
  266. if (file_exists($config['upload_path'].'/'.$filename))
  267. {
  268. unlink($config['upload_path'].'/'.$filename);
  269. }
  270. if (!isset($failure_message))
  271. {
  272. $this->_access_denied();
  273. }
  274. else
  275. {
  276. $this->_message('Upload error', $failure_message);
  277. }
  278. }
  279. }
  280. else // We are on swfupload's first pass, echo the filename so that it'll do some AJAX and stick that filename into the attachment form in preparation for it's second pass
  281. {
  282. echo $filename;
  283. }
  284. }
  285. }
  286. function _parsefile($filepath, $filename, $attachedto, $attachedid, $replacefileid, $filetypeid)
  287. {
  288. // If the file isn't replacing an existing one, we need to create it in the database
  289. if ($replacefileid == NULL)
  290. {
  291. // Determine file is an image or not
  292. $info = @getimagesize($filepath.'/'.$filename);
  293. if(!$info)
  294. {
  295. $isimage = "0";
  296. }
  297. else
  298. {
  299. $isimage = "1";
  300. }
  301. // Break down filename into it's name and extension
  302. $filepieces = explode(".", $filename);
  303. $extension = $filepieces[count($filepieces)-1];
  304. $filename = substr($filename, 0, strrpos($filename, "."));
  305. // Create file
  306. $this->load->library('file_lib','','new_file');
  307. $this->new_file->new_file['userid'] = $this->session->userdata('userid');
  308. $this->new_file->new_file['filename'] = $filename;
  309. $this->new_file->new_file['extension'] = $extension;
  310. $this->new_file->new_file['isimage'] = $isimage;
  311. $this->new_file->new_file['attachedto'] = $attachedto;
  312. $this->new_file->new_file['attachedid'] = $attachedid;
  313. $this->new_file->new_file['filetypeid'] = $filetypeid;
  314. // Although CI ensures a unique upload name, our upload was to 'files_managed', and if there's a file with the same name sitting in the 'files' folder we will have problems
  315. // Let's have the file library suggest a new file name that lacks spaces, invalid symbols and caps doesn't collide with an existing file
  316. $this->new_file->suggest();
  317. if ($filename.'.'.$extension != $this->new_file->new_file['filename'].'.'.$this->new_file->new_file['extension'])
  318. {
  319. copy($filepath.'/'.$filename.'.'.$extension, $filepath.'/'.$this->new_file->new_file['filename'].'.'.$this->new_file->new_file['extension']);
  320. unlink($filepath.'/'.$filename.'.'.$extension);
  321. }
  322. $this->new_file->save();
  323. }
  324. else
  325. {
  326. $object = instantiate_library('file', $replacefileid);
  327. $object->overwrite($filepath.'/'.$filename);
  328. }
  329. }
  330. }