BaseRenderer.php 5.07 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
<?php
/**
 * @link http://www.yiiframework.com/
 * @copyright Copyright (c) 2008 Yii Software LLC
 * @license http://www.yiiframework.com/license/
 */

namespace yii\apidoc\renderers;

use Yii;
use yii\apidoc\helpers\ApiMarkdown;
use yii\apidoc\models\BaseDoc;
use yii\apidoc\models\ClassDoc;
use yii\apidoc\models\ConstDoc;
use yii\apidoc\models\Context;
use yii\apidoc\models\EventDoc;
use yii\apidoc\models\InterfaceDoc;
use yii\apidoc\models\MethodDoc;
use yii\apidoc\models\PropertyDoc;
use yii\apidoc\models\TraitDoc;
use yii\apidoc\models\TypeDoc;
use yii\base\Component;
use yii\console\Controller;
use yii\helpers\Html;

/**
 * Base class for all documentation renderers
 *
 * @author Carsten Brandt <mail@cebe.cc>
 * @since 2.0
 */
abstract class BaseRenderer extends Component
{
34 35
	const GUIDE_PREFIX = 'guide-';

36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
	public $apiUrl;
	/**
	 * @var Context the [[Context]] currently being rendered.
	 */
	public $apiContext;
	/**
	 * @var Controller the apidoc controller instance. Can be used to control output.
	 */
	public $controller;

	public $guideUrl;
	public $guideReferences = [];


	public function init()
	{
		ApiMarkdown::$renderer = $this;
	}

	/**
	 * creates a link to a type (class, interface or trait)
	 * @param ClassDoc|InterfaceDoc|TraitDoc|ClassDoc[]|InterfaceDoc[]|TraitDoc[] $types
	 * @param string $title a title to be used for the link TODO check whether [[yii\...|Class]] is supported
	 * @param BaseDoc $context
Carsten Brandt committed
60
	 * @param array $options additional HTML attributes for the link.
61 62
	 * @return string
	 */
Carsten Brandt committed
63
	public function createTypeLink($types, $context = null, $title = null, $options = [])
64 65 66 67 68 69 70 71
	{
		if (!is_array($types)) {
			$types = [$types];
		}
		if (count($types) > 1) {
			$title = null;
		}
		$links = [];
Luciano Baraglia committed
72
		foreach ($types as $type) {
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
			$postfix = '';
			if (!is_object($type)) {
				if (substr($type, -2, 2) == '[]') {
					$postfix = '[]';
					$type = substr($type, 0, -2);
				}

				if (($t = $this->apiContext->getType(ltrim($type, '\\'))) !== null) {
					$type = $t;
				} elseif ($type[0] !== '\\' && ($t = $this->apiContext->getType($this->resolveNamespace($context) . '\\' . ltrim($type, '\\'))) !== null) {
					$type = $t;
				} else {
					ltrim($type, '\\');
				}
			}
			if (!is_object($type)) {
89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
				$linkText = ltrim($type, '\\');
				if ($title !== null) {
					$linkText = $title;
				}
				$phpTypes = [
					'callable',
					'array',
					'string',
					'boolean',
					'integer',
					'float',
					'object',
					'resource',
					'null',
				];
				// check if it is PHP internal class
				if (((class_exists($type, false) || interface_exists($type, false) || trait_exists($type, false)) &&
					($reflection = new \ReflectionClass($type)) && $reflection->isInternal())) {
Carsten Brandt committed
107
					$links[] = $this->generateLink($linkText, 'http://www.php.net/class.' . strtolower(ltrim($type, '\\')), $options) . $postfix;
108
				} elseif (in_array($type, $phpTypes)) {
Carsten Brandt committed
109
					$links[] = $this->generateLink($linkText, 'http://www.php.net/language.types.' . strtolower(ltrim($type, '\\')), $options) . $postfix;
110 111 112
				} else {
					$links[] = $type;
				}
113 114 115 116 117
			} else {
				$linkText = $type->name;
				if ($title !== null) {
					$linkText = $title;
				}
Carsten Brandt committed
118
				$links[] = $this->generateLink($linkText, $this->generateApiUrl($type->name), $options) . $postfix;
119 120
			}
		}
Carsten Brandt committed
121
		return implode('|', $links);
122 123 124 125 126 127 128
	}


	/**
	 * creates a link to a subject
	 * @param PropertyDoc|MethodDoc|ConstDoc|EventDoc $subject
	 * @param string $title
Carsten Brandt committed
129
	 * @param array $options additional HTML attributes for the link.
130 131
	 * @return string
	 */
Carsten Brandt committed
132
	public function createSubjectLink($subject, $title = null, $options = [])
133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150
	{
		if ($title === null) {
			if ($subject instanceof MethodDoc) {
				$title = $subject->name . '()';
			} else {
				$title = $subject->name;
			}
		}
		if (($type = $this->apiContext->getType($subject->definedBy)) === null) {
			return $subject->name;
		} else {
			$link = $this->generateApiUrl($type->name);
			if ($subject instanceof MethodDoc) {
				$link .= '#' . $subject->name . '()';
			} else {
				$link .= '#' . $subject->name;
			}
			$link .= '-detail';
Carsten Brandt committed
151
			return $this->generateLink($title, $link, $options);
152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179
		}
	}

	/**
	 * @param BaseDoc $context
	 */
	private function resolveNamespace($context)
	{
		// TODO use phpdoc Context for this
		if ($context === null) {
			return '';
		}
		if ($context instanceof TypeDoc) {
			return $context->namespace;
		}
		if ($context->hasProperty('definedBy')) {
			$type = $this->apiContext->getType($context);
			if ($type !== null) {
				return $type->namespace;
			}
		}
		return '';
	}

	/**
	 * generate link markup
	 * @param $text
	 * @param $href
Carsten Brandt committed
180
	 * @param array $options additional HTML attributes for the link.
181 182
	 * @return mixed
	 */
Carsten Brandt committed
183
	protected abstract function generateLink($text, $href, $options = []);
184 185 186 187 188 189 190

	/**
	 * Generate an url to a type in apidocs
	 * @param $typeName
	 * @return mixed
	 */
	public abstract function generateApiUrl($typeName);
191 192 193 194 195 196 197 198 199 200

	/**
	 * Generate an url to a guide page
	 * @param string $file
	 * @return string
	 */
	public function generateGuideUrl($file)
	{
		return rtrim($this->guideUrl, '/') . '/' . static::GUIDE_PREFIX . basename($file, '.md') . '.html';
	}
Luciano Baraglia committed
201
}