plup.module 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634
  1. <?php
  2. /**
  3. * _menu
  4. */
  5. function plup_menu() {
  6. $items = array();
  7. $items['plupload'] = array(
  8. 'title' => 'Plupload upload page',
  9. 'page callback' => 'plup_upload_page',
  10. 'access callback' => 'plup_upload_access',
  11. 'access arguments' => array('access content', 'allow plupload'),
  12. 'type' => MENU_CALLBACK
  13. );
  14. $items['plupload/%'] = array(
  15. 'title' => 'Plupload upload page',
  16. 'page callback' => 'plup_upload_page',
  17. 'access callback' => 'plup_upload_access',
  18. 'access arguments' => array('access content', 'allow plupload'),
  19. 'type' => MENU_CALLBACK
  20. );
  21. return $items;
  22. }
  23. /**
  24. * Verifies the token for this request.
  25. */
  26. function plup_upload_access() {
  27. foreach(func_get_args() as $permission) {
  28. if (!user_access($permission)) {
  29. return FALSE;
  30. }
  31. }
  32. return !empty($_REQUEST['plupload_token']) && drupal_valid_token($_REQUEST['plupload_token'], 'plupload-handle-uploads');
  33. }
  34. /**
  35. * _permission
  36. */
  37. function plup_permission() {
  38. return array(
  39. 'allow plupload' => array(
  40. 'title' => t('Allow Plupload'),
  41. 'description' => t('Allow user to upload files via Plupload.'),
  42. ),
  43. );
  44. }
  45. /**
  46. * _library
  47. */
  48. function plup_library() {
  49. $module = drupal_get_path('module', 'plup');
  50. $plupload = libraries_get_path('plupload');
  51. $lib['plupload'] = array(
  52. 'title' => 'Plupload',
  53. 'website' => 'http://www.plupload.com',
  54. 'version' => '1.5.1.1',
  55. 'js' => array(
  56. "$plupload/js/plupload.full.js" => array(),
  57. "$module/plup.js" => array(),
  58. ),
  59. 'css' => array(
  60. "$module/plup.css" => array(
  61. 'type' => 'file',
  62. 'media' => 'screen',
  63. ),
  64. ),
  65. 'dependencies' => array(
  66. array('system', 'ui.progressbar'),
  67. array('system', 'ui.sortable')
  68. ),
  69. );
  70. return $lib;
  71. }
  72. /**
  73. * _element_info
  74. */
  75. function plup_element_info() {
  76. $plupload = libraries_get_path('plupload');
  77. $types['plupload_file'] = array(
  78. '#input' => TRUE,
  79. '#title' => NULL,
  80. '#process' => array('plup_process_element'),
  81. '#value_callback' => 'plup_value_element',
  82. '#element_validate' => array('plup_validate_element'),
  83. '#pre_render' => array('plup_pre_render_element'),
  84. '#default_value' => NULL,
  85. '#required' => FALSE,
  86. '#autocomplete_path' => FALSE,
  87. '#theme_wrappers' => array('form_element'),
  88. '#theme' => 'plup_plupload',
  89. '#upload_location' => NULL,
  90. '#info' => array(),
  91. '#attached' => array(
  92. 'library' => array(
  93. array('plup', 'plupload')
  94. )
  95. ),
  96. '#plup' => array(
  97. 'container' => NULL,
  98. 'browse_button' => NULL,
  99. 'upload' => NULL,
  100. 'runtimes' => 'html5,gears,flash,silverlight,browserplus,html4',
  101. 'max_file_size' => '512MB',
  102. 'url' => url('plupload', array('query' => array('plupload_token' => drupal_get_token('plupload-handle-uploads')))),
  103. 'filters' => array(),
  104. 'chunk_size' => '512K',
  105. 'unique_names' => TRUE,
  106. 'flash_swf_url' => base_path() ."$plupload/js/plupload.flash.swf",
  107. 'silverlight_xap_url' => base_path() ."$plupload/js/plupload.silverlight.xap",
  108. 'drop_element' => NULL,
  109. 'multipart' => FALSE,
  110. 'dragdrop' => TRUE,
  111. 'multiple_queues' => TRUE,
  112. 'urlstream_upload' => FALSE,
  113. 'image_style' => 'thumbnail',
  114. 'image_style_path' => '',
  115. 'max_files' => -1
  116. ),
  117. '#plup_override' => array()
  118. );
  119. return $types;
  120. }
  121. /**
  122. * Value callback needed for removing all items.
  123. */
  124. function plup_value_element(&$element, $input = FALSE, $form_state = NULL) {
  125. // Default state - no new data
  126. if ($input === FALSE) {
  127. return NULL;
  128. }
  129. // Field was emptied - user deleted all files
  130. if (is_null($input)) {
  131. return array(array('fid' => 0));
  132. }
  133. // Field has new data
  134. return $input;
  135. }
  136. /**
  137. * Process callback to set JS settings before Plupload init.
  138. */
  139. function plup_process_element($element, &$form_state, $form) {
  140. $element['#default_value'] = isset($element['#value']) ? $element['#value'] : $element['#default_value'];
  141. $element['#plup']['container'] = $element['#id'];
  142. $element['#plup']['browse_button'] = $element['#id'] .'-plup-select';
  143. $element['#plup']['upload'] = $element['#id'] .'-plup-upload';
  144. $element['#plup']['drop_element'] = $element['#id'] .'-plup-filelist';
  145. $element['#plup']['name'] = $element['#name'];
  146. $element['#plup'] = array_merge($element['#plup'], $element['#plup_override']);
  147. $files = variable_get('file_public_path', 'sites/default/files');
  148. $element['#plup']['image_style_path'] = base_path() . $files .'/styles/'. $element['#plup']['image_style'] .'/temporary/';
  149. $element['#attached']['js'][] = array(
  150. 'data' => array('plup' => array($element['#name'] => $element['#plup'])),
  151. 'type' => 'setting',
  152. );
  153. return $element;
  154. }
  155. /**
  156. * Pre-render callback to load existing items.
  157. */
  158. function plup_pre_render_element($element) {
  159. if (isset($element['#default_value']) && !empty($element['#default_value'])) {
  160. foreach ($element['#default_value'] AS $delta => $item) {
  161. $element['#default_value'][$delta] = array_merge($item, (array) file_load($item['fid']));
  162. }
  163. }
  164. return $element;
  165. }
  166. /**
  167. * Element validation callback.
  168. */
  169. function plup_validate_element($element, &$form_state, $form) {
  170. $item = reset($element['#value']);
  171. if ($element['#required'] == TRUE && $item['fid'] == 0 && count($element['#value']) == 1) {
  172. form_error($element, t("@field field is required.", array('@field' => $element['#title'])));
  173. }
  174. $cardinality = isset($element['#plup_override']['max_files']) ? $element['#plup_override']['max_files'] : $element['#plup']['max_files'];
  175. if ($cardinality > 0 && count($element['#value']) > $cardinality) {
  176. form_error($element, t("Only !num items are allowed.", array('!num' => $cardinality)));
  177. }
  178. }
  179. /**
  180. * _theme
  181. */
  182. function plup_theme() {
  183. return array(
  184. 'plup_plupload' => array(
  185. 'render element' => 'element',
  186. ),
  187. 'plup_items' => array(
  188. 'render element' => 'element'
  189. )
  190. );
  191. }
  192. /**
  193. * Theme Plupload widget.
  194. */
  195. function theme_plup_plupload($variables) {
  196. $element = $variables['element'];
  197. $attributes = array();
  198. if (isset($element['#id'])) {
  199. $attributes['id'] = $element['#id'];
  200. }
  201. if (!empty($element['#attributes']['class'])) {
  202. $attributes['class'] = (array) $element['#attributes']['class'];
  203. }
  204. $attributes['class'][] = 'plupload';
  205. $hasTitle = (bool) (isset($element['#plup_override']['title_field']) && $element['#plup_override']['title_field'] == 1);
  206. $hasAlt = (bool) (isset($element['#plup_override']['alt_field']) && $element['#plup_override']['alt_field'] == 1);
  207. if ($hasTitle) {
  208. $attributes['class'][] = 'has-title';
  209. }
  210. if ($hasAlt) {
  211. $attributes['class'][] = 'has-alt';
  212. }
  213. $output = '<div' . drupal_attributes($attributes) . '>';
  214. $output .= '<div id="'. $element['#id'] .'-plupload-container" class="plupload-container">';
  215. $output .= '<div class="plup-list-wrapper"><ul class="plup-list clearfix">';
  216. $output .= theme('plup_items', array('element' => $element));
  217. $output .= '</ul></div>';
  218. $output .= '<div id="'. $element['#id'] .'-plup-filelist" class="plup-filelist"><table><tr class="plup-drag-info"><td><div class="drag-main">'. t('Drag files here') .'</div><div class="drag-more">'. implode("\n", $element['#info']) .'</div></td></tr></table></div>';
  219. $output .= '<div class="plup-bar clearfix">';
  220. $output .= '<a id="'. $element['#id'] .'-plup-select" class="plup-select"><div></div>'. t('Add') .'</a>';
  221. $output .= '<a id="'. $element['#id'] .'-plup-upload" class="plup-upload"><div></div>'. t('Upload') .'</a>';
  222. $output .= '<div class="plup-progress"></div>';
  223. $output .= '</div>';
  224. $output .= '</div>';
  225. $output .= '</div>';
  226. return $output;
  227. }
  228. /**
  229. * Theme Plupload items within widget.
  230. */
  231. function theme_plup_items($vars) {
  232. $element = &$vars['element'];
  233. if (isset($element['#default_value']) && !empty($element['#default_value'])) {
  234. $items = &$element['#default_value'];
  235. } else {
  236. return '';
  237. }
  238. $output = '';
  239. foreach ($items AS $delta => $item) {
  240. // If user deleted all items I'll get array('fid' => 0)
  241. if ($item['fid'] > 0) {
  242. $hasTitle = (bool) (isset($element['#plup_override']['title_field']) && $element['#plup_override']['title_field'] == 1);
  243. $hasAlt = (bool) (isset($element['#plup_override']['alt_field']) && $element['#plup_override']['alt_field'] == 1);
  244. $name = $element['#name'] .'['. $delta .']';
  245. $output .= '<li class="ui-state-default">';
  246. $output .= '<div class="plup-thumb-wrapper">'. theme('image_style', array('style_name' => $element['#plup']['image_style'], 'path' => $item['uri'], 'title' => $item['filename'])) .'</div>';
  247. $output .= '<a class="plup-remove-item"></a>';
  248. if ($hasTitle) {
  249. $output .= '<input title="'. t('Title') .'" type="text" class="form-text plup-title" name="'. $name .'[title]" value="'. $item['title'] .'" />';
  250. }
  251. if ($hasAlt) {
  252. $output .= '<input title="'. t('Alternative text') .'" type="text" class="form-text plup-alt" name="'. $name .'[alt]" value="'. $item['alt'] .'" />';
  253. }
  254. $output .= '<input type="hidden" name="'. $name .'[fid]" value="'. $item['fid'] .'" />';
  255. $output .= '<input type="hidden" name="'. $name .'[weight]" value="'. $delta .'" />';
  256. if (isset($item['rename'])) {
  257. $output .= '<input type="hidden" name="'. $name .'[rename]" value="'. $item['rename'] .'" />';
  258. }
  259. $output .= '</li>';
  260. }
  261. }
  262. return $output;
  263. }
  264. /**
  265. * Plupload's upload function.
  266. */
  267. function plup_upload_page() {
  268. drupal_add_http_header('Expires', 'Mon, 26 Jul 1997 05:00:00 GMT', TRUE);
  269. drupal_add_http_header('Last-Modified', gmdate("D, d M Y H:i:s") . ' GMT', TRUE);
  270. drupal_add_http_header('Cache-Control', 'no-store, no-cache, must-revalidate post-check=0, pre-check=0', TRUE);
  271. drupal_add_http_header('Pragma', 'no-cache', TRUE);
  272. // Settings
  273. $targetDir = $GLOBALS['conf']['file_temporary_path'] .'/';
  274. // 5 minutes execution time
  275. @set_time_limit(5 * 60);
  276. // Uncomment this one to fake upload time
  277. // usleep(5000);
  278. // Get parameters
  279. $chunk = isset($_REQUEST['chunk']) ? $_REQUEST['chunk'] : 0;
  280. $chunks = isset($_REQUEST['chunks']) ? $_REQUEST['chunks'] : 0;
  281. $filename = isset($_REQUEST['name']) ? $_REQUEST['name'] : '';
  282. // Clean the fileName for security reasons
  283. $extensions = 'jpg jpeg gif png txt doc xls pdf ppt pps odt ods odp';
  284. $filename = file_munge_filename($filename, $extensions, FALSE);
  285. // Make sure the fileName is unique but only if chunking is disabled
  286. if ($chunks < 2 && file_exists($targetDir . DIRECTORY_SEPARATOR . $filename)) {
  287. $ext = strrpos($filename, '.');
  288. $filename_a = substr($filename, 0, $ext);
  289. $filename_b = substr($filename, $ext);
  290. $count = 1;
  291. while (file_exists($targetDir . DIRECTORY_SEPARATOR . $filename_a . '_' . $count . $filename_b))
  292. $count++;
  293. $filename = $filename_a . '_' . $count . $filename_b;
  294. }
  295. // Look for the content type header
  296. if (isset($_SERVER['HTTP_CONTENT_TYPE'])) {
  297. $contentType = $_SERVER['HTTP_CONTENT_TYPE'];
  298. }
  299. if (isset($_SERVER['CONTENT_TYPE'])) {
  300. $contentType = $_SERVER['CONTENT_TYPE'];
  301. }
  302. // Handle non multipart uploads older WebKit versions didn't support multipart in HTML5
  303. if (strpos($contentType, 'multipart') !== false) {
  304. if (isset($_FILES['file']['tmp_name']) && is_uploaded_file($_FILES['file']['tmp_name'])) {
  305. // Open temp file
  306. $out = fopen($targetDir . DIRECTORY_SEPARATOR . $filename, $chunk == 0 ? 'wb' : 'ab');
  307. if ($out) {
  308. // Read binary input stream and append it to temp file
  309. $in = fopen($_FILES['file']['tmp_name'], 'rb');
  310. if ($in) {
  311. while ($buff = fread($in, 4096))
  312. fwrite($out, $buff);
  313. } else {
  314. die('{"jsonrpc" : "2.0", "error" : {"code": 101, "message": "Failed to open input stream."}, "id" : "id"}');
  315. }
  316. fclose($in);
  317. fclose($out);
  318. @unlink($_FILES['file']['tmp_name']);
  319. } else {
  320. die('{"jsonrpc" : "2.0", "error" : {"code": 102, "message": "Failed to open output stream."}, "id" : "id"}');
  321. }
  322. } else {
  323. die('{"jsonrpc" : "2.0", "error" : {"code": 103, "message": "Failed to move uploaded file."}, "id" : "id"}');
  324. }
  325. } else {
  326. // Open temp file
  327. $out = fopen($targetDir . DIRECTORY_SEPARATOR . $filename, $chunk == 0 ? 'wb' : 'ab');
  328. if ($out) {
  329. // Read binary input stream and append it to temp file
  330. $in = fopen("php://input", 'rb');
  331. if ($in) {
  332. while ($buff = fread($in, 4096)) {
  333. fwrite($out, $buff);
  334. }
  335. } else {
  336. die('{"jsonrpc" : "2.0", "error" : {"code": 101, "message": "Failed to open input stream."}, "id" : "id"}');
  337. }
  338. fclose($in);
  339. fclose($out);
  340. } else {
  341. die('{"jsonrpc" : "2.0", "error" : {"code": 102, "message": "Failed to open output stream."}, "id" : "id"}');
  342. }
  343. }
  344. if ((isset($_GET['chunk']) && ($_GET['chunk'] + 1) == $_GET['chunks']) || (!isset($_GET['chunk']))) {
  345. $source = 'temporary://'. $filename;
  346. $file = new stdClass();
  347. $file->uid = $GLOBALS['user']->uid;
  348. $file->status = 0;
  349. $file->filename = $filename;
  350. $file->uri = $source;
  351. $file->filemime = file_get_mimetype($file->filename);
  352. $file->filesize = filesize($source);
  353. // Save url argument(instance_id) so we can validate file by instance settings
  354. $file->arg = arg(1);
  355. $e = FALSE;
  356. // Here we validate file
  357. drupal_alter('plup_file_validation', $file, $e);
  358. if ($e === FALSE) {
  359. $return = file_save($file);
  360. } else {
  361. file_unmanaged_delete($file->uri);
  362. $return = (object) array('error_message' => $e);
  363. }
  364. drupal_json_output($return);
  365. }
  366. }
  367. /**
  368. * Default validation function.
  369. * In most cases Pluplaod will be used for images so we use image-specific validation.
  370. * Non-image files has no support right now.
  371. */
  372. function plup_plup_file_validation_alter(&$file, &$e) {
  373. if (!isset($file->arg) || (isset($file->arg) && is_numeric($file->arg))) {
  374. $instance = db_select('field_config_instance','i')->fields('i', array('data'))->condition('id', $file->arg)->execute()->fetchField();
  375. $instance = unserialize($instance);
  376. $settings = $instance['settings'];
  377. // Check if file is image
  378. $passImage = file_validate_is_image($file);
  379. if (!empty($passImage)) {
  380. $e = reset($passImage);
  381. return;
  382. }
  383. // Check if file has allowed extension
  384. $passExt = file_validate_extensions($file, $settings['file_extensions']);
  385. if (!empty($passExt)) {
  386. $e = reset($passExt);
  387. return;
  388. }
  389. // Check if file doesn't exceed the maximal allowed size
  390. $passSize = file_validate_size($file, parse_size($settings['max_filesize']), 0);
  391. if (!empty($passSize)) {
  392. $e = reset($passSize);
  393. return;
  394. }
  395. // Check if file name isn't too long
  396. $passLength = file_validate_name_length($file);
  397. if (!empty($passLength)) {
  398. $e = reset($passLength);
  399. return;
  400. }
  401. // Check if file meet the resolution restrictions
  402. $passRes = file_validate_image_resolution($file, $settings['max_resolution'], $settings['min_resolution']);
  403. if (!empty($passRes)) {
  404. $e = reset($passRes);
  405. return;
  406. }
  407. }
  408. }
  409. /*********************************************
  410. * FIELD WIDGET
  411. ********************************************/
  412. /**
  413. * _field_widget_info
  414. */
  415. function plup_field_widget_info() {
  416. return array(
  417. 'image_plupload' => array(
  418. 'label' => t('Plupload'),
  419. 'field types' => array('image'),
  420. 'behaviors' => array(
  421. 'multiple values' => FIELD_BEHAVIOR_CUSTOM,
  422. 'default value' => FIELD_BEHAVIOR_NONE,
  423. ),
  424. ),
  425. );
  426. }
  427. /**
  428. * _field_widget_settings_form
  429. */
  430. function plup_field_widget_settings_form($field, $instance) {
  431. $styles = array();
  432. foreach (image_styles() as $name => $style) {
  433. $styles[$name] = $style['name'];
  434. }
  435. $form['image_style'] = array(
  436. '#type' => 'select',
  437. '#title' => t('Image style'),
  438. '#default_value' => isset($instance['widget']['settings']['image_style']) ? $instance['widget']['settings']['image_style'] : 'thumbnail',
  439. '#options' => $styles
  440. );
  441. return $form;
  442. }
  443. /**
  444. * _field_widget_form
  445. */
  446. function plup_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) {
  447. $parents = array_merge(array('values', $element['#field_name'], $element['#language']), $element['#field_parents']);
  448. $state_data = drupal_array_get_nested_value($form_state, $parents);
  449. if (isset($state_data)) {
  450. $default_values = $state_data;
  451. } else if (isset($items)) {
  452. $default_values = $items;
  453. } else {
  454. $default_values = array();
  455. }
  456. // We inform user about restrictions
  457. $info = array();
  458. if ($field['cardinality'] > 0) {
  459. $info[] = '<div>'. t("You can upload up to !num files.", array('!num' => '<strong>'. $field['cardinality'] .'</strong>')) .'</div>';
  460. }
  461. if (isset($instance['settings']['max_filesize']) && !empty($instance['settings']['max_filesize'])) {
  462. $info[] = '<div>'. t("Maximal file size: !size", array('!size' => '<strong>'. $instance['settings']['max_filesize'] .'</strong>')) .'</div>';
  463. }
  464. $info[] = '<div>'. t("Allowed files types: !types.", array('!types' => '<strong>'. $instance['settings']['file_extensions'] .'</strong>')) .'</div>';
  465. $max = $instance['settings']['max_resolution'];
  466. $min = $instance['settings']['min_resolution'];
  467. if ($min && $max && $min == $max) {
  468. $info[] = '<div>'. t('Images must be exactly !size pixels.', array('!size' => '<strong>' . $max . '</strong>')) .'</div>';
  469. }
  470. elseif ($min && $max) {
  471. $info[] = '<div>'. t('Images must be between !min and !max pixels.', array('!min' => '<strong>' . $min . '</strong>', '!max' => '<strong>' . $max . '</strong>')) .'</div>';
  472. }
  473. elseif ($min) {
  474. $info[] = '<div>'. t('Images must be larger than !min pixels.', array('!min' => '<strong>' . $min . '</strong>')) .'</div>';
  475. }
  476. elseif ($max) {
  477. $info[] = '<div>'. t('Images must be smaller than !max pixels.', array('!max' => '<strong>' . $max . '</strong>')) .'</div>';
  478. }
  479. $images = array(
  480. '#type' => 'plupload_file',
  481. '#default_value' => $default_values,
  482. '#info' => $info
  483. );
  484. // Allowed file types(extensions) needs to be set here
  485. $ext = new stdClass();
  486. $ext->title = 'Allowed extensions'; // This won't show up anywhere so no t()
  487. $ext->extensions = (isset($instance['settings']['file_extensions']) && !empty($instance['settings']['file_extensions'])) ? strtr($instance['settings']['file_extensions'], ' ', ',') : 'jpg,png,gif';
  488. $images['#plup_override']['filters'] = array($ext);
  489. // Maximal file size
  490. if (isset($instance['settings']['max_filesize']) && !empty($instance['settings']['max_filesize'])) {
  491. $images['#plup_override']['max_file_size'] = $instance['settings']['max_filesize'];
  492. }
  493. // URL callback for Plupload library has to be altered so we can get instance ID for later validation
  494. $images['#plup_override']['url'] = url('plupload/'. $instance['id'], array('query' => array('plupload_token' => drupal_get_token('plupload-handle-uploads'))));
  495. // We set image style to present uploaded images in Plupload widget
  496. $images['#plup_override']['image_style'] = isset($instance['widget']['settings']['image_style']) ? $instance['widget']['settings']['image_style'] : 'thumbnail';
  497. // We set if we want to enable title and alt fields for images
  498. $images['#plup_override']['alt_field'] = (int) $instance['settings']['alt_field'];
  499. $images['#plup_override']['title_field'] = (int) $instance['settings']['title_field'];
  500. // We set the maximum files user can upload
  501. $images['#plup_override']['max_files'] = (int) $field['cardinality'];
  502. $element += $images;
  503. return $element;
  504. }
  505. /**
  506. * _field_attach_presave
  507. * Somehow Drupal 7 doesn't have proper field hooks so we have to use
  508. * this big global hook so we can move files to their desiganted folder
  509. * because image module won't pick on #upload_location attribute(don't know why yet).
  510. * We also rename files back to their original name.
  511. */
  512. function plup_field_attach_presave($entity_type, $entity) {
  513. $entityInfo = entity_get_info($entity_type);
  514. $bundleKey = (isset($entityInfo['entity keys']['bundle']) && !empty($entityInfo['entity keys']['bundle'])) ? $entityInfo['entity keys']['bundle'] : $entity_type;
  515. $bundle = isset($entity->{$bundleKey}) ? $entity->{$bundleKey} : $entity_type;
  516. $instances = field_info_instances();
  517. $entityFields = $instances[$entity_type][$bundle];
  518. if (!is_array($entityFields) || empty($entityFields)) {
  519. return;
  520. }
  521. foreach ($entityFields AS $field_name => $instance) {
  522. if ($instance['widget']['type'] == 'image_plupload' && $instance['widget']['module'] == 'plup') {
  523. $items = field_get_items($entity_type, $entity, $field_name);
  524. if ($items && $items[0]['fid'] > 0) {
  525. $field = field_info_field($instance['field_name']);
  526. $destination = file_field_widget_uri($field, $instance);
  527. foreach ($items AS $delta => $item) {
  528. $file = file_load($item['fid']);
  529. // Filefield paths integration
  530. if (module_exists('filefield_paths') && isset($item['rename'])) {
  531. $file->origname = $item['rename'];
  532. file_save($file);
  533. } else {
  534. $fileName = isset($item['rename']) ? $item['rename'] : $file->filename;
  535. $dir = isset($instance['settings']['file_directory']) ? $instance['settings']['file_directory'] .'/' : '';
  536. $location = token_replace($field['settings']['uri_scheme'] .'://'. $dir);
  537. $filePath = $location . $fileName;
  538. if ($file->uri !== $filePath) {
  539. file_prepare_directory($location, FILE_CREATE_DIRECTORY);
  540. file_move($file, $filePath);
  541. }
  542. }
  543. }
  544. }
  545. }
  546. }
  547. }