2010-03-04 05:39:02 +01:00
|
|
|
<?php
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Documentation Handler.
|
|
|
|
*
|
2010-04-11 06:02:25 +02:00
|
|
|
* Reads the bundled markdown files from docs/ folders and displays output in
|
2010-03-04 05:39:02 +01:00
|
|
|
* a formatted page
|
|
|
|
*
|
2010-03-04 11:18:02 +01:00
|
|
|
* @todo Tidy up template / styling
|
2010-03-04 05:39:02 +01:00
|
|
|
*
|
|
|
|
* @package sapphiredocs
|
|
|
|
*/
|
|
|
|
|
|
|
|
class DocumentationViewer extends Controller {
|
|
|
|
|
|
|
|
static $url_handlers = array(
|
|
|
|
'' => 'index',
|
|
|
|
'$Module/$Class' => 'parsePage'
|
|
|
|
);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* An array of files to ignore from the listing
|
|
|
|
*
|
|
|
|
* @var array
|
|
|
|
*/
|
2010-03-26 03:50:30 +01:00
|
|
|
static $ignored_files = array('.', '..', '.DS_Store', '.svn', '.git', 'assets');
|
2010-03-04 05:39:02 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Documentation Home
|
|
|
|
*
|
|
|
|
* Displays a welcome message as well as links to the sapphire sections and the
|
|
|
|
* installed modules
|
|
|
|
*/
|
|
|
|
function index() {
|
2010-03-04 06:00:13 +01:00
|
|
|
$this->writeHeader();
|
2010-03-04 05:39:02 +01:00
|
|
|
$base = Director::baseURL();
|
|
|
|
|
2010-03-04 11:18:02 +01:00
|
|
|
$readme = ($this->readmeExists('sapphire')) ? "<a href=''>Read Me</a>" : false;
|
|
|
|
|
2010-03-04 05:39:02 +01:00
|
|
|
// write the main content (sapphire) on the left
|
2010-03-04 11:18:02 +01:00
|
|
|
echo "<div id='Home'><div id='LeftColumn'><div class='box'>";
|
|
|
|
echo "<h2>sapphire $readme</h2>";
|
2010-03-04 05:39:02 +01:00
|
|
|
|
|
|
|
$this->generateNestedTree('sapphire');
|
|
|
|
|
|
|
|
echo "</div></div>";
|
|
|
|
echo "<div id='RightColumn'>";
|
|
|
|
|
|
|
|
$modules = scandir(BASE_PATH);
|
|
|
|
|
2010-03-04 11:18:02 +01:00
|
|
|
// modules which are not documented
|
|
|
|
$undocumented = array();
|
|
|
|
|
2010-03-04 05:39:02 +01:00
|
|
|
// generate a list of module documentation (not core)
|
|
|
|
if($modules) {
|
|
|
|
foreach($modules as $module) {
|
|
|
|
// skip sapphire since this is on the left
|
|
|
|
$ignored_modules = array('sapphire', 'assets', 'themes');
|
|
|
|
|
|
|
|
if(!in_array($module, $ignored_modules) && !in_array($module, self::$ignored_files) && is_dir(BASE_PATH .'/'. $module)) {
|
|
|
|
|
|
|
|
// see if docs folder is present
|
|
|
|
$subfolders = scandir(BASE_PATH .'/'. $module);
|
|
|
|
|
2010-04-11 06:02:25 +02:00
|
|
|
if($subfolders && in_array('docs', $subfolders)) {
|
2010-03-04 11:18:02 +01:00
|
|
|
$readme = ($filename = $this->readmeExists($module)) ? "<a href='todo'>Read Me</a>" : false;
|
|
|
|
echo "<div class='box'><h2>". $module .' '. $readme."</h2>";
|
2010-03-04 05:39:02 +01:00
|
|
|
$this->generateNestedTree($module);
|
2010-03-04 11:18:02 +01:00
|
|
|
echo "</div>";
|
2010-03-04 05:39:02 +01:00
|
|
|
}
|
|
|
|
else {
|
2010-03-04 11:18:02 +01:00
|
|
|
$undocumented[] = $module;
|
2010-03-04 05:39:02 +01:00
|
|
|
}
|
2010-03-04 11:18:02 +01:00
|
|
|
|
2010-03-04 05:39:02 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// for each of the modules. Display them here
|
|
|
|
|
2010-03-04 11:18:02 +01:00
|
|
|
echo "</div></div><div class='undocumentedModules'>";
|
|
|
|
|
|
|
|
if($undocumented) {
|
|
|
|
echo "<p>Undocumented Modules: ";
|
|
|
|
echo implode(', ', $undocumented);
|
|
|
|
}
|
|
|
|
|
2010-03-04 05:39:02 +01:00
|
|
|
|
2010-03-04 06:00:13 +01:00
|
|
|
$this->writeFooter();
|
2010-03-04 05:39:02 +01:00
|
|
|
}
|
|
|
|
|
2010-03-04 05:59:00 +01:00
|
|
|
|
2010-03-04 05:39:02 +01:00
|
|
|
/**
|
|
|
|
* Parse a given individual markdown page
|
|
|
|
*
|
|
|
|
* @param HTTPRequest
|
|
|
|
*/
|
|
|
|
function parsePage($request) {
|
|
|
|
|
|
|
|
require_once('../sapphiredocs/thirdparty/markdown.php');
|
|
|
|
|
|
|
|
$class = $request->param('Class');
|
|
|
|
$module = $request->param('Module');
|
|
|
|
|
2010-03-04 11:18:02 +01:00
|
|
|
$this->writeHeader($class, $module);
|
2010-03-04 05:59:00 +01:00
|
|
|
|
2010-03-04 05:39:02 +01:00
|
|
|
$base = Director::baseURL();
|
|
|
|
|
|
|
|
// find page
|
2010-04-11 06:02:25 +02:00
|
|
|
$path = BASE_PATH . '/'. $module .'/docs';
|
2010-03-04 05:39:02 +01:00
|
|
|
|
|
|
|
echo "<div id='LeftColumn'><div class='box'>";
|
|
|
|
if($page = $this->findPage($path, $class)) {
|
|
|
|
echo Markdown(file_get_contents($page));
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
echo "<p>Documentation Page Not Found</p>";
|
|
|
|
}
|
|
|
|
|
|
|
|
echo "</div></div> <div id='RightColumn'></div>";
|
|
|
|
|
2010-03-26 03:50:30 +01:00
|
|
|
echo '<script type="text/javascript" src="'. Director::absoluteBaseURL(). 'sapphire/thirdparty/jquery/jquery.js"></script>
|
2010-03-04 05:39:02 +01:00
|
|
|
<script type="text/javascript" src="'. Director::absoluteBaseURL() .'sapphiredocs/javascript/DocumentationViewer.js"></script>
|
|
|
|
';
|
|
|
|
|
2010-03-04 05:59:00 +01:00
|
|
|
$this->writeFooter();
|
2010-03-04 05:39:02 +01:00
|
|
|
}
|
|
|
|
|
2010-03-04 11:18:02 +01:00
|
|
|
/**
|
|
|
|
* @todo - This is nasty, ripped out of DebugView.
|
|
|
|
*/
|
|
|
|
function writeHeader($class = "", $module = "") {
|
|
|
|
$breadcrumbs = false;
|
|
|
|
if($module) {
|
|
|
|
$parts = array();
|
|
|
|
$parts[] = "<a href='dev/docs/'>Documentation Home</a>";
|
|
|
|
$parts[] = "<a href='dev/docs/$module'>$module</a>";
|
|
|
|
|
|
|
|
if($class) $parts[] = $this->formatStringForTitle($class);
|
|
|
|
|
|
|
|
$breadcrumbs = implode(" » ", $parts);
|
|
|
|
$breadcrumbs = '<p class="breadcrumbs">'. $breadcrumbs .'</p>';
|
|
|
|
}
|
|
|
|
|
|
|
|
echo '<!DOCTYPE html>
|
|
|
|
<html>
|
|
|
|
<head>
|
|
|
|
<base href="'. Director::absoluteBaseURL() .'> "
|
|
|
|
<title>' . htmlentities($_SERVER['REQUEST_METHOD'] . ' ' . $_SERVER['REQUEST_URI']) . '</title>
|
|
|
|
<link rel="stylesheet" href="sapphiredocs/css/DocumentationViewer.css" type="text/css">
|
|
|
|
</head>
|
|
|
|
<body>
|
|
|
|
<div id="Container">
|
|
|
|
<div id="Header">
|
|
|
|
<h1><a href="dev/docs/">SilverStripe Documentation</a></h1>
|
|
|
|
'.$breadcrumbs.'
|
|
|
|
</div>
|
|
|
|
';
|
|
|
|
}
|
|
|
|
|
|
|
|
function writeFooter() {
|
|
|
|
echo "</div></body></html>";
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Work out if a module contains a readme
|
|
|
|
*
|
|
|
|
* @param String - Module to check
|
|
|
|
* @return bool|String - of path
|
|
|
|
*/
|
|
|
|
private function readmeExists($module) {
|
|
|
|
$children = scandir(BASE_PATH.'/'.$module);
|
|
|
|
|
|
|
|
$readmeOptions = array('readme', 'readme.md', 'readme.txt');
|
|
|
|
|
|
|
|
if($children) {
|
|
|
|
foreach($children as $i => $file) {
|
|
|
|
if(in_array(strtolower($file), $readmeOptions)) return $file;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-03-04 05:39:02 +01:00
|
|
|
/**
|
|
|
|
* Find a documentation page within a given module.
|
|
|
|
*
|
|
|
|
* @todo Currently this only works on pages - eg if you go /dev/docs/Forms/ it won't show the
|
|
|
|
* overall forms page
|
|
|
|
*
|
|
|
|
* @param String - Name of Module
|
|
|
|
* @param String - Name of doc page
|
|
|
|
*
|
|
|
|
* @return String|false - File path
|
|
|
|
*/
|
|
|
|
private function findPage($path, $name) {
|
|
|
|
|
|
|
|
// open docs folder
|
|
|
|
$handle = opendir($path);
|
|
|
|
|
|
|
|
if($handle) {
|
|
|
|
while (false !== ($file = readdir($handle))) {
|
2010-03-26 03:50:30 +01:00
|
|
|
$newpath = $path .'/'. $file;
|
|
|
|
|
2010-03-04 05:39:02 +01:00
|
|
|
if(!in_array($file, self::$ignored_files)) {
|
2010-03-26 03:50:30 +01:00
|
|
|
|
|
|
|
if(is_dir($newpath)) {
|
2010-03-04 05:39:02 +01:00
|
|
|
// keep looking down the tree
|
2010-03-26 03:50:30 +01:00
|
|
|
return $this->findPage($newpath, $name);
|
2010-03-04 05:39:02 +01:00
|
|
|
}
|
2010-03-26 03:50:30 +01:00
|
|
|
|
|
|
|
elseif(strtolower($this->formatStringForTitle($file)) == strtolower($name)) {
|
|
|
|
return $newpath;
|
2010-03-04 05:39:02 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2010-03-26 03:50:30 +01:00
|
|
|
|
2010-03-04 05:39:02 +01:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Generate a nested tree for a given folder via recursion
|
|
|
|
*
|
|
|
|
* @param String - module to generate
|
|
|
|
*/
|
|
|
|
private function generateNestedTree($module) {
|
2010-04-11 06:02:25 +02:00
|
|
|
$path = BASE_PATH . '/'. $module .'/docs/';
|
2010-03-04 05:39:02 +01:00
|
|
|
return (is_dir($path)) ? $this->recursivelyGenerateTree($path, $module) : false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Recursive method to generate the tree
|
|
|
|
*
|
|
|
|
* @param String - folder to work through
|
|
|
|
* @param String - module we're working through
|
|
|
|
*/
|
|
|
|
private function recursivelyGenerateTree($path, $module) {
|
|
|
|
echo "<ul class='tree'>";
|
|
|
|
$handle = opendir($path);
|
|
|
|
|
|
|
|
if($handle) {
|
|
|
|
while (false !== ($file = readdir($handle))) {
|
|
|
|
if(!in_array($file, self::$ignored_files)) {
|
2010-03-04 11:18:02 +01:00
|
|
|
$newPath = $path.'/'.$file;
|
|
|
|
|
2010-03-04 05:39:02 +01:00
|
|
|
// if the file is a dir nest the pages
|
|
|
|
if(is_dir($newPath)) {
|
|
|
|
|
|
|
|
// if this has a number
|
2010-03-04 11:18:02 +01:00
|
|
|
echo "<li class='folder'>". $this->formatStringForTitle($file) ."</li>";
|
2010-03-04 05:39:02 +01:00
|
|
|
$this->recursivelyGenerateTree($newPath, $module);
|
|
|
|
|
|
|
|
}
|
|
|
|
else {
|
2010-03-26 03:50:30 +01:00
|
|
|
$offset = (strpos($file,'-') > 0) ? strpos($file,'-') + 1 : 0;
|
|
|
|
|
|
|
|
$file = substr(str_ireplace('.md', '', $file), $offset);
|
2010-03-04 05:39:02 +01:00
|
|
|
|
|
|
|
echo "<li class='page'><a href='". Director::absoluteBaseURL() . 'dev/docs/' . $module .'/'. $file . "'>". $this->formatStringForTitle($file) ."</a></li>";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
closedir($handle);
|
|
|
|
echo "</ul>";
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Take a file name and generate a 'nice' title for it
|
|
|
|
*
|
|
|
|
* @todo find a nicer way of removing the numbers.
|
|
|
|
*
|
|
|
|
* @param String
|
|
|
|
* @return String
|
|
|
|
*/
|
|
|
|
private function formatStringForTitle($title) {
|
|
|
|
// remove numbers if used.
|
|
|
|
if(substr($title, 2, 1) == '-') $title = substr($title, 3);
|
|
|
|
|
|
|
|
// change - to spaces
|
|
|
|
$title = str_ireplace('-', ' ', $title);
|
|
|
|
|
2010-03-04 11:18:02 +01:00
|
|
|
// remove extension
|
2010-03-26 03:50:30 +01:00
|
|
|
$title = str_ireplace('.md', '', $title);
|
2010-03-04 11:18:02 +01:00
|
|
|
|
2010-03-04 05:39:02 +01:00
|
|
|
return $title;
|
|
|
|
}
|
|
|
|
}
|