Ejemplo n.º 1
0
 /**
  * Performs synchronisation of reference to an external file if the previous one has expired.
  *
  * @param stored_file $file
  * @param bool $resetsynchistory whether to reset all history of sync (used by phpunit)
  * @return bool success
  */
 public static function sync_external_file($file, $resetsynchistory = false)
 {
     global $DB;
     // TODO MDL-25290 static should be replaced with MUC code.
     static $synchronized = array();
     if ($resetsynchistory) {
         $synchronized = array();
     }
     $fs = get_file_storage();
     if (!$file || !$file->get_referencefileid()) {
         return false;
     }
     if (array_key_exists($file->get_id(), $synchronized)) {
         return $synchronized[$file->get_id()];
     }
     // remember that we already cached in current request to prevent from querying again
     $synchronized[$file->get_id()] = false;
     if (!($reference = $DB->get_record('files_reference', array('id' => $file->get_referencefileid())))) {
         return false;
     }
     if (!empty($reference->lastsync) and $reference->lastsync + $reference->lifetime > time()) {
         $synchronized[$file->get_id()] = true;
         return true;
     }
     if (!($repository = self::get_repository_by_id($reference->repositoryid, SYSCONTEXTID))) {
         return false;
     }
     if (!$repository->sync_individual_file($file)) {
         return false;
     }
     $lifetime = $repository->get_reference_file_lifetime($reference);
     $fileinfo = $repository->get_file_by_reference($reference);
     if ($fileinfo === null) {
         // does not exist any more - set status to missing
         $file->set_missingsource($lifetime);
         $synchronized[$file->get_id()] = true;
         return true;
     }
     $contenthash = null;
     $filesize = null;
     if (!empty($fileinfo->filesize)) {
         // filesize returned
         if (!empty($fileinfo->contenthash) && $fs->content_exists($fileinfo->contenthash)) {
             // contenthash is specified and valid
             $contenthash = $fileinfo->contenthash;
         } else {
             if ($fileinfo->filesize == $file->get_filesize()) {
                 // we don't know the new contenthash but the filesize did not change,
                 // assume the contenthash did not change either
                 $contenthash = $file->get_contenthash();
             } else {
                 // we can't save empty contenthash so generate contenthash from empty string
                 $fs->add_string_to_pool('');
                 $contenthash = sha1('');
             }
         }
         $filesize = $fileinfo->filesize;
     } else {
         if (!empty($fileinfo->filepath)) {
             // File path returned
             list($contenthash, $filesize, $newfile) = $fs->add_file_to_pool($fileinfo->filepath);
         } else {
             if (!empty($fileinfo->handle) && is_resource($fileinfo->handle)) {
                 // File handle returned
                 $contents = '';
                 while (!feof($fileinfo->handle)) {
                     $contents .= fread($handle, 8192);
                 }
                 fclose($fileinfo->handle);
                 list($contenthash, $filesize, $newfile) = $fs->add_string_to_pool($content);
             } else {
                 if (isset($fileinfo->content)) {
                     // File content returned
                     list($contenthash, $filesize, $newfile) = $fs->add_string_to_pool($fileinfo->content);
                 }
             }
         }
     }
     if (!isset($contenthash) or !isset($filesize)) {
         return false;
     }
     // update files table
     $file->set_synchronized($contenthash, $filesize, 0, $lifetime);
     $synchronized[$file->get_id()] = true;
     return true;
 }
Ejemplo n.º 2
0
 /**
  * Copies a file from somewhere else in moodle
  * to the portfolio temporary working directory
  * associated with this export
  *
  * @param stored_file $oldfile existing stored file object
  * @return stored_file|bool new file object
  */
 public function copy_existing_file($oldfile)
 {
     if (array_key_exists($oldfile->get_contenthash(), $this->newfilehashes)) {
         return $this->newfilehashes[$oldfile->get_contenthash()];
     }
     $fs = get_file_storage();
     $file_record = $this->new_file_record_base($oldfile->get_filename());
     if ($dir = $this->get('format')->get_file_directory()) {
         $file_record->filepath = '/' . $dir . '/';
     }
     try {
         $newfile = $fs->create_file_from_storedfile($file_record, $oldfile->get_id());
         $this->newfilehashes[$newfile->get_contenthash()] = $newfile;
         return $newfile;
     } catch (file_exception $e) {
         return false;
     }
 }
