summaryrefslogtreecommitdiffstats
path: root/modules/doc/application/controllers/ModuleController.php
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--modules/doc/application/controllers/ModuleController.php206
1 files changed, 206 insertions, 0 deletions
diff --git a/modules/doc/application/controllers/ModuleController.php b/modules/doc/application/controllers/ModuleController.php
new file mode 100644
index 0000000..47dfb1c
--- /dev/null
+++ b/modules/doc/application/controllers/ModuleController.php
@@ -0,0 +1,206 @@
+<?php
+/* Icinga Web 2 | (c) 2014 Icinga Development Team | GPLv2+ */
+
+namespace Icinga\Module\Doc\Controllers;
+
+use finfo;
+use SplFileInfo;
+use Icinga\Application\Icinga;
+use Icinga\Module\Doc\DocController;
+use Icinga\Module\Doc\Exception\DocException;
+use Icinga\Web\Url;
+
+class ModuleController extends DocController
+{
+ /**
+ * Get the path to a module documentation
+ *
+ * @param string $module The name of the module
+ * @param string $default The default path
+ * @param bool $suppressErrors Whether to not throw an exception if the module documentation is not available
+ *
+ * @return string|null Path to the documentation or null if the module documentation is not available
+ * and errors are suppressed
+ *
+ * @throws \Icinga\Exception\Http\HttpNotFoundException If the module documentation is not available and errors
+ * are not suppressed
+ */
+ protected function getPath($module, $default, $suppressErrors = false)
+ {
+ if (is_dir($default)) {
+ return $default;
+ }
+ if (($path = $this->Config()->get('documentation', 'modules')) !== null) {
+ $path = str_replace('{module}', $module, $path);
+ if (is_dir($path)) {
+ return $path;
+ }
+ }
+ if ($suppressErrors) {
+ return null;
+ }
+ $this->httpNotFound($this->translate('Documentation for module \'%s\' is not available'), $module);
+ }
+
+ /**
+ * List modules which are enabled and having the 'doc' directory
+ */
+ public function indexAction()
+ {
+ $moduleManager = Icinga::app()->getModuleManager();
+ $modules = array();
+ foreach ($moduleManager->listInstalledModules() as $module) {
+ $path = $this->getPath($module, $moduleManager->getModuleDir($module, '/doc'), true);
+ if ($path !== null) {
+ $modules[] = $moduleManager->getModule($module, false);
+ }
+ }
+ $this->view->modules = $modules;
+ $this->getTabs()->add('module-documentation', array(
+ 'active' => true,
+ 'title' => $this->translate('Module Documentation', 'Tab title'),
+ 'url' => Url::fromRequest()
+ ));
+ }
+
+ /**
+ * Assert that the given module is installed
+ *
+ * @param string $moduleName
+ *
+ * @throws \Icinga\Exception\Http\HttpNotFoundException If the given module is not installed
+ */
+ protected function assertModuleInstalled($moduleName)
+ {
+ $moduleManager = Icinga::app()->getModuleManager();
+ if (! $moduleManager->hasInstalled($moduleName)) {
+ $this->httpNotFound($this->translate('Module \'%s\' is not installed'), $moduleName);
+ }
+ }
+
+ /**
+ * View the toc of a module's documentation
+ *
+ * @throws \Icinga\Exception\MissingParameterException If the required parameter 'moduleName' is empty
+ * @throws \Icinga\Exception\Http\HttpNotFoundException If the given module is not installed
+ * @see assertModuleInstalled()
+ */
+ public function tocAction()
+ {
+ $module = $this->params->getRequired('moduleName');
+ $this->assertModuleInstalled($module);
+ $moduleManager = Icinga::app()->getModuleManager();
+ $name = $moduleManager->getModule($module, false)->getTitle();
+ try {
+ $this->renderToc(
+ $this->getPath($module, Icinga::app()->getModuleManager()->getModuleDir($module, '/doc')),
+ $name,
+ 'doc/module/chapter',
+ array('moduleName' => $module)
+ );
+ } catch (DocException $e) {
+ $this->httpNotFound($e->getMessage());
+ }
+ }
+
+ /**
+ * View a chapter of a module's documentation
+ *
+ * @throws \Icinga\Exception\MissingParameterException If one of the required parameters 'moduleName' and
+ * 'chapter' is empty
+ * @throws \Icinga\Exception\Http\HttpNotFoundException If the given module is not installed
+ * @see assertModuleInstalled()
+ */
+ public function chapterAction()
+ {
+ $module = $this->params->getRequired('moduleName');
+ $this->assertModuleInstalled($module);
+ $chapter = $this->params->getRequired('chapter');
+ $this->view->moduleName = $module;
+ try {
+ $this->renderChapter(
+ $this->getPath($module, Icinga::app()->getModuleManager()->getModuleDir($module, '/doc')),
+ $chapter,
+ 'doc/module/chapter',
+ 'doc/module/img',
+ array('moduleName' => $module)
+ );
+ } catch (DocException $e) {
+ $this->httpNotFound($e->getMessage());
+ }
+ }
+
+ /**
+ * Deliver images
+ */
+ public function imageAction()
+ {
+ $module = $this->params->getRequired('moduleName');
+ $image = $this->params->getRequired('image');
+ $docPath = $this->getPath($module, Icinga::app()->getModuleManager()->getModuleDir($module, '/doc'));
+ $imagePath = realpath($docPath . '/' . $image);
+ if ($imagePath === false || substr($imagePath, 0, strlen($docPath)) !== $docPath) {
+ $this->httpNotFound('%s does not exist', $image);
+ }
+
+ $this->_helper->viewRenderer->setNoRender(true);
+ $this->_helper->layout()->disableLayout();
+
+ $imageInfo = new SplFileInfo($imagePath);
+
+ $etag = md5($imageInfo->getMTime() . $imagePath);
+ $lastModified = gmdate('D, d M Y H:i:s T', $imageInfo->getMTime());
+ $match = false;
+
+ if (isset($_SERER['HTTP_IF_NONE_MATCH'])) {
+ $ifNoneMatch = explode(', ', stripslashes($_SERVER['HTTP_IF_NONE_MATCH']));
+ foreach ($ifNoneMatch as $tag) {
+ if ($tag === $etag) {
+ $match = true;
+ break;
+ }
+ }
+ } elseif (isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])) {
+ $lastModifiedSince = stripslashes($_SERVER['HTTP_IF_MODIFIED_SINCE']);
+ if ($lastModifiedSince === $lastModified) {
+ $match = true;
+ }
+ }
+
+ $this->getResponse()
+ ->setHeader('ETag', $etag)
+ ->setHeader('Cache-Control', 'no-transform,public,max-age=3600,must-revalidate', true);
+
+ if ($match) {
+ $this->getResponse()->setHttpResponseCode(304);
+ } else {
+ $finfo = new finfo();
+ $this->getResponse()
+ ->setHeader('Content-Type', $finfo->file($imagePath, FILEINFO_MIME_TYPE))
+ ->setHeader('Content-Length', $imageInfo->getSize())
+ ->sendHeaders();
+
+ ob_end_clean();
+ readfile($imagePath);
+ }
+ }
+
+ /**
+ * View a module's documentation as PDF
+ *
+ * @throws \Icinga\Exception\MissingParameterException If the required parameter 'moduleName' is empty
+ * @throws \Icinga\Exception\Http\HttpNotFoundException If the given module is not installed
+ * @see assertModuleInstalled()
+ */
+ public function pdfAction()
+ {
+ $module = $this->params->getRequired('moduleName');
+ $this->assertModuleInstalled($module);
+ $this->renderPdf(
+ $this->getPath($module, Icinga::app()->getModuleManager()->getModuleDir($module, '/doc')),
+ $module,
+ 'doc/module/chapter',
+ array('moduleName' => $module)
+ );
+ }
+}