Пример #1
0
 /**
  * Handles view events for latex files
  *
  * @param   \Hubzero\Filesystem\Collection  $collection  The file collection to view
  * @return  void
  **/
 public function onHandleView(\Hubzero\Filesystem\Collection $collection)
 {
     if (!$this->canHandle($collection)) {
         return false;
     }
     $file = $collection->findFirstWithExtension('tex');
     // Create view
     $view = new \Hubzero\Plugin\View(['folder' => 'handlers', 'element' => 'latex', 'name' => 'latex', 'layout' => 'view']);
     // Build path for storing temp previews
     $outputDir = PATH_APP . DS . trim($this->params->get('compile_dir', 'site/latex/compiled'), DS);
     $adapter = Manager::adapter('local', ['path' => $outputDir]);
     $uniqid = md5(uniqid());
     $temp = File::fromPath($uniqid . '.tex', $adapter);
     // Clean up data from Windows characters - important!
     $data = preg_replace('/[^(\\x20-\\x7F)\\x0A]*/', '', $file->read());
     // Store file locally
     $temp->write($data);
     // Build the command
     $command = DS . trim($this->params->get('texpath', '/usr/bin/pdflatex'), DS);
     $command .= ' -output-directory=' . $outputDir . ' -interaction=batchmode ' . escapeshellarg($temp->getAbsolutePath());
     // Exec and capture output
     exec($command, $out);
     $compiled = File::fromPath($uniqid . '.pdf', $adapter);
     $log = File::fromPath($uniqid . '.log', $adapter);
     if (!$compiled->size()) {
         $view->setError(Lang::txt('PLG_HANDLERS_LATEX_ERROR_COMPILE_TEX_FAILED'));
     }
     // Read log (to show in case of error)
     if ($log->size()) {
         $view->log = $log->read();
     }
     $view->compiled = $compiled;
     return $view;
 }
Пример #2
0
 /**
  * Expand archive
  *
  * @param   bool  $cleanup  Whether or not to clean up after expansion (i.e. removing known OS files, etc...)
  * @return  bool
  */
 public function expand($cleanup = true)
 {
     // Create local tmp copy of the archive that's being expanded
     $temp = Manager::getTempPath($this->getName());
     $this->copy($temp);
     $archive = new \PharData($temp->getAbsolutePath());
     foreach ($archive as $file) {
         // Add 7 to the length for the 'phar://' prefix to the file
         $path = substr($file, strlen($temp->getAbsolutePath()) + 7);
         $entity = Entity::fromPath($this->getParent() . $path, $this->getAdapter());
         if ($entity->isFile()) {
             // Open
             $item = fopen($file, 'r');
             // Write stream
             $entity->putStream($item);
             // Close
             fclose($item);
         } else {
             // Create the directory
             $entity->create();
         }
     }
     // Clean up
     $temp->delete();
     return parent::expand($cleanup);
 }
Пример #3
0
 /**
  * Expand archive
  *
  * @param   bool  $cleanup  Whether or not to clean up after expansion (i.e. removing known OS files, etc...)
  * @return  bool
  */
 public function expand($cleanup = true)
 {
     // Create local tmp copy of the archive that's being expanded
     $temp = Manager::getTempPath($this->getName());
     $this->copy($temp);
     $zip = new \ZipArchive();
     // Open the temp archive (we use the absolute path because we're on the local filesystem)
     if ($zip->open($temp->getAbsolutePath()) === true) {
         // We don't actually have to extract the archive, we can just read out of it and copy over to the original location
         for ($i = 0; $i < $zip->numFiles; $i++) {
             $filename = $zip->getNameIndex($i);
             $entity = Entity::fromPath($this->getParent() . '/' . $filename, $this->getAdapter());
             if ($entity->isFile()) {
                 // Open
                 $item = fopen('zip://' . $temp->getAbsolutePath() . '#' . $filename, 'r');
                 // Write stream
                 $entity->putStream($item);
                 // Close
                 fclose($item);
             } else {
                 // Create the directory
                 $entity->create();
             }
         }
         // Clean up
         $zip->close();
         $temp->delete();
         return parent::expand($cleanup);
     }
     return false;
 }
