Example #1
0
 /**
  * Creates a file artefact based on the given entry.
  *
  * @param SimpleXMLElement $entry The entry to base the file's data on
  * @param PluginImport $importer  The importer
  * @param int $parent             The ID of the parent artefact for this file
  * @throws ImportException If the given entry is not detected as being a file
  * @return ArtefactTypeFile The file artefact created
  */
 public static function create_file(SimpleXMLElement $entry, PluginImport $importer, $parent = null)
 {
     if (!self::is_file($entry, $importer)) {
         throw new ImportException($importer, "create_file(): Cannot create a file artefact from an entry we don't recognise as a file");
     }
     // TODO: make sure there's no arbitrary file inclusion
     // TODO: the src attribute must be an IRI, according to the ATOM spec.
     // This means that it could have UTF8 characters in it, and the PHP
     // documentation doesn't sound hopeful that urldecode will work with
     // UTF8 characters
     $pathname = urldecode((string) $entry->content['src']);
     // TODO: might want to make it easier to get at the directory where the import files are
     $data = $importer->get('data');
     $dir = dirname($data['filename']);
     // Note: this data is passed (eventually) to ArtefactType->__construct,
     // which calls strtotime on the dates for us
     $data = (object) array('title' => (string) $entry->title, 'owner' => $importer->get('usr'), 'filetype' => (string) $entry->content['type']);
     if (isset($entry->summary)) {
         $data->description = (string) $entry->summary;
     }
     if ($published = strtotime((string) $entry->published)) {
         $data->ctime = (string) $entry->published;
     }
     if ($updated = strtotime((string) $entry->updated)) {
         $data->mtime = (string) $entry->updated;
     }
     if ($parent) {
         $data->parent = $parent;
     }
     $pathname = $dir . DIRECTORY_SEPARATOR . $pathname;
     // This API sucks, but that's not my problem
     if (!($id = ArtefactTypeFile::save_file($pathname, $data, $importer->get('usrobj')))) {
         throw new ImportException($importer, 'TODO: get_string: was unable to import file');
     }
     // Work out if the file was really a profile icon
     $isprofileicon = false;
     $match = $entry->xpath('mahara:artefactplugin[@mahara:plugin="file" and @mahara:type="profileicon"]');
     if (count($match) == 1) {
         $isprofileicon = true;
     }
     $artefact = artefact_instance_from_id($id);
     // Work around that save_file doesn't let us set the mtime
     $artefact->set('mtime', strtotime((string) $entry->updated));
     if ($isprofileicon) {
         $artefact->set('artefacttype', 'profileicon');
         $artefact->set('parent', null);
         // Sadly the process for creating a profile icon is a bit dumb. To
         // be honest, it shouldn't even be a separate artefact type
         $basedir = get_config('dataroot') . 'artefact/file/';
         $olddir = 'originals/' . $id % 256 . '/';
         $newdir = 'profileicons/originals/' . $id % 256 . '/';
         check_dir_exists($basedir . $newdir);
         if (!rename($basedir . $olddir . $id, $basedir . $newdir . $id)) {
             throw new ImportException($importer, 'TODO: get_string: was unable to move profile icon');
         }
         // Unconditionally set as default, even if there is more than one
         $importer->get('usrobj')->profileicon = $id;
         $importer->get('usrobj')->commit();
     }
     $artefact->commit();
     return $artefact;
 }
Example #2
0
 /**
  * Attaches a file to a blogpost entry that was just linked directly, rather than having a Leap2a entry
  * See http://wiki.leapspecs.org/2A/files
  *
  * @param SimpleXMLElement $entry
  * @param SimpleXMLElement $link
  */
 private function create_linked_file(SimpleXMLElement $entry, SimpleXMLElement $link)
 {
     $this->trace($link);
     $pathname = urldecode((string) $link['href']);
     $dir = dirname($this->get('filename'));
     $pathname = $dir . '/' . $pathname;
     if (!file_exists($pathname)) {
         return false;
     }
     // Note: this data is passed (eventually) to ArtefactType->__construct,
     // which calls strtotime on the dates for us
     require_once 'file.php';
     $data = (object) array('title' => (string) $entry->title . ' ' . get_string('attachment'), 'owner' => $this->get('usr'));
     $data->oldextension = end(explode('.', $data->title));
     return ArtefactTypeFile::save_file($pathname, $data, $this->get('usrobj'), true);
 }
