Upgrade to KH 3.1.3.1

This commit is contained in:
Deon George
2011-05-13 16:00:25 +10:00
parent 8013aadc4c
commit 6d256839fc
675 changed files with 22771 additions and 24111 deletions

View File

@@ -17,7 +17,7 @@ class Controller_Userguide extends Controller_Template {
public function before()
{
if ($this->request->action === 'media')
if ($this->request->action() === 'media')
{
// Do not template media files
$this->auto_render = FALSE;
@@ -28,26 +28,6 @@ class Controller_Userguide extends Controller_Template {
$this->media = Route::get('docs/media');
$this->guide = Route::get('docs/guide');
if (isset($_GET['lang']))
{
$lang = $_GET['lang'];
// Load the accepted language list
$translations = array_keys(Kohana::message('userguide', 'translations'));
if (in_array($lang, $translations))
{
// Set the language cookie
Cookie::set('userguide_language', $lang, Date::YEAR);
}
// Reload the page
$this->request->redirect($this->request->uri);
}
// Set the translation language
I18n::$lang = Cookie::get('userguide_language', Kohana::config('userguide')->lang);
if (defined('MARKDOWN_PARSER_CLASS'))
{
throw new Kohana_Exception('Markdown parser already registered. Live documentation will not work in your environment.');
@@ -70,92 +50,182 @@ class Controller_Userguide extends Controller_Template {
parent::before();
}
// List all modules that have userguides
public function index()
{
$this->template->title = "Userguide";
$this->template->breadcrumb = array('User Guide');
$this->template->content = View::factory('userguide/index', array('modules' => $this->_modules()));
$this->template->menu = View::factory('userguide/menu', array('modules' => $this->_modules()));
// Don't show disqus on the index page
$this->template->hide_disqus = TRUE;
}
// Display an error if a page isn't found
public function error($message)
{
$this->response->status(404);
$this->template->title = "Userguide - Error";
$this->template->content = View::factory('userguide/error',array('message' => $message));
// Don't show disqus on error pages
$this->template->hide_disqus = TRUE;
// If we are in a module and that module has a menu, show that
if ($module = $this->request->param('module') AND $menu = $this->file($module.'/menu') AND Kohana::config('userguide.modules.'.$module.'.enabled'))
{
// Namespace the markdown parser
Kodoc_Markdown::$base_url = URL::site($this->guide->uri()).'/'.$module.'/';
Kodoc_Markdown::$image_url = URL::site($this->media->uri()).'/'.$module.'/';
$this->template->menu = Markdown($this->_get_all_menu_markdown());
$this->template->breadcrumb = array(
$this->guide->uri() => 'User Guide',
$this->guide->uri(array('module' => $module)) => Kohana::config('userguide.modules.'.$module.'.name'),
'Error'
);
}
// If we are in the api browser, show the menu and show the api browser in the breadcrumbs
else if (Route::name($this->request->route()) == 'docs/api')
{
$this->template->menu = Kodoc::menu();
// Bind the breadcrumb
$this->template->breadcrumb = array(
$this->guide->uri(array('page' => NULL)) => 'User Guide',
$this->request->route()->uri() => 'API Browser',
'Error'
);
}
// Otherwise, show the userguide module menu on the side
else
{
$this->template->menu = View::factory('userguide/menu',array('modules' => $this->_modules()));
$this->template->breadcrumb = array($this->request->route()->uri() => 'User Guide','Error');
}
}
public function action_docs()
{
$module = $this->request->param('module');
$page = $this->request->param('page');
if ( ! $page)
// Trim trailing slash
$page = rtrim($page, '/');
// If no module provided in the url, show the user guide index page, which lists the modules.
if ( ! $module)
{
// Redirect to the default page
$this->request->redirect($this->guide->uri(array('page' => Kohana::config('userguide')->default_page)));
return $this->index();
}
$file = $this->file($page);
// If this module's userguide pages are disabled, show the error page
if ( ! Kohana::config('userguide.modules.'.$module.'.enabled'))
{
return $this->error(__('That module doesn\'t exist, or has userguide pages disabled.'));
}
// Prevent "guide/module" and "guide/module/index" from having duplicate content
if ( $page == 'index')
{
return $this->error(__('Userguide page not found'));
}
// If a module is set, but no page was provided in the url, show the index page
if ( ! $page )
{
$page = 'index';
}
// Find the markdown file for this page
$file = $this->file($module.'/'.$page);
// If it's not found, show the error page
if ( ! $file)
{
$this->error(__('Userguide page not found'));
return;
return $this->error(__('Userguide page not found'));
}
// Namespace the markdown parser
Kodoc_Markdown::$base_url = URL::site($this->guide->uri()).'/'.$module.'/';
Kodoc_Markdown::$image_url = URL::site($this->media->uri()).'/'.$module.'/';
// Set the page title
$this->template->title = $this->title($page);
$this->template->title = $page == 'index' ? Kohana::config('userguide.modules.'.$module.'.name') : $this->title($page);
// Parse the page contents into the template
Kodoc_Markdown::$show_toc = true;
$this->template->content = Markdown(file_get_contents($file));
Kodoc_Markdown::$show_toc = false;
// Attach the menu to the template
$this->template->menu = Markdown(file_get_contents($this->file('menu')));
// Bind module menu items
$this->template->bind('module_menus', $module_menus);
// Attach module-specific menu items
$module_menus = array();
foreach(Kohana::modules() as $module => $path)
{
if ($file = $this->file('menu.'.$module))
{
$module_menus[$module] = Markdown(file_get_contents($file));
}
}
// Attach this module's menu to the template
$this->template->menu = Markdown($this->_get_all_menu_markdown());
// Bind the breadcrumb
$this->template->bind('breadcrumb', $breadcrumb);
// Add the breadcrumb
// Bind the copyright
$this->template->copyright = Kohana::config('userguide.modules.'.$module.'.copyright');
// Add the breadcrumb trail
$breadcrumb = array();
$breadcrumb[$this->guide->uri()] = __('User Guide');
$breadcrumb[] = $this->section($page);
$breadcrumb[] = $this->template->title;
$breadcrumb[$this->guide->uri(array('module' => $module))] = Kohana::config('userguide.modules.'.$module.'.name');
// TODO try and get parent category names (from menu). Regex magic or javascript dom stuff perhaps?
// Only add the current page title to breadcrumbs if it isn't the index, otherwise we get repeats.
if ($page != 'index')
{
$breadcrumb[] = $this->template->title;
}
}
public function action_api()
{
// Enable the missing class autoloader
// Enable the missing class autoloader. If a class cannot be found a
// fake class will be created that extends Kodoc_Missing
spl_autoload_register(array('Kodoc_Missing', 'create_class'));
// Get the class from the request
$class = $this->request->param('class');
if ($class)
{
try
{
$_class = Kodoc_Class::factory($class);
if ( ! Kodoc::show_class($_class))
throw new Exception(__('That class is hidden'));
}
catch (Exception $e)
{
return $this->error(__('API Reference: Class not found.'));
}
$this->template->title = $class;
$this->template->content = View::factory('userguide/api/class')
->set('doc', Kodoc::factory($class))
->set('route', $this->request->route);
}
else
// If no class was passed to the url, display the API index page
if ( ! $class)
{
$this->template->title = __('Table of Contents');
$this->template->content = View::factory('userguide/api/toc')
->set('classes', Kodoc::class_methods())
->set('route', $this->request->route);
->set('route', $this->request->route());
}
else
{
// Create the Kodoc_Class version of this class.
$_class = Kodoc_Class::factory($class);
// If the class requested and the actual class name are different
// (different case, orm vs ORM, auth vs Auth) redirect
if ($_class->class->name != $class)
{
$this->request->redirect($this->request->route()->uri(array('class'=>$_class->class->name)));
}
// If this classes immediate parent is Kodoc_Missing, then it should 404
if ($_class->class->getParentClass() AND $_class->class->getParentClass()->name == 'Kodoc_Missing')
return $this->error('That class was not found. Check your url and make sure that the module with that class is enabled.');
// If this classes package has been disabled via the config, 404
if ( ! Kodoc::show_class($_class))
return $this->error('That class is in package that is hidden. Check the <code>api_packages</code> config setting.');
// Everything is fine, display the class.
$this->template->title = $class;
$this->template->content = View::factory('userguide/api/class')
->set('doc', Kodoc::factory($class))
->set('route', $this->request->route());
}
// Attach the menu to the template
@@ -170,15 +240,12 @@ class Controller_Userguide extends Controller_Template {
// Add the breadcrumb
$breadcrumb = array();
$breadcrumb[$this->guide->uri(array('page' => NULL))] = __('User Guide');
$breadcrumb[$this->request->route->uri()] = $this->title('api');
$breadcrumb[$this->request->route()->uri()] = 'API Browser';
$breadcrumb[] = $this->template->title;
}
public function action_media()
{
// Generate and check the ETag for this file
$this->request->check_cache(sha1($this->request->uri));
// Get the file path from the request
$file = $this->request->param('file');
@@ -188,31 +255,23 @@ class Controller_Userguide extends Controller_Template {
// Remove the extension from the filename
$file = substr($file, 0, -(strlen($ext) + 1));
if ($file = Kohana::find_file('media', $file, $ext))
if ($file = Kohana::find_file('media/guide', $file, $ext))
{
// Check if the browser sent an "if-none-match: <etag>" header, and tell if the file hasn't changed
$this->response->check_cache(sha1($this->request->uri()).filemtime($file), $this->request);
// Send the file content as the response
$this->request->response = file_get_contents($file);
$this->response->body(file_get_contents($file));
// Set the proper headers to allow caching
$this->response->headers('content-type', File::mime_by_ext($ext));
$this->response->headers('last-modified', date('r', filemtime($file)));
}
else
{
// Return a 404 status
$this->request->status = 404;
$this->response->status(404);
}
// Set the proper headers to allow caching
$this->request->headers['Content-Type'] = File::mime_by_ext($ext);
$this->request->headers['Content-Length'] = filesize($file);
$this->request->headers['Last-Modified'] = date('r', filemtime($file));
}
// Display an error if a page isn't found
public function error($message)
{
$this->request->status = 404;
$this->template->title = __('User Guide').' - '.__('Error');
$this->template->content = View::factory('userguide/error',array('message'=>$message));
$this->template->menu = Kodoc::menu();
$this->template->breadcrumb = array($this->guide->uri() => __('User Guide'), __('Error'));
}
public function after()
@@ -234,7 +293,9 @@ class Controller_Userguide extends Controller_Template {
// Add scripts
$this->template->scripts = array(
$media->uri(array('file' => 'js/jquery.min.js')),
$media->uri(array('file' => 'js/jquery.cookie.js')),
$media->uri(array('file' => 'js/kodoc.js')),
// Syntax Highlighter
$media->uri(array('file' => 'js/shCore.js')),
$media->uri(array('file' => 'js/shBrushPhp.js')),
);
@@ -248,67 +309,82 @@ class Controller_Userguide extends Controller_Template {
public function file($page)
{
if ( ! ($file = Kohana::find_file('guide', I18n::$lang.'/'.$page, 'md')))
{
// Use the default file
$file = Kohana::find_file('guide', $page, 'md');
}
return $file;
return Kohana::find_file('guide', $page, 'md');
}
public function section($page)
{
$markdown = $this->_get_all_menu_markdown();
if (preg_match('~\*{2}(.+?)\*{2}[^*]+\[[^\]]+\]\('.preg_quote($page).'\)~mu', $markdown, $matches))
{
return $matches[1];
}
return $page;
}
public function title($page)
{
$markdown = $this->_get_all_menu_markdown();
if (preg_match('~\[([^\]]+)\]\('.preg_quote($page).'\)~mu', $markdown, $matches))
{
// Found a title for this link
return $matches[1];
}
return $page;
}
protected function _get_all_menu_markdown()
{
// Only do this once per request...
static $markdown = '';
if (empty($markdown))
{
// Get core menu items
$file = $this->file('menu');
// Get menu items
$file = $this->file($this->request->param('module').'/menu');
if ($file AND $text = file_get_contents($file))
{
// Add spans around non-link categories. This is a terrible hack.
//echo Kohana::debug($text);
//$text = preg_replace('/(\s*[\-\*\+]\s*)(.*)/','$1<span>$2</span>',$text);
$text = preg_replace('/^(\s*[\-\*\+]\s*)([^\[\]]+)$/m','$1<span>$2</span>',$text);
//echo Kohana::debug($text);
$markdown .= $text;
}
// Look in module specific files
foreach(Kohana::modules() as $module => $path)
{
if ($file = $this->file('menu.'.$module) AND $text = file_get_contents($file))
{
// Concatenate markdown to produce one string containing all menu items
$markdown .="\n".$text;
}
}
}
return $markdown;
}
// Get the list of modules from the config, and reverses it so it displays in the order the modules are added, but move Kohana to the top.
protected function _modules()
{
$modules = array_reverse(Kohana::config('userguide.modules'));
if (isset($modules['kohana']))
{
$kohana = $modules['kohana'];
unset($modules['kohana']);
$modules = array_merge(array('kohana' => $kohana), $modules);
}
// Remove modules that have been disabled via config
foreach ($modules as $key => $value)
{
if ( ! Kohana::config('userguide.modules.'.$key.'.enabled'))
{
unset($modules[$key]);
}
}
return $modules;
}
} // End Userguide

View File

@@ -10,6 +10,39 @@
*/
class Kohana_Kodoc {
/**
* @var string PCRE fragment for matching 'Class', 'Class::method', 'Class::method()' or 'Class::$property'
*/
public static $regex_class_member = '((\w++)(?:::(\$?\w++))?(?:\(\))?)';
/**
* Make a class#member API link using an array of matches from [Kodoc::$regex_class_member]
*
* @param array $matches array( 1 => link text, 2 => class name, [3 => member name] )
* @return string
*/
public static function link_class_member($matches)
{
$link = $matches[1];
$class = $matches[2];
$member = NULL;
if (isset($matches[3]))
{
// If the first char is a $ it is a property, e.g. Kohana::$base_url
if ($matches[3][0] === '$')
{
$member = '#property:'.substr($matches[3], 1);
}
else
{
$member = '#'.$matches[3];
}
}
return HTML::anchor(Route::get('docs/api')->uri(array('class' => $class)).$member, $link, NULL, NULL, TRUE);
}
public static function factory($class)
{
return new Kodoc_Class($class);
@@ -135,9 +168,9 @@ class Kohana_Kodoc {
{
$_class = new ReflectionClass($class);
if (stripos($_class->name, 'Kohana') === 0)
if (stripos($_class->name, 'Kohana_') === 0)
{
// Skip the extension stuff stuff
// Skip transparent extension classes
continue;
}
@@ -147,13 +180,13 @@ class Kohana_Kodoc {
{
$declares = $_method->getDeclaringClass()->name;
if (stripos($declares, 'Kohana') === 0)
if (stripos($declares, 'Kohana_') === 0)
{
// Remove "Kohana_"
$declares = substr($declares, 7);
}
if ($declares === $_class->name)
if ($declares === $_class->name OR $declares === "Core")
{
$methods[] = $_method->name;
}
@@ -219,7 +252,7 @@ class Kohana_Kodoc {
}
break;
case 'throws':
if (preg_match('/^(\w+)\W(.*)$/',$text,$matches))
if (preg_match('/^(\w+)\W(.*)$/', $text, $matches))
{
$text = HTML::anchor(Route::get('docs/api')->uri(array('class' => $matches[1])), $matches[1]).' '.$matches[2];
}
@@ -229,10 +262,9 @@ class Kohana_Kodoc {
}
break;
case 'uses':
if (preg_match('/^([a-z_]+)::([a-z_]+)$/i', $text, $matches))
if (preg_match('/^'.Kodoc::$regex_class_member.'$/i', $text, $matches))
{
// Make a class#method API link
$text = HTML::anchor(Route::get('docs/api')->uri(array('class' => $matches[1])).'#'.$matches[2], $text);
$text = Kodoc::link_class_member($matches);
}
break;
// Don't show @access lines, they are shown elsewhere
@@ -269,10 +301,7 @@ class Kohana_Kodoc {
*/
public static function source($file, $start, $end)
{
if ( ! $file)
{
return FALSE;
}
if ( ! $file) return FALSE;
$file = file($file, FILE_IGNORE_NEW_LINES);
@@ -306,7 +335,7 @@ class Kohana_Kodoc {
return TRUE;
// Get the package tags for this class (as an array)
$packages = Arr::get($class->tags,'package',Array('None'));
$packages = Arr::get($class->tags, 'package', array('None'));
$show_this = FALSE;
@@ -314,7 +343,7 @@ class Kohana_Kodoc {
foreach ($packages as $package)
{
// If this package is in the allowed packages, set show this to true
if (in_array($package,explode(',',$api_packages)))
if (in_array($package, explode(',', $api_packages)))
$show_this = TRUE;
}

View File

@@ -56,7 +56,7 @@ class Kohana_Kodoc_Class extends Kodoc {
{
foreach ($constants as $name => $value)
{
$this->constants[$name] = Kohana::debug($value);
$this->constants[$name] = Debug::vars($value);
}
}
@@ -73,6 +73,22 @@ class Kohana_Kodoc_Class extends Kodoc {
while ($parent = $parent->getParentClass());
list($this->description, $this->tags) = Kodoc::parse($comment);
// If this class extends Kodoc_Missing, add a warning about possible
// incomplete documentation
$parent = $this->class;
while ($parent = $parent->getParentClass())
{
if ($parent->name == 'Kodoc_Missing')
{
$warning = "[!!] **This class, or a class parent, could not be
found or loaded. This could be caused by a missing
module or other dependancy. The documentation for
class may not be complete!**";
$this->description = Markdown($warning).$this->description;
}
}
}
/**
@@ -84,23 +100,34 @@ class Kohana_Kodoc_Class extends Kodoc {
{
$props = $this->class->getProperties();
sort($props);
usort($props, array($this,'_prop_sort'));
foreach ($props as $key => $property)
{
// Only show public properties, because Reflection can't get the private ones
if ($property->isPublic())
{
$props[$key] = new Kodoc_Property($this->class->name, $property->name);
}
else
{
unset($props[$key]);
}
// Create Kodoc Properties for each property
$props[$key] = new Kodoc_Property($this->class->name, $property->name);
}
return $props;
}
protected function _prop_sort($a, $b)
{
// If one property is public, and the other is not, it goes on top
if ($a->isPublic() AND ( ! $b->isPublic()))
return -1;
if ($b->isPublic() AND ( ! $a->isPublic()))
return 1;
// If one property is protected and the other is private, it goes on top
if ($a->isProtected() AND $b->isPrivate())
return -1;
if ($b->isProtected() AND $a->isPrivate())
return 1;
// Otherwise just do alphabetical
return strcmp($a->name, $b->name);
}
/**
* Gets a list of the class properties as [Kodoc_Method] objects.
@@ -120,22 +147,44 @@ class Kohana_Kodoc_Class extends Kodoc {
return $methods;
}
protected function _method_sort($a,$b)
/**
* Sort methods based on their visibility and declaring class based on:
* - methods will be sorted public, protected, then private.
* - methods that are declared by an ancestor will be after classes
* declared by the current class
* - lastly, they will be sorted alphabetically
*
*/
protected function _method_sort($a, $b)
{
// If one method is public, and the other is not, it goes on top
if ($a->isPublic() AND ( ! $b->isPublic()))
return -1;
if ($b->isPublic() AND ( ! $a->isPublic()))
return 1;
// If one method is protected and the other is private, it goes on top
if ($a->isProtected() AND $b->isPrivate())
return -1;
if ($b->isProtected() AND $a->isPrivate())
return 1;
// The methods have the same visibility, so check the declaring class depth:
/*
echo kohana::debug('a is '.$a->class.'::'.$a->name,'b is '.$b->class.'::'.$b->name,
'are the classes the same?',$a->class == $b->class,'if they are, the result is:',strcmp($a->name,$b->name),
'is a this class?',$a->name == $this->class->name,-1,
'is b this class?',$b->name == $this->class->name,1,
'otherwise, the result is:',strcmp($a->class,$b->class)
'are the classes the same?', $a->class == $b->class,'if they are, the result is:',strcmp($a->name, $b->name),
'is a this class?', $a->name == $this->class->name,-1,
'is b this class?', $b->name == $this->class->name,1,
'otherwise, the result is:',strcmp($a->class, $b->class)
);
*/
// If both methods are defined in the same class, just compare the method names
if ($a->class == $b->class)
return strcmp($a->name,$b->name);
return strcmp($a->name, $b->name);
// If one of them was declared by this class, it needs to be on top
if ($a->name == $this->class->name)

View File

@@ -19,7 +19,25 @@ class Kohana_Kodoc_Markdown extends MarkdownExtra_Parser {
* @var string base url for images
*/
public static $image_url = '';
/**
* Currently defined heading ids.
* Used to prevent creating multiple headings with same id.
* @var array
*/
protected $_heading_ids = array();
/**
* @var string the generated table of contents
*/
protected static $_toc = "";
/**
* Slightly less terrible way to make it so the TOC only shows up when we
* want it to. set this to true to show the toc.
*/
public static $show_toc = false;
public function __construct()
{
// doImage is 10, add image url just before
@@ -35,11 +53,92 @@ class Kohana_Kodoc_Markdown extends MarkdownExtra_Parser {
$this->span_gamut['doNotes'] = 100;
// Parse Kohana view inclusions at the very end
$this->document_gamut['doIncludeViews'] = 100;
$this->document_gamut['doIncludeViews'] = 99;
// Show table of contents for userguide pages
$this->document_gamut['doTOC'] = 100;
// PHP4 makes me sad.
parent::MarkdownExtra_Parser();
}
/**
* Callback for the heading setext style
*
* Heading 1
* =========
*
* @param array Matches from regex call
* @return string Generated html
*/
function _doHeaders_callback_setext($matches)
{
if ($matches[3] == '-' && preg_match('{^- }', $matches[1]))
return $matches[0];
$level = $matches[3]{0} == '=' ? 1 : 2;
$attr = $this->_doHeaders_attr($id =& $matches[2]);
// Only auto-generate id if one doesn't exist
if(empty($attr))
$attr = ' id="'.$this->make_heading_id($matches[1]).'"';
// Add this header to the page toc
$this->_add_to_toc($level,$matches[1],$this->make_heading_id($matches[1]));
$block = "<h$level$attr>".$this->runSpanGamut($matches[1])."</h$level>";
return "\n" . $this->hashBlock($block) . "\n\n";
}
/**
* Callback for the heading atx style
*
* # Heading 1
*
* @param array Matches from regex call
* @return string Generated html
*/
function _doHeaders_callback_atx($matches)
{
$level = strlen($matches[1]);
$attr = $this->_doHeaders_attr($id =& $matches[3]);
// Only auto-generate id if one doesn't exist
if(empty($attr))
$attr = ' id="'.$this->make_heading_id($matches[2]).'"';
// Add this header to the page toc
$this->_add_to_toc($level,$matches[2],$this->make_heading_id($matches[2]));
$block = "<h$level$attr>".$this->runSpanGamut($matches[2])."</h$level>";
return "\n" . $this->hashBlock($block) . "\n\n";
}
/**
* Makes a heading id from the heading text
* If any heading share the same name then subsequent headings will have an integer appended
*
* @param string The heading text
* @return string ID for the heading
*/
function make_heading_id($heading)
{
$id = url::title($heading, '-', TRUE);
if(isset($this->_heading_ids[$id]))
{
$id .= '-';
$count = 0;
while (isset($this->_heading_ids[$id]) AND ++$count)
{
$id .= $count;
}
}
return $id;
}
public function doIncludeViews($text)
{
@@ -47,6 +146,8 @@ class Kohana_Kodoc_Markdown extends MarkdownExtra_Parser {
{
$replace = array();
$replace = array();
foreach ($matches as $set)
{
list($search, $view) = $set;
@@ -60,7 +161,7 @@ class Kohana_Kodoc_Markdown extends MarkdownExtra_Parser {
ob_start();
// Capture the exception handler output and insert it instead
Kohana::exception_handler($e);
Kohana_exception::handler($e);
$replace[$search] = ob_get_clean();
}
@@ -83,7 +184,7 @@ class Kohana_Kodoc_Markdown extends MarkdownExtra_Parser {
public function doBaseURL($text)
{
// URLs containing "://" are left untouched
return preg_replace('~(?<!!)(\[.+?\]\()(?!\w++://)([^#]\S*(?:\s*+".+?")?\))~', '$1'.Kodoc_Markdown::$base_url.'$2', $text);
return preg_replace('~(?<!!)(\[.+?\]\()(?!\w++://)(?!#)(\S*(?:\s*+".+?")?\))~', '$1'.Kodoc_Markdown::$base_url.'$2', $text);
}
/**
@@ -103,49 +204,14 @@ class Kohana_Kodoc_Markdown extends MarkdownExtra_Parser {
/**
* Parses links to the API browser.
*
* [Class_Name] or [Class::$property]
* [Class_Name], [Class::method] or [Class::$property]
*
* @param string span text
* @return string
*/
public function doAPI($text)
{
return preg_replace_callback('/\[([a-z_]++(?:::\$?[a-z_]++)?)\]/i', array($this, '_convert_api_link'), $text);
}
public function _convert_api_link($matches)
{
static $route;
if ($route === NULL)
{
$route = Route::get('docs/api');
}
$link = $matches[1];
if (strpos($link, '::'))
{
// Split the class and method
list($class, $method) = explode('::', $link, 2);
if ($method[0] === '$')
{
// Class property, not method
$method = 'property:'.substr($method, 1);
}
// Add the id symbol to the method
$method = '#'.$method;
}
else
{
// Class with no method
$class = $link;
$method = NULL;
}
return HTML::anchor($route->uri(array('class' => $class)).$method, $link);
return preg_replace_callback('/\['.Kodoc::$regex_class_member.'\]/i', 'Kodoc::link_class_member', $text);
}
/**
@@ -165,5 +231,34 @@ class Kohana_Kodoc_Markdown extends MarkdownExtra_Parser {
return $this->hashBlock('<p class="note">'.$match[1].'</p>');
}
protected function _add_to_toc($level, $name, $id)
{
self::$_toc[] = array(
'level' => $level,
'name' => $name,
'id' => $id);
}
public function doTOC($text)
{
// Only add the toc do userguide pages, not api since they already have one
if (self::$show_toc AND Route::name(Request::current()->route()) == "docs/guide")
{
$toc = View::factory('userguide/page-toc')
->set('array', self::$_toc)
->render()
;
if (($offset = strpos($text, '<p>')) !== FALSE)
{
// Insert the page TOC just before the first <p>, which every
// Markdown page should (will?) have.
$text = substr_replace($text, $toc, $offset, 0);
}
}
return $text;
}
} // End Kodoc_Markdown

View File

@@ -64,7 +64,7 @@ class Kohana_Kodoc_Method extends Kodoc {
foreach ($this->method->getParameters() as $i => $param)
{
$param = new Kodoc_Method_Param(array($this->method->class,$this->method->name),$i);
$param = new Kodoc_Method_Param(array($this->method->class, $this->method->name),$i);
if (isset($tags['param'][$i]))
{
@@ -74,7 +74,7 @@ class Kohana_Kodoc_Method extends Kodoc {
if (isset($matches[2]))
{
$param->description = $matches[2];
$param->description = ucfirst($matches[2]);
}
}
$params[] = $param;

View File

@@ -53,7 +53,7 @@ class Kohana_Kodoc_Method_Param extends Kodoc {
if ($this->param->isDefaultValueAvailable())
{
$this->default = Kohana::dump($this->param->getDefaultValue());
$this->default = Debug::dump($this->param->getDefaultValue());
}
if ($this->param->isPassedByReference())

View File

@@ -1,8 +1,8 @@
<?php defined('SYSPATH') or die('No direct script access.');
/**
* [!!] This class, or a class parent, could not be found or loaded. This could
* be caused by a missing module or other dependancy. The documentation for
* class will not be complete!
* Set Kodoc_Missing::create_class as an autoloading to prevent missing classes
* from crashing the api browser. Classes that are missing a parent will
* extend this class, and get a warning in the API browser.
*
* @package Kohana/Userguide
* @category Undocumented

View File

@@ -51,17 +51,33 @@ class Kohana_Kodoc_Property extends Kodoc {
if (isset($matches[2]))
{
$this->description = $matches[2];
$this->description = Markdown($matches[2]);
}
}
}
$this->property = $property;
if ($property->isStatic())
// Show the value of static properties, but only if they are public or we are php 5.3 or higher and can force them to be accessible
if ($property->isStatic() AND ($property->isPublic() OR version_compare(PHP_VERSION, '5.3', '>=')))
{
$this->value = Kohana::debug($property->getValue($class));
// Force the property to be accessible
if (version_compare(PHP_VERSION, '5.3', '>='))
{
$property->setAccessible(TRUE);
}
// Don't debug the entire object, just say what kind of object it is
if (is_object($property->getValue($class)))
{
$this->value = '<pre>object '.get_class($property->getValue($class)).'()</pre>';
}
else
{
$this->value = Debug::vars($property->getValue($class));
}
}
}
} // End Kodoc_Property