Class Kohana_Kodoc_Method

Kohana_Kodoc_Method

extends Kodoc
extends Kohana_Kodoc

Class method documentation generator.

package
Kohana/Userguide
category
Base
author
Kohana Team
copyright
(c) Kohana Team
license
https://koseven.ga/LICENSE.md


Properties

public ReflectionMethod $method

The ReflectionMethod for this class

Default value:
NULL

public array $params

Array of Kodoc_Method_Param

Default value:
NULL

public static string $regex_class_member

PCRE fragment for matching 'Class', 'Class::method', 'Class::method()' or 'Class::$property'

string(33) "((\w++)(?:::(\$?\w++))?(?:\(\))?)"

public array $return

The things this function can return

Default value:
array(0) 

public string $source

The source code for this function

Default value:
NULL

Methods

public __construct() (defined in Kohana_Kodoc_Method)

Source Code

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()) AND empty($this->class->getTraitNames()))
	{
		$this->source = Kodoc::source($file, $this->method->getStartLine(), $this->method->getEndLine());
	}

	if (isset($tags['param']))
	{
		$params = [];

		foreach ($this->method->getParameters() as $i => $param)
		{
			$param = new Kodoc_Method_Param([$this->method->class, $this->method->name],$i);

			if (isset($tags['param'][$i]))
			{
				preg_match('/^(\S+)(?:\s*(?:\$'.$param->name.'\s*)?(.+))?$/s', $tags['param'][$i], $matches);

				$param->type = $matches[1];

				if (isset($matches[2]))
				{
					$param->description = ucfirst($matches[2]);
				}
			}
			$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[] = [$matches[1], isset($matches[2]) ? $matches[2] : ''];
			}
		}

		unset($tags['return']);
	}

	$this->tags = $tags;
}

public params_short() (defined in Kohana_Kodoc_Method)

Source Code

public function params_short()
{
	$out = '';
	$required = TRUE;
	$first = TRUE;
	foreach ($this->params as $param)
	{
		if ($required AND $param->default AND $first)
		{
			$out .= '[ '.$param;
			$required = FALSE;
			$first = FALSE;
		}
		elseif ($required AND $param->default)
		{
			$out .= '[, '.$param;
			$required = FALSE;
		}
		elseif ($first)
		{
			$out .= $param;
			$first = FALSE;
		}
		else
		{
			$out .= ', '.$param;
		}
	}

	if ( ! $required)
	{
		$out .= '] ';
	}

	return $out;
}

public static class_methods() (defined in Kohana_Kodoc)

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

Source Code

public static function class_methods(array $list = NULL)
{
	$list = Kodoc::classes($list);

	$classes = [];

	foreach ($list as $class)
	{
		// Skip transparent extension classes
		if (Kodoc::is_transparent($class))
			continue;

		$_class = new ReflectionClass($class);

		$methods = [];

		foreach ($_class->getMethods() as $_method)
		{
			$declares = $_method->getDeclaringClass()->name;

			// Remove the transparent prefix from declaring classes
			if ($child = Kodoc::is_transparent($declares))
			{
				$declares = $child;
			}

			if ($declares === $_class->name OR $declares === "Core")
			{
				$methods[] = $_method->name;
			}
		}

		sort($methods);

		$classes[$_class->name] = $methods;
	}

	return $classes;
}

public static classes([ array $list = NULL ] ) (defined in Kohana_Kodoc)

Returns an array of all the classes available, built by listing all files in the classes folder.

Parameters

  • array $list = NULL - Array of files, obtained using Kohana::list_files

Return Values

  • array - An array of all the class names

Source Code

public static function classes(array $list = NULL)
{
	if ($list === NULL)
	{
		$list = Kohana::list_files('classes');
	}

	$classes = [];

	// This will be used a lot!
	$ext_length = strlen(EXT);

	foreach ($list as $name => $path)
	{
		if (is_array($path))
		{
			$classes += Kodoc::classes($path);
		}
		elseif (substr($name, -$ext_length) === EXT)
		{
			// Remove "classes/" and the extension
			$class = substr($name, 8, -$ext_length);

			// Convert slashes to underscores
			$class = str_replace(DIRECTORY_SEPARATOR, '_', $class);

			$classes[$class] = $class;
		}
	}

	return $classes;
}

