/** * @param string|Component[] $content * @return Component[] */ private static function checkContent($content) { if (!is_array($content) && !is_string($content)) { throw new \InvalidArgumentException(sprintf("Block content must be <kbd>string|Component[]</kbd>, %s given", Debug::typeInfoOf($content))); } return $content; }
/** * Performs the main execution sequence. * * @param ServerRequestInterface $request * @param ResponseInterface $response * @param callable $next * @return ResponseInterface * @throws FatalException * @throws FileException * @throws FlashMessageException */ function __invoke(ServerRequestInterface $request, ResponseInterface $response, callable $next) { $this->request = $request; $this->response = $response; $this->initialize(); //custom setup $this->model(); switch ($this->request->getMethod()) { /** @noinspection PhpMissingBreakStatementInspection */ case 'POST': // Perform the requested action. $res = $this->doFormAction(); if ($res) { if ($res instanceof ResponseInterface) { throw new FatalException(sprintf("Invalid HTTP response type: %s<p>Expected: <kbd>ResponseInterface</kbd>", Debug::typeInfoOf($res))); } $response = $res; } if (!$this->renderOnAction) { if (!$res) { $response = $this->autoRedirect(); } break; } case 'GET': // Render the component. $out = $this->getRendering(); $response->getBody()->write($out); } $this->finalize($response); return $response; }
public function __construct(Component $component = null, $msg = '', $deep = false) { // Prevent infinite recursion when this constructor throws an exception itself. static $nest = 0; if ($nest++ == 2) { return; } if (ctype_alnum(substr($msg, -1))) { $msg .= '.'; } if (is_null($component)) { parent::__construct($msg); } else { $class = Debug::typeInfoOf($component); $id = $o = ''; try { $id = $component->supportsProperties() && isset($component->props->id) ? $component->props->id : null; $props = isset($component->props) ? $component->props->getBeingAssigned() : []; $o = $props ? self::properties($props) : ''; // Append a period, if applicable. $i = $this->inspect($component, $deep); $o = (!$component->props || !$component->props->getAll() ? '' : "<h6>Properties</h6>{$i}") . $o; } catch (\Exception $e) { } $header = $component instanceof Text ? "" : ($id ? "Error on {$class} component <b>{$id}</b>" : "Error on a {$class} component."); $msg = "<p>{$header}<p>{$msg}</p>" . ($o ? "<hr>{$o}" : ''); parent::__construct($msg); } }
function __construct($s) { if (is_null($s)) { $this->s = ''; } elseif ($s instanceof RenderableInterface) { $this->s = $s->getRendering(); return; } elseif (!is_string($s)) { throw new MatisseException("A <kbd>RawText</kbd> instance must hold a string value, not a " . Debug::typeInfoOf($s)); } $this->s = $s; }
function __call($name, $args) { $method = "filter_{$name}"; if (isset($this->filters[$method])) { return call_user_func_array($this->filters[$method], $args); } if (isset($this->fallbackHandler)) { if (method_exists($this->fallbackHandler, $method)) { return call_user_func_array([$this->fallbackHandler, $method], $args); } } throw new FilterHandlerNotFoundException(sprintf("<p><p>Handler method: <kbd>%s</kbd><p>Arguments: <kbd>%s</kbd>", $method, print_r(map($args, function ($e) { return Debug::typeInfoOf($e); }), true))); }
/** * For internal use. * * @param Component $component * @param bool $deep * @throws ComponentException */ private static function _inspect(Component $component, $deep = true) { if (self::$recursionMap->contains($component)) { echo "<i>recursion</i>"; return; } self::$recursionMap->attach($component); $COLOR_BIND = '#5AA'; $COLOR_CONST = '#5A5'; $COLOR_INFO = '#CCC'; $COLOR_PROP = '#B00'; $COLOR_TAG = '#000;font-weight:bold'; $COLOR_TYPE = '#55A'; $COLOR_VALUE = '#333'; $COLOR_SHADOW_DOM = '#5AA;font-weight:bold'; $Q = "<i style='color:#CCC'>\"</i>"; $tag = $component->getTagName(); $hasContent = false; echo "<div class=__component><span style='color:{$COLOR_TAG}'><{$tag}</span>"; $isDoc = $component instanceof DocumentFragment; if (!$component->parent && !$isDoc) { echo " <span style='color:{$COLOR_INFO}'>(detached)</span>"; } $type = typeOf($component) . ' #' . Debug::objectId($component); echo "<span class='icon hint--rounded hint--right' data-hint='Component:\n{$type}'><i class='fa fa-info-circle'></i></span>"; $type1 = str_pad('#' . Debug::objectId($component->context), 4, ' ', STR_PAD_LEFT); $type2 = str_pad('#' . Debug::objectId($component->getDataBinder()), 4, ' ', STR_PAD_LEFT); $type3 = str_pad('#' . Debug::objectId($component->getViewModel()), 4, ' ', STR_PAD_LEFT); $type4 = str_pad('#' . Debug::objectId($component->getDataBinder()->getViewModel()), 4, ' ', STR_PAD_LEFT); $type5 = str_pad('#' . Debug::objectId($component->getDataBinder()->getProps()), 4, ' ', STR_PAD_LEFT); echo "<span class='icon hint--rounded hint--bottom' data-hint='Context: {$type1} Data binder: {$type2}\nView model: {$type3} Binder view model: {$type4}\nProperties: {$type5}'><i class='fa fa-database'></i></span>"; // Handle text node if ($component instanceof Text) { echo "<span style='color:{$COLOR_TAG}'>></span><div style='margin:0 0 0 15px'>"; try { if ($component->isBound('value')) { /** @var Expression $exp */ $exp = $component->getBinding('value'); $exp = self::inspectString((string) $exp); echo "<span style='color:{$COLOR_BIND}'>{$exp}</span> = "; $v = self::getBindingValue('value', $component, $error); if ($error) { echo $v; return; } if (!is_string($v)) { echo Debug::typeInfoOf($v); return; } } else { $v = $component->props->value; } $v = strlen(trim($v)) ? HtmlSyntaxHighlighter::highlight($v) : "<i>'{$v}'</i>"; echo $v; } finally { echo "</div><span style='color:{$COLOR_TAG}'></{$tag}><br></span></div>"; } return; } // Handle other node types if ($component instanceof DocumentFragment) { self::inspectViewModel($component); } if ($component->supportsProperties()) { /** @var ComponentProperties $propsObj */ $propsObj = $component->props; if ($propsObj) { $props = $propsObj->getAll(); } else { $props = null; } if ($props) { ksort($props); } if ($props) { $type = typeOf($propsObj); $tid = Debug::objectId($propsObj); echo "<span class='icon hint--rounded hint--right' data-hint='Properties: #{$tid}\n{$type}'><i class='fa fa-list'></i></span>"; echo "<table class='__console-table' style='color:{$COLOR_VALUE}'>"; // Display all scalar properties. foreach ($props as $k => $v) { $t = $component->props->getTypeOf($k); $isModified = $component->props->isModified($k); $modifStyle = $isModified ? ' class=__modified' : ' class=__original'; if ($t != type::content && $t != type::collection && $t != type::metadata) { $tn = $component->props->getTypeNameOf($k); echo "<tr{$modifStyle}><td style='color:{$COLOR_PROP}'>{$k}<td><i style='color:{$COLOR_TYPE}'>{$tn}</i><td>"; // Display data-binding if ($component->isBound($k)) { /** @var Expression $exp */ $exp = $component->getBinding($k); $exp = self::inspectString((string) $exp); echo "<span style='color:{$COLOR_BIND}'>{$exp}</span> = "; $v = self::getBindingValue($k, $component, $error); if ($error) { break; } } if (is_null($v)) { echo "<i style='color:{$COLOR_INFO}'>null</i>"; } else { switch ($t) { case type::bool: echo "<i style='color:{$COLOR_CONST}'>" . ($v ? 'true' : 'false') . '</i>'; break; case type::id: echo "{$Q}{$v}{$Q}"; break; case type::number: echo $v; break; case type::string: echo "{$Q}<span style='white-space: pre-wrap'>" . self::inspectString(strval($v)) . "</span>{$Q}"; break; default: if (is_object($v)) { echo sprintf("<i style='color:{$COLOR_CONST}'>%s</i>", Debug::typeInfoOf($v)); } elseif (is_array($v)) { echo sprintf("<i style='color:{$COLOR_CONST}'>array(%d)</i>", count($v)); } else { $v = _e($v); echo "{$Q}{$v}{$Q}"; } } } } } // Display all slot properties. foreach ($props as $k => $v) { $t = $component->props->getTypeOf($k); if ($t == type::content || $t == type::collection || $t == type::metadata) { $tn = $component->props->getTypeNameOf($k); $isModified = $component->props->isModified($k); $modifStyle = $isModified ? ' style="background:#FFE"' : ' style="opacity:0.5"'; echo "<tr{$modifStyle}><td style='color:{$COLOR_PROP}'>{$k}<td><i style='color:{$COLOR_TYPE}'>{$tn}</i><td>"; /** @var Expression $exp */ $exp = $component->getBinding($k); if (isset($exp)) { $exp = self::inspectString((string) $exp); echo "<span style='color:{$COLOR_BIND}'>{$exp}</span> = "; $v = self::getBindingValue($k, $component, $error); if ($error) { echo $v; break; } } if ($v && ($v instanceof Component || is_array($v))) { switch ($t) { case type::content: if ($v) { echo "<tr><td><td colspan=2>"; self::_inspect($v, $deep); } else { echo "<i style='color:{$COLOR_INFO}'>null</i>"; } break; case type::metadata: if ($v) { echo "<tr><td><td colspan=2>"; self::_inspect($v, $deep); } else { echo "<i style='color:{$COLOR_INFO}'>null</i>"; } break; case type::collection: echo "of <i style='color:{$COLOR_TYPE}'>", $component->props->getRelatedTypeNameOf($k), '</i>'; if ($v) { echo "<tr><td><td colspan=2>"; self::_inspectSet($v, true); } else { echo " = <i style='color:{$COLOR_INFO}'>[]</i>"; } break; } } else { if (is_array($v)) { echo "<i style='color:{$COLOR_INFO}'>[]</i>"; } else { if (isset($v)) { printf("<b style='color:red'>WRONG TYPE: %s</b>", Debug::typeInfoOf($v)); } else { echo "<i style='color:{$COLOR_INFO}'>null</i>"; } } } echo '</tr>'; } } echo "</table>"; } } // If deep inspection is enabled, recursively inspect all children components. if ($deep) { $content = $shadowDOM = null; if ($component->hasChildren()) { $content = $component->getChildren(); } if ($component instanceof CompositeComponent) { $shadowDOM = $component->provideShadowDOM(); } if ($content || $shadowDOM) { echo "<span style='color:{$COLOR_TAG}'>></span><div style=\"margin:0 0 0 15px\">"; if ($content) { self::_inspectSet($content, $deep); } if ($shadowDOM) { echo "<span style='color:{$COLOR_SHADOW_DOM}'><Shadow DOM></span><div style=\"margin:0 0 0 15px\">"; self::_inspect($shadowDOM, $deep); echo "</div><span style='color:{$COLOR_SHADOW_DOM}'></Shadow DOM></span>"; } echo '</div>'; $hasContent = true; } } echo "<span style='color:{$COLOR_TAG}'>" . ($hasContent ? "</{$tag}><br>" : "/><br>") . "</span></div>"; }
/** * Throws an exception if the specified property is not available. * * @param $propName * @throws ComponentException */ function ensurePropertyExists($propName) { if (!$this->defines($propName)) { throw new ComponentException($this->component, sprintf("Invalid property <kbd>%s</kbd> specified for a %s instance.", $propName, Debug::typeInfoOf($this))); } }
/** * @param \Error|\Exception $e * @param Expression $exp * @throws ComponentException */ private function evalError($e, Expression $exp) { throw new ComponentException($this, Debug::grid(['Expression' => Debug::RAW_TEXT . "<kbd>{$exp}</kbd>", 'Compiled' => sprintf('%s<code>%s</code>', Debug::RAW_TEXT, \PhpCode::highlight("{$exp->translated}")), 'Error' => sprintf('%s%s %s', Debug::RAW_TEXT, Debug::typeInfoOf($e), $e->getMessage()), 'At' => sprintf('%s%s, line <b>%s</b>', Debug::RAW_TEXT, ErrorConsole::errorLink($e->getFile(), $e->getLine()), $e->getLine())], 'Error while evaluating data-binding expression')); }
/** * @param \Exception $exception * @return string */ private static function getStackTrace($exception) { ob_start(); // $trace = self::filterStackTrace ($exception instanceof PHPError ? debug_backtrace () : $exception->getTrace ()); $trace = $exception->getTrace(); if (count($trace) && $trace[count($trace) - 1]['function'] == '{main}') { array_pop($trace); } $count = count($trace); foreach ($trace as $k => $v) { $class = isset($v['class']) ? $v['class'] : ''; if ($class == 'ErrorHandler') { continue; } //$class = $class ? "<span class='class'>$class</span>" : ''; if (isset($v['function'])) { $f = $v['function']; $type = isset($v['type']) ? $v['type'] : '->'; if (strpos($f, '{closure}') !== false) { if ($class) { $fn = "<span class='info' title='On class {$class}'>Closure</span>"; } else { $fn = "<span class='type'>Closure</span>"; } } else { if ($class) { $z = explode('\\', $class); $className = array_pop($z); $namespace = implode('\\', $z); $fn = $f == '__construct' ? "new <span class='class' title='{$namespace}'>{$className}</span>" : "<span class='class' title='{$namespace}'>{$className}</span>{$type}<span class='fn'>{$f}</span>"; } else { $fn = "<span class='fn'>{$f}</span>"; } } $fn = "Call {$fn}"; } else { $fn = 'global scope'; } if (isset($v['function'])) { $args = []; if (isset($v['args'])) { foreach ($v['args'] as $arg) { switch (gettype($arg)) { case 'boolean': $arg = $arg ? 'true' : 'false'; break; case 'string': $arg = mb_strlen($arg) > self::TRIM_WIDTH ? sprintf("'<span class='string hint--rounded hint--top' data-hint='%s'>%s</span>'", htmlspecialchars(mb_strimwidth(chunk_split($arg, self::TRIM_WIDTH, "\n"), 0, self::TOOLTIP_MAX_LEN, "..."), ENT_QUOTES), htmlspecialchars(mb_strimwidth($arg, 0, self::TRIM_WIDTH, "..."))) : sprintf("'<span class='string'>%s</span>'", htmlspecialchars($arg, ENT_QUOTES)); break; case 'integer': case 'double': break; case 'array': $arg = '<span class="info __type hint--rounded hint--top" data-hint="' . ($arg ? "[\n " . htmlspecialchars(implode(",\n ", array_map(function ($k, $v) use($arg) { return "{$k} => " . self::debugVal($v); }, array_keys($arg), $arg))) . "\n]" : 'Empty array') . '">array</span>'; break; default: if (is_object($arg)) { switch (get_class($arg)) { case \ReflectionMethod::class: /** @var \ReflectionMethod $arg */ $arg = sprintf('<span class=type>ReflectionMethod</span><%s::%s>', $arg->getDeclaringClass()->getName(), $arg->getName()); break; case \ReflectionFunction::class: /** @var \ReflectionFunction $arg */ $arg = sprintf('<span class=type>ReflectionFunction</span><function at %s>', self::errorLink($arg->getFileName(), $arg->getStartLine(), 1, sprintf('%s line %d', basename($arg->getFileName()), $arg->getStartLine()), 'tag hint--rounded hint--top')); break; case \ReflectionParameter::class: /** @var \ReflectionParameter $arg */ $arg = sprintf('<span class=type>ReflectionParameter</span><$%s>', $arg->getName()); break; default: $arg = Debug::typeInfoOf($arg); } } else { $arg = Debug::typeInfoOf($arg); } } $args[] = $arg; } } $args = implode(", ", $args); $args = "({$args})"; } else { $args = ''; } $file = isset($v['file']) ? $v['file'] : ''; $fitems = explode(DIRECTORY_SEPARATOR, $file); $fname = '<span class="file">' . end($fitems) . '</span>'; $line = isset($v['line']) ? $v['line'] : ' '; $lineStr = $line ? "<span class='line'>{$line}</span>" : ''; $edit = $file ? self::errorLink($file, $line, 1, 'edit', '__btn') : ''; $at = $file ? self::errorLink($file, $line, 1) : '<unknown location>'; ErrorConsoleRenderer::renderStackFrame($count - $k, $fname, $lineStr, $fn, $args, $at, $edit); } return ob_get_clean(); }
/** * Performs the main execution sequence. * * @param ServerRequestInterface $request * @param ResponseInterface $response * @param callable $next * @return ResponseInterface * @throws FatalException * @throws FileException * @throws FlashMessageException */ function __invoke(ServerRequestInterface $request, ResponseInterface $response, callable $next) { if (!$this->kernelSettings) { throw new FatalException("Class <kbd class=type>" . get_class($this) . "</kbd>'s constructor forgot to call <kbd>parent::__construct()</kbd>"); } $this->request = $request; $this->response = $response; $this->redirection->setRequest($request); $this->currentLink = $this->navigation->currentLink(); $this->navigation->getCurrentTrail(); if (!$this->indexPage && $this->autoRedirectUp && $this->currentLink && ($parent = $this->currentLink->parent())) { $this->indexPage = $parent->url(); } // remove page number parameter $this->URI_noPage = preg_replace('#&?' . $this->kernelSettings->pageNumberParam . '=\\d*#', '', $this->request->getUri()->getPath()); $this->URI_noPage = preg_replace('#\\?$#', '', $this->URI_noPage); $this->initialize(); //custom setup $this->modelController->setRequest($request); $this->model(); $this->modelController->handleRequest(); $this->model = $this->modelController->getModel(); switch ($this->request->getMethod()) { /** @noinspection PhpMissingBreakStatementInspection */ case 'POST': // Perform the requested action. $res = $this->doFormAction(); if ($res) { if (!$res instanceof ResponseInterface) { throw new FatalException(sprintf("Invalid HTTP response type: %s<p>Expected: <kbd>%s</kbd>", Debug::typeInfoOf($res), Debug::formatClassName(ResponseInterface::class))); } $response = $res; } if (!$this->renderOnAction) { if (!$res) { $response = $this->autoRedirect(); } break; } // Fall through. // Fall through. case 'GET': // Render the component. $out = $this->getRendering(); $response->getBody()->write($out); } $this->finalize($response); return $response; }