Ejemplo n.º 3
0
 /**
  * Add new local file based on existing local file.
  *
  * @param stdClass|array $filerecord object or array describing changes
  * @param stored_file|int $fileorid id or stored_file instance of the existing local file
  * @return stored_file instance of newly created file
  */
 public function create_file_from_storedfile($filerecord, $fileorid)
 {
     global $DB;
     if ($fileorid instanceof stored_file) {
         $fid = $fileorid->get_id();
     } else {
         $fid = $fileorid;
     }
     $filerecord = (array) $filerecord;
     // We support arrays too, do not modify the submitted record!
     unset($filerecord['id']);
     unset($filerecord['filesize']);
     unset($filerecord['contenthash']);
     unset($filerecord['pathnamehash']);
     $sql = "SELECT " . self::instance_sql_fields('f', 'r') . "\n                  FROM {files} f\n             LEFT JOIN {files_reference} r\n                       ON f.referencefileid = r.id\n                 WHERE f.id = ?";
     if (!($newrecord = $DB->get_record_sql($sql, array($fid)))) {
         throw new file_exception('storedfileproblem', 'File does not exist');
     }
     unset($newrecord->id);
     foreach ($filerecord as $key => $value) {
         // validate all parameters, we do not want any rubbish stored in database, right?
         if ($key == 'contextid' and (!is_number($value) or $value < 1)) {
             throw new file_exception('storedfileproblem', 'Invalid contextid');
         }
         if ($key == 'component') {
             $value = clean_param($value, PARAM_COMPONENT);
             if (empty($value)) {
                 throw new file_exception('storedfileproblem', 'Invalid component');
             }
         }
         if ($key == 'filearea') {
             $value = clean_param($value, PARAM_AREA);
             if (empty($value)) {
                 throw new file_exception('storedfileproblem', 'Invalid filearea');
             }
         }
         if ($key == 'itemid' and (!is_number($value) or $value < 0)) {
             throw new file_exception('storedfileproblem', 'Invalid itemid');
         }
         if ($key == 'filepath') {
             $value = clean_param($value, PARAM_PATH);
             if (strpos($value, '/') !== 0 or strrpos($value, '/') !== strlen($value) - 1) {
                 // path must start and end with '/'
                 throw new file_exception('storedfileproblem', 'Invalid file path');
             }
         }
         if ($key == 'filename') {
             $value = clean_param($value, PARAM_FILE);
             if ($value === '') {
                 // path must start and end with '/'
                 throw new file_exception('storedfileproblem', 'Invalid file name');
             }
         }
         if ($key === 'timecreated' or $key === 'timemodified') {
             if (!is_number($value)) {
                 throw new file_exception('storedfileproblem', 'Invalid file ' . $key);
             }
             if ($value < 0) {
                 //NOTE: unfortunately I make a mistake when creating the "files" table, we can not have negative numbers there, on the other hand no file should be older than 1970, right? (skodak)
                 $value = 0;
             }
         }
         if ($key == 'referencefileid' or $key == 'referencelastsync') {
             $value = clean_param($value, PARAM_INT);
         }
         $newrecord->{$key} = $value;
     }
     $newrecord->pathnamehash = $this->get_pathname_hash($newrecord->contextid, $newrecord->component, $newrecord->filearea, $newrecord->itemid, $newrecord->filepath, $newrecord->filename);
     if ($newrecord->filename === '.') {
         // special case - only this function supports directories ;-)
         $directory = $this->create_directory($newrecord->contextid, $newrecord->component, $newrecord->filearea, $newrecord->itemid, $newrecord->filepath, $newrecord->userid);
         // update the existing directory with the new data
         $newrecord->id = $directory->get_id();
         $DB->update_record('files', $newrecord);
         return $this->get_file_instance($newrecord);
     }
     // note: referencefileid is copied from the original file so that
     // creating a new file from an existing alias creates new alias implicitly.
     // here we just check the database consistency.
     if (!empty($newrecord->repositoryid)) {
         if ($newrecord->referencefileid != $this->get_referencefileid($newrecord->repositoryid, $newrecord->reference, MUST_EXIST)) {
             throw new file_reference_exception($newrecord->repositoryid, $newrecord->reference, $newrecord->referencefileid);
         }
     }
     try {
         $newrecord->id = $DB->insert_record('files', $newrecord);
     } catch (dml_exception $e) {
         throw new stored_file_creation_exception($newrecord->contextid, $newrecord->component, $newrecord->filearea, $newrecord->itemid, $newrecord->filepath, $newrecord->filename, $e->debuginfo);
     }
     $this->create_directory($newrecord->contextid, $newrecord->component, $newrecord->filearea, $newrecord->itemid, $newrecord->filepath, $newrecord->userid);
     return $this->get_file_instance($newrecord);
 }