Example #3
0
 public function extract($progresscallback = null)
 {
     global $USER;
     $quotauser = $this->owner ? $USER : null;
     $this->data['basefolderid'] = $this->create_base_folder();
     $this->data['folderids'] = array('.' => $this->data['basefolderid']);
     $this->data['folderscreated'] = 1;
     $this->data['filescreated'] = 0;
     $this->data['template'] = (object) array('owner' => $this->get('owner'), 'group' => $this->get('group'), 'institution' => $this->get('institution'));
     $tempdir = get_config('dataroot') . 'artefact/file/temp';
     check_dir_exists($tempdir);
     if ($this->archivetype == 'tar') {
         $this->read_archive();
         // Untar everything into a temp directory first
         $tempsubdir = tempnam($tempdir, '');
         unlink($tempsubdir);
         mkdir($tempsubdir, get_config('directorypermissions'));
         if (!$this->handle->extract($tempsubdir)) {
             throw new SystemException("Unable to extract archive into {$tempsubdir}");
         }
         $i = 0;
         foreach ($this->info->names as $name) {
             $folder = dirname($name);
             $this->data['template']->parent = $this->data['folderids'][$folder];
             $this->data['template']->title = basename($name);
             // set the file extension for later use (eg by flowplayer)
             $this->data['template']->extension = pathinfo($this->data['template']->title, PATHINFO_EXTENSION);
             $this->data['template']->oldextension = $this->data['template']->extension;
             if (substr($name, -1) == '/') {
                 $this->create_folder($folder);
             } else {
                 ArtefactTypeFile::save_file($tempsubdir . '/' . $name, $this->data['template'], $quotauser, true);
                 $this->data['filescreated']++;
             }
             if ($progresscallback && ++$i % 5 == 0) {
                 call_user_func($progresscallback, $i);
             }
         }
     } else {
         if ($this->archivetype == 'zip') {
             $this->open_archive();
             $tempfile = tempnam($tempdir, '');
             $i = 0;
             while ($entry = zip_read($this->handle)) {
                 $name = zip_entry_name($entry);
                 $folder = dirname($name);
                 // Create parent folders if necessary
                 if (!isset($this->data['folderids'][$folder])) {
                     $parent = '.';
                     $child = '';
                     $path = explode('/', $folder);
                     for ($i = 0; $i < count($path); $i++) {
                         $child .= $path[$i] . '/';
                         if (!isset($this->data['folderids'][$child])) {
                             $this->data['template']->parent = $this->data['folderids'][$parent];
                             $this->data['template']->title = $path[$i];
                             $this->create_folder($parent);
                         }
                         $parent = $child;
                     }
                 }
                 $this->data['template']->parent = $this->data['folderids'][$folder == '.' ? '.' : $folder . '/'];
                 $this->data['template']->title = basename($name);
                 // set the file extension for later use (eg by flowplayer)
                 $this->data['template']->extension = pathinfo($this->data['template']->title, PATHINFO_EXTENSION);
                 $this->data['template']->oldextension = $this->data['template']->extension;
                 if (substr($name, -1) != '/') {
                     $h = fopen($tempfile, 'w');
                     $size = zip_entry_filesize($entry);
                     $contents = zip_entry_read($entry, $size);
                     fwrite($h, $contents);
                     fclose($h);
                     ArtefactTypeFile::save_file($tempfile, $this->data['template'], $quotauser, true);
                     $this->data['filescreated']++;
                 }
                 if ($progresscallback && ++$i % 5 == 0) {
                     call_user_func($progresscallback, $i);
                 }
             }
         }
     }
     return $this->data;
 }