Пример #4
0
 /**
  * Compiles PDF/image preview for any kind of file
  *
  * @return  string
  */
 public function compile()
 {
     // Combine file and folder data
     $items = $this->getCollection();
     // Incoming
     $download = Request::getInt('download', 0);
     // Check that we have compile enabled
     // @FIXME: why are latex and compiled preview tied together?
     //         presumedly we are also 'compiling' pdfs?
     if (!$this->params->get('latex')) {
         $this->setError(Lang::txt('PLG_PROJECTS_FILES_COMPILE_NOTALLOWED'));
         return;
     }
     // Output HTML
     $view = new \Hubzero\Plugin\View(['folder' => 'projects', 'element' => 'files', 'name' => 'connected', 'layout' => 'compiled']);
     // Make sure we have an item
     if (count($items) == 0) {
         $view->setError(Lang::txt('PLG_PROJECTS_FILES_ERROR_NO_FILES_TO_COMPILE'));
         $view->loadTemplate();
         return;
     }
     // We can only handle one file at a time
     $file = $items->first();
     // Build path for storing temp previews
     $imagePath = trim($this->model->config()->get('imagepath', '/site/projects'), DS);
     $outputDir = DS . $imagePath . DS . strtolower($this->model->get('alias')) . DS . 'compiled';
     // Make sure output dir exists
     if (!is_dir(PATH_APP . $outputDir)) {
         if (!Filesystem::makeDirectory(PATH_APP . $outputDir)) {
             $this->setError(Lang::txt('PLG_PROJECTS_FILES_UNABLE_TO_CREATE_UPLOAD_PATH'));
             return;
         }
     }
     // Get LaTeX helper
     $compiler = new \Components\Projects\Helpers\Compiler();
     // Tex compiler path
     $texPath = DS . trim($this->params->get('texpath'), DS);
     // Set view args and defaults
     $view->file = $file;
     $view->oWidth = '780';
     $view->oHeight = '460';
     $view->url = $this->model->link('files');
     $cExt = 'pdf';
     // Tex file?
     $tex = $compiler->isTexFile($file->getName());
     // Build temp name
     $tempBase = $tex ? 'temp__' . \Components\Projects\Helpers\Html::takeOutExt($file->getName()) : $file->getName();
     $tempBase = str_replace(' ', '_', $tempBase);
     $view->data = $file->isImage() ? NULL : $file->read();
     // LaTeX file?
     if ($tex && !empty($view->data)) {
         // Clean up data from Windows characters - important!
         $view->data = preg_replace('/[^(\\x20-\\x7F)\\x0A]*/', '', $view->data);
         // Store file locally
         $tmpfile = PATH_APP . $outputDir . DS . $tempBase;
         file_put_contents($tmpfile, $view->data);
         // Compile and get path to PDF
         $contentFile = $compiler->compileTex($tmpfile, $view->data, $texPath, PATH_APP . $outputDir, 1, $tempBase);
         // Read log (to show in case of error)
         $logFile = $tempBase . '.log';
         if (file_exists(PATH_APP . $outputDir . DS . $logFile)) {
             $view->log = Filesystem::read(PATH_APP . $outputDir . DS . $logFile);
         }
         if (!$contentFile) {
             $this->setError(Lang::txt('PLG_PROJECTS_FILES_ERROR_COMPILE_TEX_FAILED'));
         }
         $cType = Filesystem::mimetype(PATH_APP . $outputDir . DS . $contentFile);
     } else {
         // Make sure we can handle preview of this type of file
         if ($file->hasExtension('pdf') || $file->isImage() || !$file->isBinary()) {
             $origin = $this->connection->provider->alias . '://' . $file->getPath();
             $dest = 'compiled://' . $tempBase;
             // Do the copy
             Manager::adapter('local', ['path' => PATH_APP . $outputDir . DS], 'compiled');
             Manager::copy($origin, $dest);
             $contentFile = $tempBase;
         }
     }
     // Parse output
     if (!empty($contentFile) && file_exists(PATH_APP . $outputDir . DS . $contentFile)) {
         // Get compiled content mimetype
         $cType = Filesystem::mimetype(PATH_APP . $outputDir . DS . $contentFile);
         // Is image?
         if (strpos($cType, 'image/') !== false) {
             // Fix up object width & height
             list($width, $height, $type, $attr) = getimagesize(PATH_APP . $outputDir . DS . $contentFile);
             $xRatio = $view->oWidth / $width;
             $yRatio = $view->oHeight / $height;
             if ($xRatio * $height < $view->oHeight) {
                 // Resize the image based on width
                 $view->oHeight = ceil($xRatio * $height);
             } else {
                 // Resize the image based on height
                 $view->oWidth = ceil($yRatio * $width);
             }
         }
         // Download compiled file?
         if ($download) {
             $pdfName = $tex ? str_replace('temp__', '', basename($contentFile)) : basename($contentFile);
             // Serve up file
             $server = new \Hubzero\Content\Server();
             $server->filename(PATH_APP . $outputDir . DS . $contentFile);
             $server->disposition('attachment');
             $server->acceptranges(false);
             $server->saveas($pdfName);
             $result = $server->serve();
             if (!$result) {
                 // Should only get here on error
                 throw new Exception(Lang::txt('PLG_PROJECTS_FILES_SERVER_ERROR'), 404);
             } else {
                 exit;
             }
         }
         // Generate preview image for browsers that cannot embed pdf
         if ($cType == 'application/pdf') {
             // GS path
             $gspath = trim($this->params->get('gspath'), DS);
             if ($gspath && file_exists(DS . $gspath . DS . 'gs')) {
                 $gspath = DS . $gspath . DS;
                 $pdfName = $tex ? str_replace('temp__', '', basename($contentFile)) : basename($contentFile);
                 $pdfPath = PATH_APP . $outputDir . DS . $contentFile;
                 $exportPath = PATH_APP . $outputDir . DS . $tempBase . '%d.jpg';
                 exec($gspath . "gs -dNOPAUSE -sDEVICE=jpeg -r300 -dFirstPage=1 -dLastPage=1 -sOutputFile={$exportPath} {$pdfPath} 2>&1", $out);
                 if (is_file(PATH_APP . $outputDir . DS . $tempBase . '1.jpg')) {
                     $hi = new \Hubzero\Image\Processor(PATH_APP . $outputDir . DS . $tempBase . '1.jpg');
                     if (count($hi->getErrors()) == 0) {
                         $hi->resize($view->oWidth, false, false, true);
                         $hi->save(PATH_APP . $outputDir . DS . $tempBase . '1.jpg');
                     } else {
                         return false;
                     }
                 }
                 if (is_file(PATH_APP . $outputDir . DS . $tempBase . '1.jpg')) {
                     $image = $tempBase . '1.jpg';
                 }
             }
         }
     } elseif (!$this->getError()) {
         $this->setError(Lang::txt('PLG_PROJECTS_FILES_ERROR_COMPILE_PREVIEW_FAILED'));
     }
     $view->file = $file;
     $view->outputDir = $outputDir;
     $view->embed = $contentFile;
     $view->cType = $cType;
     $view->subdir = $this->subdir;
     $view->option = $this->_option;
     $view->image = !empty($image) ? $image : NULL;
     $view->model = $this->model;
     $view->repo = $this->repo;
     $view->connection = $this->connection;
     if ($this->getError()) {
         $view->setError($this->getError());
     }
     return $view->loadTemplate();
 }
