Exemple #1
0
 /**
  * Send file back or from to remote service for remote editing
  * Local repo only
  *
  * @return  void  redirect
  */
 protected function _share()
 {
     // Check permission
     if (!$this->model->access('content')) {
         App::abort(403, Lang::txt('ALERTNOTAUTH'));
     }
     // Incoming
     $converted = Request::getInt('converted', 0);
     $service = Request::getVar('service', 'google');
     $sync = false;
     $shared = 0;
     // Get stored remote connections
     $remotes = $this->_getRemoteConnections(false);
     // Params for repo call
     $params = array('subdir' => $this->subdir, 'remoteConnections' => $remotes);
     // Combine file and folder data
     $items = $this->_sortIncoming();
     if (empty($items)) {
         $this->setError(Lang::txt('PLG_PROJECTS_FILES_ERROR_NO_FILES_TO_SHARE'));
     } else {
         // Sharing for a single file
         $type = key($items[0]);
         $item = $items[0][$type];
         // Build metadata object
         $file = $this->repo->getMetadata($item, $type, $params);
     }
     // Build return url
     $url = $this->model->link('files');
     $url .= $this->repo->isLocal() ? '' : '&repo=' . $this->repo->get('name');
     $url .= $this->subdir ? '&subdir=' . urlencode($this->subdir) : '';
     // Check user is connected
     if (!empty($this->_remoteService)) {
         $connected = $this->_connect->getStoredParam($this->_remoteService . '_token', $this->_uid);
         if (!$connected) {
             // Redirect to connect screen
             \Notify::message(Lang::txt('PLG_PROJECTS_FILES_REMOTE_PLEASE_CONNECT'), 'success', 'projects');
             App::redirect(Route::url($this->model->link('files') . '&action=connect'));
         }
     } else {
         $this->setError(Lang::txt('PLG_PROJECTS_FILES_ERROR_REMOTE_NOT_ENABLED'));
     }
     // Confirmation screen
     if ($this->_task == 'share') {
         // Output HTML
         $view = new \Hubzero\Plugin\View(array('folder' => 'projects', 'element' => 'files', 'name' => 'share'));
         $view->option = $this->_option;
         $view->model = $this->model;
         $view->repo = $this->repo;
         $view->uid = $this->_uid;
         $view->subdir = $this->subdir;
         $view->path = $this->_path;
         if ($this->getError()) {
             $view->setError($this->getError());
         } else {
             $view->file = !empty($file) ? $file : NULL;
             $view->connect = $this->_connect;
             $view->service = $this->_remoteService;
         }
         return $view->loadTemplate();
     }
     // On error
     if ($this->getError()) {
         // Output error
         $view = new \Hubzero\Plugin\View(array('folder' => 'projects', 'element' => 'files', 'name' => 'error'));
         $view->title = '';
         $view->option = $this->_option;
         $view->setError($this->getError());
         return $view->loadTemplate();
     }
     // Send file for remote editing on Google
     if ($this->_task == 'shareit') {
         // Get convertable formats
         $formats = \Components\Projects\Helpers\Google::getGoogleConversionExts();
         // Import remote file
         if ($file->get('converted')) {
             // Load remote resource
             $resource = $this->_connect->loadRemoteResource($service, $this->_uid, $file->get('remoteId'));
             if (!$resource) {
                 $this->setError(Lang::txt('PLG_PROJECTS_FILES_SHARING_NO_REMOTE'));
             } else {
                 // Incoming
                 $importExt = Request::getVar('format', 'pdf', 'post');
                 // Remove Google native extension from title
                 $title = $file->get('name');
                 if (in_array($file->get('ext'), array('gdoc', 'gsheet', 'gslides', 'gdraw'))) {
                     $title = preg_replace("/." . $file->get('ext') . "\\z/", "", $file->get('name'));
                 }
                 // Do we have extention in name already? - take it out
                 $n_parts = explode('.', $title);
                 $n_ext = count($n_parts) > 1 ? array_pop($n_parts) : '';
                 $title = implode($n_parts);
                 $title .= '.' . $importExt;
                 $newpath = $this->subdir ? $this->subdir . DS . $title : $title;
                 $file->set('localPath', $newpath);
                 $file->set('name', $title);
                 $file->set('fullPath', $this->_path . DS . $newpath);
                 // Replacing file?
                 $exists = file_exists($file->get('fullPath')) ? 1 : 0;
                 // Download remote file
                 if ($this->_connect->importFile($this->_remoteService, $this->_uid, $resource, $file->get('localPath'), $this->repo->get('path'), $importExt)) {
                     // Checkin into repo
                     $params['file'] = $file;
                     $this->repo->call('checkin', $params);
                     // Remove remote resource
                     $deleted = $this->_connect->deleteRemoteItem($this->model->get('id'), $service, $this->_uid, $file->get('remoteId'), false);
                     // Create remote file for imported file
                     $created = NULL;
                     if (!$exists) {
                         $created = $this->_connect->addRemoteFile($this->model->get('id'), $this->_remoteService, $this->_uid, $file);
                     }
                     // Update connection record
                     $this->_connect->savePairing($this->model->get('id'), $this->_remoteService, $created, $file->get('localPath'), $file->get('recordId'), $file->get('originalPath'), $file->get('originalFormat'), $file->get('remoteId'));
                 }
                 // Output message
                 \Notify::message(Lang::txt('PLG_PROJECTS_FILES_UNSHARE_SUCCESS') . ' ' . $title, 'success', 'projects');
                 // Force sync
                 $sync = true;
             }
         } else {
             // Check that local file exists
             if (!$this->repo->fileExists($file->get('localPath'))) {
                 $this->setError(Lang::txt('PLG_PROJECTS_FILES_SHARING_LOCAL_FILE_MISSING'));
             } else {
                 // LaTeX?
                 $tex = Components\Projects\Helpers\Compiler::isTexFile($file->get('name'), $file->getMimeType());
                 // Check format
                 if (!in_array($file->get('ext'), $formats) && !$tex) {
                     $this->setError(Lang::txt('PLG_PROJECTS_FILES_SHARING_NOT_CONVERTABLE'));
                 }
                 if (!$this->getError()) {
                     if ($tex) {
                         // LaTeX? Convert to text file first
                         $file->set('mimeType', 'text/plain');
                     }
                     if ($file->get('ext') == 'wmf') {
                         // WMF files need this mime type specified for conversion to Google drawing
                         $file->set('mimeType', 'application/x-msmetafile');
                     }
                     if ($file->get('ext') == 'ppt' || $file->get('ext') == 'pps' || $file->get('ext') == 'pptx') {
                         $file->set('mimeType', 'application/vnd.openxmlformats-officedocument.presentationml.presentation');
                     }
                     // Convert file
                     $added = $this->_connect->addRemoteFile($this->model->get('id'), $this->_remoteService, $this->_uid, $file, $file->get('remoteParent'), true);
                     if ($added) {
                         // Remove original local file
                         $params['file'] = $file;
                         $this->repo->deleteItem($params);
                         // Remove original remote file
                         $deleted = $this->_connect->deleteRemoteItem($this->model->get('id'), $this->_remoteService, $this->_uid, $file->get('remoteId'), false);
                         $file->clear('mimeType');
                         $file->setMimeType();
                         // Update connection record
                         $this->_connect->savePairing($this->model->get('id'), $this->_remoteService, $added, '', $file->get('recordId'), $file->get('originalPath'), $file->get('mimeType'), $file->get('remoteId'));
                         // Output message
                         \Notify::message(Lang::txt('PLG_PROJECTS_FILES_SHARE_SUCCESS'), 'success', 'projects');
                         // Force sync
                         $sync = true;
                     } else {
                         // Something went wrong
                         $this->setError(Lang::txt('PLG_PROJECTS_FILES_SHARE_ERROR_NO_CONVERT'));
                         if ($this->_connect->getError()) {
                             $this->setError($this->_connect->getError());
                         }
                     }
                 }
             }
         }
     }
     // Pass success or error message
     if ($this->getError()) {
         \Notify::message($this->getError(), 'error', 'projects');
     }
     // Force sync
     if ($sync && $this->repo->isLocal()) {
         $this->model->saveParam('google_sync_queue', 1);
     }
     // Redirect to file list
     App::redirect(Route::url($url));
 }
 /**
  * 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();
 }