Example #4
0
oAAAAAAAAAD4DR1+AAGgmQaxAAAAAElFTkSuQmCC'), 'text/html' => 'te<b>xt/h</b>tml', 'text/plain' => 'text/plain', 'video/x-flv' => file_get_contents(get_config('docroot') . 'junk.flv'), 'application/octet-stream' => '??');
$profileicons = get_records_sql_array("\n    SELECT f.*, a.artefacttype\n    FROM {artefact_file_files} f JOIN {artefact} a ON f.artefact = a.id\n    WHERE a.artefacttype = 'profileicon'", null);
db_begin();
foreach ($profileicons as $r) {
    $filetype = isset($samples[$r->filetype]) ? $r->filetype : 'application/octet-stream';
    $dir = get_config('dataroot') . 'artefact/file/profileicons/originals/' . $r->artefact % 256;
    check_dir_exists($dir);
    $file = $dir . '/' . $r->artefact;
    if (!file_exists($file)) {
        file_put_contents($dir . '/' . $r->artefact, $samples[$filetype]);
        execute_sql("UPDATE {artefact_file_files} SET size = ?, fileid = ?, filetype = ? WHERE artefact = ?", array(filesize($dir . '/' . $r->artefact), $r->artefact, $filetype, $r->artefact));
    }
}
safe_require('artefact', 'file');
$files = array();
$ids = array();
foreach ($samples as $k => $v) {
    $n = 'a.' . get_random_key();
    $fn = "/tmp/{$n}";
    file_put_contents($fn, $v);
    $d = (object) array('title' => $n, 'owner' => $USER->get('id'), 'filetype' => $k);
    $id = ArtefactTypeFile::save_file($fn, $d, $USER, true);
    $ids[$id] = $id;
    $files[$k] = artefact_instance_from_id($id);
}
$records = get_records_sql_array("\n    SELECT f.*, a.artefacttype\n    FROM {artefact_file_files} f JOIN {artefact} a ON f.artefact = a.id\n    WHERE a.artefacttype != 'profileicon' AND NOT a.id IN (" . join(',', $ids) . ')', null);
foreach ($samples as $k => $v) {
    execute_sql("\n        UPDATE {artefact_file_files} SET size = ?, fileid = ? WHERE filetype = ?", array($files[$k]->get('size'), $files[$k]->get('fileid'), $k));
}
db_commit();
set_config('samplefiles', 1);
Example #5
0
 public function add_artefacts()
 {
     // we're just adding them as files into an 'incoming' directory in the user's file area.
     safe_require('artefact', 'file');
     try {
         $this->importdir = ArtefactTypeFolder::get_folder_id('incoming', get_string('incomingfolderdesc'), null, true, $this->get('usr'));
     } catch (Exception $e) {
         throw new ImportException($e->getMessage());
     }
     $savedfiles = array();
     // to put files into so we can delete them should we encounter an exception
     foreach ($this->files as $f) {
         try {
             $data = (object) array('title' => $f->wantsfilename, 'description' => $f->wantsfilename . ' (' . get_string('importedfrom', 'mahara', $this->get('importertransport')->get_description()) . ')', 'parent' => $this->importdir, 'owner' => $this->get('usr'), 'container' => 0, 'locked' => 0);
             if ($imagesize = getimagesize($this->tempdir . 'extract/' . $f->actualfilename)) {
                 $mime = $imagesize['mime'];
                 $data->filetype = $mime;
             }
             $id = ArtefactTypeFile::save_file($this->tempdir . 'extract/' . $f->actualfilename, $data, $this->get('usrobj'), true);
             if (empty($id)) {
                 throw new ImportException("Failed to create new artefact for {$f->sha1}");
             }
             $savedfiles[] = $id;
         } catch (Exception $e) {
             foreach ($savedfiles as $fileid) {
                 $tmp = artefact_instance_from_id($fileid);
                 $tmp->delete();
             }
             throw new ImportException('Failed to create some new artefacts');
         }
     }
     $this->artefacts = $savedfiles;
 }
 /**
  * Creates a file artefact based on the given entry.
  *
  * @param SimpleXMLElement $entry    The entry to base the file's data on
  * @param PluginImportLeap $importer The importer
  * @param int $parent                The ID of the parent artefact for this file
  * @throws ImportException If the given entry is not detected as being a file
  * @return ArtefactTypeFile The file artefact created
  */
 public static function create_file(SimpleXMLElement $entry, PluginImportLeap $importer, $parent = null)
 {
     if (!self::is_file($entry, $importer)) {
         throw new ImportException($importer, "create_file(): Cannot create a file artefact from an entry we don't recognise as a file");
     }
     // TODO: make sure there's no arbitrary file inclusion
     // TODO: the src attribute must be an IRI, according to the ATOM spec.
     // This means that it could have UTF8 characters in it, and the PHP
     // documentation doesn't sound hopeful that urldecode will work with
     // UTF8 characters
     $pathname = false;
     $description = '';
     if (isset($entry->content['src'])) {
         $pathname = urldecode((string) $entry->content['src']);
         $filetype = (string) $entry->content['type'];
     } else {
         foreach ($entry->link as $link) {
             if ($importer->curie_equals($link['rel'], '', 'enclosure') && isset($link['href']) && !$importer->entry_exists((string) $link['href'])) {
                 $pathname = urldecode((string) $link['href']);
                 $filetype = (string) $link['type'];
                 $description = strip_tags(PluginImportLeap::get_entry_content($entry, $importer));
                 // TODO do we have a better way of stripping tags? and why isn't this html anyway?
             }
         }
     }
     if (!$pathname) {
         $importer->trace("WARNING: couldn't find a file for {$entry->id} ");
         return;
     }
     // TODO: might want to make it easier to get at the directory where the import files are
     $dir = dirname($importer->get('filename'));
     // Note: this data is passed (eventually) to ArtefactType->__construct,
     // which calls strtotime on the dates for us
     $data = (object) array('title' => (string) $entry->title, 'description' => $description, 'owner' => $importer->get('usr'), 'filetype' => $filetype);
     if (isset($entry->summary) && empty($description)) {
         $data->description = (string) $entry->summary;
     }
     if ($published = strtotime((string) $entry->published)) {
         $data->ctime = (string) $entry->published;
     }
     if ($updated = strtotime((string) $entry->updated)) {
         $data->mtime = (string) $entry->updated;
     }
     if ($parent) {
         $data->parent = $parent;
     }
     $pathname = $dir . DIRECTORY_SEPARATOR . $pathname;
     // This API sucks, but that's not my problem
     if (!($id = ArtefactTypeFile::save_file($pathname, $data, $importer->get('usrobj'), true))) {
         $importer->trace("WARNING: the file for entry {$entry->id} does not exist in the import (path={$pathname})");
         return;
     }
     $artefact = artefact_instance_from_id($id);
     $artefact->set('tags', PluginImportLeap::get_entry_tags($entry));
     // Work out if the file was really a profile icon
     $isprofileicon = false;
     if ($artefact->get('artefacttype') == 'image') {
         $match = $entry->xpath('mahara:artefactplugin[@mahara:plugin="file" and @mahara:type="profileicon"]');
         if (count($match) == 1) {
             $isprofileicon = true;
         } else {
             if ($importer->get('persondataid')) {
                 $persondata = $importer->get_entry_by_id($importer->get('persondataid'));
                 if (count($persondata->xpath('a:link[@rel="related" and @href="' . (string) $entry->id . '"]')) == 1) {
                     $isprofileicon = true;
                 }
             }
         }
     }
     // Work around that save_file doesn't let us set the mtime
     $artefact->set('mtime', strtotime((string) $entry->updated));
     if ($isprofileicon) {
         $artefact->set('artefacttype', 'profileicon');
         $artefact->set('parent', null);
         // Sadly the process for creating a profile icon is a bit dumb. To
         // be honest, it shouldn't even be a separate artefact type
         $basedir = get_config('dataroot') . 'artefact/file/';
         $olddir = 'originals/' . $id % 256 . '/';
         $newdir = 'profileicons/originals/' . $id % 256 . '/';
         check_dir_exists($basedir . $newdir);
         if (!rename($basedir . $olddir . $id, $basedir . $newdir . $id)) {
             throw new ImportException($importer, 'TODO: get_string: was unable to move profile icon');
         }
     }
     $artefact->commit();
     return $artefact;
 }
