public function __construct($class, $property) { $property = new ReflectionProperty($class, $property); list($description, $tags) = Kodoc::parse($property->getDocComment()); $this->description = $description; if ($modifiers = $property->getModifiers()) { $this->modifiers = '<small>' . implode(' ', Reflection::getModifierNames($modifiers)) . '</small> '; } if (isset($tags['var'])) { if (preg_match('/^(\\S*)(?:\\s*(.+?))?$/', $tags['var'][0], $matches)) { $this->type = $matches[1]; if (isset($matches[2])) { $this->description = Markdown($matches[2]); } } } $this->property = $property; // 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', '>='))) { // 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 = Kohana::debug($property->getValue($class)); } } }
public function __construct($file) { if ($filename = Kohana::find_file('config', $file)) { $this->name = $file; $source = file_get_contents($filename[0]); $start_offset = 0; // Find the config file comment first if (preg_match('~(/\\*.*?\\*/)~s', $source, $config_comment)) { $comment = Kodoc::parse($config_comment[0]); $this->description = $comment[0]; $this->tags = $comment[1]; $start_offset = strlen($config_comment[0]); } preg_match_all('~(/\\*.*?\\*/)?\\s*(\\$config\\[([^\\]]+)]\\s*=\\s*([^;]*?);)~s', $source, $matches, PREG_SET_ORDER, $start_offset); foreach ($matches as $item) { $comment = Kodoc::parse($item[1]); $default = isset($comment[1]['default'][0]) ? Kohana::debug($comment[1]['default'][0]) : NULL; // Remove the @default tag unset($comment[1]['default']); $this->options[] = (object) array('description' => $comment[0], 'source' => $item[2], 'name' => trim($item[3], '\'"'), 'default' => $default, 'tags' => $comment[1]); } } else { throw new Kohana_Exception('Error reading config file'); } }
/** * Loads a class and uses [reflection](http://php.net/reflection) to parse * the class. Reads the class modifiers, constants and comment. Parses the * comment to find the description and tags. * * @param string class name * @return void */ public function __construct($class) { $this->class = new ReflectionClass($class); if ($modifiers = $this->class->getModifiers()) { $this->modifiers = '<small>' . implode(' ', Reflection::getModifierNames($modifiers)) . '</small> '; } if ($constants = $this->class->getConstants()) { foreach ($constants as $name => $value) { $this->constants[$name] = Kohana::debug($value); } } $parent = $this->class; do { if ($comment = $parent->getDocComment()) { // Found a description for this class break; } } 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\n\t\t\t\t found or loaded. This could be caused by a missing\n\t\t\t\t\t\t module or other dependancy. The documentation for\n\t\t\t\t\t\t class may not be complete!**"; $this->description = Markdown($warning) . $this->description; } } }
public function __construct($class, $method) { $this->method = new ReflectionMethod($class, $method); $this->class = $parent = $this->method->getDeclaringClass(); if ($modifiers = $this->method->getModifiers()) { $this->modifiers = '<small>' . implode(' ', Reflection::getModifierNames($modifiers)) . '</small> '; } do { if ($parent->hasMethod($method) and $comment = $parent->getMethod($method)->getDocComment()) { // Found a description for this method break; } } while ($parent = $parent->getParentClass()); list($this->description, $tags) = Kodoc::parse($comment); if ($file = $this->class->getFileName()) { $this->source = Kodoc::source($file, $this->method->getStartLine(), $this->method->getEndLine()); } if (isset($tags['param'])) { $params = array(); foreach ($this->method->getParameters() as $i => $param) { if (isset($tags['param'][$i])) { if ($param->isDefaultValueAvailable()) { $name = $param->name . ' = ' . var_export($param->getDefaultValue(), TRUE); } else { $name = $param->name; } preg_match('/^(\\S+)(?:\\s*(.+))?$/', $tags['param'][$i], $matches); $verbose = '<small>' . $matches[1] . '</small> '; if (isset($matches[2])) { $verbose .= '<span class="param" title="' . $matches[2] . '">$' . $name . '</span>'; } else { $verbose .= '<span class="param">$' . $name . '</span>'; } $params[] = $verbose; } } $this->params = implode(', ', $params); unset($tags['param']); } if (isset($tags['return'])) { foreach ($tags['return'] as $return) { if (preg_match('/^(\\S*)(?:\\s*(.+?))?$/', $return, $matches)) { $this->return[] = array($matches[1], isset($matches[2]) ? $matches[2] : ''); } } unset($tags['return']); } $this->tags = $tags; }
public function __construct($class, $method) { $method = new ReflectionMethod($class, $method); $this->name = $method->name; $class = $parent = $method->getDeclaringClass(); if ($modifiers = $method->getModifiers()) { $this->modifiers = '<small>' . implode(' ', Reflection::getModifierNames($modifiers)) . '</small> '; } $comment = ''; do { if ($parent->hasMethod($this->name)) { $comment = $parent->getMethod($this->name)->getDocComment(); // Found a description for this method break; } } while ($parent = $parent->getParentClass()); list($this->description, $tags) = Kodoc::parse($comment); if ($file = $class->getFileName()) { $this->source = Kodoc::source($file, $method->getStartLine(), $method->getEndLine()); } if (isset($tags['param'])) { $params = array(); foreach ($method->getParameters() as $i => $param) { $param = new Kodoc_Method_Param(array($method->class, $method->name), $i); if (isset($tags['param'][$i])) { if (preg_match('/^(\\S*)\\s*(\\$\\w+)?(?:\\s*(.+?))?$/', $tags['param'][$i], $matches)) { $param->type = $matches[1]; $param->description = arr::get($matches, 3); } } $params[] = $param; } $this->params = $params; unset($tags['param']); } if (isset($tags['return'])) { foreach ($tags['return'] as $return) { if (preg_match('/^(\\S*)(?:\\s*(.+?))?$/', $return, $matches)) { $this->return[] = array($matches[1], isset($matches[2]) ? $matches[2] : ''); } } unset($tags['return']); } $this->tags = $tags; }
public function action_api() { // Get the class from the request $class = $this->request->param('class', 'Kohana'); // Set the template title $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 $this->template->menu = Kodoc::menu(); // Bind the breadcrumb $this->template->bind('breadcrumb', $breadcrumb); // Get the docs URI $guide = Route::get('docs/guide'); // Add the breadcrumb $breadcrumb = array(); $breadcrumb[$guide->uri(array('page' => NULL))] = __('User Guide'); $breadcrumb[$this->request->route->uri()] = $this->title('api'); $breadcrumb[] = $this->template->title; }
public function __construct($class_name) { $class_prefix = Kohana::config('core.extension_prefix'); if (substr($class_name, 0, strlen($class_prefix)) === $class_prefix) { $class_name = substr($class_name, strlen($class_prefix)); } $class = $parent = new ReflectionClass($class_name); $this->name = $class->name; $this->parents = array(); if ($modifiers = $class->getModifiers()) { $this->modifiers = '<small>' . implode(' ', Reflection::getModifierNames($modifiers)) . '</small> '; } if ($constants = $class->getConstants()) { foreach ($constants as $name => $value) { $this->constants[$name] = Kohana::debug($value); } } if ($props = $class->getProperties()) { foreach ($props as $key => $property) { // Only show public properties, because Reflection can't get the private ones if ($property->isPublic()) { $this->properties[$key] = new Kodoc_Property($class->name, $property->name); } } } if ($methods = $class->getMethods()) { foreach ($methods as $key => $method) { // Only show methods declared in this class $declaring_class = str_replace('_Core', '', $method->getDeclaringClass()->name); if ($declaring_class === $class->name) { $this->methods[$key] = new Kodoc_Method($class->name, $method->name); } } } do { // Skip the comments in the bootstrap file if ($comment = $parent->getDocComment() and basename($parent->getFileName()) !== 'Bootstrap.php') { // Found a description for this class break; } } while ($parent = $parent->getParentClass()); list($this->description, $this->tags) = Kodoc::parse($comment); }
/** * Loads a class and uses [reflection](http://php.net/reflection) to parse * the class. Reads the class modifiers, constants and comment. Parses the * comment to find the description and tags. * * @param string class name * @return void */ public function __construct($class) { $this->class = new ReflectionClass($class); if ($modifiers = $this->class->getModifiers()) { $this->modifiers = '<small>' . implode(' ', Reflection::getModifierNames($modifiers)) . '</small> '; } if ($constants = $this->class->getConstants()) { foreach ($constants as $name => $value) { $this->constants[$name] = Kohana::debug($value); } } $parent = $this->class; do { if ($comment = $parent->getDocComment()) { // Found a description for this class break; } } while ($parent = $parent->getParentClass()); list($this->description, $this->tags) = Kodoc::parse($comment); }
public function __call($method, $args) { if (count($segments = $this->uri->segment_array(1)) > 1) { // Find directory (type) and filename $type = array_shift($segments); $file = implode('/', $segments); if (substr($file, -strlen(EXT)) === EXT) { // Remove extension $file = substr($file, 0, -strlen(EXT)); } if ($type === 'config') { if ($file === 'config') { // This file can only exist in one location $file = APPPATH . $type . '/config' . EXT; } else { foreach (array_reverse(Kohana::include_paths()) as $path) { if (is_file($path . $type . '/' . $file . EXT)) { // Found the file $file = $path . $type . '/' . $file . EXT; break; } } } } else { // Get absolute path to file $file = Kohana::find_file($type, $file); } if (in_array($type, Kodoc::get_types())) { // Load Kodoc $this->kodoc = new Kodoc($type, $file); // Set the title $this->template->title = implode('/', $this->uri->segment_array(1)); // Load documentation for this file $this->template->content = new View('kodoc/documentation'); // Exit this method return; } } // Nothing to document url::redirect('kodoc'); }
public function __construct($class, $property) { $property = new ReflectionProperty($class, $property); list($description, $tags) = Kodoc::parse($property->getDocComment()); $this->description = $description; if ($modifiers = $property->getModifiers()) { $this->modifiers = '<small>' . implode(' ', Reflection::getModifierNames($modifiers)) . '</small> '; } if (isset($tags['var'])) { if (preg_match('/^(\\S*)(?:\\s*(.+?))?$/', $tags['var'][0], $matches)) { $this->type = $matches[1]; if (isset($matches[2])) { $this->description = $matches[2]; } } } $this->property = $property; if ($property->isStatic()) { $this->value = Kohana::debug($property->getValue($class)); } }
/** * Loads a class and uses [reflection](http://php.net/reflection) to parse * the class. Reads the class modifiers, constants and comment. Parses the * comment to find the description and tags. * * @param string class name * @return void */ public function __construct($class) { $this->class = new ReflectionClass($class); if ($modifiers = $this->class->getModifiers()) { $this->modifiers = '<small>' . implode(' ', Reflection::getModifierNames($modifiers)) . '</small> '; } if ($constants = $this->class->getConstants()) { foreach ($constants as $name => $value) { $this->constants[$name] = Debug::vars($value); } } // If ReflectionClass::getParentClass() won't work if the class in // question is an interface if ($this->class->isInterface()) { $this->parents = $this->class->getInterfaces(); } else { $parent = $this->class; while ($parent = $parent->getParentClass()) { $this->parents[] = $parent; } } $parents = $this->parents; array_unshift($parents, $this->class); foreach ($parents as $parent) { if ($comment = $parent->getDocComment()) { // Found a description for this class break; } } list($this->description, $this->tags) = Kodoc::parse($comment); // If this class extends Kodoc_Missing, add a warning about possible // incomplete documentation foreach ($parents as $parent) { if ($parent->name == 'Kodoc_Missing') { $warning = "[!!] **This class, or a class parent, could not be\r\n\t\t\t\t found or loaded. This could be caused by a missing\r\n\t\t\t\t\t\t module or other dependancy. The documentation for\r\n\t\t\t\t\t\t class may not be complete!**"; $this->description = Markdown($warning) . $this->description; } } }
/** * Get all classes and methods of files in a list. * * > I personally don't like this as it was used on the index page. Way too much stuff on one page. It has potential for a package index page though. * > For example: class_methods( Kohana::list_files('classes/sprig') ) could make a nice index page for the sprig package in the api browser * > ~bluehawk * */ public static function class_methods(array $list = NULL) { $list = Kodoc::classes($list); $classes = array(); foreach ($list as $class) { $_class = new ReflectionClass($class); if (stripos($_class->name, 'Kohana') === 0) { // Skip the extension stuff stuff continue; } $methods = array(); foreach ($_class->getMethods() as $_method) { $declares = $_method->getDeclaringClass()->name; if (stripos($declares, 'Kohana') === 0) { // Remove "Kohana_" $declares = substr($declares, 7); } if ($declares === $_class->name) { $methods[] = $_method->name; } } sort($methods); $classes[$_class->name] = $methods; } return $classes; }
public function action_index() { $msg = array(); $exclude_class = array_map('strtolower', Kohana::config('cs.exclude_class')); // arrays of different mask types and precise names $prec = array(); // like 'someword' $ast_left = array(); // like '*someword' $ast_right = array(); // like 'someword*' $two_ast = array(); // like '*someword*' foreach ($exclude_class as $mask) { if (strpos($mask, '*') === 0 and strrpos($mask, '*') === strlen($mask) - 1) { // any occurrence $two_ast[] = substr($mask, 1, -1); } elseif (strpos($mask, '*') === 0) { // masked as '*someword' $ast_left[] = substr($mask, 1); } elseif (strrpos($mask, '*') === strlen($mask) - 1) { // masked as 'someword*' $ast_right[] = substr($mask, 0, -1); } else { $prec[] = $mask; } } $classes = Kodoc::classes(); // remove excluded classes from list foreach ($classes as $class) { if (isset($classes['kohana_' . $class])) { unset($classes['kohana_' . $class]); } // exclude classes that have names set precisely if (in_array(strtolower($class), $prec)) { unset($classes[$class]); continue; } $is_class_unset = FALSE; // exclude classes that have names set by mask of type '*someword*' foreach ($two_ast as $mask) { if (strpos(strtolower($class), $mask) !== FALSE) { unset($classes[$class]); $is_class_unset = TRUE; break; } } if ($is_class_unset) { continue; } // exclude classes that have names set by mask of type '*someword' foreach ($ast_left as $mask) { if (substr(strtolower($class), -strlen($mask)) == $mask) { unset($classes[$class]); $is_class_unset = TRUE; break; } } if ($is_class_unset) { continue; } // exclude classes that have names set by mask of type 'someword*' foreach ($ast_right as $mask) { if (strpos(strtolower($class), $mask) === 0) { unset($classes[$class]); break; } } } $is_cache = Kohana::config('cs.cache'); // do we need to save actual state in cache $is_save_cache = FALSE; // check if caching turned on if ($is_cache) { // check whether classes set + exclude classes set was modified $cache_name = sha1(serialize($classes)) . $this->ext; $dir = Kohana_Core::$cache_dir . DIRECTORY_SEPARATOR; if (!is_dir($dir)) { $msg[] = 'No cache directory ' . $dir; $is_save_cache = TRUE; } else { if (is_file($dir . $cache_name)) { $tmp = file_get_contents($dir . $cache_name); if ($tmp) { $classes = unserialize($tmp); $msg[] = 'Data loaded from cache'; } else { $is_save_cache = TRUE; // set for data not be taken from cache $msg[] = 'Failed to load cache'; } } else { $is_save_cache = TRUE; foreach (glob($dir . '*' . $this->ext) as $filename) { if (!unlink($filename)) { $msg[] = 'Can not delete cache file ' . $filename; } } } } } if (!$is_cache or $is_save_cache) { foreach ($classes as $class) { $r_class = Kodoc_Class::factory($class); // to prevent exception when Kodoc::properties() throws exception try { $props = $r_class->properties(); } catch (Kohana_Exception $e) { $props = array(); $msg[] = $e->getMessage(); } $classes[$class] = array('description' => $r_class->description, 'modifiers' => $r_class->modifiers, 'properties' => $props, 'methods' => $r_class->methods()); } if ($is_save_cache) { if (is_dir($dir) and is_writable($dir)) { if (!file_put_contents($dir . $cache_name, serialize($classes))) { $msg[] = 'Failed to save cache'; } } else { $msg[] = 'Not exsisting or not writable cache dir'; } } } $this->template->content = $classes; $this->template->msg = $msg; }
/** * Parse a comment to extract the description and the tags * * [!!] Converting the output to HTML in this method is deprecated in 3.3 * * @param string $comment The DocBlock to parse * @param boolean $html Whether or not to convert the return values * to HTML (deprecated) * @return array array(string $description, array $tags) */ public static function parse($comment, $html = TRUE) { // Normalize all new lines to \n $comment = str_replace(array("\r\n", "\n"), "\n", $comment); // Split into lines while capturing without leading whitespace preg_match_all('/^\\s*\\* ?(.*)\\n/m', $comment, $lines); // Tag content $tags = array(); /** * Process a tag and add it to $tags * * @param string $tag Name of the tag without @ * @param string $text Content of the tag * @return void */ $add_tag = function ($tag, $text) use($html, &$tags) { // Don't show @access lines, they are shown elsewhere if ($tag !== 'access') { if ($html) { $text = Kodoc::format_tag($tag, $text); } // Add the tag $tags[$tag][] = $text; } }; $comment = $tag = NULL; $end = count($lines[1]) - 1; foreach ($lines[1] as $i => $line) { // Search this line for a tag if (preg_match('/^@(\\S+)\\s*(.+)?$/', $line, $matches)) { if ($tag) { // Previous tag is finished $add_tag($tag, $text); } $tag = $matches[1]; $text = isset($matches[2]) ? $matches[2] : ''; if ($i === $end) { // No more lines $add_tag($tag, $text); } } elseif ($tag) { // This is the continuation of the previous tag $text .= "\n" . $line; if ($i === $end) { // No more lines $add_tag($tag, $text); } } else { $comment .= "\n" . $line; } } $comment = trim($comment, "\n"); if ($comment and $html) { // Parse the comment with Markdown $comment = Kodoc_Markdown::markdown($comment); } return array($comment, $tags); }
} ?> </dl> <?php } if (!empty($comment)) { foreach ($comment as $tag => $vals) { switch ($tag) { case 'throws': case 'return': foreach ($vals as $i => $val) { if (strpos($val, ' ') !== FALSE) { // Extract the type from the val list($type, $val) = explode(' ', $val, 2); // Add the type to the val $val = Kodoc::humanize_type($type) . ' ' . $val; } else { $val = '<tt>' . $val . '</tt>'; } // Put the val back into the array $vals[$i] = $val; } break; } ?> <p class="<?php echo $tag; ?> "><strong><?php echo ucfirst($tag); ?>
/** * Parse a comment to extract the description and the tags * * @param string the comment retreived using ReflectionClass->getDocComment() * @return array array(string $description, array $tags) */ public static function parse($comment) { // Normalize all new lines to \n $comment = str_replace(array("\r\n", "\n"), "\n", $comment); // Remove the phpdoc open/close tags and split $comment = array_slice(explode("\n", $comment), 1, -1); // Tag content $tags = array(); foreach ($comment as $i => $line) { // Remove all leading whitespace $line = preg_replace('/^\\s*\\* ?/m', '', $line); // Search this line for a tag if (preg_match('/^@(\\S+)(?:\\s*(.+))?$/', $line, $matches)) { // This is a tag line unset($comment[$i]); $name = $matches[1]; $text = isset($matches[2]) ? trim($matches[2]) : ''; switch ($name) { case 'license': if (strpos($text, '://') !== FALSE) { // Convert the lincense into a link $text = HTML::anchor($text); } break; case 'link': $text = preg_split('/\\s+/', $text, 2); $text = HTML::anchor($text[0], isset($text[1]) ? $text[1] : $text[0]); break; case 'copyright': if (strpos($text, '(c)') !== FALSE) { // Convert the copyright sign $text = str_replace('(c)', '©', $text); } break; case 'throws': if (preg_match('/^(\\w+)\\W(.*)$/', $text, $matches)) { $text = HTML::anchor(Route::get('docs/api')->uri(array('class' => $matches[1])), $matches[1]) . ' ' . $matches[2]; } else { $text = HTML::anchor(Route::get('docs/api')->uri(array('class' => $text)), $text); } break; case 'uses': if (preg_match('/^' . Kodoc::$regex_class_member . '$/i', $text, $matches)) { $text = Kodoc::link_class_member($matches); } break; // Don't show @access lines, they are shown elsewhere // Don't show @access lines, they are shown elsewhere case 'access': continue 2; } // Add the tag $tags[$name][] = $text; } else { // Overwrite the comment line $comment[$i] = (string) $line; } } // Concat the comment lines back to a block of text if ($comment = trim(implode("\n", $comment))) { // Parse the comment with Markdown $comment = Markdown($comment); } return array($comment, $tags); }
/** * Tests Kodoc::is_transparent * * Checks that a selection of transparent and non-transparent classes give expected results * * @group kohana.userguide.3529-configurable-transparent-classes * @dataProvider provider_transparent_classes * @param mixed $expected * @param string $class * @param array $classes */ public function test_transparent_classes($expected, $class, $classes) { $result = Kodoc::is_transparent($class, $classes); $this->assertSame($expected, $result); }
/** * Returns an array of all the classes available, built by listing all files in the classes folder and then trying to create that class. * * This means any empty class files (as in complety empty) will cause an exception * * @param array array of files, obtained using Kohana::list_files * @return array an array of all the class names */ public static function classes($type = NULL) { $classes = array(); if ($type === NULL) { foreach (array('libraries', 'helpers', 'models', 'controllers', 'core', 'config') as $type) { $classes[$type] = Kodoc::classes($type); } } else { $files = Kohana::list_files($type); foreach ($files as $class) { // Remove directory and the extension $class = basename($class, EXT); // Add Controller prefix if ($type === 'controllers') { $class .= '_Controller'; } else { if ($type === 'models') { $class .= '_Model'; } } $classes[$class] = $class; } } return $classes; }
public function api($package = NULL, $class_name = NULL) { if ($class_name) { // Do we have anything cached? if ($this->cache and ($class = $this->cache->get('kodoc_class_' . $class_name)) !== NULL) { // Nothing to do, it's cached. } else { try { $class = Kodoc_Class::factory($class_name); } catch (Exception $e) { Event::run('system.404'); } if ($this->cache) { $this->cache->set('kodoc_class_' . $class_name, $class); } } $this->breadcrumb['userguide/api/kohana'] = 'API Reference'; $this->template->title = $class_name; $this->template->content = View::factory('userguide/api/class', array('class' => $class)); $this->template->menu = View::factory('userguide/api/menu', array('class' => $class)); } else { $this->template->title = 'API Reference'; $this->template->content = View::factory('userguide/api/toc', array('toc' => Kodoc::packages())); $this->template->menu = $this->markdown('kohana/menu'); } $breadcrumb[] = $this->template->title; }
<div id="menu"> <ul> <?php foreach (Kodoc::get_files() as $group => $files) { ?> <li class="first<?php echo $active == $group ? ' active' : ''; ?> "><?php echo ucfirst($group); ?> <ul> <?php foreach ($files as $name => $drivers) { ?> <li><?php echo html::anchor('kodoc/' . $group . '/' . $name, $name); if (is_array($drivers)) { ?> <ul class="expanded"> <?php foreach ($drivers as $driver) { $file = $name === $driver ? $driver : $name . '_' . $driver; ?> <li><?php echo html::anchor('kodoc/' . $group . '/drivers/' . $file, $driver); ?> </li> <?php } ?>
/** * Get the tags of this class as HTML. * * @return array */ public function tags() { $result = array(); foreach ($this->tags as $name => $set) { foreach ($set as $text) { $result[$name][] = Kodoc::format_tag($name, $text); } } return $result; }
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 action_api() { // 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 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()); } 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->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', $_class)->set('route', $this->request->route()); } // Attach the menu to the template $this->template->menu = Kodoc::menu(); // Bind the breadcrumb $this->template->bind('breadcrumb', $breadcrumb); // Add the breadcrumb $breadcrumb = array(); $breadcrumb[$this->guide->uri(array('page' => NULL))] = 'User Guide'; $breadcrumb[$this->request->route()->uri()] = 'API Browser'; $breadcrumb[] = $this->template->title; }
public static function api_menu() { $classes = Kodoc::classes(); ksort($classes); $menu = array(); $route = Route::get('jelly/docs/api'); foreach ($classes as $class) { $class = Kodoc::factory($class); $link = HTML::anchor($route->uri(array('class' => $class->class->name)), $class->class->name); // Only include classes in the Jelly or Jelly Test packages if (isset($class->tags['package'])) { foreach ($class->tags['package'] as $package) { if (in_array($package, array('Jelly', 'Jelly Test'))) { $menu[$package][] = $link; } } } } // Sort the packages ksort($menu); $output = array('<ol>'); foreach ($menu as $package => $list) { // Sort the class list sort($list); $output[] = "<li><strong>{$package}</strong>\n\t<ul><li>" . implode("</li><li>", $list) . "</li></ul>\n</li>"; } $output[] = '</ol>'; return implode("\n", $output); }