Ejemplo n.º 4
0
 /**
  * Export the data for the given file in relation to this document.
  *
  * @param \stored_file $file The stored file we are talking about.
  * @return array
  */
 public function export_file_for_engine($file)
 {
     $data = $this->export_for_engine();
     // Content is index in the main document.
     unset($data['content']);
     unset($data['description1']);
     unset($data['description2']);
     // Going to append the fileid to give it a unique id.
     $data['id'] = $data['id'] . '-solrfile' . $file->get_id();
     $data['type'] = \core_search\manager::TYPE_FILE;
     $data['solr_fileid'] = $file->get_id();
     $data['solr_filecontenthash'] = $file->get_contenthash();
     $data['solr_fileindexstatus'] = self::INDEXED_FILE_TRUE;
     $data['title'] = $file->get_filename();
     $data['modified'] = self::format_time_for_engine($file->get_timemodified());
     return $data;
 }
Ejemplo n.º 5
0
 /**
  * Return the link to a file
  *
  * @param stored_file $file information for existing file
  * @param array $options array of options to pass. can contain:
  *              attributes => hash of existing html attributes (eg title, height, width, etc)
  * @return string
  */
 public static function file_output($file, $options = null)
 {
     $id = '';
     if (!is_array($options)) {
         $options = array();
     }
     if (!array_key_exists('entry', $options)) {
         $options['entry'] = true;
     }
     if (!empty($options['entry'])) {
         $path = 'portfolio:' . self::file_id_prefix() . $file->get_id();
     } else {
         $path = self::get_file_directory() . $file->get_filename();
     }
     $attributes = array();
     if (!empty($options['attributes']) && is_array($options['attributes'])) {
         $attributes = $options['attributes'];
     }
     $attributes['rel'] = 'enclosure';
     return self::make_tag($file, $path, $attributes);
 }
Ejemplo n.º 6
0
 /**
  * Add new local file based on existing local file.
  *
  * @param stdClass|array $file_record object or array describing changes
  * @param stored_file|int $fileorid id or stored_file instance of the existing local file
  * @return stored_file instance of newly created file
  */
 public function create_file_from_storedfile($file_record, $fileorid)
 {
     global $DB;
     if ($fileorid instanceof stored_file) {
         $fid = $fileorid->get_id();
     } else {
         $fid = $fileorid;
     }
     $file_record = (array) $file_record;
     // we support arrays too, do not modify the submitted record!
     unset($file_record['id']);
     unset($file_record['filesize']);
     unset($file_record['contenthash']);
     unset($file_record['pathnamehash']);
     if (!($newrecord = $DB->get_record('files', array('id' => $fid)))) {
         throw new file_exception('storedfileproblem', 'File does not exist');
     }
     unset($newrecord->id);
     foreach ($file_record as $key => $value) {
         // validate all parameters, we do not want any rubbish stored in database, right?
         if ($key == 'contextid' and (!is_number($value) or $value < 1)) {
             throw new file_exception('storedfileproblem', 'Invalid contextid');
         }
         if ($key == 'component') {
             $value = clean_param($value, PARAM_COMPONENT);
             if (empty($value)) {
                 throw new file_exception('storedfileproblem', 'Invalid component');
             }
         }
         if ($key == 'filearea') {
             $value = clean_param($value, PARAM_AREA);
             if (empty($value)) {
                 throw new file_exception('storedfileproblem', 'Invalid filearea');
             }
         }
         if ($key == 'itemid' and (!is_number($value) or $value < 0)) {
             throw new file_exception('storedfileproblem', 'Invalid itemid');
         }
         if ($key == 'filepath') {
             $value = clean_param($value, PARAM_PATH);
             if (strpos($value, '/') !== 0 or strrpos($value, '/') !== strlen($value) - 1) {
                 // path must start and end with '/'
                 throw new file_exception('storedfileproblem', 'Invalid file path');
             }
         }
         if ($key == 'filename') {
             $value = clean_param($value, PARAM_FILE);
             if ($value === '') {
                 // path must start and end with '/'
                 throw new file_exception('storedfileproblem', 'Invalid file name');
             }
         }
         if ($key === 'timecreated' or $key === 'timemodified') {
             if (!is_number($value)) {
                 throw new file_exception('storedfileproblem', 'Invalid file ' . $key);
             }
             if ($value < 0) {
                 //NOTE: unfortunately I make a mistake when creating the "files" table, we can not have negative numbers there, on the other hand no file should be older than 1970, right? (skodak)
                 $value = 0;
             }
         }
         $newrecord->{$key} = $value;
     }
     $newrecord->pathnamehash = $this->get_pathname_hash($newrecord->contextid, $newrecord->component, $newrecord->filearea, $newrecord->itemid, $newrecord->filepath, $newrecord->filename);
     if ($newrecord->filename === '.') {
         // special case - only this function supports directories ;-)
         $directory = $this->create_directory($newrecord->contextid, $newrecord->component, $newrecord->filearea, $newrecord->itemid, $newrecord->filepath, $newrecord->userid);
         // update the existing directory with the new data
         $newrecord->id = $directory->get_id();
         $DB->update_record('files', $newrecord);
         return $this->get_file_instance($newrecord);
     }
     try {
         $newrecord->id = $DB->insert_record('files', $newrecord);
     } catch (dml_exception $e) {
         throw new stored_file_creation_exception($newrecord->contextid, $newrecord->component, $newrecord->filearea, $newrecord->itemid, $newrecord->filepath, $newrecord->filename, $e->debuginfo);
     }
     $this->create_directory($newrecord->contextid, $newrecord->component, $newrecord->filearea, $newrecord->itemid, $newrecord->filepath, $newrecord->userid);
     return $this->get_file_instance($newrecord);
 }
