diff options
Diffstat (limited to 'modules/doc/application/controllers')
5 files changed, 433 insertions, 0 deletions
diff --git a/modules/doc/application/controllers/IcingawebController.php b/modules/doc/application/controllers/IcingawebController.php new file mode 100644 index 0000000..f6ff738 --- /dev/null +++ b/modules/doc/application/controllers/IcingawebController.php @@ -0,0 +1,62 @@ +<?php +/* Icinga Web 2 | (c) 2013 Icinga Development Team | GPLv2+ */ + +namespace Icinga\Module\Doc\Controllers; + +use Icinga\Application\Icinga; +use Icinga\Module\Doc\DocController; + +class IcingawebController extends DocController +{ + /** + * Get the path to Icinga Web 2's documentation + * + * @return ?string + * + * @throws \Icinga\Exception\Http\HttpNotFoundException If Icinga Web 2's documentation is not available + */ + protected function getPath() + { + $path = Icinga::app()->getBaseDir('doc'); + if (is_dir($path)) { + return $path; + } + if (($path = $this->Config()->get('documentation', 'icingaweb2')) !== null) { + if (is_dir($path)) { + return $path; + } + } + $this->httpNotFound($this->translate('Documentation for Icinga Web 2 is not available')); + } + + /** + * View the toc of Icinga Web 2's documentation + */ + public function tocAction() + { + $this->renderToc($this->getPath(), 'Icinga Web 2', 'doc/icingaweb/chapter'); + } + + /** + * View a chapter of Icinga Web 2's documentation + * + * @throws \Icinga\Exception\MissingParameterException If the required parameter 'chapter' is missing + */ + public function chapterAction() + { + $chapter = $this->params->getRequired('chapter'); + $this->renderChapter( + $this->getPath(), + $chapter, + 'doc/icingaweb/chapter' + ); + } + + /** + * View Icinga Web 2's documentation as PDF + */ + public function pdfAction() + { + $this->renderPdf($this->getPath(), 'Icinga Web 2', 'doc/icingaweb/chapter'); + } +} diff --git a/modules/doc/application/controllers/IndexController.php b/modules/doc/application/controllers/IndexController.php new file mode 100644 index 0000000..3ff5aa1 --- /dev/null +++ b/modules/doc/application/controllers/IndexController.php @@ -0,0 +1,27 @@ +<?php +/* Icinga Web 2 | (c) 2013 Icinga Development Team | GPLv2+ */ + +namespace Icinga\Module\Doc\Controllers; + +use Icinga\Module\Doc\DocController; +use Icinga\Web\Url; + +/** + * Documentation module index + */ +class IndexController extends DocController +{ + /** + * Documentation module landing page + * + * Lists documentation links + */ + public function indexAction() + { + $this->getTabs()->add('documentation', array( + 'active' => true, + 'title' => $this->translate('Documentation', 'Tab title'), + 'url' => Url::fromRequest() + )); + } +} diff --git a/modules/doc/application/controllers/ModuleController.php b/modules/doc/application/controllers/ModuleController.php new file mode 100644 index 0000000..9e94a61 --- /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($_SERVER['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) + ); + } +} diff --git a/modules/doc/application/controllers/SearchController.php b/modules/doc/application/controllers/SearchController.php new file mode 100644 index 0000000..6d26f52 --- /dev/null +++ b/modules/doc/application/controllers/SearchController.php @@ -0,0 +1,97 @@ +<?php +/* Icinga Web 2 | (c) 2015 Icinga Development Team | GPLv2+ */ + +namespace Icinga\Module\Doc\Controllers; + +use Icinga\Application\Icinga; +use Icinga\Module\Doc\DocController; +use Icinga\Module\Doc\DocParser; +use Icinga\Module\Doc\Exception\DocException; +use Icinga\Module\Doc\Renderer\DocSearchRenderer; +use Icinga\Module\Doc\Search\DocSearch; +use Icinga\Module\Doc\Search\DocSearchIterator; + +class SearchController extends DocController +{ + /** + * Render search + */ + public function indexAction() + { + $parser = new DocParser($this->getWebPath()); + $search = new DocSearchRenderer( + new DocSearchIterator( + $parser->getDocTree()->getIterator(), + new DocSearch($this->params->get('q')) + ) + ); + $search->setUrl('doc/icingaweb/chapter'); + if (strlen($this->params->get('q')) < 3) { + $this->view->searches = array(); + return; + } + $searches = array( + 'Icinga Web 2' => $search + ); + foreach (Icinga::app()->getModuleManager()->listEnabledModules() as $module) { + if (($path = $this->getModulePath($module)) !== null) { + try { + $parser = new DocParser($path); + $search = new DocSearchRenderer( + new DocSearchIterator( + $parser->getDocTree()->getIterator(), + new DocSearch($this->params->get('q')) + ) + ); + } catch (DocException $e) { + continue; + } + $search + ->setUrl('doc/module/chapter') + ->setUrlParams(array('moduleName' => $module)); + $searches[$module] = $search; + } + } + $this->view->searches = $searches; + } + + /** + * Get the path to a module's documentation + * + * @param string $module + * + * @return string|null + */ + protected function getModulePath($module) + { + if (is_dir(($path = Icinga::app()->getModuleManager()->getModuleDir($module, '/doc')))) { + return $path; + } + if (($path = $this->Config()->get('documentation', 'modules')) !== null) { + $path = str_replace('{module}', $module, $path); + if (is_dir($path)) { + return $path; + } + } + return null; + } + + /** + * Get the path to Icinga Web 2's documentation + * + * @return ?string + */ + protected function getWebPath() + { + $path = Icinga::app()->getBaseDir('doc'); + if (is_dir($path)) { + return $path; + } + if (($path = $this->Config()->get('documentation', 'icingaweb2')) !== null) { + if (is_dir($path)) { + return $path; + } + } + $this->httpNotFound($this->translate('Documentation for Icinga Web 2 is not available')); + } +} diff --git a/modules/doc/application/controllers/StyleController.php b/modules/doc/application/controllers/StyleController.php new file mode 100644 index 0000000..5890367 --- /dev/null +++ b/modules/doc/application/controllers/StyleController.php @@ -0,0 +1,41 @@ +<?php +/* Icinga Web 2 | (c) 2014 Icinga Development Team | GPLv2+ */ + +namespace Icinga\Module\Doc\Controllers; + +use Icinga\Application\Icinga; +use Icinga\Web\Controller; +use Icinga\Web\Widget; + +class StyleController extends Controller +{ + public function guideAction() + { + $this->view->tabs = $this->tabs()->activate('guide'); + } + + public function fontAction() + { + $this->view->tabs = $this->tabs()->activate('font'); + $confFile = Icinga::app()->getApplicationDir('fonts/fontello-ifont/config.json'); + $this->view->font = json_decode(file_get_contents($confFile)); + } + + protected function tabs() + { + return Widget::create('tabs')->add( + 'guide', + array( + 'label' => $this->translate('Style Guide'), + 'url' => 'doc/style/guide' + ) + )->add( + 'font', + array( + 'label' => $this->translate('Icons'), + 'title' => $this->translate('List all available icons'), + 'url' => 'doc/style/font' + ) + ); + } +} |