public static factory() (defined in Kohana_Kodoc)

Source Code

public static function factory($class)
{
	return new Kodoc_Class($class);
}

public static format_tag(string $tag , string $text ) (defined in Kohana_Kodoc)

Generate HTML for the content of a tag.

Parameters

  • string $tag required - Name of the tag without @
  • string $text required - Content of the tag

Return Values

  • string - HTML

Source Code

public static function format_tag($tag, $text)
{
	if ($tag === 'license')
	{
		if (strpos($text, '://') !== FALSE)
			return HTML::anchor($text);
	}
	elseif ($tag === 'link')
	{
		$split = preg_split('/\s+/', $text, 2);

		return HTML::anchor(
			$split[0],
			isset($split[1]) ? $split[1] : $split[0]
		);
	}
	elseif ($tag === 'copyright')
	{
		// Convert the copyright symbol
		return str_replace('(c)', '&copy;', $text);
	}
	elseif ($tag === 'throws')
	{
		$route = Route::get('docs/api');

		if (preg_match('/^(\w+)\W(.*)$/D', $text, $matches))
		{
			return HTML::anchor(
				$route->uri(['class' => $matches[1]]),
				$matches[1]
			).' '.$matches[2];
		}

		return HTML::anchor(
			$route->uri(['class' => $text]),
			$text
		);
	}
	elseif ($tag === 'see' OR $tag === 'uses')
	{
		if (preg_match('/^'.Kodoc::$regex_class_member.'/', $text, $matches))
			return Kodoc::link_class_member($matches);
	}

	return $text;
}

public static is_transparent(string $class [, array $classes = NULL ] ) (defined in Kohana_Kodoc)

Checks whether a class is a transparent extension class or not.

This method takes an optional $classes parameter, a list of all defined class names. If provided, the method will return false unless the extension class exists. If not, the method will only check known transparent class prefixes.

Transparent prefixes are defined in the userguide.php config file:

'transparent_prefixes' => array(
    'Kohana' => TRUE,
);

Module developers can therefore add their own transparent extension namespaces and exclude them from the userguide.

Parameters

  • string $class required - The name of the class to check for transparency
  • array $classes = NULL - An optional list of all defined classes

Tags

Return Values

  • false - If this is not a transparent extension class
  • string - The name of the class that extends this (in the case provided)

Source Code

public static function is_transparent($class, $classes = NULL)
{

	static $transparent_prefixes = NULL;

	if ( ! $transparent_prefixes)
	{
		$transparent_prefixes = Kohana::$config->load('userguide.transparent_prefixes');
	}

	// Split the class name at the first underscore
	$segments = explode('_',$class,2);

	if ((count($segments) == 2) AND (isset($transparent_prefixes[$segments[0]])))
	{
		if ($segments[1] === 'Core')
		{
			// Cater for Module extends Module_Core naming
			$child_class = $segments[0];
		}
		else
		{
			// Cater for Foo extends Module_Foo naming
			$child_class = $segments[1];
		}

		// It is only a transparent class if the unprefixed class also exists
		if ($classes AND ! isset($classes[$child_class]))
			return FALSE;

		// Return the name of the child class
		return $child_class;
	}
	else
	{
		// Not a transparent class
		return FALSE;
	}
}

Make a class#member API link using an array of matches from Kodoc::$regex_class_member

Parameters

  • array $matches required - Array( 1 => link text, 2 => class name, [3 => member name] )

Return Values

  • string

