/** * Compile PDF/image preview for any kind of file * * * @return mixed array or false */ protected function _compile() { // Combine file and folder data $items = $this->_sortIncoming(); // Get stored remote connections $remotes = $this->_getRemoteConnections(); // Params for repo call $params = array('subdir' => $this->subdir, 'remoteConnections' => $remotes); // Incoming $commit = Request::getInt('commit', 0); $download = Request::getInt('download', 0); // Check that we have compile enabled if (!$this->params->get('latex')) { $this->setError(Lang::txt('PLG_PROJECTS_FILES_COMPILE_NOTALLOWED')); return; } // Output HTML $view = new \Hubzero\Plugin\View(array('folder' => 'projects', 'element' => 'files', 'name' => 'compiled')); // Get selected item if (!$items) { $view->setError(Lang::txt('PLG_PROJECTS_FILES_ERROR_NO_FILES_TO_COMPILE')); $view->loadTemplate(); return; } else { foreach ($items as $element) { foreach ($element as $type => $item) { // Get our metadata $file = $this->repo->getMetadata($item, 'file', $params); break; } } } // We need a file if (empty($file)) { $view->setError(Lang::txt('PLG_PROJECTS_FILES_ERROR_NO_FILES_TO_COMPILE')); $view->loadTemplate(); return; } // 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); $view->file = $file; $view->oWidth = '780'; $view->oHeight = '460'; $view->url = Route::url($this->model->link('files')); $cExt = 'pdf'; // Take out Google native extension if present $fileName = $file->get('name'); if (in_array($file->get('ext'), \Components\Projects\Helpers\Google::getGoogleNativeExts())) { $fileName = preg_replace("/." . $file->get('ext') . "\\z/", "", $file->get('name')); } // Tex file? $tex = $compiler->isTexFile($fileName); // Build temp name $tempBase = $tex ? 'temp__' . \Components\Projects\Helpers\Html::takeOutExt($fileName) : $fileName; $tempBase = str_replace(' ', '_', $tempBase); // Get file contents if (!empty($this->_remoteService) && $file->get('converted')) { // Load remote resource $this->_connect->setUser($this->model->get('owned_by_user')); $resource = $this->_connect->loadRemoteResource($this->_remoteService, $this->model->get('owned_by_user'), $file->get('remoteId')); $cExt = $tex ? 'tex' : \Components\Projects\Helpers\Google::getGoogleImportExt($resource['mimeType']); $cExt = in_array($cExt, array('tex', 'jpeg')) ? $cExt : 'pdf'; $url = \Components\Projects\Helpers\Google::getDownloadUrl($resource, $cExt); // Get data $view->data = $this->_connect->sendHttpRequest($this->_remoteService, $this->model->get('owned_by_user'), $url); } elseif ($file->exists()) { $view->data = $file->isImage() ? NULL : $file->contents(); } else { $this->setError(Lang::txt('PLG_PROJECTS_FILES_ERROR_COMPILE_NO_DATA')); } // LaTeX file? if ($tex && !empty($view->data)) { // Clean up data from Windows characters - important! $view->data = preg_replace('/[^(\\x20-\\x7F)\\x0A]*/', '', $view->data); // Compile and get path to PDF $contentFile = $compiler->compileTex($file->get('fullPath'), $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')); } } elseif ($file->get('converted') && !empty($view->data)) { $tempBase = \Components\Projects\Helpers\Google::getImportFilename($file->get('name'), $cExt); // Write content to temp file $this->_connect->fetchFile($view->data, $tempBase, PATH_APP . $outputDir); $contentFile = $tempBase; } elseif (!$this->getError()) { // Make sure we can handle preview of this type of file if ($file->get('ext') == 'pdf' || $file->isImage() || !$file->isBinary()) { Filesystem::copy($file->get('fullPath'), PATH_APP . $outputDir . DS . $tempBase); $contentFile = $tempBase; } } $url = $this->model->link('files'); $url .= $this->repo->isLocal() ? '' : '&repo=' . $this->repo->get('name'); $url .= $this->subdir ? '&subdir=' . urlencode($this->subdir) : ''; // 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_attachment(PATH_APP . $outputDir . DS . $contentFile, $pdfName, false); if (!$result) { // Should only get here on error App::abort(404, Lang::txt('PLG_PROJECTS_FILES_SERVER_ERROR')); } else { exit; } } // Add compiled PDF to repository? if ($commit && $tex) { $pdfName = str_replace('temp__', '', basename($contentFile)); $where = $this->subdir ? $this->subdir . DS . $pdfName : $pdfName; if (Filesystem::copy(PATH_APP . $outputDir . DS . $contentFile, $this->_path . DS . $where)) { // Checkin into repo $params = array('subdir' => $this->subdir); $params['file'] = $this->repo->getMetadata($pdfName, 'file', $params); $this->repo->call('checkin', $params); if ($this->repo->isLocal()) { $this->model->saveParam('google_sync_queue', 1); } \Notify::message(Lang::txt('PLG_PROJECTS_FILES_SUCCESS_COMPILED'), 'success', 'projects'); // Redirect to file list App::redirect(Route::url($url)); return; } } // 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; if ($this->getError()) { $view->setError($this->getError()); } return $view->loadTemplate(); }