/** * Simple gate for Nette object events. * @param string method name * @param array arguments * @return mixed * @throws MemberAccessException */ public function __call($name, $args) { if ($name >= 'onA' && $name < 'on_') { return ObjectMixin::call($this, $name, $args); } else { throw new MemberAccessException($name); } }
public static function registerControls() { ObjectMixin::setExtensionMethod(Container::class, 'addDatePicker', function (Container $container, $name, $label = null) { return $container[$name] = new Controls\DatePicker($label); }); ObjectMixin::setExtensionMethod(Container::class, 'addDateTimePicker', function (Container $container, $name, $label = null) { return $container[$name] = new Controls\DateTimePicker($label); }); ObjectMixin::setExtensionMethod(Container::class, 'addTypeahead', function (Container $container, $name, $label = null, $callback = null) { return $container[$name] = new Controls\Typeahead($label, $callback); }); }
/** * Checks whether $config contains only $expected items and returns combined array. * @return array * @throws Nette\InvalidStateException */ public function validateConfig(array $expected, array $config = NULL, $name = NULL) { if (func_num_args() === 1) { return $this->config = $this->validateConfig($expected, $this->config); } if ($extra = array_diff_key((array) $config, $expected)) { $name = $name ?: $this->name; $hint = Nette\Utils\ObjectMixin::getSuggestion(array_keys($expected), key($extra)); $extra = $hint ? key($extra) : implode(", {$name}.", array_keys($extra)); throw new Nette\InvalidStateException("Unknown configuration option {$name}.{$extra}" . ($hint ? ", did you mean {$name}.{$hint}?" : '.')); } return Config\Helpers::merge($config, $expected); }
public function fireEvent($method, $args = []) { if (!method_exists($this, $method)) { throw new InvalidArgumentException("Event '{$method}' does not exist."); } $this->eventCheck = FALSE; call_user_func_array([$this, $method], $args); if (!$this->eventCheck) { throw new InvalidStateException("Event '{$method}' was not correctly propagate to overwritten methods."); } if (property_exists($this, $method)) { ObjectMixin::call($this, $method, $args); } }
public function hasProperty(ClassReflection $classReflection, string $propertyName) : bool { $traitNames = $this->getTraitNames($classReflection->getNativeReflection()); if (!in_array(\Nette\SmartObject::class, $traitNames, true)) { return false; } $property = \Nette\Utils\ObjectMixin::getMagicProperty($classReflection->getName(), $propertyName); if ($property === null) { return false; } $getterMethod = $this->getMethodByProperty($classReflection, $propertyName); if ($getterMethod === null) { return false; } return $getterMethod->isPublic(); }
/** * Removes property. * @param string property name * @return void * @throws Nette\MemberAccessException */ public function __unset($name) { Nette\Utils\ObjectMixin::remove($this, $name); }
public function __call($name, $args) { if (method_exists(ClassType::class, $name)) { trigger_error("getReflection()->{$name}() is deprecated, use Nette\\Reflection\\ClassType::from(\$presenter)->{$name}()", E_USER_DEPRECATED); return call_user_func_array([new ClassType($this->getName()), $name], $args); } Nette\Utils\ObjectMixin::strictCall(get_class($this), $name); }
public function __get($name) { return ObjectMixin::get($this, $name); }
/** * Access to undeclared property. * * @param string $name * * @throws \Nette\MemberAccessException * @return void */ public function __unset($name) { if ($name === '_conn') { $this->{$name} = NULL; return; } ObjectMixin::remove($this, $name); }
/** * Returns component specified by name or path. * @param string * @param bool throw exception if component doesn't exist? * @return IComponent|NULL */ public function getComponent($name, $need = TRUE) { if (isset($this->components[$name])) { return $this->components[$name]; } if (is_int($name)) { $name = (string) $name; } elseif (!is_string($name)) { throw new Nette\InvalidArgumentException(sprintf('Component name must be integer or string, %s given.', gettype($name))); } else { $a = strpos($name, self::NAME_SEPARATOR); if ($a !== FALSE) { $ext = (string) substr($name, $a + 1); $name = substr($name, 0, $a); } if ($name === '') { if ($need) { throw new Nette\InvalidArgumentException('Component or subcomponent name must not be empty string.'); } return; } } if (!isset($this->components[$name])) { $component = $this->createComponent($name); if ($component) { if (!$component instanceof IComponent) { throw new Nette\UnexpectedValueException('Method createComponent() did not return Nette\\ComponentModel\\IComponent.'); } elseif (!isset($this->components[$name])) { $this->addComponent($component, $name); } } } if (isset($this->components[$name])) { if (!isset($ext)) { return $this->components[$name]; } elseif ($this->components[$name] instanceof IContainer) { return $this->components[$name]->getComponent($ext, $need); } elseif ($need) { throw new Nette\InvalidArgumentException("Component with name '{$name}' is not container and cannot have '{$ext}' component."); } } elseif ($need) { $hint = Nette\Utils\ObjectMixin::getSuggestion(array_merge(array_keys($this->components), array_map('lcfirst', preg_filter('#^createComponent([A-Z0-9].*)#', '$1', get_class_methods($this)))), $name); throw new Nette\InvalidArgumentException("Component with name '{$name}' does not exist" . ($hint ? ", did you mean '{$hint}'?" : '.')); } }
protected function fireEvent(IEntity $entity, $event) { if (!property_exists($this, $event)) { throw new InvalidArgumentException("Event '{$event}' is not defined."); } $entity->fireEvent($event); ObjectMixin::call($this, $event, [$entity]); }
/** * Access to undeclared property. * * @param string $name * * @throws \Nette\MemberAccessException * @return void */ public function __unset($name) { ObjectMixin::remove($this, $name); }
/** * @param string * @return ActiveRow|mixed * @throws Nette\MemberAccessException */ public function &__get($key) { $this->accessColumn($key); if (array_key_exists($key, $this->data)) { return $this->data[$key]; } $referenced = $this->table->getReferencedTable($this, $key); if ($referenced !== FALSE) { $this->accessColumn($key, FALSE); return $referenced; } $this->removeAccessColumn($key); $hint = Nette\Utils\ObjectMixin::getSuggestion(array_keys($this->data), $key); throw new Nette\MemberAccessException("Cannot read an undeclared column '{$key}'" . ($hint ? ", did you mean '{$hint}'?" : '.')); }
/** * @param $key * @return bool */ public function __isset($key) { return ObjectMixin::has($this, $key) || $this->activeRow->__isset($key); }
private function registerReplicator() { if (!ObjectMixin::getExtensionMethod(SubmitButton::class, 'addCreateOnClick')) { Replicator::register(); } }
/** * @param string $name * @param array $args * * @return mixed */ public function __call($name, $args) { if (method_exists('Nette\\Utils\\ObjectMixin', 'callProperty')) { return ObjectMixin::callProperty($this, $name, $args); } else { return ObjectMixin::call($this, $name, $args); } }
/** * Převede databázový název sloupce s lomítkama na camelFont. * @example group_id => groupId * @param string $name * @return string */ private function normalizePropertyName($name) { $propertyName = $name; if (!\Nette\Utils\ObjectMixin::has($this, $name)) { $propertyName = ''; $nameParts = explode('_', $name); foreach ($nameParts as $key => $partName) { $propertyName .= $key == 0 ? $partName : ucfirst($partName); } } return $propertyName; }
/** @internal */ public function processExtensions() { $last = $this->getExtensions(Extensions\InjectExtension::class); $this->extensions = array_merge(array_diff_key($this->extensions, $last), $last); $this->config = Helpers::expand(array_diff_key($this->config, self::$reserved), $this->builder->parameters) + array_intersect_key($this->config, self::$reserved); foreach ($first = $this->getExtensions(Extensions\ExtensionsExtension::class) as $name => $extension) { $extension->setConfig(isset($this->config[$name]) ? $this->config[$name] : []); $extension->loadConfiguration(); } $extensions = array_diff_key($this->extensions, $first); foreach (array_intersect_key($extensions, $this->config) as $name => $extension) { $extension->setConfig($this->config[$name] ?: []); } foreach ($extensions as $extension) { $extension->loadConfiguration(); } if ($extra = array_diff_key($this->extensions, $extensions, $first)) { $extra = implode("', '", array_keys($extra)); throw new Nette\DeprecatedException("Extensions '{$extra}' were added while container was being compiled."); } elseif ($extra = key(array_diff_key($this->config, self::$reserved, $this->extensions))) { $hint = Nette\Utils\ObjectMixin::getSuggestion(array_keys(self::$reserved + $this->extensions), $extra); throw new Nette\InvalidStateException("Found section '{$extra}' in configuration, but corresponding extension is missing" . ($hint ? ", did you mean '{$hint}'?" : '.')); } }
private function resolveImplement(ServiceDefinition $def, $name) { $interface = $def->getImplement(); if (!interface_exists($interface)) { throw new ServiceCreationException("Interface {$interface} used in service '{$name}' not found."); } self::checkCase($interface); $rc = new ReflectionClass($interface); $method = $rc->hasMethod('create') ? $rc->getMethod('create') : ($rc->hasMethod('get') ? $rc->getMethod('get') : NULL); if (count($rc->getMethods()) !== 1 || !$method || $method->isStatic()) { throw new ServiceCreationException("Interface {$interface} used in service '{$name}' must have just one non-static method create() or get()."); } $def->setImplementType($methodName = $rc->hasMethod('create') ? 'create' : 'get'); if (!$def->getClass() && !$def->getEntity()) { $returnType = PhpReflection::getReturnType($method); if (!$returnType) { throw new ServiceCreationException("Method {$interface}::{$methodName}() used in service '{$name}' has no @return annotation."); } elseif (!class_exists($returnType)) { throw new ServiceCreationException("Check a @return annotation of the {$interface}::{$methodName}() method used in service '{$name}', class '{$returnType}' cannot be found."); } $def->setClass($returnType); } if ($methodName === 'get') { if ($method->getParameters()) { throw new ServiceCreationException("Method {$interface}::get() used in service '{$name}' must have no arguments."); } if (!$def->getEntity()) { $def->setFactory('@\\' . ltrim($def->getClass(), '\\')); } elseif (!$this->getServiceName($def->getFactory()->getEntity())) { throw new ServiceCreationException("Invalid factory in service '{$name}' definition."); } } if (!$def->parameters) { $ctorParams = array(); if (!$def->getEntity()) { $def->setFactory($def->getClass(), $def->getFactory() ? $def->getFactory()->arguments : array()); } if (($class = $this->resolveEntityClass($def->getFactory(), array($name => 1))) && ($rc = new ReflectionClass($class)) && ($ctor = $rc->getConstructor())) { foreach ($ctor->getParameters() as $param) { $ctorParams[$param->getName()] = $param; } } foreach ($method->getParameters() as $param) { $hint = PhpReflection::getParameterType($param); if (isset($ctorParams[$param->getName()])) { $arg = $ctorParams[$param->getName()]; if ($hint !== PhpReflection::getParameterType($arg)) { throw new ServiceCreationException("Type hint for \${$param->getName()} in {$interface}::{$methodName}() doesn't match type hint in {$class} constructor."); } $def->getFactory()->arguments[$arg->getPosition()] = self::literal('$' . $arg->getName()); } elseif (!$def->getSetup()) { $hint = Nette\Utils\ObjectMixin::getSuggestion(array_keys($ctorParams), $param->getName()); throw new ServiceCreationException("Unused parameter \${$param->getName()} when implementing method {$interface}::{$methodName}()" . ($hint ? ", did you mean \${$hint}?" : '.')); } $paramDef = $hint . ' ' . $param->getName(); if ($param->isOptional()) { $def->parameters[$paramDef] = $param->getDefaultValue(); } else { $def->parameters[] = $paramDef; } } } }
public static function extensionMethod($name, $callback) { Nette\Utils\ObjectMixin::setExtensionMethod(__CLASS__, $name, $callback); }
public static function extensionMethod($name, $callback = NULL) { if (strpos($name, '::') !== FALSE) { // back compatibility list(, $name) = explode('::', $name); } Nette\Utils\ObjectMixin::setExtensionMethod(get_called_class(), $name, $callback); }
/** @internal */ public function processExtensions() { $this->config = Helpers::expand(array_diff_key($this->config, self::$reserved), $this->builder->parameters) + array_intersect_key($this->config, self::$reserved); foreach ($first = $this->getExtensions('Nette\\DI\\Extensions\\ExtensionsExtension') as $name => $extension) { $extension->setConfig(isset($this->config[$name]) ? $this->config[$name] : array()); $extension->loadConfiguration(); } $last = $this->getExtensions('Nette\\DI\\Extensions\\InjectExtension'); $this->extensions = array_merge(array_diff_key($this->extensions, $last), $last); $extensions = array_diff_key($this->extensions, $first); foreach (array_intersect_key($extensions, $this->config) as $name => $extension) { if (isset($this->config[$name]['services'])) { trigger_error("Support for inner section 'services' inside extension was removed (used in '{$name}').", E_USER_DEPRECATED); } $extension->setConfig($this->config[$name] ?: array()); } foreach ($extensions as $extension) { $extension->loadConfiguration(); } if ($extra = array_diff_key($this->extensions, $extensions, $first)) { $extra = implode("', '", array_keys($extra)); throw new Nette\DeprecatedException("Extensions '{$extra}' were added while container was being compiled."); } elseif ($extra = key(array_diff_key($this->config, self::$reserved, $this->extensions))) { $hint = Nette\Utils\ObjectMixin::getSuggestion(array_keys(self::$reserved + $this->extensions), $extra); throw new Nette\InvalidStateException("Found section '{$extra}' in configuration, but corresponding extension is missing" . ($hint ? ", did you mean '{$hint}'?" : '.')); } }
public function __get($key) { $hint = Nette\Utils\ObjectMixin::getSuggestion(array_keys((array) $this), $key); throw new Nette\MemberAccessException("Cannot read an undeclared column '{$key}'" . ($hint ? ", did you mean '{$hint}'?" : '.')); }
/** * Parses single service definition from configuration. * @return void */ public static function loadDefinition(ServiceDefinition $definition, $config) { if ($config === NULL) { return; } elseif (is_string($config) && interface_exists($config)) { $config = ['class' => NULL, 'implement' => $config]; } elseif ($config instanceof Statement && is_string($config->getEntity()) && interface_exists($config->getEntity())) { $config = ['class' => NULL, 'implement' => $config->getEntity(), 'factory' => array_shift($config->arguments)]; } elseif (!is_array($config) || isset($config[0], $config[1])) { $config = ['class' => NULL, 'factory' => $config]; } if (array_key_exists('create', $config)) { trigger_error("Key 'create' is deprecated, use 'factory' or 'class' in configuration.", E_USER_DEPRECATED); $config['factory'] = $config['create']; unset($config['create']); } $known = ['class', 'factory', 'arguments', 'setup', 'autowired', 'dynamic', 'inject', 'parameters', 'implement', 'run', 'tags']; if ($error = array_diff(array_keys($config), $known)) { $hints = array_filter(array_map(function ($error) use($known) { return Nette\Utils\ObjectMixin::getSuggestion($known, $error); }, $error)); $hint = $hints ? ", did you mean '" . implode("', '", $hints) . "'?" : '.'; throw new Nette\InvalidStateException(sprintf("Unknown key '%s' in definition of service{$hint}", implode("', '", $error))); } $config = Helpers::filterArguments($config); if (array_key_exists('class', $config) || array_key_exists('factory', $config)) { $definition->setClass(NULL); $definition->setFactory(NULL); } if (array_key_exists('class', $config)) { Validators::assertField($config, 'class', 'string|Nette\\DI\\Statement|null'); if (!$config['class'] instanceof Statement) { $definition->setClass($config['class']); } $definition->setFactory($config['class']); } if (array_key_exists('factory', $config)) { Validators::assertField($config, 'factory', 'callable|Nette\\DI\\Statement|null'); $definition->setFactory($config['factory']); } if (array_key_exists('arguments', $config)) { Validators::assertField($config, 'arguments', 'array'); $arguments = $config['arguments']; if (!Config\Helpers::takeParent($arguments) && !Nette\Utils\Arrays::isList($arguments) && $definition->getFactory()) { $arguments += $definition->getFactory()->arguments; } $definition->setArguments($arguments); } if (isset($config['setup'])) { if (Config\Helpers::takeParent($config['setup'])) { $definition->setSetup([]); } Validators::assertField($config, 'setup', 'list'); foreach ($config['setup'] as $id => $setup) { Validators::assert($setup, 'callable|Nette\\DI\\Statement|array:1', "setup item #{$id}"); if (is_array($setup)) { $setup = new Statement(key($setup), array_values($setup)); } $definition->addSetup($setup); } } if (isset($config['parameters'])) { Validators::assertField($config, 'parameters', 'array'); $definition->setParameters($config['parameters']); } if (isset($config['implement'])) { Validators::assertField($config, 'implement', 'string'); $definition->setImplement($config['implement']); $definition->setAutowired(TRUE); } if (isset($config['autowired'])) { Validators::assertField($config, 'autowired', 'bool|string|array'); $definition->setAutowired($config['autowired']); } if (isset($config['dynamic'])) { Validators::assertField($config, 'dynamic', 'bool'); $definition->setDynamic($config['dynamic']); } if (isset($config['inject'])) { Validators::assertField($config, 'inject', 'bool'); $definition->addTag(Extensions\InjectExtension::TAG_INJECT, $config['inject']); } if (isset($config['run'])) { trigger_error("Option 'run' is deprecated, use 'run' as tag.", E_USER_DEPRECATED); $config['tags']['run'] = (bool) $config['run']; } if (isset($config['tags'])) { Validators::assertField($config, 'tags', 'array'); if (Config\Helpers::takeParent($config['tags'])) { $definition->setTags([]); } foreach ($config['tags'] as $tag => $attrs) { if (is_int($tag) && is_string($attrs)) { $definition->addTag($attrs); } else { $definition->addTag($tag, $attrs); } } } }
/** * Callbacks * @param string $name * @param array $args * @return mixed * @throws MemberAccessException */ public function __call($name, $args) { return ObjectMixin::call($this, $name, $args); }
/** * @return mixed * @deprecated use Nette\Utils\ObjectMixin::setExtensionMethod() */ public static function extensionMethod($name, $callback = NULL) { if (strpos($name, '::') === FALSE) { $class = get_called_class(); } else { list($class, $name) = explode('::', $name); $class = (new \ReflectionClass($class))->getName(); } trigger_error("Extension methods such as {$class}::{$name}() are deprecated" . ObjectMixin::getSource(), E_USER_DEPRECATED); if ($callback === NULL) { return ObjectMixin::getExtensionMethod($class, $name); } else { ObjectMixin::setExtensionMethod($class, $name, $callback); } }