/** * 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(); }