Example #7
0
 /**
  * Logic shared by create_file_from_request() and create_file(). This actually takes the data and processes it into a file artefact
  * @param object $data
  * @param PluginImportLeap $importer
  * @param int $parent
  * @param SimplexMLElement $entry
  * @param unknown_type $entry_request
  * @return PluginArtefactFile
  * @throws ImportException
  */
 private static function create_file_from_entry_data($data, PluginImportLeap $importer, $entryid, $fromrequest = false)
 {
     global $USER;
     if ($fromrequest) {
         $usr = $USER;
     } else {
         $usr = $importer->get('usrobj');
     }
     $data->oldextension = end(explode('.', $data->title));
     // This API sucks, but that's not my problem
     if (!($id = ArtefactTypeFile::save_file($data->pathname, $data, $usr, true))) {
         $importer->trace("WARNING: the file for entry {$entryid} does not exist in the import (path={$data->pathname})");
         return false;
     }
     $artefact = artefact_instance_from_id($id);
     $artefact->set('tags', $data->tags);
     if ($fromrequest) {
         $artefact->set('mtime', $data->mtime);
     } else {
         // Work around that save_file doesn't let us set the mtime
         $artefact->set('mtime', strtotime($data->mtime));
     }
     // Now that we've actually imported the file, let's check to see whether it was an image, before making it a real profile icon
     $isprofileicon = $data->isprofileicon && $artefact->get('artefacttype') == 'image';
     if ($isprofileicon) {
         $artefact->set('artefacttype', 'profileicon');
         // Put profile pic in 'profile pics' folder
         $artefact->set('parent', ArtefactTypeFolder::get_folder_id(get_string('imagesdir', 'artefact.file'), get_string('imagesdirdesc', 'artefact.file'), null, true, $importer->get('usr')));
         // Sadly the process for creating a profile icon is a bit dumb. To
         // be honest, it shouldn't even be a separate artefact type
         $basedir = get_config('dataroot') . 'artefact/file/';
         $olddir = 'originals/' . $id % 256 . '/';
         $newdir = 'profileicons/originals/' . $id % 256 . '/';
         check_dir_exists($basedir . $newdir);
         if (!rename($basedir . $olddir . $id, $basedir . $newdir . $id)) {
             throw new ImportException($importer, 'TODO: get_string: was unable to move profile icon');
         }
     }
     $artefact->commit();
     return $artefact;
 }
Example #8
0
 /**
  * Attaches a file to a blogpost entry that was just linked directly, rather than having a Leap2a entry
  * See http://wiki.leapspecs.org/2A/files
  *
  * @param SimpleXMLElement $blogpostentry
  * @param SimpleXMLElement $blogpostlink
  * @param PluginImportLeap $importer
  */
 private static function attach_linked_file($blogpostentry, $blogpostlink, PluginImportLeap $importer)
 {
     $importer->trace($blogpostlink);
     $pathname = urldecode((string) $blogpostlink['href']);
     $dir = dirname($importer->get('filename'));
     $pathname = $dir . '/' . $pathname;
     if (!file_exists($pathname)) {
         return false;
     }
     // Note: this data is passed (eventually) to ArtefactType->__construct,
     // which calls strtotime on the dates for us
     require_once 'file.php';
     $data = (object) array('title' => (string) $blogpostentry->title . ' ' . get_string('attachment', 'artefact.blog'), 'owner' => $importer->get('usr'));
     $data->oldextension = end(explode('.', $data->title));
     return ArtefactTypeFile::save_file($pathname, $data, $importer->get('usrobj'), true);
 }