File manager - Edit - /home/opticamezl/www/newok/view.tar
Back
src/View.php 0000644 00000016572 15174725765 0007014 0 ustar 00 <?php namespace YOOtheme; use YOOtheme\Theme\ViewHelperInterface; use YOOtheme\View\HtmlElementInterface; use YOOtheme\View\HtmlHelperInterface; /** * @method string builder($node, $params = []) * @mixin ViewHelperInterface * @mixin HtmlHelperInterface * @mixin HtmlElementInterface */ class View implements \ArrayAccess { /** * @var \SplStack */ protected $loader; /** * @var array */ protected $template = []; /** * @var array */ protected $parameters = []; /** * @var array */ protected $filters = []; /** * @var array */ protected $globals = []; /** * @var array */ protected $helpers = []; /** * @var array */ protected $functions = []; /** * @var array */ private $evalParameters; /** * Constructor. * * @param callable $loader */ public function __construct(?callable $loader = null) { $this->loader = new \SplStack(); $this->loader->push([$this, 'evaluate']); if ($loader) { $this->addLoader($loader); } $this->addFunction('e', [$this, 'escape']); } /** * Renders a template (shortcut). * * @param string $name * @param mixed $parameters * * @return string|false */ public function __invoke($name, $parameters = []) { return $this->render($name, $parameters); } /** * Handles dynamic calls to the class. * * @param string $name * @param array $args * * @return mixed */ public function __call($name, $args) { if (!isset($this->functions[($key = strtolower($name))])) { trigger_error( sprintf('Call to undefined method %s::%s()', get_class($this), $name), E_USER_ERROR, ); } return call_user_func_array($this->functions[$key], $args); } /** * Gets the global parameters. * * @return array */ public function getGlobals() { return $this->globals; } /** * Adds a global parameter. * * @param string $name * @param mixed $value * * @return $this */ public function addGlobal($name, $value) { $this->globals[$name] = $value; return $this; } /** * Adds a helper. * * @param string|callable $helper * * @return $this */ public function addHelper($helper) { if (is_callable($helper)) { $helper($this); } elseif (class_exists($helper)) { new $helper($this); } return $this; } /** * Adds a custom function. * * @param string $name * @param callable $callback * * @return View */ public function addFunction($name, callable $callback) { $this->functions[strtolower($name)] = $callback; return $this; } /** * Adds a loader callback. * * @param callable $loader * @param string $filter * * @return $this */ public function addLoader(callable $loader, $filter = null) { if (is_null($filter)) { $next = $this->loader->top(); $this->loader->push(function ($name, array $parameters = []) use ($loader, $next) { return $loader($name, $parameters, $next); }); } else { $this->filters[$filter][] = $loader; } return $this; } /** * Applies multiple functions. * * @param mixed $value * @param string $functions * * @return string */ public function apply($value, $functions) { $functions = explode('|', strtolower($functions)); return array_reduce( $functions, fn($value, $function) => call_user_func([$this, $function], $value), $value, ); } /** * Converts special characters to HTML entities. * * @param string $value * @param string $functions * * @return string */ public function escape($value, $functions = '') { $value = strval($value); if ($functions) { $value = $this->apply($value, $functions); } return htmlspecialchars($value, ENT_COMPAT, 'UTF-8'); } /** * Renders a template. * * @param string $name * @param array|callable $parameters * * @return string|callable|false */ public function render($name, $parameters = []) { if (is_callable($parameters)) { return fn() => $this->render( $name, call_user_func_array($parameters, func_get_args()) ?: [], ); } $next = $this->loader->top(); foreach ($this->filters as $filter => $loaders) { if (!Str::is($filter, $name)) { continue; } foreach ($loaders as $loader) { $next = fn($name, array $parameters = []) => $loader($name, $parameters, $next); } } return $next( $name, array_replace(end($this->parameters) ?: $this->globals, $parameters, [ '_root' => empty($this->template), ]), ); } /** * Renders current template. * * @param mixed $parameters * * @return string|false */ public function self($parameters = []) { return $this->render(end($this->template), $parameters); } /** * Evaluates a template. * * @param string $template * @param array $parameters * * @return string|false */ public function evaluate($template, array $parameters = []) { $this->template[] = $template; $this->parameters[] = $this->evalParameters = $parameters; unset($template, $parameters); extract($this->evalParameters, EXTR_SKIP); unset($this->evalParameters); $__file = end($this->template); $__dir = dirname($__file); if (is_file($__file)) { ob_start(); require $__file; $result = ob_get_clean(); } array_pop($this->template); array_pop($this->parameters); return $result ?? false; } /** * Checks if a helper is registered. * * @param string $name * * @return bool */ #[\ReturnTypeWillChange] public function offsetExists($name) { return isset($this->helpers[$name]); } /** * Gets a helper. * * @param string $name * * @return mixed */ #[\ReturnTypeWillChange] public function offsetGet($name) { if (!$this->offsetExists($name)) { throw new \InvalidArgumentException(sprintf('Undefined helper "%s"', $name)); } return $this->helpers[$name]; } /** * Sets a helper. * * @param string $name * @param object $helper */ #[\ReturnTypeWillChange] public function offsetSet($name, $helper) { $this->helpers[$name] = $helper; } /** * Removes a helper. * * @param string $name */ #[\ReturnTypeWillChange] public function offsetUnset($name) { throw new \LogicException(sprintf('You can\'t remove a helper "%s"', $name)); } } src/View/HtmlHelperInterface.php 0000644 00000002045 15174725765 0012667 0 ustar 00 <?php namespace YOOtheme\View; interface HtmlHelperInterface { /** * Creates an element. * * @param string $name * @param array $attrs * @param mixed $contents * * @return HtmlElement */ public function el($name, array $attrs = [], $contents = false); /** * Renders a link tag. * * @param string $title * @param string $url * @param array $attrs * * @return string */ public function link($title, $url = null, array $attrs = []); /** * Renders an image tag. * * @param array|string $url * @param array $attrs * * @return string */ public function image($url, array $attrs = []); /** * Renders a form tag. * * @param array $tags * @param array $attrs * * @return string */ public function form($tags, array $attrs = []); /** * Renders tag attributes. * * @param array $attrs * * @return string */ public function attrs(array $attrs); } src/View/FileLoader.php 0000644 00000000636 15174725765 0011014 0 ustar 00 <?php namespace YOOtheme\View; use YOOtheme\File; class FileLoader { protected array $resolvedPaths = []; public function __invoke($name, $parameters, $next) { if (!str_ends_with(strtolower($name), '.php')) { $name .= '.php'; } $this->resolvedPaths[$name] ??= File::find($name); return $next($this->resolvedPaths[$name] ?: $name, $parameters); } } src/View/SectionHelper.php 0000644 00000004272 15174725765 0011552 0 ustar 00 <?php namespace YOOtheme\View; use YOOtheme\View; class SectionHelper { /** * @var array */ protected $sections = []; /** * @var array */ protected $openSections = []; /** * Constructor. * * @param View $view */ public function __construct(View $view) { $view['sections'] = $this; $view->addFunction('section', [$this, 'get']); } /** * Gets a section. * * @param string $name * @param string|false $default * * @return string|false */ public function get($name, $default = false) { if (empty($this->sections[$name])) { return $default; } return array_reduce($this->sections[$name], function ($result, $content) { if (is_callable($content)) { $result = $content($result); } elseif (is_string($content)) { $result .= $content; } return $result; }); } /** * Sets a section value. * * @param string $name * @param string|callable $content */ public function set($name, $content) { $this->sections[$name] = [$content]; } /** * Adds a section value by appending it. * * @param string $name * @param string|callable $content */ public function add($name, $content) { $this->sections[$name][] = $content; } /** * Checks if a section exists. * * @param string $name * * @return bool */ public function exists($name) { return isset($this->sections[$name]); } /** * Starts a new section. * * @param string $name */ public function start($name) { if (ob_start()) { $this->openSections[] = $name; } } /** * Stops a section. * * @throws \LogicException */ public function stop() { if (!($name = array_pop($this->openSections))) { throw new \LogicException('Cannot stop a section without first starting one.'); } $this->sections[$name] = [ob_get_clean()]; } } src/View/HtmlHelper.php 0000644 00000006620 15174725765 0011051 0 ustar 00 <?php namespace YOOtheme\View; use YOOtheme\View; class HtmlHelper implements HtmlHelperInterface { /** * @var callable[][] */ public $transforms = []; /** * Constructor. * * @param View $view */ public function __construct(View $view) { $view['html'] = $this; $view->addFunction('el', [$this, 'el']); $view->addFunction('link', [$this, 'link']); $view->addFunction('image', [$this, 'image']); $view->addFunction('form', [$this, 'form']); $view->addFunction('attrs', [$this, 'attrs']); $view->addFunction('expr', [HtmlElement::class, 'expr']); $view->addFunction('tag', [HtmlElement::class, 'tag']); } /** * @inheritdoc */ public function el($name, array $attrs = [], $contents = false) { return new HtmlElement($name, $attrs, $contents, [$this, 'applyTransform']); } /** * @inheritdoc */ public function link($title, $url = null, array $attrs = []) { return "<a{$this->attrs(['href' => $url], $attrs)}>{$title}</a>"; } /** * @inheritdoc */ public function image($url, array $attrs = []) { $url = (array) $url; $path = array_shift($url); $params = $url ? '#' . http_build_query( array_map(fn($value) => is_array($value) ? implode(',', $value) : $value, $url), '', '&', ) : ''; if (empty($attrs['alt'])) { $attrs['alt'] = true; } return "<img{$this->attrs(['src' => $path . $params], $attrs)}>"; } /** * @inheritdoc */ public function form($tags, array $attrs = []) { return HtmlElement::tag( 'form', $attrs, array_map( fn($tag) => HtmlElement::tag($tag['tag'], array_diff_key($tag, ['tag' => null])), $tags, ), ); } /** * @inheritdoc */ public function attrs(array $attrs) { $params = []; if (count($args = func_get_args()) > 1) { $attrs = call_user_func_array('array_merge_recursive', $args); } if (isset($attrs[':params'])) { $params = $attrs[':params']; unset($attrs[':params']); } return HtmlElement::attrs($attrs, $params); } /** * Adds a component. * * @param string $name * @param callable $component */ public function addComponent($name, callable $component) { $this->addTransform($name, $component); } /** * Adds a transform. * * @param string $name * @param callable $transform */ public function addTransform($name, callable $transform) { $this->transforms[$name][] = $transform; } /** * Applies transform callbacks. * * @param HtmlElement $element * @param array $params * * @return string|void */ public function applyTransform(HtmlElement $element, array $params = []) { if (empty($this->transforms[$element->name])) { return; } foreach ($this->transforms[$element->name] as $transform) { if ($result = call_user_func($transform, $element, $params)) { return $result; } } } } src/View/HtmlElementInterface.php 0000644 00000001120 15174725765 0013032 0 ustar 00 <?php namespace YOOtheme\View; interface HtmlElementInterface { /** * Renders element tag. * * @param string $name * @param array $attrs * @param false|string|string[] $contents * @param array $params * * @return string */ public static function tag($name, $attrs = null, $contents = null, array $params = []); /** * Evaluate expression attribute. * * @param array $expressions * @param array $params * * @return string|null */ public static function expr($expressions, array $params = []); } src/View/StrHelper.php 0000644 00000002333 15174725765 0010712 0 ustar 00 <?php namespace YOOtheme\View; use YOOtheme\Str; use YOOtheme\View; class StrHelper extends Str { /** * Constructor. * * @param View $view */ public function __construct(View $view) { $functions = [ // native 'trim' => 'trim', 'json' => 'json_encode', 'nl2br' => 'nl2br', 'striptags' => 'strip_tags', // date 'date' => [$this, 'date'], // string util 'limit' => [$this, 'limit'], 'words' => [$this, 'words'], 'upper' => [$this, 'upper'], 'lower' => [$this, 'lower'], 'title' => [$this, 'titleCase'], ]; foreach ($functions as $name => $function) { $view->addFunction($name, $function); } } /** * Formats a date. * * @param mixed $date * @param string $format * * @return string */ public function date($date, $format = 'F j, Y H:i') { if (is_string($date)) { $date = strtotime($date); } elseif ($date instanceof \DateTime) { $date = $date->getTimestamp(); } return date($format, $date); } } src/View/HtmlElement.php 0000644 00000020173 15174725765 0011222 0 ustar 00 <?php namespace YOOtheme\View; use YOOtheme\Arr; class HtmlElement implements HtmlElementInterface { /** * @var string */ public $name; /** * @var array */ public $attrs; /** * @var mixed */ public $contents; /** * @var callable|null */ protected $transform; /** * Constructor. * * @param string $name * @param array $attrs * @param mixed $contents * @param callable|null $transform */ public function __construct( $name, array $attrs = [], $contents = '', ?callable $transform = null ) { $this->name = $name; $this->attrs = $attrs; $this->contents = $contents; $this->transform = $transform; } /** * Renders element shortcut. * * @see render() */ public function __toString() { return $this->render(); } /** * Render element shortcut. * * @param array $params * @param null|mixed $attrs * @param null|mixed $contents * @param null|mixed $name * * @return string * * @see render() */ public function __invoke(array $params = [], $attrs = null, $contents = null, $name = null) { return $this->render($params, $attrs, $contents, $name); } /** * Renders the element tag. * * @param array $params * @param array $attrs * @param string $contents * @param string $name * * @return string */ public function render(array $params = [], $attrs = null, $contents = null, $name = null) { $element = isset($attrs) ? $this->copy($attrs, $contents, $name) : $this; if (($transform = $this->transform) && ($result = $transform($element, $params))) { return $result; } return self::tag($element->name, $element->attrs, $element->contents, $params); } /** * Renders element closing tag. * * @return string */ public function end() { return self::isSelfClosing($this->name) ? '' : "</{$this->name}>"; } /** * Adds an attribute. * * @param string|array $name * @param mixed|null $value * * @return $this */ public function attr($name, $value = null) { $attrs = is_array($name) ? $name : [$name => $value]; $this->attrs = Arr::merge($this->attrs, $attrs); return $this; } /** * Copy instance. * * @param array|string $attrs * @param string $contents * @param string $name * * @return static */ public function copy($attrs = null, $contents = null, $name = null) { $clone = clone $this; if (is_array($attrs)) { $clone->attr($attrs); } elseif (isset($attrs)) { $contents = $attrs; } if (isset($name)) { $clone->name = $name; } if (isset($contents)) { $clone->contents = $contents; } return $clone; } /** * @inheritdoc */ public static function tag($name, $attrs = null, $contents = null, array $params = []) { $tag = $contents === false || self::isSelfClosing($name); if (is_array($attrs)) { $attrs = self::attrs($attrs, $params); } if (is_array($contents)) { $contents = join($contents); } return $tag ? "<{$name}{$attrs}>" : "<{$name}{$attrs}>{$contents}</{$name}>"; } /** * Renders tag attributes. * * @param array $attrs * @param array $params * * @return string */ public static function attrs(array $attrs, array $params = []) { $output = []; foreach ($attrs as $key => $value) { if (is_array($value)) { $value = self::expr($value, $params); } if (empty($value) && !is_numeric($value)) { continue; } if (is_numeric($key)) { $output[] = $value; } elseif ($value === true) { $output[] = $key; } elseif ($value !== '') { $output[] = sprintf( '%s="%s"', $key, htmlspecialchars($value, ENT_COMPAT, 'UTF-8', false), ); } } return $output ? ' ' . implode(' ', $output) : ''; } /** * @inheritdoc */ public static function expr($expressions, array $params = []) { $output = []; if (func_num_args() > 2) { $params = call_user_func_array('array_replace', array_slice(func_get_args(), 1)); } foreach ((array) $expressions as $expression => $condition) { if (!$condition) { continue; } if (is_int($expression)) { $expression = $condition; } if ( $expression = self::evaluateExpression( $expression, array_replace($params, (array) $condition), ) ) { $output[] = $expression; } } return $output ? join(' ', $output) : null; } /** * Checks if tag name is self-closing. * * @param string $name * * @return bool */ public static function isSelfClosing($name) { static $tags; if (is_null($tags)) { $tags = array_flip([ 'area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input', 'keygen', 'link', 'menuitem', 'meta', 'param', 'source', 'track', 'wbr', ]); } return isset($tags[strtolower($name)]); } /** * Parse expression string. * * @param string $expression * * @return array */ protected static function parseExpression($expression) { static $expressions; if (isset($expressions[$expression])) { return $expressions[$expression]; } $optionals = []; // match all optionals $output = preg_replace_callback( '/\[((?:[^\[\]]+|(?R))*)\]/', function ($matches) use (&$optionals) { return '%' . array_push($optionals, $matches[1]) . '$s'; }, $expression, ); // match all parameters preg_match_all( '/\{\s*(@?)(!?)(\w+)\s*(?::\s*([^{}]*(?:\{(?-1)\}[^{}]*)*))?\}/', $output, $parameters, PREG_SET_ORDER, ); return $expressions[$expression] = [$output, $parameters, $optionals]; } /** * Evaluate expression string. * * @param string $expression * @param array $params * * @return string */ protected static function evaluateExpression($expression, array $params = []) { if (!str_contains($expression, '{')) { return trim($expression); } [$output, $parameters, $optionals] = self::parseExpression($expression); foreach ($parameters as $match) { [$parameter, $empty, $negate, $name] = $match; $regex = isset($match[4]) ? "/^({$match[4]})$/" : ''; $value = $params[$name] ?? ''; $result = $regex ? preg_match($regex, $value) : $value || (is_string($value) && $value !== ''); if ($result xor $negate) { $output = str_replace($parameter, $empty ? '' : $value, $output); } else { return ''; } } if ($optionals) { $args = [$output]; foreach ($optionals as $match) { $args[] = self::evaluateExpression($match, $params); } $output = call_user_func_array('sprintf', $args); } return trim($output); } } bootstrap.php 0000644 00000001004 15174725765 0007310 0 ustar 00 <?php namespace YOOtheme; use YOOtheme\View\FileLoader; use YOOtheme\View\HtmlHelper; use YOOtheme\View\SectionHelper; use YOOtheme\View\StrHelper; return [ 'services' => [ View::class => function (FileLoader $loader) { $view = new View($loader); $view->addGlobal('view', $view); $view->addHelper(StrHelper::class); $view->addHelper(HtmlHelper::class); $view->addHelper(SectionHelper::class); return $view; }, ], ];
| ver. 1.4 |
Github
|
.
| PHP 8.3.23 | Generation time: 0 |
proxy
|
phpinfo
|
Settings