/** * Calls wrapped event * * @param array $arguments * @throws InvalidEventArgumentDefinitionException */ public function call(array $arguments) { $parameters = $this->method->getParameters(); if (!isset($this->annotations['param'])) { throw new InvalidEventArgumentDefinitionException('@param annotation at method ' . $this->method->getName() . ' not found.'); } $count = count($parameters); for ($i = 0; $i < $count; $i++) { $arguments[$i] = $this->validateArgument($arguments[$i], $i); } call_user_func_array([$this->service, $this->method->getName()], $arguments); }
/** * Request/URL factory. * @param Component base * @param string destination in format "[//] [[[module:]presenter:]action | signal! | this] [#fragment]" * @param array array of arguments * @param string forward|redirect|link * @return string URL * @throws InvalidLinkException * @internal */ protected function createRequest($component, $destination, array $args, $mode) { if (!$component instanceof self || substr($destination, -1) === '!') { // check if signal must be secured $signal = strtr(rtrim($destination, '!'), ':', '-'); $method = $component->formatSignalMethod($signal); $signalMethodReflection = new Nette\Reflection\Method($component, $method); if (!$signalMethodReflection->hasAnnotation('secured')) { goto parent; } // gather args, create hash and append to args $namedArgs = $args; self::argsToParams($this, $method, $namedArgs); // convert indexed args to named args $protectedParams = array($component->getUniqueId()); foreach ($signalMethodReflection->getParameters() as $param) { if ($param->isOptional()) { continue; } if (isset($namedArgs[$component->getParameterId($param->name)])) { $protectedParams[$param->name] = $namedArgs[$component->getParameterId($param->name)]; } } $args['_sec'] = $this->getCsrfToken(get_class($component), $method, $protectedParams); } parent: return parent::createRequest($component, $destination, $args, $mode); }
/** * For @secured annotated signal handler methods checks if URL parameters has not been changed * * @param string $signal * @throws Nette\Application\UI\BadSignalException if there is no handler method or the security token does not match * @throws \LogicException if there is no redirect in a secured signal */ public function signalReceived($signal) { $method = $this->formatSignalMethod($signal); $secured = FALSE; if (method_exists($this, $method)) { $reflection = new Nette\Reflection\Method($this, $method); $secured = $reflection->hasAnnotation('secured'); if ($secured) { $params = array($this->getUniqueId()); if ($this->params) { foreach ($reflection->getParameters() as $param) { if ($param->isOptional()) { continue; } if (isset($this->params[$param->name])) { $params[$param->name] = $this->params[$param->name]; list($type, $isClass) = Nette\Application\UI\ComponentReflection::getParameterType($param); Nette\Application\UI\ComponentReflection::convertType($params[$param->name], $type, $isClass); } } } if (!isset($this->params['_sec']) || $this->params['_sec'] !== $this->getPresenter()->getCsrfToken(get_class($this), $method, $params)) { throw new Nette\Application\UI\BadSignalException("Invalid security token for signal '{$signal}' in class {$this->getReflection()->name}."); } } } parent::signalReceived($signal); if ($secured && !$this->getPresenter()->isAjax()) { throw new \LogicException("Secured signal '{$signal}' did not redirect. Possible csrf-token reveal by http referer header."); } }
/** * Create definition statement for method * @param ServiceDefinition $definition * @param \Nette\Reflection\Method $method */ protected function autowireParams(ServiceDefinition $definition, \Nette\Reflection\Method $method) { $parameters = $method->getParameters(); foreach ($parameters as $num => $param) { /** @var \Nette\Reflection\Parameter $param */ if ($targetClass = $param->getClass()) { if ($targetClass->getName() === 'Kdyby\\Doctrine\\EntityDao' && !isset($definition->factory->arguments[$num])) { $annotations = $method->getAnnotations(); $entity = $this->getEntityName($param, $annotations); if ($definition->factory === NULL) { $definition->setFactory($definition->class); } $definition->factory->arguments[$num] = new \Nette\DI\Statement('@doctrine.dao', array($entity)); } } } }
/** * @param $name * @return Nette\ComponentModel\IComponent * @throws Nette\UnexpectedValueException */ protected function createComponent($name) { $sl = $this->getComponentFactoriesLocator(); $ucName = ucfirst($name); $method = 'createComponent' . $ucName; if ($ucName !== $name && method_exists($this, $method)) { $methodReflection = new Method($this, $method); if ($methodReflection->getName() !== $method) { return; } $parameters = $methodReflection->getParameters(); $args = []; if (($first = reset($parameters)) && !$first->className) { $args[] = $name; } $args = Nette\DI\Helpers::autowireArguments($methodReflection, $args, $sl); $component = call_user_func_array([$this, $method], $args); if (!$component instanceof Nette\ComponentModel\IComponent && !isset($this->components[$name])) { throw new Nette\UnexpectedValueException("Method {$methodReflection} did not return or create the desired component."); } return $component; } }
/** * @return array */ public function getParameterNames() { return array_keys($this->method->getParameters()); }