Пример #5
0
 /**
  * Compresses/archives entities in collection
  *
  * @param   bool  $structure  Whether or not to retain directory location of files being zipped
  * @param   bool  $upload     Whether or not to reupload compressed to filesystem location
  * @return  string|bool
  */
 public function compress($structure = false, $upload = false)
 {
     if (!extension_loaded('zip')) {
         return false;
     }
     // Get temp directory
     $adapter = null;
     $temp = sys_get_temp_dir();
     $tarname = uniqid() . '.zip';
     $zip = new \ZipArchive();
     if ($zip->open($temp . DS . $tarname, \ZipArchive::OVERWRITE) === true) {
         foreach ($this->_data as $entity) {
             if ($entity->isFile()) {
                 $zip->addFromString($structure ? $entity->getPath() : $entity->getName(), $entity->read());
             } else {
                 if ($entity->isDir() && $structure) {
                     $zip->addEmptyDir($entity->getPath());
                 }
             }
             // Set some vars in case we need them later
             $adapter = $adapter ?: $entity->getAdapter();
         }
         $zip->close();
         $local = Manager::getTempPath();
         if ($upload) {
             // @FIXME: use manager copy?
             $entity = Entity::fromPath($tarname, $adapter);
             $entity->put($local->readAndDelete());
             return $entity;
         } else {
             return $local;
         }
     } else {
         return false;
     }
 }
