Squiz Matrix  4.12.2
 All Data Structures Namespaces Functions Variables Pages
file_edit_fns.inc
1 <?php
17 require_once SQ_INCLUDE_PATH.'/asset_edit/asset_edit_fns.inc';
18 require_once SQ_FUDGE_PATH.'/general/text.inc';
19 
32 {
33 
34 
39  function File_Edit_Fns()
40  {
41  parent::__construct();
42  $this->static_screens['details']['lock_type'] = 'attr_links';
43  unset($this->static_screens['lookupValues']);
44 
45  }//end constructor
46 
47 
58  function paintFilename(&$asset, &$o, $prefix)
59  {
60  $wa = $asset->writeAccess('attributes');
61  if ($wa) {
62  text_box($prefix.'_filename', $asset->attr('name'), 25);
63  } else {
64  echo $asset->attr('name');
65  }
66  return $wa;
67 
68  }//end paintFilename()
69 
70 
81  function processFilename(&$asset, &$o, $prefix)
82  {
83  $wa = $asset->writeAccess('attributes');
84  $submitted = isset($_REQUEST[$prefix.'_filename']) && !empty($_REQUEST[$prefix.'_filename']);
85  $process = $wa && $submitted;
86 
87  if ($process) {
88  $info = get_file_upload_info($prefix);
89 
90  // if the user is uploading the file, do not process the name
91  if ($info !== FALSE && !empty($info)) {
92  return FALSE;
93  }
94 
95  if ($asset->name != $_REQUEST[$prefix.'_filename']) {
96  $info = Array();
97  $info['name'] = $_REQUEST[$prefix.'_filename']; // Asset new filename
98  $info['tmp_name'] = $asset->data_path.'/'.$asset->name; // Source file new
99  $info['non_uploaded_file'] = TRUE; // Specify that file is already uploaded.
100  $info['setting_filename'] = TRUE; // Tell the function that we are in setting the file name process.
101  if (!$this->processFileUpload($asset, $o, $prefix, $info)) {
102  return TRUE;
103  }
104  }
105  }
106 
107  return $process;
108 
109  }//end processFilename()
110 
111 
122  public function paintFileUpload(File $asset, Backend_Outputter $o, $prefix)
123  {
124  // We redirect the header frame to the new location only if
125  // we are in limbo, the file name has been changed and allow_unrestricted is false.
126  // If allow_unrestricted is true, the asset is identified by limbo_assetid GET var
127  if (SQ_IN_LIMBO) {
128  if (!empty($_REQUEST['redirect_header'])) {
129  $url = strip_url($asset->getUrl()).'/'.SQ_CONF_LIMBO_SUFFIX
130  .'?SQ_BACKEND_PAGE=header'
131  .'&current_assetid='.$asset->id
132  .'&sq_popups_blocked=0';
133  ?>
134  <script type="text/javascript">
135  if (parent.frames["sq_header"]) {
136  lock_type = parent.frames["sq_main"].get_form_element_value('sq_lock_type');
137  parent.frames["sq_header"].location = "<?php echo $url ?>" + "&sq_lock_type=" + lock_type;
138  }
139  </script>
140  <?php
141  }
142  }
143  require_once SQ_FUDGE_PATH.'/general/file_system.inc';
144  $options = $this->getPreuploadOptions($asset);
145  echo '<div id="'.$prefix.'_file_pre_upload" style="display:none;">';
146  combo_box($prefix.'_server_file', Array(''=>'')+$options, FALSE, Array());
147  echo '&nbsp;&nbsp;';
148  normal_button($prefix.'_simple_upload_button', translate('core_upload_new_file_button'), 'document.getElementById(\''.$prefix.'_file_pre_upload\').style.display=\'none\';
149  document.getElementById(\''.$prefix.'_choose_server_file_button\').parentNode.style.display=\'\'; document.getElementById(\''.$prefix.'_server_file\').value = \'\'');
150  echo '</div>';
151 
152  if ($asset->writeAccess('attributes')) {
153  echo '<div id="'.$prefix.'_file_upload">';
154  file_upload($prefix);
155  if ($this->havePreUploadedFiles($asset, $prefix)) {
156  echo '&nbsp;&nbsp;';
157  normal_button($prefix.'_choose_server_file_button', translate('core_upload_server_file_button'),
158  'document.getElementById(\''.$prefix.'_file_upload\').style.display=\'none\';
159  document.getElementById(\''.$prefix.'_simple_upload_button\').parentNode.style.display=\'\'');
160  }
161  }
162 
163  $this->printExistingFileInfo($asset);
164  if ($asset->writeAccess('attributes')) {
165  $max_size = strtolower($GLOBALS['SQ_SYSTEM']->getUserPrefs('file', 'SQ_FILE_MAX_SIZE'));
166  if ($max_size) {
167  if (substr($max_size, -1) == 'k') {
168  $max_size = $max_size * 1024;
169  } else if (substr($max_size, -1) == 'm') {
170  $max_size = $max_size * 1024 * 1024;
171  }
172  } else {
173  // work out the max file size that PHP is allowing
174  $ini_size = strtolower(ini_get('upload_max_filesize'));
175  if (substr($ini_size, -1) == 'k') {
176  $ini_size = $ini_size * 1024;
177  } else if (substr($ini_size, -1) == 'm') {
178  $ini_size = $ini_size * 1024 * 1024;
179  }
180 
181  // work out the max post size that PHP is allowing
182  $post_size = strtolower(ini_get('post_max_size'));
183  if (substr($post_size, -1) == 'k') {
184  $post_size = $post_size * 1024;
185  } else if (substr($post_size, -1) == 'm') {
186  $post_size = $post_size * 1024 * 1024;
187  }
188 
189  $mem_limit_size = strtolower(ini_get('memory_limit'));
190  if (substr($mem_limit_size, -1) == 'k') {
191  $mem_limit_size = $mem_limit_size * 1024;
192  } else if (substr($mem_limit_size, -1) == 'm') {
193  $mem_limit_size = $mem_limit_size * 1024 * 1024;
194  }
195  $max_size = min($ini_size, $post_size, $mem_limit_size);
196  }
197  ?><br/><span style="font-size: 10px;"><?php echo translate('core_cannot_upload_file_larger_than', strtoupper(easy_filesize($max_size))); ?></span><?php
198  if (!empty($asset->allowed_extensions)) {
199  $o->note(translate('core_only_upload_files_of_type', make_readable_list($asset->allowed_extensions, strtolower(translate('and')))));
200  }
201  echo '</div>';
202  }//end if
203 
204  return TRUE;
205 
206  }//end paintFileUpload()
207 
208 
221  public function processFileUploadPreUpload(File $asset, $o, $prefix, Array $info=Array(), $redirect_in_limbo=TRUE) {
222  $processed = FALSE;
223 
224  if (isset($_POST[$prefix.'_server_file']) && empty($_POST[$prefix.'_server_file'])){
225  $processed = $this->processFileUpload($asset, $o, $prefix, $info);
226  } else {
227  $processed = $this->processFileChooser($asset, $o, $prefix);
228  }
229 
230  return $processed;
231 
232  }//end processFileUploadPreUpload()
233 
234 
259  public function processFileUpload(File $asset, &$o, $prefix, Array $info=Array(), $redirect_in_limbo=TRUE, $asset_cloned=FALSE)
260  {
261  if (!$asset->writeAccess('attributes')) return FALSE;
262  if (empty($info) && isset($_POST[$prefix.'_server_file']) && !empty($_POST[$prefix.'_server_file'])) {
263  return FALSE;
264  }
265 
266  // assetid will not be set if we are creating
267  if (!$asset->id) return TRUE;
268 
269  if (empty($info)) {
270  $info = get_file_upload_info($prefix);
271  // return on failed or no upload
272  if ($info === FALSE || empty($info)) {
273  return FALSE;
274  }//end if
275  }//end if
276 
277  // make the info array look like a result from getExistingFile()
278  if (!isset($info['path'])) {
279  $info['path'] = array_get_index($info, 'tmp_name', '');
280  }//end if
281 
282  if (!isset($info['filename'])) {
283  $info['filename'] = array_get_index($info, 'name', '');
284  }//end if
285 
286  $setting_filename = FALSE;
287  if (isset($info['setting_filename'])) {
288  $setting_filename = array_get_index($info, 'setting_filename', FALSE);
289  }//end if
290 
291  if (!$asset->validFile($info)) return FALSE;
292 
293  // Check for a virus
294  if (isset($info['path']) && !empty($info['path'])) {
295  $status = $asset->scanFile($info['path']);
296  // If infected, remove and warn the user
297  if (!$status) {
298  trigger_localised_error('CORE0300', E_USER_WARNING, $info['filename']);
299  return FALSE;
300  }//end if
301  }//end if
302 
303  require_once SQ_INCLUDE_PATH.'/general_occasional.inc';
304  $name = current(make_valid_web_paths(Array($info['name'])));
305 
306  // make sure the new web path is not already in use
307  if (!defined('SQ_IN_IMPORT') && $asset->name != $name) {
308  $parents = $GLOBALS['SQ_SYSTEM']->am->getLinks($asset->id, SQ_SC_LINK_SIGNIFICANT, '', NULL, 'minor');
309  for ($i = 0; $i < count($parents); $i++) {
310  $parent = $GLOBALS['SQ_SYSTEM']->am->getAsset($parents[$i]['majorid'], $parents[$i]['major_type_code']);
311  if (is_null($parent)) continue;
312  $bad_paths = $GLOBALS['SQ_SYSTEM']->am->webPathsInUse($parent, Array($name), $asset->id);
313  if (!empty($bad_paths)) {
314  trigger_localised_error('CORE0055', E_USER_WARNING, $name);
315  return FALSE;
316  }//end if
317  }//end if
318  }//end if
319 
320  // create the destination directory, if necessary (NOTE that checking is internal for this)
321  create_directory($asset->data_path);
322 
323 
325 
326  $fv = $GLOBALS['SQ_SYSTEM']->getFileVersioning();
327  $existing = $asset->getExistingFile();
328 
329  if ($setting_filename === TRUE) {
330  $this->getNewFile($asset, $name, $info);
331  $this->removeOldFile($asset, $existing, $fv);
332  } else {
333  if ($asset->name != $name && !empty($existing)) {
334  $this->removeOldFile($asset, $existing, $fv);
335  }
336  $this->getNewFile($asset, $name, $info);
337  }
338 
339  // if we are overwriting our current file with one that has the same name,
340  // we need to add a new version of the file to the repository
341  if ($asset->name == $name && !empty($existing)) {
342  $file_status = $fv->upToDate($asset->data_path.'/'.$name);
343  if (FUDGE_FV_MODIFIED & $file_status) {
344  if (!$fv->commit($asset->data_path.'/'.$name, '')) {
345  trigger_localised_error('CORE0034', E_USER_WARNING);
346  return FALSE;
347  }//end if
348  }//end if
349  } else {
350  // attempt to add the file to the repository
351  if (!$fv->add($asset->data_path_suffix, $asset->data_path.'/'.$name, '')) {
352  trigger_localised_error('CORE0026', E_USER_WARNING);
353  return FALSE;
354  }//end if
355  }//end else
356 
357  // make sure we have the latest version of our file
358  if (!$fv->checkOut($asset->data_path_suffix.'/'.$name, $asset->data_path)) {
359  trigger_localised_error('CORE0032', E_USER_WARNING);
360  return FALSE;
361  }//end if
362 
363  // set the name of the file to the newly uploaded one
364  $asset->_tmp['uploading_file'] = TRUE;
365  $name_changed = $asset->setAttrValue('name', $name);
366  if (!$asset->saveAttributes()) {
367  trigger_localised_error('CORE0052', E_USER_WARNING);
368  return FALSE;
369  }//end if
370  $asset->_tmp['uploading_file'] = FALSE;
371 
372  // bug fix for # 3625. If we cloning an asset then we need not call saveWebPaths now
373  // hipo_job_clone_asset will call saveWebPaths after it is sure the links have been established
374  $rm = $GLOBALS['SQ_SYSTEM']->am->getSystemAsset('remap_manager');
375  $auto_add_remaps = $rm->attr('remap_upon_webpath_change');
376  if (!defined('SQ_IN_IMPORT') && !($asset_cloned) && !($asset->saveWebPaths(Array($name),$auto_add_remaps))) {
377  trigger_localised_error('CORE0054', E_USER_WARNING);
378  return FALSE;
379  }//end if
380 
381  if (SQ_IN_LIMBO && $name_changed && $redirect_in_limbo) {
382  // if we are in limbo and the name of the file has changed, the URL will also change
383  // so we need to redirect to the new limbo URL
384  if (!$asset->attr('allow_unrestricted')) {
385  $o->setRedirect(strip_url($asset->getUrl()).'/'.SQ_CONF_LIMBO_SUFFIX.'?redirect_header=1');
386  }//end if
387  }//end if
388 
389  $em = $GLOBALS['SQ_SYSTEM']->getEventManager();
390  $em->broadcastEvent($asset, 'ContentsUpdated');
391 
392  return $asset->_updated();
393 
394  }//end processFileUpload()
395 
396 
411  public function processFileChooser(File $asset, $o, $prefix, $create=FALSE)
412  {
413  // Unless explicitly told otherwise, don't do anything if the asset is not yet completely created
414  if (!$create && (empty($asset->id) || array_get_index($asset->_tmp, '__creating__'))) {
415  return TRUE;
416  }
417 
418  if ($asset->writeAccess('attributes') && isset($_POST[$prefix.'_server_file']) && (!empty($_POST[$prefix.'_server_file']))) {
419  $info = $this->getChosenFileInfo($prefix);
420  if ($this->processFileUpload($asset, $o, $prefix, $info)) {
421  unlink($info['tmp_name']);
422  return TRUE;
423  }
424  }
425  return FALSE;
426 
427  }//end processFileChooser()
428 
429 
439  protected function havePreUploadedFiles(File $asset, $prefix)
440  {
441  $preuploads = $this->getPreuploadOptions($asset);
442  return !empty($preuploads);
443 
444  }//end havePreUploadedFiles()
445 
446 
447 //-- HELPERS --//
448 
449 
461  protected function getPreuploadOptions(File $asset)
462  {
463  $options = Array();
464  foreach (list_files(SQ_TEMP_PATH) as $filename) {
465  if (substr($filename, 0, 1) == '.') continue;
466  $options[$filename] = $filename;
467  }
468  return $options;
469 
470  }//end getPreuploadOptions()
471 
472 
483  public function removeOldFile(File $asset, &$existing, File_Versioning $fv)
484  {
485  // a new file with a new name means we need to remove the old
486  // one from the repository (NOTE that this doesnt actually 'remove' the
487  // files from the repository - just marks the branch as complete)
488  // If we are setting filename then don't remove the file yet
489  $result = $fv->remove($existing['path'], '');
490  if ($result != FUDGE_FV_OK && $result != FUDGE_FV_NOT_CHECKED_OUT) {
491  trigger_localised_error('CORE0042', E_USER_WARNING);
492  return FALSE;
493  }//end if
494 
495  // remove the old copy in the public directory (bug#1370)
496  if ($asset->usePublicPath()) {
497  $unrestricted = $asset->data_path_public.'/'.$existing['filename'];
498  if (file_exists($unrestricted)) {
499  $fv->clearOut($unrestricted);
500  }//end if
501  }//end if
502 
503  }//end removeOldFile()
504 
505 
516  public function getNewFile(File $asset, $name, Array $info)
517  {
518  // copy over the new uploaded file
519  if (is_uploaded_file($info['tmp_name'])) {
520  // a normal uploaded file
521  if (!move_uploaded_file($info['tmp_name'], $asset->data_path.'/'.$name)) {
522  trigger_localised_error('CORE0037', E_USER_WARNING, $info['tmp_name'], $asset->data_path.'/'.$name);
523  return FALSE;
524  }//end if
525  } else if (isset($info['non_uploaded_file']) && $info['non_uploaded_file'] === TRUE) {
526  // we have special permission to move a non-uploaded file
527  if (!copy($info['tmp_name'], $asset->data_path.'/'.$name)) {
528  trigger_localised_error('CORE0036', E_USER_WARNING, $info['tmp_name'], $asset->data_path.'/'.$name);
529  return FALSE;
530  }//end if
531  } else if (isset($info['created_file']) && $info['created_file'] === TRUE) {
532  // when empty file is created by matrix when no file is uploaded
533  if (!rename($info['tmp_name'].'/'.$name, $asset->data_path.'/'.$name)) {
534  trigger_localised_error('CORE0036', E_USER_WARNING, $info['tmp_name'], $asset->data_path.'/'.$name);
535  return FALSE;
536  }//end if
537 
538  } else {
539  trigger_localised_error('CORE0067', E_USER_ERROR);
540  return FALSE;
541  }
542 
543  }//end getNewFile()
544 
545 
554  public function getChosenFileInfo($prefix)
555  {
556  $info = Array();
557  if (isset($_POST[$prefix.'_server_file']) && (!empty($_POST[$prefix.'_server_file']))) {
558  $filename = trim($_POST[$prefix.'_server_file'], './');
559  $info['name'] = $filename;
560  $info['tmp_name'] = SQ_TEMP_PATH.'/'.$filename;
561  $info['non_uploaded_file'] = TRUE;
562  }
563  return $info;
564 
565  }//end getChosenFileInfo()
566 
567 
576  public function printExistingFileInfo(File $asset)
577  {
578  $existing = $asset->getExistingFile();
579  if (!empty($existing)) {
580  require_once SQ_FUDGE_PATH.'/general/datetime.inc';
581  ?>
582  <div>
583  <b><a href="<?php echo current_url(TRUE, TRUE).'?a='.$asset->id?>&now=<?php echo time()?>" target="_blank"><?php echo translate('core_current_file'); ?></a></b><br/>
584  <b><?php echo translate('info'); ?>:</b> <?php echo get_asset_tag_line($asset->id); ?><br/>
585  <b><?php echo translate('size'); ?>:</b> <?php echo easy_filesize($existing['size'])?><br/>
586  <b><?php echo translate('updated'); ?>:</b> <?php echo readable_datetime($existing['modified'])?>
587  </div>
588  <?php
589  }
590 
591  }//end printExistingFileInfo()
592 
593 
594 }//end class
595 
596 ?>