2013-07-13 05:26:27 +02:00
< ? php
2013-07-30 16:11:07 +02:00
// Enable for debugging
// ini_set('display_errors', 1);
// error_reporting(E_ALL);
2013-06-12 00:28:29 +02:00
/*
* WARNING : DO NOT EDIT THIS FILE .
* If you edit this file , you will not be able to update to new versions of
* Daux . io without overwritting your changes . Instead use the config . json file
* in the / docs folder to customize your documentation .
*
2013-06-21 17:49:05 +02:00
* Want to add a new feature ? Send me a pull request or open an issue - https :// github . com / justinwalsh / daux . io
*
2013-06-12 00:28:29 +02:00
* Learn more about what you can customize here : http :// daux . io
*/
2014-02-16 14:12:14 +01:00
require_once dirname ( __FILE__ ) . '/markdown_extended.php' ;
2013-06-12 00:28:29 +02:00
// Check for homepage
2013-07-22 11:35:56 +02:00
$homepage = ( get_uri ( false ) === " " ) ? true : false ;
// Stores the base url under which daux is running
2014-02-12 11:42:33 +01:00
global $base_url ;
2013-07-22 11:35:56 +02:00
$base_url = '/' ;
// Set the base url of where the script is located
if ( isset ( $_SERVER [ 'SCRIPT_NAME' ]))
{
2014-02-19 06:43:50 +01:00
$base_url = substr ( $_SERVER [ 'SCRIPT_NAME' ], 0 , strrpos ( $_SERVER [ 'SCRIPT_NAME' ] , '/' )); // find the full URL to this application from server root
2013-06-12 00:28:29 +02:00
}
2014-02-16 18:52:32 +01:00
// Hide annoying date() Warnings due to no Timezone being set.
if ( ! ini_get ( 'date.timezone' ) )
{
date_default_timezone_set ( 'GMT' );
}
2014-02-12 11:42:33 +01:00
function get_base_url ()
{
global $base_url ;
return $base_url ;
};
2013-06-21 17:49:05 +02:00
// Daux.io Functions
2013-06-12 00:28:29 +02:00
function get_options () {
$options = array (
'title' => " Documentation " ,
'tagline' => false ,
'image' => false ,
'theme' => 'blue' ,
2014-01-20 13:26:34 +01:00
'docs_path' => 'docs' ,
2013-07-29 20:49:58 +02:00
'date_modified' => true ,
2013-06-12 00:28:29 +02:00
'float' => true ,
'repo' => false ,
2014-02-19 06:43:50 +01:00
'toggle_code' => false ,
2013-06-12 00:28:29 +02:00
'twitter' => array (),
'links' => array (),
2013-06-21 21:36:50 +02:00
'colors' => false ,
2013-07-26 21:43:11 +02:00
'clean_urls' => true ,
2013-07-22 08:13:00 +02:00
'google_analytics' => false ,
2013-07-22 17:48:18 +02:00
'piwik_analytics' => false ,
2014-02-19 06:43:50 +01:00
'piwik_analytics_id' => 1 ,
'ignore' => array (),
'languages' => array (),
'file_editor' => false ,
'template' => 'default'
2013-06-12 00:28:29 +02:00
);
// Load User Config
$config_file = './docs/config.json' ;
if ( file_exists ( $config_file )) {
$config = json_decode ( file_get_contents ( $config_file ), true );
$options = array_merge ( $options , $config );
}
if ( $options [ 'theme' ] !== 'custom' ) {
// Load Theme
if ( ! in_array ( $options [ 'theme' ], array ( " blue " , " navy " , " green " , " red " ))) {
echo " <strong>Daux.io Config Error:</strong><br>The theme you set is not not a valid option. Please use one of the following options: " . join ( array_keys ( $themes ), ', ' ) . ' or <a href="http://daux.io">learn more</a> about how to customize the colors.' ;
exit ;
}
} else {
if ( empty ( $options [ 'colors' ])) {
echo '<strong>Daux.io Config Error:</strong><br>You are trying to use a custom theme, but did not setup your color options in the config. <a href="http://daux.io">Learn more</a> about how to customize the colors.' ;
exit ;
}
}
2013-06-21 17:49:05 +02:00
return $options ;
}
function homepage_url ( $tree ) {
// Check for homepage
if ( isset ( $tree [ 'index' ])) {
return '/' ;
} else {
2013-08-23 21:49:08 +02:00
return docs_url ( $tree , false );
2013-06-12 00:28:29 +02:00
}
2013-06-21 17:49:05 +02:00
}
2013-06-12 00:28:29 +02:00
2013-06-21 17:49:05 +02:00
function docs_url ( $tree , $branch = false ) {
// Get next branch
if ( ! $branch ) {
$branch = current ( $tree );
}
if ( $branch [ 'type' ] === 'file' ) {
return $branch [ 'url' ];
} else if ( ! empty ( $branch [ 'tree' ])) {
return docs_url ( $branch [ 'tree' ]);
} else {
// Try next folder...
$branch = next ( $tree );
if ( $branch ) {
return docs_url ( $tree , $branch );
} else {
echo '<strong>Daux.io Config Error:</strong><br>Unable to find the first page in the /docs folder. Double check you have at least one file in the root of of the /docs folder. Also make sure you do not have any empty folders. Visit the docs to <a href="http://daux.io">learn more</a> about how the default routing works.' ;
exit ;
}
}
2013-06-12 00:28:29 +02:00
}
2013-08-23 21:49:08 +02:00
function load_page ( $tree , $url_params ) {
2014-02-19 06:43:50 +01:00
if ( count ( $url_params ) > 0 ) {
$branch = find_branch ( $tree , $url_params );
} else {
$branch = current ( $tree );
}
2013-06-12 00:28:29 +02:00
2013-07-29 20:49:58 +02:00
$page = array ();
2013-06-12 00:28:29 +02:00
if ( isset ( $branch [ 'type' ]) && $branch [ 'type' ] == 'file' ) {
$html = '' ;
if ( $branch [ 'name' ] !== 'index' ) {
2013-07-23 22:40:08 +02:00
2013-07-29 20:49:58 +02:00
$page [ 'title' ] = $branch [ 'title' ];
$page [ 'modified' ] = filemtime ( $branch [ 'path' ]);
2013-07-23 22:40:08 +02:00
2013-06-12 00:28:29 +02:00
}
$html .= MarkdownExtended ( file_get_contents ( $branch [ 'path' ]));
2013-07-29 20:49:58 +02:00
2014-01-19 23:24:23 +01:00
// Markdown editor related
$page [ 'markdown' ] = file_get_contents ( $branch [ 'path' ]);
$page [ 'path' ] = $branch [ 'path' ];
2013-07-29 20:49:58 +02:00
$page [ 'html' ] = $html ;
2013-06-12 00:28:29 +02:00
} else {
2013-07-29 20:49:58 +02:00
$page [ 'title' ] = " Oh no " ;
2013-09-24 21:58:30 +02:00
$page [ 'html' ] = " <h3>Oh No. That page doesn't exist</h3> " ;
2013-07-29 20:49:58 +02:00
2013-06-12 00:28:29 +02:00
}
2014-02-12 17:34:28 +01:00
2013-07-29 20:49:58 +02:00
return $page ;
2013-06-12 00:28:29 +02:00
}
2013-10-03 23:16:42 +02:00
2013-08-23 21:49:08 +02:00
function find_branch ( $tree , $url_params ) {
foreach ( $url_params as $peice ) {
2013-10-03 17:30:27 +02:00
// Support for cyrillic URLs
$peice = urldecode ( $peice );
2013-06-12 00:28:29 +02:00
// Check for homepage
if ( empty ( $peice )) {
$peice = 'index' ;
}
if ( isset ( $tree [ $peice ])) {
if ( $tree [ $peice ][ 'type' ] == 'folder' ) {
$tree = $tree [ $peice ][ 'tree' ];
} else {
$tree = $tree [ $peice ];
}
} else {
return false ;
}
}
return $tree ;
}
function url_path () {
2014-02-12 11:42:33 +01:00
$url = parse_url (( isset ( $_SERVER [ 'REQUEST_URI' ])) ? $_SERVER [ 'REQUEST_URI' ] : '' );
2013-06-12 00:28:29 +02:00
$url = $url [ 'path' ];
return $url ;
}
function url_params () {
2013-09-10 05:15:46 +02:00
$url = rawurldecode ( get_uri ());
2013-06-12 00:28:29 +02:00
$params = explode ( '/' , trim ( $url , '/' ));
return $params ;
}
function clean_sort ( $text ) {
// Remove .md file extension
$text = str_replace ( '.md' , '' , $text );
// Remove sort placeholder
$parts = explode ( '_' , $text );
if ( isset ( $parts [ 0 ]) && is_numeric ( $parts [ 0 ])) {
unset ( $parts [ 0 ]);
}
$text = implode ( '_' , $parts );
return $text ;
}
function clean_name ( $text ) {
$text = str_replace ( '_' , ' ' , $text );
return $text ;
}
2013-09-09 11:57:11 +02:00
function RFC3986UrlEncode ( $string ) {
$entities = array ( '%21' , '%2A' , '%27' , '%28' , '%29' , '%3B' , '%3A' , '%40' , '%26' , '%3D' , '%2B' , '%24' , '%2C' , '%2F' , '%3F' , '%25' , '%23' , '%5B' , '%5D' );
$replacements = array ( '!' , '*' , " ' " , " ( " , " ) " , " ; " , " : " , " @ " , " & " , " = " , " + " , " $ " , " , " , " / " , " ? " , " % " , " # " , " [ " , " ] " );
return str_replace ( $entities , $replacements , urlencode ( $string ));
}
2013-08-23 21:49:08 +02:00
function build_nav ( $tree , $url_params ) {
2013-06-21 17:49:05 +02:00
// Remove Index
unset ( $tree [ 'index' ]);
2013-06-12 00:28:29 +02:00
$url_path = url_path ();
$html = '<ul class="nav nav-list">' ;
foreach ( $tree as $key => $val ) {
// Active Tree Node
if ( isset ( $url_params [ 0 ]) && $url_params [ 0 ] == $val [ 'clean' ]) {
array_shift ( $url_params );
// Final Node
2013-09-09 11:57:11 +02:00
if ( $url_path == RFC3986UrlEncode ( $val [ 'url' ])) {
2013-06-12 00:28:29 +02:00
$html .= '<li class="active">' ;
} else {
$html .= '<li class="open">' ;
}
} else {
$html .= '<li>' ;
}
if ( $val [ 'type' ] == 'folder' ) {
$html .= '<a href="#" class="aj-nav folder">' . $val [ 'name' ] . '</a>' ;
$html .= build_nav ( $val [ 'tree' ], $url_params );
} else {
2014-02-12 11:42:33 +01:00
$html .= '<a href="' . $val [ 'url' ] . (( CLI ) ? '.html' : '' ) . '">' . $val [ 'name' ] . '</a>' ;
2013-06-12 00:28:29 +02:00
}
$html .= '</li>' ;
}
$html .= '</ul>' ;
return $html ;
}
2013-07-22 17:48:18 +02:00
function get_ignored () {
// TODO: Add support for wildcards
// TODO: Add support for specific paths, i.e. /Publish/Somefile.md vs. /Don't_Publish/Somefile.md
$options = get_options ();
2013-09-09 18:13:08 +02:00
$default_ignored_files = array ( 'config.json' , 'cgi-bin' , 'Thumbs.db' );
2013-07-22 17:48:18 +02:00
$default_ignored_folders = array (); // To allow for easy addition of default folders if found necessary in the future
$user_ignored_files = array ();
$user_ignored_folders = array ();
// Check if ignore settings exist
if ( array_key_exists ( 'ignore' , $options )) {
if ( array_key_exists ( 'files' , $options [ 'ignore' ])) {
$user_ignored_files = $options [ 'ignore' ][ 'files' ];
}
if ( array_key_exists ( 'folders' , $options [ 'ignore' ])) {
$user_ignored_folders = $options [ 'ignore' ][ 'folders' ];
}
}
// Merge all ignore arrays together
$all_ignored = array_merge ( $default_ignored_files , $default_ignored_folders , $user_ignored_files , $user_ignored_folders );
// Return array of all ignored files and folders
return $all_ignored ;
}
2014-02-12 11:42:33 +01:00
function get_tree ( $path = '.' , $clean_path = '' , $title = '' , $first = true , $language = null , & $flat_tree = null ){
2014-02-19 06:43:50 +01:00
$options = get_options ();
$tree = array ();
$ignore = get_ignored ();
$dh = @ opendir ( $path );
$index = 0 ;
// Build array of paths
$paths = array ();
while ( false !== ( $file = readdir ( $dh ))){
2013-06-21 18:12:14 +02:00
$paths [ $file ] = $file ;
}
// Close the directory handle
closedir ( $dh );
// Sort paths
sort ( $paths );
2014-02-12 17:34:28 +01:00
2014-02-19 06:43:50 +01:00
if ( $first && $language !== null ) {
$language_path = $language . " / " ;
} else {
$language_path = " " ;
}
2013-06-21 18:12:14 +02:00
2014-02-19 06:43:50 +01:00
// Loop through the paths
// while(false !== ($file = readdir($dh))){
2013-06-21 18:12:14 +02:00
foreach ( $paths as $file ) {
2013-06-12 00:28:29 +02:00
2014-02-19 06:43:50 +01:00
// Check that this file or folder is not to be ignored
if ( ! in_array ( $file , $ignore ) && $file [ 0 ] !== '.' ) {
$full_path = " $path / $file " ;
$clean_sort = clean_sort ( $file );
// If clean_urls is set to false and this is the first branch of the tree, append index.php to the clean_path.
if ( $options [ 'clean_urls' ] == false )
{
if ( $first )
{
$url = $clean_path . '/' . $language_path . 'index.php/' . $clean_sort ;
}
else
{
$url = $clean_path . '/' . $language_path . $clean_sort ;
}
}
else
{
$url = $clean_path . '/' . $language_path . $clean_sort ;
}
$clean_name = clean_name ( $clean_sort );
// Title
if ( empty ( $title )) {
$full_title = $clean_name ;
} else {
$full_title = $title . ': ' . $clean_name ;
}
if ( is_dir ( " $path / $file " )) {
// Directory
$tree [ $clean_sort ] = array (
'type' => 'folder' ,
'name' => $clean_name ,
'title' => $full_title ,
'path' => $full_path ,
'clean' => $clean_sort ,
'url' => $url ,
'tree' => ( isset ( $flat_tree ) && $flat_tree !== NULL ) ?
get_tree ( $full_path , $url , $full_title , false , $language , $flat_tree ) :
get_tree ( $full_path , $url , $full_title , false , $language )
);
} else {
// File
$tree [ $clean_sort ] = array (
'type' => 'file' ,
'name' => $clean_name ,
'title' => $full_title ,
'path' => $full_path ,
'clean' => $clean_sort ,
'url' => $url ,
);
if ( isset ( $flat_tree ) && $flat_tree !== NULL )
array_push ( $flat_tree , $tree [ $clean_sort ]);
}
}
$index ++ ;
}
return $tree ;
2013-06-12 00:28:29 +02:00
}
2013-07-22 11:35:56 +02:00
/**
* Get ' s the current " pretty " URI from the URL . It will also correct the QUERY_STRING server var and the $_GET array .
* It supports all forms of mod_rewrite and the following forms of URL :
*
* http :// example . com / index . php / foo ( returns '/foo' )
* http :// example . com / index . php ? / foo ( returns '/foo' )
* http :// example . com / index . php / foo ? baz = bar ( returns '/foo' )
* http :// example . com / index . php ? / foo ? baz = bar ( returns '/foo' )
*
* Similarly using mod_rewrite to remove index . php :
* http :// example . com / foo ( returns '/foo' )
* http :// example . com / foo ? baz = bar ( returns '/foo' )
*
* @ author Dan Horrigan < http :// dhorrigan . com >
* @ copyright Dan Horrigan
* @ license MIT License < http :// www . opensource . org / licenses / mit - license . php >
* @ param bool $prefix_slash whether to return the uri with a '/' in front
* @ return string the uri
*/
function get_uri ( $prefix_slash = true )
{
2014-02-19 06:43:50 +01:00
if ( isset ( $_SERVER [ 'PATH_INFO' ]))
{
$uri = $_SERVER [ 'PATH_INFO' ];
}
elseif ( isset ( $_SERVER [ 'REQUEST_URI' ]))
{
$uri = $_SERVER [ 'REQUEST_URI' ];
if ( strpos ( $uri , $_SERVER [ 'SCRIPT_NAME' ]) === 0 )
{
$uri = substr ( $uri , strlen ( $_SERVER [ 'SCRIPT_NAME' ]));
}
elseif ( strpos ( $uri , dirname ( $_SERVER [ 'SCRIPT_NAME' ])) === 0 )
{
$uri = substr ( $uri , strlen ( dirname ( $_SERVER [ 'SCRIPT_NAME' ])));
}
// This section ensures that even on servers that require the URI to be in the query string (Nginx) a correct
// URI is found, and also fixes the QUERY_STRING server var and $_GET array.
if ( strncmp ( $uri , '?/' , 2 ) === 0 )
{
$uri = substr ( $uri , 2 );
}
$parts = preg_split ( '#\?#i' , $uri , 2 );
$uri = $parts [ 0 ];
if ( isset ( $parts [ 1 ]))
{
$_SERVER [ 'QUERY_STRING' ] = $parts [ 1 ];
parse_str ( $_SERVER [ 'QUERY_STRING' ], $_GET );
}
else
{
$_SERVER [ 'QUERY_STRING' ] = '' ;
$_GET = array ();
}
$uri = parse_url ( $uri , PHP_URL_PATH );
}
else
{
// Couldn't determine the URI, so just return false
return false ;
}
// Do some final cleaning of the URI and return it
return ( $prefix_slash ? '/' : '' ) . str_replace ( array ( '//' , '../' ), '/' , trim ( $uri , '/' ));
2013-07-22 17:53:28 +02:00
}
2014-01-19 23:24:23 +01:00
function handle_editor_post ( $post , $page ) {
2014-02-19 06:43:50 +01:00
if ( file_exists ( $page [ " path " ])) {
file_put_contents ( $page [ " path " ], $post [ " markdown " ]);
} else {
throw new Exception ( " File doesn't exist " , 1 );
}
2014-02-12 11:42:33 +01:00
}
/**
* Generate the page using the correct $url_params
*/
function generate_page ( $options , $url_params , $base_url , $return = FALSE , & $flat_tree = NULL ){
//documentation folder defined in various folder languages
if ( count ( $options [ 'languages' ]) > 0 && count ( $url_params ) > 0 && strlen ( $url_params [ 0 ]) > 0 ) {
2014-02-19 06:43:50 +01:00
$language = array_shift ( $url_params );
$base_path = $options [ 'docs_path' ] . DIRECTORY_SEPARATOR . $language ;
} else {
$language = null ;
$base_path = $options [ 'docs_path' ];
}
2014-02-12 11:42:33 +01:00
// If a timezone has been set in the config file, override the default PHP timezone for this application.
if ( isset ( $options [ 'timezone' ]))
{
2014-02-19 06:43:50 +01:00
date_default_timezone_set ( $options [ 'timezone' ]);
2014-02-12 11:42:33 +01:00
}
2014-02-19 06:43:50 +01:00
$tree = ( isset ( $flat_tree )) ?
get_tree ( $base_path , $base_url , '' , true , $language , $flat_tree ) :
get_tree ( $base_path , $base_url , '' , true , $language );
2014-02-12 11:42:33 +01:00
2014-02-19 06:43:50 +01:00
// If a language is set in the config, rewrite urls based on the language
2014-02-12 11:42:33 +01:00
if ( ! isset ( $language ) || $language === null ) {
2014-02-19 06:43:50 +01:00
$homepage_url = homepage_url ( $tree );
2014-02-12 11:42:33 +01:00
} else {
2014-02-19 06:43:50 +01:00
$homepage_url = " / " ;
2014-02-12 11:42:33 +01:00
}
// Redirect to docs, if there is no homepage
if ( $homepage_url !== '/' ) {
2014-02-19 06:43:50 +01:00
header ( 'Location: ' . $homepage_url );
2014-02-12 11:42:33 +01:00
}
2014-02-19 06:43:50 +01:00
$docs_url = docs_url ( $tree );
$page = load_page ( $tree , $url_params );
2014-02-12 11:42:33 +01:00
// Handle AJAX requests for file editing
if ( isset ( $_POST [ " markdown " ]) && $options [ " file_editor " ] === true ) {
2014-02-19 06:43:50 +01:00
handle_editor_post ( $_POST , $page );
die ;
2014-02-12 11:42:33 +01:00
}
2014-02-19 06:43:50 +01:00
if ( $url_params [ 0 ] == '' )
$homepage = TRUE ;
else
$homepage = FALSE ;
2014-02-12 11:42:33 +01:00
2014-02-19 06:43:50 +01:00
ob_start ();
2014-02-12 11:42:33 +01:00
2014-02-19 06:43:50 +01:00
include ( 'template/' . $options [ 'template' ] . '.tpl' );
if ( $return === TRUE )
2014-02-12 11:42:33 +01:00
{
$buffer = ob_get_contents ();
@ ob_end_clean ();
return $buffer ;
} else {
ob_end_flush ();
}
}
function load_tpl_block ( $file , $options , $base_url ){
ob_start ();
2014-02-19 06:43:50 +01:00
include ( 'template/' . $file . '.tpl' );
$buffer = ob_get_contents ();
2014-02-12 11:42:33 +01:00
@ ob_end_clean ();
return $buffer ;
}
2014-02-12 17:34:28 +01:00
function copy_recursive ( $source , $dest , $ignoreList = array ()){
2014-02-12 11:42:33 +01:00
$src_folder = str_replace ( array ( '.' , '/' ), '' , $source );
@ mkdir ( $dest . DIRECTORY_SEPARATOR . $src_folder );
foreach (
$iterator = new RecursiveIteratorIterator (
new RecursiveDirectoryIterator ( $source , RecursiveDirectoryIterator :: SKIP_DOTS ),
RecursiveIteratorIterator :: SELF_FIRST ) as $item
) {
if ( $item -> isDir ()) {
2014-02-19 06:43:50 +01:00
@ mkdir ( $dest . DIRECTORY_SEPARATOR . $src_folder . DIRECTORY_SEPARATOR . $iterator -> getSubPathName ());
2014-02-12 11:42:33 +01:00
} else {
2014-02-19 06:43:50 +01:00
if ( ! $ignoreList || ! in_array ( $item , $ignoreList )) @ copy ( $item , $dest . DIRECTORY_SEPARATOR . $src_folder . DIRECTORY_SEPARATOR . $iterator -> getSubPathName ());
2014-02-12 11:42:33 +01:00
}
}
}
function clean_directory ( $directory ){
foreach (
$iterator = new RecursiveIteratorIterator (
new RecursiveDirectoryIterator ( $directory , RecursiveDirectoryIterator :: SKIP_DOTS ),
RecursiveIteratorIterator :: SELF_FIRST ) as $item
) {
2014-02-19 06:43:50 +01:00
@ unlink ( $directory . DIRECTORY_SEPARATOR . $iterator -> getSubPathName ());
2014-02-12 11:42:33 +01:00
}
}
function relative_base ( $count ){
$relative = '' ;
for ( $i = 0 ; ( $i < $count ); $i ++ ){
if ( ! ( $i == 0 ))
$relative .= '/' ;
$relative .= '..' ;
}
return $relative ;
}
function clean_copy_assets ( $path ){
@ mkdir ( $path );
2014-02-19 06:43:50 +01:00
$options = $GLOBALS [ " options " ];
2014-02-12 11:42:33 +01:00
//Clean
2014-02-19 06:43:50 +01:00
clean_directory ( $path );
//Copy assets
$unnecessaryImgs = array ( './img/favicon.png' , './img/favicon-blue.png' , './img/favicon-green.png' , './img/favicon-navy.png' , './img/favicon-red.png' );
$unnecessaryJs = array ();
if ( $options [ 'colors' ]) {
@ mkdir ( $path . '/less' );
@ mkdir ( $path . '/less/import' );
@ copy ( './less/import/daux-base.less' , $path . '/less/import/daux-base.less' );
$unnecessaryImgs = array_diff ( $unnecessaryImgs , array ( './img/favicon.png' ));
} else {
$unnecessaryJs = array ( './js/less.min.js' );
@ mkdir ( $path . '/css' );
@ copy ( './css/daux-' . $options [ 'theme' ] . '.min.css' , $path . '/css/daux-' . $options [ 'theme' ] . '.min.css' );
$unnecessaryImgs = array_diff ( $unnecessaryImgs , array ( './img/favicon-' . $options [ 'theme' ] . '.png' ));
}
copy_recursive ( './img' , $path . '/' , $unnecessaryImgs );
copy_recursive ( './js' , $path . '/' , $unnecessaryJs );
2014-02-12 11:42:33 +01:00
}