/vendor/laravel/framework/src/Illuminate/View/Component.php
https://github.com/ladybirdweb/agorainvoicing · PHP · 276 lines · 135 code · 41 blank · 100 comment · 5 complexity · cad9414d7c32e84c6750e6452bf50167 MD5 · raw file
- <?php
- namespace Illuminate\View;
- use Closure;
- use Illuminate\Container\Container;
- use Illuminate\Support\Str;
- use ReflectionClass;
- use ReflectionMethod;
- use ReflectionProperty;
- abstract class Component
- {
- /**
- * The cache of public property names, keyed by class.
- *
- * @var array
- */
- protected static $propertyCache = [];
- /**
- * The cache of public method names, keyed by class.
- *
- * @var array
- */
- protected static $methodCache = [];
- /**
- * The properties / methods that should not be exposed to the component.
- *
- * @var array
- */
- protected $except = [];
- /**
- * The component alias name.
- *
- * @var string
- */
- public $componentName;
- /**
- * The component attributes.
- *
- * @var \Illuminate\View\ComponentAttributeBag
- */
- public $attributes;
- /**
- * Get the view / view contents that represent the component.
- *
- * @return \Illuminate\View\View|string
- */
- abstract public function render();
- /**
- * Resolve the Blade view or view file that should be used when rendering the component.
- *
- * @return \Illuminate\View\View|string
- */
- public function resolveView()
- {
- $view = $this->render();
- if ($view instanceof View) {
- return $view;
- }
- $resolver = function ($view) {
- $factory = Container::getInstance()->make('view');
- return $factory->exists($view)
- ? $view
- : $this->createBladeViewFromString($factory, $view);
- };
- return $view instanceof Closure ? function (array $data = []) use ($view, $resolver) {
- return $resolver($view($data));
- }
- : $resolver($view);
- }
- /**
- * Create a Blade view with the raw component string content.
- *
- * @param \Illuminate\Contracts\View\Factory $factory
- * @param string $contents
- * @return string
- */
- protected function createBladeViewFromString($factory, $contents)
- {
- $factory->addNamespace(
- '__components',
- $directory = Container::getInstance()['config']->get('view.compiled')
- );
- if (! file_exists($viewFile = $directory.'/'.sha1($contents).'.blade.php')) {
- if (! is_dir($directory)) {
- mkdir($directory, 0755, true);
- }
- file_put_contents($viewFile, $contents);
- }
- return '__components::'.basename($viewFile, '.blade.php');
- }
- /**
- * Get the data that should be supplied to the view.
- *
- * @author Freek Van der Herten
- * @author Brent Roose
- *
- * @return array
- */
- public function data()
- {
- $this->attributes = $this->attributes ?: new ComponentAttributeBag;
- return array_merge($this->extractPublicProperties(), $this->extractPublicMethods());
- }
- /**
- * Extract the public properties for the component.
- *
- * @return array
- */
- protected function extractPublicProperties()
- {
- $class = get_class($this);
- if (! isset(static::$propertyCache[$class])) {
- $reflection = new ReflectionClass($this);
- static::$propertyCache[$class] = collect($reflection->getProperties(ReflectionProperty::IS_PUBLIC))
- ->reject(function (ReflectionProperty $property) {
- return $this->shouldIgnore($property->getName());
- })
- ->map(function (ReflectionProperty $property) {
- return $property->getName();
- })->all();
- }
- $values = [];
- foreach (static::$propertyCache[$class] as $property) {
- $values[$property] = $this->{$property};
- }
- return $values;
- }
- /**
- * Extract the public methods for the component.
- *
- * @return array
- */
- protected function extractPublicMethods()
- {
- $class = get_class($this);
- if (! isset(static::$methodCache[$class])) {
- $reflection = new ReflectionClass($this);
- static::$methodCache[$class] = collect($reflection->getMethods(ReflectionMethod::IS_PUBLIC))
- ->reject(function (ReflectionMethod $method) {
- return $this->shouldIgnore($method->getName());
- })
- ->map(function (ReflectionMethod $method) {
- return $method->getName();
- });
- }
- $values = [];
- foreach (static::$methodCache[$class] as $method) {
- $values[$method] = $this->createVariableFromMethod(new ReflectionMethod($this, $method));
- }
- return $values;
- }
- /**
- * Create a callable variable from the given method.
- *
- * @param \ReflectionMethod $method
- * @return mixed
- */
- protected function createVariableFromMethod(ReflectionMethod $method)
- {
- return $method->getNumberOfParameters() === 0
- ? $this->createInvokableVariable($method->getName())
- : Closure::fromCallable([$this, $method->getName()]);
- }
- /**
- * Create an invokable, toStringable variable for the given component method.
- *
- * @param string $method
- * @return \Illuminate\View\InvokableComponentVariable
- */
- protected function createInvokableVariable(string $method)
- {
- return new InvokableComponentVariable(function () use ($method) {
- return $this->{$method}();
- });
- }
- /**
- * Determine if the given property / method should be ignored.
- *
- * @param string $name
- * @return bool
- */
- protected function shouldIgnore($name)
- {
- return Str::startsWith($name, '__') ||
- in_array($name, $this->ignoredMethods());
- }
- /**
- * Get the methods that should be ignored.
- *
- * @return array
- */
- protected function ignoredMethods()
- {
- return array_merge([
- 'data',
- 'render',
- 'resolveView',
- 'shouldRender',
- 'view',
- 'withName',
- 'withAttributes',
- ], $this->except);
- }
- /**
- * Set the component alias name.
- *
- * @param string $name
- * @return $this
- */
- public function withName($name)
- {
- $this->componentName = $name;
- return $this;
- }
- /**
- * Set the extra attributes that the component should make available.
- *
- * @param array $attributes
- * @return $this
- */
- public function withAttributes(array $attributes)
- {
- $this->attributes = $this->attributes ?: new ComponentAttributeBag;
- $this->attributes->setAttributes($attributes);
- return $this;
- }
- /**
- * Determine if the component should be rendered.
- *
- * @return bool
- */
- public function shouldRender()
- {
- return true;
- }
- }