Пример #6
0
 /**
  * Generates the filesystem adapter for the given provider
  *
  * @param   array   $options  extra params to include with defaults
  * @return  object
  **/
 public function adapter($options = [])
 {
     $params = (array) json_decode($this->params);
     $params = array_merge($params, $options);
     return Manager::adapter($this->provider->alias, $params);
 }
Пример #7
0
 /**
  * Copies the entity
  *
  * @param   string|object  $to  What/where to copy the entity to
  * @return  bool
  **/
 public function copy($to)
 {
     if (is_string($to)) {
         return $this->hasAdapterOrFail()->adapter->copy($this->getPath(), $to);
     } else {
         return Manager::copy($this, $to);
     }
 }
Пример #8
0
 /**
  * Save incoming file selection
  *
  * @return  boolean
  */
 public function save($element, $elementId, $pub, $blockParams, $toAttach = array())
 {
     // Incoming selections
     if (empty($toAttach)) {
         $selections = Request::getVar('selecteditems', '');
         $toAttach = explode(',', $selections);
     }
     // Get configs
     $configs = $this->getConfigs($element, $elementId, $pub, $blockParams);
     // Cannot make changes
     if ($configs->freeze) {
         return false;
     }
     // Nothing to change
     if (empty($toAttach)) {
         return false;
     }
     // Git helper
     include_once PATH_CORE . DS . 'components' . DS . 'com_projects' . DS . 'helpers' . DS . 'githelper.php';
     $this->_git = new \Components\Projects\Helpers\Git($configs->path);
     // Counter
     $i = 0;
     $a = 0;
     // Attach/refresh each selected item
     foreach ($toAttach as $identifier) {
         if (!trim($identifier)) {
             continue;
         }
         $identifier = urldecode($identifier);
         // Catch items coming in from connections
         if (preg_match('/^([0-9]*):\\/\\//', $identifier, $matches)) {
             if (isset($matches[1])) {
                 require_once PATH_CORE . DS . 'components' . DS . 'com_projects' . DS . 'models' . DS . 'orm' . DS . 'connection.php';
                 // Grab the connection id
                 $connection = $matches[1];
                 // Reset identifier
                 $identifier = str_replace($matches[0], '', $identifier);
                 $connection = Connection::oneOrFail($connection);
                 // Create file objects
                 $conFile = Entity::fromPath($identifier, $connection->adapter());
                 if (!$conFile->isLocal()) {
                     // Create a temp file and write to it
                     $tempFile = Manager::getTempPath($conFile->getName());
                     Manager::copy($conFile, $tempFile);
                 } else {
                     $tempFile = $conFile;
                 }
                 // Insert the file into the repo
                 $result = $pub->_project->repo()->insert(['subdir' => $conFile->getParent(), 'dataPath' => $tempFile->getAbsolutePath(), 'update' => false]);
                 if (!$conFile->isLocal()) {
                     $tempFile->delete();
                 }
             }
         }
         $a++;
         $ordering = $i + 1;
         if ($this->addAttachment($identifier, $pub, $configs, User::get('id'), $elementId, $element, $ordering)) {
             $i++;
         }
     }
     // Success
     if ($i > 0 && $i == $a) {
         Event::trigger('filesystem.onAfterSaveFileAttachments', [$pub, $configs, $elementId, $element]);
         $message = $this->get('_message') ? $this->get('_message') : Lang::txt('Selection successfully saved');
         $this->set('_message', $message);
     }
     return true;
 }