Squiz Matrix  4.12.2
 All Data Structures Namespaces Functions Variables Pages
file.inc
1 <?php
18 require_once SQ_INCLUDE_PATH.'/asset.inc';
19 require_once SQ_FUDGE_PATH.'/general/file_system.inc';
20 
32 class File extends Asset
33 {
34 
35 
40  public $allowed_extensions = Array();
41 
42 
47  public $ignore_update = FALSE;
48 
49 
56  function File($assetid=0)
57  {
58  parent::__construct($assetid);
59 
60  }//end constructor
61 
62 
73  protected function _preCreateCheck(Array &$link)
74  {
75  if (!parent::_preCreateCheck($link)) return FALSE;
76 
77  $name = trim($this->attr('name'));
78  if ($name == '') {
79  trigger_localised_error('CORE0083', E_USER_WARNING, $GLOBALS['SQ_SYSTEM']->am->getTypeInfo($this->type(), 'name'));
80  return FALSE;
81  }
82 
83  return TRUE;
84 
85  }//end _preCreateCheck()
86 
87 
98  public function create(Array &$link, $info=Array())
99  {
100  $this->_tmp['file_create_data'] =& $info;
101 
102  if (empty($info)) {
103  // Try getting the uploaded file details
104  $info = get_file_upload_info($this->getPrefix(), isset($info['non_uploaded_file']) && $info['non_uploaded_file']);
105  }
106 
107  if ($info === FALSE || empty($info)) {
108  // See if they've chosen a pre-uploaded file
109  $edit = $this->getEditFns();
110  $info = $edit->getChosenFileInfo($this->getPrefix());
111  }
112 
113  if ($GLOBALS['SQ_SYSTEM']->runLevelEnables(SQ_SECURITY_DATA_VALIDATION)) {
114  if ($info === FALSE || empty($info)) {
115  trigger_localised_error('CORE0056', E_USER_WARNING, $GLOBALS['SQ_SYSTEM']->am->getTypeInfo($this->type(), 'name'));
116  return FALSE;
117  }
118  }
119 
120  // Make the info array look like a result from getExistingFile()
121  if (!isset($info['path'])) {
122  $info['path'] = array_get_index($info, 'tmp_name', '');
123  }
124  if (!isset($info['filename'])) {
125  $info['filename'] = array_get_index($info, 'name', '');
126  }
127 
128  if ($GLOBALS['SQ_SYSTEM']->runLevelEnables(SQ_SECURITY_DATA_VALIDATION)) {
129  if (!$this->validFile($info)) return FALSE;
130  }
131 
132  if ($GLOBALS['SQ_SYSTEM']->runLevelEnables(SQ_SECURITY_DATA_VALIDATION)) {
133  // Check that we are not going to have web path conflicts
134  require_once SQ_INCLUDE_PATH.'/general_occasional.inc';
135  $valid_names = make_valid_web_paths(Array($info['name']));
136  $name = array_shift($valid_names);
137 
138  // Make sure the new web path is not already is use
139  if (!defined('SQ_IN_IMPORT')) {
140  $bad_paths = $GLOBALS['SQ_SYSTEM']->am->webPathsInUse($link['asset'], Array($name));
141  if (!empty($bad_paths)) {
142  trigger_localised_error('CORE0086', E_USER_WARNING, $name);
143  return FALSE;
144  }
145  }
146 
147  $this->setAttrValue('name', $name);
148  //creating the asset? set the allow_unrestricted to true ...which is default value anyways
149  if (!isset($this->_tmp['vars_set']['allow_unrestricted'])) $this->setAttrValue('allow_unrestricted', TRUE);
150 
151  }//end if
152 
153  return parent::create($link);
154 
155  }//end create()
156 
157 
168  protected function _createAdditional(Array &$link)
169  {
170  // Save return value of acquireLock(), if it is 1 then lock was newly acquired
171  // and we have to give it back at the end, if it is 2 then it's already taken
172  // and we should leave it be
173  if (!$lock_held = $GLOBALS['SQ_SYSTEM']->am->acquireLock($this->id, 'attributes')) {
174  return FALSE;
175  }
176 
177  $edit = $this->getEditFns();
178 
179  // we need to fudge a few attributes to make sure we can
180  // process the file upload in the middle of creation
181  $this->_tmp['uploading_file'] = 1;
182  $prefix = $this->type().'_0';
183  $o = NULL;
184  if ((!is_null($GLOBALS['SQ_SYSTEM']->backend)) && (!is_null($GLOBALS['SQ_SYSTEM']->backend->out))) {
185  $o = $GLOBALS['SQ_SYSTEM']->backend->out;
186  }
187  $info = $this->_tmp['file_create_data'];
188 
189  $ret_val = $edit->processFileChooser($this, $o, $prefix, TRUE) || $edit->processFileUpload($this, $o, $prefix, $info, FALSE);
190 
191  $this->saveAttributes();
192 
193  if ($lock_held == 1) {
194  $GLOBALS['SQ_SYSTEM']->am->releaseLock($this->id, 'attributes');
195  }
196 
197  return $ret_val;
198 
199  }//end _createAdditional()
200 
201 
210  public function createAdditional(Array &$link)
211  {
212  return $this->_createAdditional($link);
213 
214  }//end createAdditional()
215 
216 
242  public function cloneComponents(Asset $clone, Array $components, $override=FALSE)
243  {
244  // create some information so we know where to clone the file from
245  $temp_info = Array('name' => $this->name, 'tmp_name' => $this->data_path.'/'.$this->name, 'non_uploaded_file' => TRUE);
246 
247  $edit_fns = $clone->getEditFns();
248  // fix for bug 3625:
249  // we make sure to tell the processFileChooser function that we are cloning and not creating new asset
250  if (!$edit_fns->processFileUpload($clone, $GLOBALS['SQ_SYSTEM']->backend->out, $clone->getPrefix(), $temp_info,TRUE, TRUE)) {
251  trigger_localised_error('CORE0010', E_USER_WARNING, $this->name, $this->id);
252  return FALSE;
253  }
254 
255  return parent::cloneComponents($clone, $components, $override);
256 
257  }//end cloneComponents()
258 
259 
266  public function lockTypes()
267  {
268  $lock_types = parent::lockTypes();
269  $lock_types['attr_links'] = ($lock_types['attributes'] | $lock_types['links']);
270  return $lock_types;
271 
272  }//end lockTypes()
273 
274 
282  public function saveSystemVersion()
283  {
284  require_once SQ_FUDGE_PATH.'/general/file_system.inc';
285 
286  // make sure our data directory exists
287  if (!create_directory($this->data_path)) {
288  trigger_localised_error('CORE0049', E_USER_WARNING, $this->name);
289  return FALSE;
290  }
291 
292  // make sure our system directory exists
293  if (!create_directory($this->data_path.'/.sq_system')) {
294  trigger_localised_error('CORE0050', E_USER_WARNING, $this->name);
295  return FALSE;
296  }
297 
298  // make sure there is nothing in the system directory
299  if (!clear_directory($this->data_path.'/.sq_system')) {
300  trigger_localised_error('CORE0046', E_USER_WARNING, $this->name);
301  return FALSE;
302  }
303 
304  // save the object for later (in the restricted directory)
305  if (!string_to_file(serialize($this), $this->data_path.'/.sq_system/.object_data')) {
306  trigger_localised_error('CORE0051', E_USER_WARNING, $this->name);
307  return FALSE;
308  }
309 
310  $contexts = $GLOBALS['SQ_SYSTEM']->getAllContexts();
311  foreach ($contexts as $contextid => $context_data) {
312  if ($contextid === 0) {
313  $files_to_copy = Array('metadata.php', 'metadata_field_values.php');
314  } else {
315  $files_to_copy = Array('metadata.'.$contextid.'.php', 'metadata_field_values.'.$contextid.'.php');
316  }
317  foreach ($files_to_copy as $filename) {
318  if (file_exists($this->data_path.'/'.$filename) === TRUE) {
319  if (!copy_file($this->data_path.'/'.$filename, $this->data_path.'/.sq_system/'.$filename)){
320  trigger_localised_error('SYS0166', E_USER_WARNING, $this->name, $filename);
321  return FALSE;
322  }
323  }
324  }
325  }
326 
327  // update our lookup tables to not use __data
328  if (!parent::updateLookups()) {
329  trigger_localised_error('CORE0053', E_USER_WARNING, $this->name);
330  $GLOBALS['SQ_SYSTEM']->doTransaction('ROLLBACK');
331  $GLOBALS['SQ_SYSTEM']->restoreDatabaseConnection();
332  return FALSE;
333  }
334  // still insert the __data url for safe edit
335  if($this->attr('allow_unrestricted') && $this->effectiveUnrestricted()) {
336  if(!$this->insertDataLookup()) {
337  trigger_localised_error('CORE0053', E_USER_WARNING, $this->name);
338  $GLOBALS['SQ_SYSTEM']->doTransaction('ROLLBACK');
339  $GLOBALS['SQ_SYSTEM']->restoreDatabaseConnection();
340  return FALSE;
341  }
342  }
343 
344  // store the current version of the file
345  $fv = $GLOBALS['SQ_SYSTEM']->getFileVersioning();
346  $file_info = $fv->_checkOutCheck($this->data_path_suffix.'/'.$this->name);
347  $latest_version = $file_info['version'];
348  if (!string_to_file($latest_version, $this->data_path.'/.sq_system/sq_system_version_no')) {
349  trigger_localised_error('CORE0051', E_USER_WARNING, $this->name);
350  return FALSE;
351  }
352 
353  return TRUE;
354 
355  }//end saveSystemVersion()
356 
357 
364  public function revertToSystemVersion()
365  {
366  // get the safe edit file name before it's lost
367  $se_name = $this->attr('name');
368 
369  // pretend we are uploading a file because we may be changing the name of the file
370  // and we want to fool setAttributeValue
371  $this->_tmp['uploading_file'] = TRUE;
372  if (!parent::revertToSystemVersion()) {
373  $this->_tmp['uploading_file'] = FALSE;
374  return FALSE;
375  }
376  $this->_tmp['uploading_file'] = FALSE;
377 
378  require_once SQ_FUDGE_PATH.'/general/file_system.inc';
379 
380  $file_version = NULL;
381  if (is_file($this->data_path.'/sq_system_version_no')) {
382  $file_version = file_to_string($this->data_path.'/sq_system_version_no');
383  }
384 
385  // clear the private data directory to get rid of the new uploaded file we had there
386  // but we should not clear the meta data files (see Bug #4460)
387  if (!clear_directory($this->data_path, Array('metadata.php', 'metadata_field_values.php'))){
388  trigger_localised_error('CORE0045', E_USER_WARNING, $this->name);
389  return FALSE;
390  }
391 
392  $fv = $GLOBALS['SQ_SYSTEM']->getFileVersioning();
393 
394  // we want to remove the safe edit file name from the repository because
395  // there's a chance someone will try and use that name later
396  if ($this->attr('name') != $se_name) {
397  $se_rep_path = $this->data_path_suffix.'/'.$se_name;
398  $result = $fv->remove($se_rep_path, '');
399  if ($result != FUDGE_FV_OK && $result != FUDGE_FV_NOT_CHECKED_OUT) {
400  trigger_localised_error('CORE0042', E_USER_WARNING);
401  return FALSE;
402  }
403  $removed_file_info = $fv->_checkOutCheck($se_rep_path);
404  $fv->_updateFile($removed_file_info['fileid'], $this->data_path_suffix, $this->data_path.'/'.$se_name);
405  }
406 
407  // check out the old version of the file into the private data directory
408  $rep_path = $this->data_path_suffix.'/'.$this->name;
409  if (!$fv->checkOut($rep_path, $this->data_path, $file_version)) {
410  trigger_localised_error('CORE0044', E_USER_WARNING, $this->name);
411  return FALSE;
412  }
413 
414  // create a new versioning entry for the old version
415  $file_info = $fv->_checkOutCheck($rep_path, $file_version);
416  $fv->_updateFile($file_info['fileid'], $this->data_path_suffix, $this->data_path.'/'.$this->name);
417 
418  // check out the new version
419  if (!$fv->checkOut($rep_path, $this->data_path)) {
420  trigger_localised_error('CORE0044', E_USER_WARNING, $this->name);
421  return FALSE;
422  }
423 
424  return TRUE;
425 
426  }//end revertToSystemVersion()
427 
428 
435  public function clearSystemVersion()
436  {
437  require_once SQ_FUDGE_PATH.'/general/file_system.inc';
438 
439  // Bug #5084: After safe edit, old files remain in public data directory.
440  // So clean it out, latest version will be checked out from _checkFileState() function.
441  // make sure our data directory exists
442  if (!create_directory($this->data_path_public)) {
443  trigger_localised_error('CORE0049', E_USER_WARNING, $this->name);
444  return FALSE;
445  }
446 
447  if (!clear_directory($this->data_path_public)) {
448  trigger_localised_error('CORE0305', E_USER_WARNING, $this->name);
449  return FALSE;
450  }
451 
452  return parent::clearSystemVersion();
453 
454  }//end clearSystemVersion()
455 
456 
466  public function morph($new_type_code)
467  {
468  $am = $GLOBALS['SQ_SYSTEM']->am;
469 
470  $file_types = array_merge($am->getTypeAncestors($this->type(), FALSE), $am->getTypeDescendants($this->type()));
471 
472  if (in_array($new_type_code, $file_types)) {
473  // we are morphing into another file type, so check that the actual
474  // file currently uploaded is not going to conflict with the new type
475  $am->includeAsset($new_type_code);
476  $tmp = new $new_type_code();
477  $existing = $this->getExistingFile();
478  if (!empty($existing)) {
479  if (!$tmp->validFile($existing)) {
480  trigger_localised_error('CORE0008', E_USER_WARNING, $this->name, $new_type_code, $existing['filename'], $new_type_code);
481  return FALSE;
482  }
483 
484  $fv = $GLOBALS['SQ_SYSTEM']->getFileVersioning();
485  $fv->changeFvTypeCode($existing['path'], $new_type_code);
486  }
487  unset($tmp);
488  }
489 
490  return parent::morph($new_type_code);
491 
492  }//end morph()
493 
494 
505  public function processStatusChange($new_status, $update_parents=TRUE, $run_updated=TRUE)
506  {
507  // let ourselves know not to do any extra updating
508  $this->ignore_update = TRUE;
509 
510  // event data to be passed to the trigger action
511  $old_status = $this->status;
512  $this->_tmp['old_status'] = $old_status;
513  $this->_tmp['old_urls'] = $this->getURLs();
514  $this->_tmp['allow_unrestricted'] = $this->attr('allow_unrestricted');
515 
516  $GLOBALS['SQ_SYSTEM']->changeDatabaseConnection('db2');
517  $GLOBALS['SQ_SYSTEM']->doTransaction('BEGIN');
518 
519  if (!parent::processStatusChange($new_status, $update_parents, $run_updated)) {
520  $GLOBALS['SQ_SYSTEM']->doTransaction('ROLLBACK');
521  $GLOBALS['SQ_SYSTEM']->restoreDatabaseConnection();
522  return FALSE;
523  }
524 
525  // NOTE : no need to update the files states or the lookups here because they are done in _updated() if a file exists
526 
527  // update manually
528  $this->ignore_update = FALSE;
529  if (!$this->_updated()) {
530  $GLOBALS['SQ_SYSTEM']->doTransaction('ROLLBACK');
531  $GLOBALS['SQ_SYSTEM']->restoreDatabaseConnection();
532  return FALSE;
533  }
534 
535  $GLOBALS['SQ_SYSTEM']->doTransaction('COMMIT');
536  $GLOBALS['SQ_SYSTEM']->restoreDatabaseConnection();
537  return TRUE;
538 
539  }//end processStatusChange()
540 
541 
549  public function _getAllowedLinks()
550  {
551  return Array(
552  SQ_LINK_TYPE_1 => Array(),
553  SQ_LINK_TYPE_2 => Array(),
554  SQ_LINK_TYPE_3 => Array(),
555  SQ_LINK_NOTICE => Array(
556  'asset' => Array(
557  'card' => 'M',
558  'exclusive' => FALSE,
559  ),
560  ),
561  );
562 
563  }//end _getAllowedLinks()
564 
565 
580  public function _updated($update_parents=TRUE)
581  {
582  if (!parent::_updated($update_parents)) return FALSE;
583 
584  if ($this->ignore_update == TRUE) {
585  return TRUE;
586  }
587 
588  if($this->status & SQ_SC_STATUS_SAFE_EDITING) {
589  $this->updateLookups();
590  return TRUE;
591  }
592 
593  return $this->_checkFileState();
594 
595  }//end _updated()
596 
597 
605  public function permissionsUpdated()
606  {
607  if ($this->status & SQ_SC_STATUS_SAFE_EDITING) {
608  $this->updateLookups();
609  return TRUE; //don't touch public file in safe edit
610  }
611  return $this->_checkFileState();
612 
613  }//end permissionsUpdated()
614 
615 
622  protected function _checkFileState()
623  {
624 
625  if ($this->status & SQ_SC_STATUS_SAFE_EDITING) return TRUE; //don't touch public file in safe edit
626 
627  require_once SQ_FUDGE_PATH.'/general/file_system.inc';
628 
629  $existing = $this->getExistingFile();
630  if (empty($existing)) return TRUE;
631 
632  $unrestricted = $this->data_path_public.'/'.$existing['filename'];
633  $changed = FALSE;
634 
635  // if we should be storing our file in the public
636  // data directory for all the world to see
637  if ($this->effectiveUnrestricted() && $this->attr('allow_unrestricted')) {
638  // make sure our data directory exists
639  if (!create_directory($this->data_path_public)) {
640  trigger_localised_error('CORE0049', E_USER_WARNING, $this->name);
641  return FALSE;
642  }
643 
644  $fv = $GLOBALS['SQ_SYSTEM']->getFileVersioning();
645  // if there is no current file or if the current file is out of date, check out a fresh copy
646  if ($fv->upToDate($unrestricted) & (FUDGE_FV_NOT_CHECKED_OUT | FUDGE_FV_OLD_VERSION)) {
647  if (file_exists($unrestricted)) {
648  unlink($this->data_path_public.'/'.$existing['filename']);
649  }
650 
651  if ($fv->checkOut($this->data_path_suffix.'/'.$existing['filename'], $this->data_path_public)) {
652  $changed = TRUE;
653  } else {
654  trigger_localised_error('CORE0032', E_USER_WARNING);
655  return FALSE;
656  }
657  } else {
658  // Because we are live, and we might be be escalated from EDITING_APPROVED, so lets update lookup to get the public url back
659  $changed = TRUE;
660  }//end else
661  } else {
662  // need to make sure our file is NOT in the public data directory
663  if (is_file($unrestricted)) {
664  $fv = $GLOBALS['SQ_SYSTEM']->getFileVersioning();
665  if ($fv->clearOut($unrestricted) & FUDGE_FV_OK) {
666  $changed = TRUE;
667  } else {
668  trigger_localised_error('CORE0104', E_USER_WARNING);
669  return FALSE;
670  }
671  }
672  }//end if effectiveUnrestricted
673 
674  if ($changed) {
675  return $this->updateLookups();
676  } else {
677  return TRUE;
678  }
679 
680  }//end _checkFileState()
681 
682 
689  protected function _removePublicFile()
690  {
691  $existing = $this->getExistingFile();
692  if (empty($existing)) return TRUE;
693 
694  $unrestricted = $this->data_path_public.'/'.$existing['filename'];
695  if (is_file($unrestricted)) {
696  $fv = $GLOBALS['SQ_SYSTEM']->getFileVersioning();
697  if ($fv->clearOut($unrestricted) & FUDGE_FV_OK) {
698  return TRUE;
699  } else {
700  trigger_localised_error('CORE0104', E_USER_WARNING);
701  return FALSE;
702  }
703  }
704 
705  return TRUE;
706 
707  }//end _removePublicFile()
708 
709 
717  protected function _updatePublicFile()
718  {
719  require_once SQ_FUDGE_PATH.'/general/file_system.inc';
720 
721  $existing = $this->getExistingFile();
722  if (empty($existing)) return TRUE;
723 
724  $unrestricted = $this->data_path_public.'/'.$existing['filename'];
725 
726  // make sure our data directory exists
727  if (!create_directory($this->data_path_public)) {
728  trigger_localised_error('CORE0049', E_USER_WARNING, $this->name);
729  return FALSE;
730  }
731 
732  $fv = $GLOBALS['SQ_SYSTEM']->getFileVersioning();
733  // if there is no current file or if the current file is out of date, check out a fresh copy
734  if ($fv->upToDate($unrestricted) & (FUDGE_FV_NOT_CHECKED_OUT | FUDGE_FV_OLD_VERSION)) {
735  if (file_exists($unrestricted)) {
736  unlink($this->data_path_public.'/'.$existing['filename']);
737  }
738 
739  if ($fv->checkOut($this->data_path_suffix.'/'.$existing['filename'], $this->data_path_public)) {
740  return TRUE;
741  } else {
742  trigger_localised_error('CORE0032', E_USER_WARNING);
743  return FALSE;
744  }
745  }
746 
747  return TRUE;
748 
749  }//end _updatePublicFile()
750 
751 
759  public function usePublicPath()
760  {
761  return ($this->attr('allow_unrestricted') && $this->effectiveUnrestricted() && !($this->status & SQ_SC_STATUS_SAFE_EDITING));
762 
763  }//end usePublicPath()
764 
765 
773  public function updateLookups($auto_add_remaps = TRUE)
774  {
775  $old_urls = $this->getURLs();
776 
777  if (!isset($this->_tmp['deleting_file'])) {
778  $this->_tmp['deleting_file'] = FALSE;
779  }
780 
781  if (!$this->usePublicPath() && !$this->_tmp['deleting_file']) {
782  // this file is either in a safe edit, restricted, or doesnt want to be unrestricted
783  // so we just call parent to update urls, if the asset is safe edit, but unrestricted otherwise, we still want to insert the __data url
784  $result = parent::updateLookups($auto_add_remaps);
785  if(($this->status & SQ_SC_STATUS_SAFE_EDITING) && $this->attr('allow_unrestricted') && $this->effectiveUnrestricted()) {
786  $result = $result && ($this->insertDataLookup());
787  }
788  return $result;
789  }
790 
791  // Remove all the old URLs
792  $GLOBALS['SQ_SYSTEM']->changeDatabaseConnection('db2');
793  $db = MatrixDAL::getDb();
794  $GLOBALS['SQ_SYSTEM']->doTransaction('BEGIN');
795 
796  unset($this->_tmp['lookups']);
797  unset($this->_tmp['url']);
798  unset($this->_tmp['href']);
799 
800  try {
801  $bind_vars = Array('assetid' => $this->id);
802  $result = MatrixDAL::executeQuery('core', 'deleteLookup', $bind_vars);
803  } catch (Exception $e) {
804  throw new Exception('Unable to delete lookup information for asset: '.$this->id.' due to database error: '.$e->getMessage());
805  }
806 
807  $GLOBALS['SQ_SYSTEM']->doTransaction('COMMIT');
808  $GLOBALS['SQ_SYSTEM']->restoreDatabaseConnection();
809  // insert __data URL
810  $result = $this->insertDataLookup();
811 
812  //Bug #5072: Trashed file assets still accessible via public data URL
813  //We only reached here because we are supposed to have a public web path but
814  //if we e.g. have moved to the trash or under a site with no URL, we should remove the public file.
815  if (empty($result)){
816  $this->_removePublicFile();
817  } else {
818  $this->_updatePublicFile();
819  }
820 
821  // broadcast the lookup updated trigger event, passing old status as event data
822  $parameter = Array();
823  if (isset($this->_tmp['old_status'])) {
824  $parameter['old_status'] = $this->_tmp['old_status'];
825  }
826  if (!empty($old_urls)) {
827  $parameter['old_urls'] = $old_urls;
828  }
829  $em = $GLOBALS['SQ_SYSTEM']->getEventManager();
830  $em->broadcastEvent($this, 'LookupsUpdated', Array('asset_name' => $this->name));
831  $GLOBALS['SQ_SYSTEM']->broadcastTriggerEvent('trigger_event_lookups_updated', $this, $parameter);
832 
833  return TRUE;
834 
835  }//end updateLookups()
836 
837 
844  protected function insertDataLookup()
845  {
846  $existing = $this->getExistingFile();
847  if (!isset($existing['filename'])) {
848  // there is no filename, so commit the removal of the current web paths and return
849  return TRUE;
850  }
851 
852 
853  // Basically what we are going to do here is find all our parents that are sites
854  // and take the system root urls that are closest to these site urls and tack on __data/... bit
855  $save_urls = Array();
856  $root_urls = explode("\n", trim(SQ_CONF_SYSTEM_ROOT_URLS));
857 
858  if (!SQ_CONF_STATIC_ROOT_URL == '') {
859  if (!$GLOBALS['SQ_SYSTEM']->am->assetInTrash($this->id, TRUE)){
860  // use the static root URL data
861  $web_path = str_replace(sq_web_path('data').'/', '', $this->getWebDataPath()).'/'.$existing['filename'];
862  $save_urls[SQ_CONF_STATIC_ROOT_URL] = Array('http' => SQ_CONF_STATIC_ROOT_HTTP, 'https' => SQ_CONF_STATIC_ROOT_HTTPS);
863  }
864  } else {
865 
866  $web_path = str_replace(sq_web_path('root_url').'/', '', $this->getWebDataPath()).'/'.$existing['filename'];
867  $site_parents = $GLOBALS['SQ_SYSTEM']->am->getParents($this->id, 'site', FALSE);
868  foreach ($site_parents as $assetid => $type_code) {
869  $site = $GLOBALS['SQ_SYSTEM']->am->getAsset($assetid, $type_code);
870  if (is_null($site)) continue;
871  $urls = $site->getSiteURLS();
872 
873  foreach ($urls as $urlid => $data) {
874 
875  $matching_roots = Array();
876 
877  foreach ($root_urls as $tmp_url) {
878  if (substr($data['url'].'/', 0, strlen($tmp_url) + 1) == $tmp_url.'/') {
879  $matching_roots[] = $tmp_url;
880  }
881  }
882 
883  if (empty($matching_roots)) continue;
884 
885  foreach ($matching_roots as $root_url) {
886  if (isset($save_urls[$root_url])) {
887  if (empty($save_urls[$root_url]['http'])) {
888  $save_urls[$root_url]['http'] = $data['http'];
889  }
890  if (empty($save_urls[$root_url]['https'])) {
891  $save_urls[$root_url]['https'] = $data['https'];
892  }
893  } else {
894  $save_urls[$root_url] = Array('http' => $data['http'], 'https' => $data['https']);
895  }
896  }
897 
898  }//end foreach
899 
900  }//end foreach
901 
902  }//end else - if SQ_CONF_STATIC_ROOT_URL is not empty
903 
904  $GLOBALS['SQ_SYSTEM']->changeDatabaseConnection('db2');
905  $db = MatrixDAL::getDb();
906  $GLOBALS['SQ_SYSTEM']->doTransaction('BEGIN');
907 
908  $result = 0;
909  foreach ($save_urls as $url => $url_data) {
910  try {
911  $bind_vars = Array (
912  'url' => $url.'/'.$web_path,
913  'assetid' => $this->id,
914  'http' => ($this->force_secure === '1') ? '0' : $url_data['http'],
915  'https' => ($this->force_secure === '-') ? '0' : $url_data['https'],
916  'root_urlid' => 0,
917  );
918  $result = MatrixDAL::executeQuery('core', 'insertLookup', $bind_vars);
919  } catch (Exception $e) {
920  throw new Exception('Unable to insert lookups for asset "'.$this->name.'" (#'.$this->id.') due to database error: '.$e->getMessage());
921  }
922 
923  // NOTE: we are not going to update the design's lookups because no
924  // designs can be attached to a file anyway (well not at this time)
925  // and it's one thing less to worry about updating for the moment
926  // NOTE NOTE: same applies to paint layouts...
927 
928  }//end foreach
929 
930  $GLOBALS['SQ_SYSTEM']->doTransaction('COMMIT');
931  $GLOBALS['SQ_SYSTEM']->restoreDatabaseConnection();
932 
933  return $result;
934  }//end insertDataLookup()
935 
936 
946  public function processBackend(Backend_Outputter $o, Array &$link)
947  {
948  if (in_array($_POST['asset_action'], Array('create', 'create_custom'))) {
949  $this->_tmp['uploading_file'] = 1;
950  }
951  switch ($_POST['asset_action']) {
952  case 'create' :
953  $ei = $this->getEI();
954  if (!$ei->process($this, $o, TRUE)) return FALSE;
955  $this->setAttrValue('name', 'temp');
956  return $this->create($link);
957  break;
958 
959  default :
960  return parent::processBackend($o, $link);
961 
962  }//end switch
963 
964  }//end processBackend()
965 
966 
976  public function saveAttributes($dont_run_updated=FALSE)
977  {
978  if (!$this->id) return TRUE;
979 
980  // if there are no values for the title attribute use the filename
981  if (trim($this->attr('title')) == '') {
982  $this->setAttrValue('title', $this->attr('name'));
983  }//end if
984 
985  if (isset($this->_tmp['vars_set']['name'])) {
986 
987  $uploading_file = !empty($this->_tmp['uploading_file']);
988 
989  if (!$uploading_file) {
990 
991  $old_filename = $this->_tmp['vars_set']['name']['old_value'];
992  $new_filename = $this->attr('name');
993 
994  // try and set the new filename - return FALSE if it fails
995  if (!parent::saveAttributes($dont_run_updated)) {
996  return FALSE;
997  }
998 
999  if (is_file($this->data_path.'/'.$old_filename)) {
1000  if (!$this->_renameFile($this->data_path, $old_filename, $new_filename)) {
1001  parent::setAttrValue('name', $old_filename);
1002  parent::saveAttributes($dont_run_updated);
1003  return FALSE;
1004  }
1005  }
1006 
1007  if ($this->effectiveUnrestricted()) {
1008  if (is_file($this->data_path_public.'/'.$old_filename)) {
1009  // trigger_event_lookups_updated needs old status event data
1010  $this->_tmp['old_status'] = $this->status;
1011  unlink($this->data_path_public.'/'.$old_filename);
1012  $fv = $GLOBALS['SQ_SYSTEM']->getFileVersioning();
1013  $fv->checkOut($this->data_path_suffix.'/'.$new_filename, $this->data_path_public);
1014  }
1015  }
1016 
1017  // update the lookups so that the __data path gets rewritten if applicable
1018  $this->updateLookups();
1019 
1020  return TRUE;
1021 
1022  }//end if not uploading a file
1023 
1024  }//end if we are changing the filename
1025 
1026  return parent::saveAttributes($dont_run_updated);
1027 
1028  }//end saveAttributes()
1029 
1030 
1041  protected function _renameFile($data_path, $old_filename, $new_filename)
1042  {
1043 
1044  $fv = $GLOBALS['SQ_SYSTEM']->getFileVersioning();
1045 
1046  // copy the file instead of a direct rename because removing the
1047  // file from the repository will also remove it from the file system
1048  if (!copy($data_path.'/'.$old_filename, $data_path.'/'.$new_filename)) {
1049  trigger_localised_error('CORE0026', E_USER_WARNING);
1050  return FALSE;
1051  }
1052 
1053  // we are renaming the file, so we need to remove the old name from
1054  // the repository and add the new one in
1055  $result = $fv->remove($data_path.'/'.$old_filename, '');
1056  if ($result != FUDGE_FV_OK && $result != FUDGE_FV_NOT_CHECKED_OUT) {
1057  trigger_localised_error('CORE0042', E_USER_WARNING);
1058  return FALSE;
1059  }
1060 
1061  // attempt to add a new version of the file to the repository
1062  if (!$fv->add($this->data_path_suffix, $data_path.'/'.$new_filename, '')) {
1063  trigger_localised_error('CORE0026', E_USER_WARNING);
1064  return FALSE;
1065  }
1066 
1067  // make sure we have the latest version of our file
1068  if (!$fv->checkOut($this->data_path_suffix.'/'.$new_filename, $data_path)) {
1069  trigger_localised_error('CORE0032', E_USER_WARNING);
1070  return FALSE;
1071  }
1072 
1073  return TRUE;
1074 
1075  }//end _renameFile()
1076 
1077 
1089  public function setAttrValue($name, $value)
1090  {
1091  $uploading_file = (!empty($this->_tmp['uploading_file'])) ? TRUE : FALSE;
1092  $created_file = isset($this->_tmp['file_create_data']['created_file']) ? $this->_tmp['file_create_data']['created_file'] : FALSE;
1093 
1094  if ($name == 'name' && !$uploading_file) {
1095  // check that we are not going to have web path conflicts
1096  require_once SQ_INCLUDE_PATH.'/general_occasional.inc';
1097  $valid_names = make_valid_web_paths(Array($value));
1098  $value = array_shift($valid_names);
1099 
1100  if (is_file($this->data_path.'/'.$this->attr('name'))) {
1101  $data_path = $this->data_path;
1102  } else {
1103  $data_path = $this->data_path_public;
1104  }
1105 
1106  require_once SQ_FUDGE_PATH.'/general/file_system.inc';
1107 
1108  $old_filename = $this->attr('name');
1109  $old_ext = get_file_type($old_filename);
1110  $new_ext = get_file_type($value);
1111  if (trim($old_ext) != '' && $old_ext != $new_ext) {
1112  trigger_localised_error('CORE0115', E_USER_WARNING);
1113  $value = $old_filename;
1114  return FALSE;
1115  }
1116  // Should be able to set attribute of file before if its created by matrix
1117  if (!is_file($data_path.'/'.$old_filename) && !$created_file) {
1118  trigger_localised_error('CORE0023', E_USER_WARNING);
1119  $value = $old_filename;
1120  return FALSE;
1121  }
1122  }
1123 
1124  return parent::setAttrValue($name, $value);
1125 
1126  }//end setAttrValue()
1127 
1128 
1137  public function validFile(Array $info)
1138  {
1139  $pre_uploaded = FALSE;
1140  if (isset($info['non_uploaded_file']) && $info['non_uploaded_file']) {
1141  $pre_uploaded = TRUE;
1142  }
1143 
1144  require_once SQ_FUDGE_PATH.'/general/file_system.inc';
1145  $ext = get_file_type($info['filename']);
1146  if (!empty($this->allowed_extensions) && !in_array($ext, $this->allowed_extensions)) {
1147  trigger_localised_error('CORE0106', E_USER_WARNING, make_readable_list($this->allowed_extensions, strtolower(translate('or'))), strtoupper($ext));
1148  // Get rid of temp copy of the uploaded file
1149  unlink($info['path']);
1150 
1151  return FALSE;
1152  }
1153 
1154  if ($this->_validFileSize($info, $pre_uploaded) && $this->_validFileExtension($info, $pre_uploaded)) {
1155  return TRUE;
1156  }
1157 
1158  unlink($info['path']);
1159 
1160  return FALSE;
1161 
1162  }//end validFile()
1163 
1164 
1174  protected function _validFileSize(Array &$info, $pre_uploaded=FALSE)
1175  {
1176  // check the file size to ensure we are not violating any restrictions
1177  $size = filesize($info['path']);
1178 
1179  $pre_uploaded = FALSE;
1180  if (isset($info['non_uploaded_file']) && $info['non_uploaded_file']) {
1181  $pre_uploaded = TRUE;
1182  }
1183 
1184  if ($pre_uploaded) {
1185  $file_max_size = $GLOBALS['SQ_SYSTEM']->getUserPrefs('file', 'SQ_FILE_PREUPLOADED_MAX_SIZE');
1186  $error_code = 'CORE0262';
1187  } else {
1188  $file_max_size = $GLOBALS['SQ_SYSTEM']->getUserPrefs('file', 'SQ_FILE_MAX_SIZE');
1189  $error_code = 'CORE0057';
1190  }
1191 
1192  if (empty($file_max_size)) return TRUE;
1193 
1194  $max_size = strtolower($file_max_size);
1195  if (!$max_size) return TRUE;
1196 
1197  if (substr($max_size, -1) == 'k') {
1198  $max_size = $max_size * 1024;
1199  } else if (substr($max_size, -1) == 'm') {
1200  $max_size = $max_size * 1024 * 1024;
1201  }
1202  if ($size > $max_size) {
1203  require_once SQ_FUDGE_PATH.'/general/file_system.inc';
1204  trigger_localised_error($error_code, E_USER_WARNING, strtoupper(easy_filesize($max_size)), strtoupper(easy_filesize($size)));
1205  return FALSE;
1206  }
1207 
1208  return TRUE;
1209 
1210  }//end _validFileSize()
1211 
1212 
1222  protected function _validFileExtension(Array &$info, $pre_uploaded=FALSE)
1223  {
1224  // check the file size to ensure we are not violating any restrictions
1225  $filename = $info['filename'];
1226 
1227  require_once SQ_FUDGE_PATH.'/general/file_system.inc';
1228  $extension = get_file_type($filename);
1229 
1230  // If the script is running from the command line, do not restrict file type
1231  // e.g. installation scripts.
1232  if (php_sapi_name() == 'cli') return TRUE;
1233 
1234  // Root and System Administrators can over rule the restriction
1235  $is_root = $GLOBALS['SQ_SYSTEM']->userRoot();
1236  $is_admin = ($is_root || $GLOBALS['SQ_SYSTEM']->userSystemAdmin());
1237  if ($is_root || $is_admin) {
1238  return TRUE;
1239  }
1240 
1241  // File with no extension
1242  $extension = trim($extension);
1243  if (empty($extension)) {
1244  $allowed_no_extension = $GLOBALS['SQ_SYSTEM']->getUserPrefs('file', 'SQ_FILE_ALLOW_NO_EXTENSION');
1245  if ($allowed_no_extension) return TRUE;
1246  trigger_localised_error('CORE0267', E_USER_WARNING);
1247  return FALSE;
1248  }
1249 
1250  if ($pre_uploaded) {
1251  $allowed_extensions = $GLOBALS['SQ_SYSTEM']->getUserPrefs('file', 'SQ_FILE_ALLOWED_PREUPLOADED_TYPES');
1252  } else {
1253  $allowed_extensions = $GLOBALS['SQ_SYSTEM']->getUserPrefs('file', 'SQ_FILE_ALLOWED_TYPES');
1254  }
1255 
1256  if (!empty($allowed_extensions)) {
1257  $allowed_extensions_list = explode(',', $allowed_extensions);
1258  if (!in_array($extension, $allowed_extensions_list)) {
1259  trigger_localised_error('CORE0266', E_USER_WARNING, $filename);
1260  return FALSE;
1261  }
1262  }
1263 
1264  if (isset($this->allowed_extensions) && !empty($this->allowed_extensions)) {
1265  if (!in_array($extension, $this->allowed_extensions)) {
1266  trigger_localised_error('CORE0266', E_USER_WARNING, $filename);
1267  return FALSE;
1268  }
1269  }
1270 
1271  return TRUE;
1272 
1273  }//end _validFileExtension()
1274 
1275 
1285  public function printFrontend()
1286  {
1287  // if we are in limbo, we want to show our editing interface and design
1288  // instead of just sending our file over
1289  // there is an exception to it: In Limbo, if we have ?a=<assetid> at the end of the URL
1290  // and <assetid> value is different from the current asset assetid we are sending our file over
1291  if (SQ_IN_LIMBO && !(isset($_REQUEST['a']) && $_REQUEST['a'] == $this->id)) {
1292  return parent::printFrontend();
1293  }
1294 
1295  if (!$this->readAccess()) {
1296  $GLOBALS['SQ_SYSTEM']->paintLogin(translate('login'), translate('cannot_access_asset', $this->name));
1297  return;
1298  }
1299 
1300  // we want to tell mysource::start() that it should not try to replace
1301  // keywords in this output, it could be a binary file after all
1302  $GLOBALS['SQ_SYSTEM']->setGlobalDefine('SQ_REPLACE_MYSOURCE_LEVEL_KEYWORDS', FALSE);
1303 
1304  $existing = $this->getExistingFile();
1305  if (!empty($existing)) {
1306  require_once SQ_FUDGE_PATH.'/standards_lists/mime_types.inc';
1307  require_once SQ_FUDGE_PATH.'/general/file_system.inc';
1308 
1309  $ext = get_file_type($existing['filename']);
1310  if (($this->status & SQ_SC_STATUS_SAFE_EDITING) && ($GLOBALS['SQ_SYSTEM']->user instanceof Public_User)) {
1311  // strip file versioning suffix from the file extension, e.g. 'pdf,ffv5' becomes 'pdf'
1312  $ext = preg_replace('/,ffv\d+$/', '', $ext);
1313  $existing['filename'] = preg_replace('/,ffv\d+$/', '', $existing['filename']);
1314  }
1315  $type = (empty($standards_lists_mime_types[$ext])) ? 'text/plain' : $standards_lists_mime_types[$ext];
1316 
1317  // get protocol information
1318  $ssl_connection = FALSE;
1319  $url_info = parse_url(current_url());
1320  $protocol = (isset($url_info['scheme'])) ? $url_info['scheme'] : NULL;
1321  if (!is_null($protocol) && $protocol == 'https') {
1322  $ssl_connection = TRUE;
1323  }
1324  $cm = $GLOBALS['SQ_SYSTEM']->am->getSystemAsset('cache_manager');
1325  $using_ie6_8 = isset ($_SERVER['HTTP_USER_AGENT']) ? preg_match('/(MSIE\s[0-8]+\.)/', $_SERVER['HTTP_USER_AGENT']) : FALSE;
1326 
1327  // send cacheable headers if file asset meets the credentials
1328  if (basename($_SERVER['PHP_SELF']) != SQ_CONF_NOCACHE_SUFFIX && SQ_CONF_SEND_CACHEABLE_HEADER && ($GLOBALS['SQ_SYSTEM']->user instanceof Public_User) && empty($_POST) && $cm->cacheableHeadersEnabledForCurrentProtocol() && $this->status >= SQ_STATUS_LIVE && $this->readAccess()) {
1329 
1330  $browser_cache_expiry = $cm->getBrowserCacheExpiry($this->type(), $this->id);
1331  if (empty($browser_cache_expiry)) {
1332  $browser_cache_expiry = $cm->getExpiry($this->type(), $this->id);
1333  }
1334 
1335  $last_updated = $this->getEffectiveLastUpdatedTime(Array());
1336  header('Expires: '.gmdate('D, d M Y H:i:s', time() + $browser_cache_expiry).' GMT');
1337  header('Cache-Control: max-age='.$browser_cache_expiry.', '.$cm->cacheControlLevel());
1338  header('Pragma: cache');
1339  header('Last-Modified: '.gmdate('D, d M Y H:i:s',$existing['modified']).' GMT');
1340  } else if (!$using_ie6_8 || !$ssl_connection) {
1341  // Internet Explorer must forcibly reload some file types from the server for correct inline operation in popup windows. (ref. http://support.microsoft.com/default.aspx?scid=kb;EN-US;q297822)
1342  // If such files do not load as expected, "Send no-cache header option for HTTP requests" should be set to "No" on the System Configuration screen. The default operation is to send this header (i.e; set to "Yes").
1343  if (SQ_CONF_SEND_NO_CACHE_HEADER) {
1344  header('Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0');
1345  } else {
1346  header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
1347  }
1348 
1349  header('Pragma: no-cache');
1350  header('Expires: '.gmdate('D, d M Y H:i:s', time()-3600).' GMT');
1351  } else {
1352  // internet explorer has a problem with SSL connection (https)
1353  // cant send no-cache header or we will get "cannot download file" error
1354  // http://support.microsoft.com/default.aspx?scid=kb;en-us;812935
1355  // http://support.microsoft.com/default.aspx?scid=kb;en-us;316431
1356  header('Cache-Control: private, max-age=0, must-revalidate');
1357  header('Pragma: private');
1358  header('Expires: '.gmdate('D, d M Y H:i:s', time()-3600).' GMT');
1359  }
1360 
1361  header('Content-Type: '.$type);
1362  header('Content-Disposition: inline; filename="'.$existing['filename'].'";');
1363  header('Content-Length: '.$existing['size']);
1364  ob_end_flush();
1365 
1366  readfile($existing['path']);
1367 
1368  }//end if
1369 
1370  }//end printFrontend()
1371 
1372 
1383  public function getURL($base_url=NULL, $ignore_rollback=FALSE)
1384  {
1385  if (SQ_ROLLBACK_VIEW) {
1386  if (is_null($base_url)) $base_url = current_url();
1387  $base_url = strip_url($base_url, FALSE);
1388  return $base_url.'/?a='.$this->id;
1389  } else {
1390  return parent::getURL($base_url, $ignore_rollback);
1391  }
1392 
1393  }//end getURL()
1394 
1395 
1406  public function getHref($base_url=NULL, $ignore_rollback=FALSE)
1407  {
1408  if (SQ_ROLLBACK_VIEW) {
1409  return './?a='.$this->id;
1410  } else {
1411  return parent::getHref($base_url, $ignore_rollback);
1412  }
1413 
1414  }//end getHref()
1415 
1416 
1423  public function getExistingFile()
1424  {
1425  $existing = Array();
1426  $path = '';
1427 
1428  if (SQ_ROLLBACK_VIEW) {
1429  // get an older version of this file
1430  $fv = $GLOBALS['SQ_SYSTEM']->getFileVersioning();
1431  $rep_file = $this->data_path_suffix.'/'.$this->name;
1432  $then = iso8601_ts($_SESSION['sq_rollback_view']['rollback_time']);
1433  $info = $fv->_checkOutCheck($rep_file, NULL, $then);
1434  $path = $info['source_file'];
1435  $existing['filename'] = $info['filename'];
1436  } else if (($this->status & SQ_SC_STATUS_SAFE_EDITING) && ($GLOBALS['SQ_SYSTEM']->user instanceof Public_User)) {
1437  // safe edit, get the previous live version from the file versioning repository for public user (bug #1049)
1438  if (is_file($this->data_path.'/sq_system_version_no')) {
1439  $file_version = file_to_string($this->data_path.'/sq_system_version_no');
1440  $fv = $GLOBALS['SQ_SYSTEM']->getFileVersioning();
1441  $rep_file = $this->data_path_suffix.'/'.$this->name;
1442  $info = $fv->_checkOutCheck($rep_file, $file_version);
1443  $path = $info['source_file'];
1444  }
1445  } else {
1446  // get the latest file
1447  $path = $this->data_path.'/'.$this->attr('name');
1448  }
1449 
1450  if (is_file($path)) {
1451  $existing['path'] = $path;
1452  $existing['modified'] = filemtime($existing['path']);
1453  $existing['size'] = filesize($existing['path']);
1454 
1455  if (isset($existing['filename']) === false) {
1456  $existing['filename'] = basename($existing['path']);
1457  }//end if
1458  }
1459 
1460  return $existing;
1461 
1462  }//end getExistingFile()
1463 
1464 
1475  public function _getName($short_name=FALSE, $contextid=NULL)
1476  {
1477  // No context specified, using the current context
1478  if ($contextid === NULL) {
1479  $contextid = $GLOBALS['SQ_SYSTEM']->getContextId();
1480  }//end if
1481 
1482  // Obtain the attribute value for Title from the specified context
1483  if ($short_name) {
1484  $values = $GLOBALS['SQ_SYSTEM']->am->getAttributeValuesByName('title', $this->type(), Array($this->id), $contextid);
1485  if (empty($values) === TRUE) {
1486  return $this->attr('title');
1487  } else {
1488  return $values[$this->id];
1489  }
1490  }
1491 
1492  return $this->attr('name');
1493 
1494  }//end _getName()
1495 
1496 
1511  public function getAvailableKeywords()
1512  {
1513  $keywords = parent::getAvailableKeywords();
1514 
1515  $keywords['asset_file_size_in_bytes'] = translate('core_file_keyword_size_in_bytes');
1516  $keywords['asset_file_size_readable'] = translate('core_file_keyword_size_readable');
1517  $keywords['asset_file_contents'] = translate('core_file_keyword_file_contents');
1518 
1519 
1520  return $keywords;
1521 
1522  }//end getAvailableKeywords()
1523 
1524 
1532  {
1533  $existing = $this->getExistingFile();
1534  $size = (isset($existing['size'])) ? $existing['size'] : 0;
1535  return $size;
1536 
1537  }//end getAssetFileSizeInBytesKeywordReplacement()
1538 
1539 
1547  {
1548  $existing = $this->getExistingFile();
1549  $size = (isset($existing['size'])) ? $existing['size'] : 0;
1550  return easy_filesize($size);
1551 
1552  }//end getAssetFileSizeReadableKeywordReplacement()
1553 
1561  {
1562  $existing = $this->getExistingFile();
1563  $file_contents = isset($existing['path']) ? file_get_contents($existing['path']) : '';
1564  return $file_contents;
1565 
1566  }//end getAssetFileContentsKeywordReplacement()
1567 
1578  public function delete($release_lock=TRUE)
1579  {
1580  $this->_tmp['deleting_file'] = TRUE;
1581  $GLOBALS['SQ_SYSTEM']->changeDatabaseConnection('db2');
1582  $GLOBALS['SQ_SYSTEM']->doTransaction('BEGIN');
1583 
1584  if (!parent::delete($release_lock)) {
1585  $GLOBALS['SQ_SYSTEM']->doTransaction('ROLLBACK');
1586  $GLOBALS['SQ_SYSTEM']->restoreDatabaseConnection();
1587  return FALSE;
1588  }
1589 
1590  $GLOBALS['SQ_SYSTEM']->doTransaction('COMMIT');
1591  $GLOBALS['SQ_SYSTEM']->restoreDatabaseConnection();
1592  $this->_tmp['deleting_file'] = FALSE;
1593 
1594  return TRUE;
1595 
1596  }//end delete()
1597 
1598 
1607  public function scanFile($path='')
1608  {
1609  // Default to not scanned
1610  $status = TRUE;
1611  // Load the virus checker
1612  require_once SQ_FUDGE_PATH.'/antivirus/antivirus.inc';
1613 
1614  if (empty($path)) {
1615  $file_to_scan = $this->data_path.'/'.$this->attr('name');
1616  } else {
1617  $file_to_scan = $path;
1618  }//end if
1619 
1620  $report = '';
1621  $status = Antivirus::scan_file($file_to_scan, $report);
1622 
1623  // Return
1624  return $status;
1625 
1626  }//end scanFile()
1627 
1628 
1636  {
1637  $ext = '';
1638  $file_info = $this->getExistingFile();
1639  if(isset($file_info['filename'])) {
1640  $ext = substr($file_info['filename'], strrpos($file_info['filename'], '.') + 1);
1641  }
1642  return $ext;
1643 
1644  }//end getFileTypeKeywordReplacement()
1645 
1646 
1653  public function getAssetSummary()
1654  {
1655  // Get the summary content defination
1656  $summary = $GLOBALS['SQ_SYSTEM']->getUserPrefs('file', 'SQ_FILE_ASSET_SUMMARY');
1657  $keywords = retrieve_keywords_replacements($summary);
1658 
1659  $keyword_replacement = Array();
1660  foreach($keywords as $full_keyword) {
1661  $modifiers = NULL;
1662  $part_keyword = parse_keyword($full_keyword, $modifiers);
1663  $keyword_value = $this->getKeywordReplacement($part_keyword);
1664  if ($part_keyword != $full_keyword) {
1665  apply_keyword_modifiers($keyword_value, $modifiers, Array('assetid' => $this->id));
1666  }
1667 
1668  $keyword_replacement[$full_keyword] = $keyword_value;
1669  }
1670 
1671  replace_keywords($summary, $keyword_replacement);
1672 
1673  return $summary;
1674 
1675  }//end getAssetSummary()
1676 
1677 
1688  public function getOriginalURL($data_url, $site_url)
1689  {
1690  $original_url = Array();
1691 
1692  // if the url passed doenst have __data in it then there is nothing to do
1693  // just return it right away
1694  if(strpos($data_url, '__data') === FALSE) return $data_url;
1695 
1696  // *should never happen*
1697  if(empty($site_url)) return $data_url;
1698 
1699  $site_parts = explode('://', $site_url);
1700  $site = $GLOBALS['SQ_SYSTEM']->am->getAssetFromURL($site_parts[0], $site_parts[1]);
1701 
1702  $site_treeid = $GLOBALS['SQ_SYSTEM']->am->getAssetTreeids($site->id);
1703 
1704  $web_paths = $this->getWebPaths();
1705  $parents = $GLOBALS['SQ_SYSTEM']->am->getParents($this->id, '', TRUE, NULL, NULL, TRUE, 1, 1);
1706 
1707  $url_found = Array();
1708  foreach($parents as $parentid => $type_code) {
1709  if($site->id != $parentid){
1710  $parent_asset = $GLOBALS['SQ_SYSTEM']->am->getAsset($parentid);
1711  } else {
1712  $parent_asset = $site;
1713  }
1714  $parent_urls = $parent_asset->getURLs();
1715  foreach ($parent_urls as $index => $parent_url) {
1716  if(strpos($parent_url['url'], $site_parts[1]) !== FALSE || $parent_url['url'] == $site_url) {
1717  $url_found = $parent_url;
1718  break(2);
1719  }
1720  }
1721  }
1722 
1723  if(!empty($url_found)) {
1724  $construct_url = ($url_found['https'] == '1') ? 'https://' : 'http://';
1725  foreach ($web_paths as $webpath) {
1726  $original_url[] = $construct_url.$url_found['url'].'/'.$webpath;
1727  }
1728  }
1729 
1730  return $original_url;
1731 
1732  }//end getOriginalURL()
1733 
1734 
1735 }//end class
1736 
1737 ?>