daux.io/libs/Server/Server.php
Morgan Zolob 7928b4365b Allow Daux to work from sub-directories
If you try to host Daux from any directory other than the root of a website (like mysite.com/docs, for example), it just gives an error that the page can't be found. This commit will make Daux remove the base directory from the request when handling it, which should make it work properly in sub-directories.
2018-09-20 20:14:43 +02:00

202 lines
5.6 KiB
PHP
Executable File

<?php namespace Todaymade\Daux\Server;
use Symfony\Component\Console\Output\NullOutput;
use Symfony\Component\HttpFoundation\BinaryFileResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesser;
use Todaymade\Daux\Daux;
use Todaymade\Daux\DauxHelper;
use Todaymade\Daux\Exception;
use Todaymade\Daux\Format\Base\ComputedRawPage;
use Todaymade\Daux\Format\Base\LiveGenerator;
use Todaymade\Daux\Format\Base\Page;
use Todaymade\Daux\Format\HTML\RawPage;
class Server
{
private $daux;
private $params;
private $base_url;
/**
* @var Request
*/
private $request;
/**
* Serve the documentation
*
* @throws Exception
*/
public static function serve()
{
$output = new NullOutput();
$daux = new Daux(Daux::LIVE_MODE, $output);
$daux->initializeConfiguration();
$class = $daux->getProcessorClass();
if (!empty($class)) {
$daux->setProcessor(new $class($daux, $output, 0));
}
// Set this critical configuration
// for the tree generation
$daux->getParams()['index_key'] = 'index';
// Improve the tree with a processor
$daux->generateTree();
$server = new static($daux);
try {
$page = $server->handle();
} catch (NotFoundException $e) {
$page = new ErrorPage('An error occured', $e->getMessage(), $daux->getParams());
}
$server->createResponse($page)->prepare($server->request)->send();
}
public function __construct(Daux $daux)
{
$this->daux = $daux;
$this->request = Request::createFromGlobals();
$this->base_url = $this->request->getHttpHost() . $this->request->getBaseUrl() . "/";
}
/**
* Create a temporary file with the file suffix, for mime type detection.
*
* @param string $postfix
* @return string
*/
private function getTemporaryFile($postfix) {
$sysFileName = tempnam(sys_get_temp_dir(), 'daux');
if ($sysFileName === false) {
throw new \RuntimeException("Could not create temporary file");
}
$newFileName = $sysFileName . $postfix;
if ($sysFileName == $newFileName) {
return $sysFileName;
}
if (DIRECTORY_SEPARATOR == '\\' ? rename($sysFileName, $newFileName) : link($sysFileName, $newFileName)) {
return $newFileName;
}
throw new \RuntimeException("Could not create temporary file");
}
/**
* @param Page $page
* @return Response
*/
public function createResponse(Page $page) {
MimeTypeGuesser::getInstance()->register(new ExtensionMimeTypeGuesser);
if ($page instanceof RawPage) {
return new BinaryFileResponse($page->getFile());
}
if ($page instanceof ComputedRawPage) {
$file = $this->getTemporaryFile($page->getFilename());
file_put_contents($file, $page->getContent());
return new BinaryFileResponse($file);
}
return new Response($page->getContent(), $page instanceof ErrorPage ? 404 : 200);
}
/**
* @return \Todaymade\Daux\Config
*/
public function getParams()
{
$params = $this->daux->getParams();
DauxHelper::rebaseConfiguration($params, '//' . $this->base_url);
$params['base_page'] = '//' . $this->base_url;
if (!$this->daux->options['live']['clean_urls']) {
$params['base_page'] .= 'index.php/';
}
// Text search would be too slow on live server
$params['html']['search'] = false;
return $params;
}
/**
* Handle an incoming request
*
* @return \Todaymade\Daux\Format\Base\Page
* @throws Exception
* @throws NotFoundException
*/
public function handle()
{
$this->params = $this->getParams();
$request = substr($this->request->getRequestUri(), strlen($this->request->getBaseUrl()) + 1);
if (substr($request, 0, 7) == 'themes/') {
return $this->serveTheme(substr($request, 6));
}
if ($request == '') {
$request = $this->daux->tree->getIndexPage()->getUri();
}
return $this->getPage($request);
}
/**
* Handle a request on custom themes
*
* @param string $request
* @return \Todaymade\Daux\Format\Base\Page
* @throws NotFoundException
*/
public function serveTheme($request)
{
$file = $this->getParams()->getThemesPath() . $request;
if (file_exists($file)) {
return new RawPage($file);
}
throw new NotFoundException;
}
/**
* @param string $request
* @return \Todaymade\Daux\Format\Base\Page
* @throws NotFoundException
*/
private function getPage($request)
{
$file = DauxHelper::getFile($this->daux->tree, $request);
if ($file === false) {
throw new NotFoundException('The Page you requested is yet to be made. Try again later.');
}
$this->daux->tree->setActiveNode($file);
$generator = $this->daux->getGenerator();
if (!$generator instanceof LiveGenerator) {
throw new \RuntimeException(
"The generator '" . get_class($generator) . "' does not implement the interface " .
"'Todaymade\\Daux\\Format\\Base\\LiveGenerator' and thus doesn't support live rendering."
);
}
return $this->daux->getGenerator()->generateOne($file, $this->params);
}
}