Ejemplo n.º 7
0
    /**
     * Call to request proxy file sync with repository source.
     *
     * @param stored_file $file
     * @param bool $resetsynchistory whether to reset all history of sync (used by phpunit)
     * @return bool success
     */
    public static function sync_external_file($file, $resetsynchistory = false) {
        global $DB;
        // TODO MDL-25290 static should be replaced with MUC code.
        static $synchronized = array();
        if ($resetsynchistory) {
            $synchronized = array();
        }

        $fs = get_file_storage();

        if (!$file || !$file->get_referencefileid()) {
            return false;
        }
        if (array_key_exists($file->get_id(), $synchronized)) {
            return $synchronized[$file->get_id()];
        }

        // remember that we already cached in current request to prevent from querying again
        $synchronized[$file->get_id()] = false;

        if (!$reference = $DB->get_record('files_reference', array('id'=>$file->get_referencefileid()))) {
            return false;
        }

        if (!empty($reference->lastsync) and ($reference->lastsync + $reference->lifetime > time())) {
            $synchronized[$file->get_id()] = true;
            return true;
        }

        if (!$repository = self::get_repository_by_id($reference->repositoryid, SYSCONTEXTID)) {
            return false;
        }

        if (!$repository->sync_individual_file($file)) {
            return false;
        }

        $fileinfo = $repository->get_file_by_reference($reference);
        if ($fileinfo === null) {
            // does not exist any more - set status to missing
            $file->set_missingsource();
            //TODO: purge content from pool if we set some other content hash and it is no used any more
            $synchronized[$file->get_id()] = true;
            return true;
        }

        $contenthash = null;
        $filesize = null;
        if (!empty($fileinfo->contenthash)) {
            // contenthash returned, file already in moodle
            $contenthash = $fileinfo->contenthash;
            $filesize = $fileinfo->filesize;
        } else if (!empty($fileinfo->filepath)) {
            // File path returned
            list($contenthash, $filesize, $newfile) = $fs->add_file_to_pool($fileinfo->filepath);
        } else if (!empty($fileinfo->handle) && is_resource($fileinfo->handle)) {
            // File handle returned
            $contents = '';
            while (!feof($fileinfo->handle)) {
                $contents .= fread($handle, 8192);
            }
            fclose($fileinfo->handle);
            list($contenthash, $filesize, $newfile) = $fs->add_string_to_pool($content);
        } else if (isset($fileinfo->content)) {
            // File content returned
            list($contenthash, $filesize, $newfile) = $fs->add_string_to_pool($fileinfo->content);
        }

        if (!isset($contenthash) or !isset($filesize)) {
            return false;
        }

        // update files table
        $file->set_synchronized($contenthash, $filesize);
        $synchronized[$file->get_id()] = true;
        return true;
    }
Ejemplo n.º 8
0
 /**
  * overridden constructor to set up the file.
  *
  */
 public function __construct($title, stored_file $file)
 {
     $id = portfolio_format_leap2a::file_id_prefix() . $file->get_id();
     parent::__construct($id, $title, 'resource');
     $this->referencedfile = $file;
     $this->published = $this->referencedfile->get_timecreated();
     $this->updated = $this->referencedfile->get_timemodified();
     $this->add_category('offline', 'resource_type');
 }