Source Code

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);
		}
		elseif (preg_match('/^[A-Z_\x7f-\xff][A-Z0-9_\x7f-\xff]*$/', $matches[3]))
		{
			$member = '#constant:'.substr($matches[3],0);
		}
		else
		{
			$member = '#'.$matches[3];
		}
	}

	return HTML::anchor(Route::get('docs/api')->uri(['class' => $class]).$member, $link, NULL, NULL, TRUE);
}

Creates an html list of all classes sorted by category (or package if no category)

Return Values

  • string - The html for the menu

Source Code

public static function menu()
{
	$classes = Kodoc::classes();

	ksort($classes);

	$menu = [];

	$route = Route::get('docs/api');

	foreach ($classes as $class)
	{
		if (Kodoc::is_transparent($class, $classes))
			continue;

		$class = Kodoc_Class::factory($class);

		// Test if we should show this class
		if ( ! Kodoc::show_class($class))
			continue;

		$link = HTML::anchor($route->uri(['class' => $class->class->name]), $class->class->name);

		if (isset($class->tags['package']))
		{
			foreach ($class->tags['package'] as $package)
			{
				if (isset($class->tags['category']))
				{
					foreach ($class->tags['category'] as $category)
					{
						$menu[$package][$category][] = $link;
					}
				}
				else
				{
					$menu[$package]['Base'][] = $link;
				}
			}
		}
		else
		{
			$menu['[Unknown]']['Base'][] = $link;
		}
	}

	// Sort the packages
	ksort($menu);

	return View::factory('userguide/api/menu')
		->bind('menu', $menu);
}

public static parse(string $comment [, boolean $html = bool TRUE ] ) (defined in Kohana_Kodoc)

Parse a comment to extract the description and the tags

Converting the output to HTML in this method is deprecated in 3.3

Parameters

  • string $comment required - The DocBlock to parse
  • boolean $html = bool TRUE - Whether or not to convert the return values to HTML (deprecated)

Return Values

  • array - Array(string $description, array $tags)

Source Code

public static function parse($comment, $html = TRUE)
{
	// Normalize all new lines to \n
	$comment = str_replace(["\r\n", "\n"], "\n", $comment);

	// Split into lines while capturing without leading whitespace
	preg_match_all('/^\s*\* ?(.*)\n/m', $comment, $lines);

	// Tag content
	$tags = [];

	/**
	 * 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 [$comment, $tags];
}

public static show_class(Kodoc_Class $class ) (defined in Kohana_Kodoc)

Test whether a class should be shown, based on the api_packages config option

Parameters

  • Kodoc_Class $class required - The class to test

Return Values

  • bool - Whether this class should be shown

Source Code

public static function show_class(Kodoc_Class $class)
{
	$api_packages = Kohana::$config->load('userguide.api_packages');

	// If api_packages is true, all packages should be shown
	if ($api_packages === TRUE)
		return TRUE;

	// Get the package tags for this class (as an array)
	$packages = Arr::get($class->tags, 'package', ['None']);

	$show_this = FALSE;

	// Loop through each package tag
	foreach ($packages as $package)
	{
		// If this package is in the allowed packages, set show this to true
		if (in_array($package, explode(',', $api_packages)))
			$show_this = TRUE;
	}

	return $show_this;
}

public static source(string $file , int $start , int $end ) (defined in Kohana_Kodoc)

Get the source of a function

Parameters

  • string $file required - The filename
  • int $start required - Start line?
  • int $end required - End line?

Source Code

public static function source($file, $start, $end)
{
	if ( ! $file) return FALSE;

	$file = file($file, FILE_IGNORE_NEW_LINES);

	$file = array_slice($file, $start - 1, $end - $start + 1);

	if (preg_match('/^(\s+)/', $file[0], $matches))
	{
		$padding = strlen($matches[1]);

		foreach ($file as & $line)
		{
			$line = substr($line, $padding);
		}
	}

	return implode("\n", $file);
}

Do you want to contribute to Koseven?

We need YOUR help!

This project is open source. What does this mean? YOU can help:
  • Found a bug? Report it on Github
  • Need a feature? Add it Here
  • Want to help? Join the Forum
Go to Github