285 lines
7.7 KiB
PHP
285 lines
7.7 KiB
PHP
<?php
|
|
error_reporting(E_ALL);
|
|
|
|
$includePath = dirname(dirname(__FILE__)) . DIRECTORY_SEPARATOR . 'lib' . PATH_SEPARATOR
|
|
. dirname(__FILE__) . DIRECTORY_SEPARATOR . 'lib' . PATH_SEPARATOR
|
|
. dirname(dirname(__FILE__)) . DIRECTORY_SEPARATOR . 'vendor';
|
|
|
|
set_include_path($includePath);
|
|
|
|
require_once('Doctrine.php');
|
|
require_once('Sensei/Sensei.php');
|
|
require_once('Text/Wiki.php');
|
|
|
|
spl_autoload_register(array('Doctrine', 'autoload'));
|
|
spl_autoload_register(array('Sensei', 'autoload'));
|
|
|
|
/**
|
|
* Returns the revision of a SVN controlled file.
|
|
*
|
|
* The revision is acquired by executing the 'svn info' command for the file and
|
|
* parsing the last changed revision from the output.
|
|
*
|
|
* @param $file string filename
|
|
* @return int|false revision of the file, or false on failure
|
|
*/
|
|
function getSvnRevision($file)
|
|
{
|
|
$cmd = 'HOME=/tmp /usr/bin/svn info ' . escapeshellarg($file);
|
|
exec($cmd, $output);
|
|
foreach ($output as $line) {
|
|
if (preg_match('/^Last Changed Rev: ([0-9]+)$/', $line, $matches)) {
|
|
return $matches[1];
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Wraps a Doctrine_Cache_Db and suppresses all exceptions thrown by caching
|
|
* operations. Uses Sqlite as database backend.
|
|
*/
|
|
class Cache
|
|
{
|
|
protected $_cache = null;
|
|
|
|
/**
|
|
* Constructs a cache object.
|
|
*
|
|
* If cache table does not exist, creates one.
|
|
*
|
|
* @param $cacheFile string filename of the sqlite database
|
|
*/
|
|
public function __construct($cacheFile)
|
|
{
|
|
try {
|
|
$dsn = 'sqlite:' . $cacheFile;
|
|
$dbh = new PDO($dsn);
|
|
$conn = Doctrine_Manager::connection($dbh);
|
|
|
|
$options = array(
|
|
'connection' => $conn,
|
|
'tableName' => 'cache'
|
|
);
|
|
|
|
$this->_cache = new Doctrine_Cache_Db($options);
|
|
|
|
try {
|
|
$this->_cache->createTable();
|
|
} catch (Doctrine_Connection_Exception $e) {
|
|
if ($e->getPortableCode() !== Doctrine::ERR_ALREADY_EXISTS) {
|
|
$this->_cache = null;
|
|
}
|
|
}
|
|
|
|
} catch (Exception $e) {
|
|
$this->_cache = null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Fetches a cache record from cache.
|
|
*
|
|
* @param $id string the id of the cache record
|
|
* @return string fetched cache record, or false on failure
|
|
*/
|
|
public function fetch($id)
|
|
{
|
|
if ($this->_cache !== null) {
|
|
try {
|
|
return $this->_cache->fetch($id);
|
|
} catch (Exception $e) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Saves a cache record to cache.
|
|
*
|
|
* @param $data mixed the data to be saved to cache
|
|
* @param $id string the id of the cache record
|
|
* @return bool True on success, false on failure
|
|
*/
|
|
public function save($data, $id)
|
|
{
|
|
if ($this->_cache !== null) {
|
|
try {
|
|
return $this->_cache->save($data, $id);
|
|
} catch (Exception $e) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Deletes all cached records from cache.
|
|
*
|
|
* @return True on success, false on failure
|
|
*/
|
|
public function deleteAll()
|
|
{
|
|
if ($this->_cache !== null) {
|
|
try {
|
|
return $this->_cache->deleteAll();
|
|
} catch (Exception $e) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// Temporary directory used by cache and LaTeX to Pdf conversion
|
|
$tempDir = dirname(__FILE__) . DIRECTORY_SEPARATOR . 'tmp';
|
|
|
|
// The file where cached data is saved
|
|
$cacheFile = $tempDir . DIRECTORY_SEPARATOR . 'cache.sq3';
|
|
|
|
$cache = new Cache($cacheFile);
|
|
|
|
// Fetch the revision of cached data
|
|
$cacheRev = $cache->fetch('revision');
|
|
|
|
// Check the revision of documentation files
|
|
$revision = getSvnRevision('.');
|
|
|
|
// Is current SVN revision greater than the revision of cached data?
|
|
if ($revision > $cacheRev) {
|
|
$cache->deleteAll(); // cached data is not valid anymore
|
|
$cache->save($revision, 'revision');
|
|
}
|
|
|
|
// Load table of contents from cache
|
|
$toc = $cache->fetch('toc');
|
|
|
|
// If table of contents was not cached, parse it from documentation files
|
|
if ( ! $toc instanceof Sensei_Doc_Toc) {
|
|
$toc = new Sensei_Doc_Toc('docs/en.txt');
|
|
$cache->save($toc, 'toc');
|
|
}
|
|
|
|
// Which format to output docs
|
|
if (isset($_GET['format'])) {
|
|
$format = ucfirst(strtolower($_GET['format']));
|
|
|
|
switch ($format) {
|
|
case 'Xhtml':
|
|
case 'Latex':
|
|
case 'Pdf':
|
|
break;
|
|
default:
|
|
$format = 'Xhtml'; // default if invalid format is specified
|
|
break;
|
|
}
|
|
|
|
} else {
|
|
$format = 'Xhtml'; // default if no format is specified
|
|
}
|
|
|
|
$rendererClass = 'Sensei_Doc_Renderer_' . $format;
|
|
$renderer = new $rendererClass($toc);
|
|
|
|
$renderer->setOptions(array(
|
|
'title' => 'Doctrine Manual',
|
|
'author' => 'Konsta Vesterinen',
|
|
'version' => 'Rev. ' . $revision,
|
|
'subject' => 'Object relational mapping',
|
|
'keywords' => 'PHP, ORM, object relational mapping, Doctrine, database'
|
|
));
|
|
|
|
$cacheId = $format;
|
|
|
|
switch ($format) {
|
|
case 'Latex':
|
|
$renderer->setOption('template', file_get_contents('templates/latex.tpl.php'));
|
|
|
|
$headers = array(
|
|
'Content-Type: application/latex',
|
|
'Content-Disposition: attachment; filename=doctrine-manual.tex'
|
|
);
|
|
break;
|
|
|
|
case 'Pdf':
|
|
$renderer->setOption('template', file_get_contents('templates/latex.tpl.php'));
|
|
|
|
$renderer->setOptions(array(
|
|
'temp_dir' => $tempDir,
|
|
'pdflatex_path' => '/usr/bin/pdflatex',
|
|
'lock' => true
|
|
));
|
|
|
|
$headers = array(
|
|
'Content-Type: application/pdf',
|
|
'Content-Disposition: attachment; filename=doctrine-manual.pdf'
|
|
);
|
|
break;
|
|
|
|
case 'Xhtml':
|
|
default:
|
|
$renderer->setOption('template', file_get_contents('templates/xhtml.tpl.php'));
|
|
|
|
$viewIndex = true;
|
|
|
|
if (isset($_GET['one-page'])) {
|
|
$viewIndex = false;
|
|
}
|
|
|
|
if (isset($_GET['chapter'])) {
|
|
$section = $toc->findByPath($_GET['chapter']);
|
|
|
|
if ($section && $section->getLevel() === 1) {
|
|
$title = $renderer->getOption('title') . ' - Chapter '
|
|
. $section->getIndex() . ' ' . $section->getName();
|
|
|
|
$renderer->setOptions(array(
|
|
'section' => $section,
|
|
'url_prefix' => '?chapter=',
|
|
'title' => $title
|
|
));
|
|
|
|
$cacheId .= '-' . $section->getPath();
|
|
$viewIndex = false;
|
|
}
|
|
}
|
|
break;
|
|
|
|
}
|
|
|
|
if (isset($viewIndex) && $viewIndex) {
|
|
|
|
$title = $renderer->getOption('title');
|
|
include 'templates/index.tpl.php';
|
|
|
|
} else {
|
|
$output = $cache->fetch($cacheId);
|
|
|
|
if ($output === false) {
|
|
try {
|
|
$output = $renderer->render();
|
|
} catch (Exception $e) {
|
|
die($e->getMessage());
|
|
}
|
|
$cache->save($output, $cacheId);
|
|
}
|
|
|
|
if (isset($headers)) {
|
|
foreach ($headers as $header) {
|
|
header($header);
|
|
}
|
|
}
|
|
|
|
// buffer output
|
|
ob_start();
|
|
echo $output;
|
|
ob_end_flush();
|
|
|
|
}
|
|
|