1: <?php
2:
3: /*
4: * The MIT License (MIT)
5: *
6: * Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
7: *
8: * Permission is hereby granted, free of charge, to any person obtaining a copy of
9: * this software and associated documentation files (the "Software"), to deal in
10: * the Software without restriction, including without limitation the rights to
11: * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
12: * the Software, and to permit persons to whom the Software is furnished to do so,
13: * subject to the following conditions:
14: *
15: * The above copyright notice and this permission notice shall be included in all
16: * copies or substantial portions of the Software.
17: *
18: * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19: * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
20: * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
21: * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
22: * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23: * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24: */
25:
26: namespace Kint\Renderer\Rich;
27:
28: use Kint\Object\BasicObject;
29: use Kint\Object\BlobObject;
30: use Kint\Object\ClosureObject;
31: use Kint\Object\MethodObject;
32: use Kint\Renderer\RichRenderer;
33:
34: class CallablePlugin extends Plugin implements ObjectPluginInterface
35: {
36: protected static $method_cache = array();
37:
38: public function renderObject(BasicObject $o)
39: {
40: if ($o instanceof MethodObject) {
41: return $this->renderMethod($o);
42: }
43:
44: if ($o instanceof ClosureObject) {
45: return $this->renderClosure($o);
46: }
47:
48: return $this->renderCallable($o);
49: }
50:
51: protected function renderClosure(ClosureObject $o)
52: {
53: $children = $this->renderer->renderChildren($o);
54:
55: $header = '';
56:
57: if (null !== ($s = $o->getModifiers())) {
58: $header .= '<var>'.$s.'</var> ';
59: }
60:
61: if (null !== ($s = $o->getName())) {
62: $header .= '<dfn>'.$this->renderer->escape($s).'('.$this->renderer->escape($o->getParams()).')</dfn>';
63: }
64:
65: if (null !== ($s = $o->getValueShort())) {
66: if (RichRenderer::$strlen_max && BlobObject::strlen($s) > RichRenderer::$strlen_max) {
67: $s = \substr($s, 0, RichRenderer::$strlen_max).'...';
68: }
69: $header .= ' '.$this->renderer->escape($s);
70: }
71:
72: return '<dl>'.$this->renderer->renderHeaderWrapper($o, (bool) \strlen($children), $header).$children.'</dl>';
73: }
74:
75: protected function renderCallable(BasicObject $o)
76: {
77: $children = $this->renderer->renderChildren($o);
78:
79: $header = '';
80:
81: if (null !== ($s = $o->getModifiers())) {
82: $header .= '<var>'.$s.'</var> ';
83: }
84:
85: if (null !== ($s = $o->getName())) {
86: $header .= '<dfn>'.$this->renderer->escape($s).'</dfn>';
87: }
88:
89: if (null !== ($s = $o->getValueShort())) {
90: if (RichRenderer::$strlen_max && BlobObject::strlen($s) > RichRenderer::$strlen_max) {
91: $s = \substr($s, 0, RichRenderer::$strlen_max).'...';
92: }
93: $header .= ' '.$this->renderer->escape($s);
94: }
95:
96: return '<dl>'.$this->renderer->renderHeaderWrapper($o, (bool) \strlen($children), $header).$children.'</dl>';
97: }
98:
99: protected function renderMethod(MethodObject $o)
100: {
101: if (!empty(self::$method_cache[$o->owner_class][$o->name])) {
102: $children = self::$method_cache[$o->owner_class][$o->name]['children'];
103:
104: $header = $this->renderer->renderHeaderWrapper(
105: $o,
106: (bool) \strlen($children),
107: self::$method_cache[$o->owner_class][$o->name]['header']
108: );
109:
110: return '<dl>'.$header.$children.'</dl>';
111: }
112:
113: $children = $this->renderer->renderChildren($o);
114:
115: $header = '';
116:
117: if (null !== ($s = $o->getModifiers()) || $o->return_reference) {
118: $header .= '<var>'.$s;
119:
120: if ($o->return_reference) {
121: if ($s) {
122: $header .= ' ';
123: }
124: $header .= $this->renderer->escape('&');
125: }
126:
127: $header .= '</var> ';
128: }
129:
130: if (null !== ($s = $o->getName())) {
131: $function = $this->renderer->escape($s).'('.$this->renderer->escape($o->getParams()).')';
132:
133: if (null !== ($url = $o->getPhpDocUrl())) {
134: $function = '<a href="'.$url.'" target=_blank>'.$function.'</a>';
135: }
136:
137: $header .= '<dfn>'.$function.'</dfn>';
138: }
139:
140: if (!empty($o->returntype)) {
141: $header .= ': <var>';
142:
143: if ($o->return_reference) {
144: $header .= $this->renderer->escape('&');
145: }
146:
147: $header .= $this->renderer->escape($o->returntype).'</var>';
148: } elseif ($o->docstring) {
149: if (\preg_match('/@return\\s+(.*)\\r?\\n/m', $o->docstring, $matches)) {
150: if (\trim($matches[1])) {
151: $header .= ': <var>'.$this->renderer->escape(\trim($matches[1])).'</var>';
152: }
153: }
154: }
155:
156: if (null !== ($s = $o->getValueShort())) {
157: if (RichRenderer::$strlen_max && BlobObject::strlen($s) > RichRenderer::$strlen_max) {
158: $s = \substr($s, 0, RichRenderer::$strlen_max).'...';
159: }
160: $header .= ' '.$this->renderer->escape($s);
161: }
162:
163: if (\strlen($o->owner_class) && \strlen($o->name)) {
164: self::$method_cache[$o->owner_class][$o->name] = array(
165: 'header' => $header,
166: 'children' => $children,
167: );
168: }
169:
170: $header = $this->renderer->renderHeaderWrapper($o, (bool) \strlen($children), $header);
171:
172: return '<dl>'.$header.$children.'</dl>';
173: }
174: }
175: