/** * Execute this configuration handler. * * @param AgaviXmlConfigDomDocument The document to parse. * * @return string Data to be written to a cache file. * * @throws <b>AgaviParseException</b> If a requested configuration file is * improperly formatted. * * @author David Zülke <*****@*****.**> * @author Sean Kerr <*****@*****.**> * @since 0.9.0 */ public function execute(AgaviXmlConfigDomDocument $document) { // set up our default namespace $document->setDefaultNamespace(self::XML_NAMESPACE, 'filters'); $config = $document->documentURI; $filters = array(); foreach ($document->getConfigurationElements() as $cfg) { if ($cfg->has('filters')) { foreach ($cfg->get('filters') as $filter) { $name = $filter->getAttribute('name', AgaviToolkit::uniqid()); if (!isset($filters[$name])) { $filters[$name] = array('params' => array(), 'enabled' => AgaviToolkit::literalize($filter->getAttribute('enabled', true))); } else { $filters[$name]['enabled'] = AgaviToolkit::literalize($filter->getAttribute('enabled', $filters[$name]['enabled'])); } if ($filter->hasAttribute('class')) { $filters[$name]['class'] = $filter->getAttribute('class'); } $filters[$name]['params'] = $filter->getAgaviParameters($filters[$name]['params']); } } } $data = array(); foreach ($filters as $name => $filter) { if (stripos($name, 'agavi') === 0) { throw new AgaviConfigurationException('Filter names must not start with "agavi".'); } if (!isset($filter['class'])) { throw new AgaviConfigurationException('No class name specified for filter "' . $name . '" in ' . $config); } if ($filter['enabled']) { $rc = new ReflectionClass($filter['class']); $if = 'AgaviI' . ucfirst(strtolower(substr(basename($config), 0, strpos(basename($config), '_filters')))) . 'Filter'; if (!$rc->implementsInterface($if)) { throw new AgaviFactoryException('Filter "' . $name . '" does not implement interface "' . $if . '"'); } $data[] = '$filter = new ' . $filter['class'] . '();'; $data[] = '$filter->initialize($this->context, ' . var_export($filter['params'], true) . ');'; $data[] = '$filters[' . var_export($name, true) . '] = $filter;'; } } return $this->generate($data, $config); }
/** * Initialize this validator. * * @param AgaviContext The Context. * @param array An array of validator parameters. * @param array An array of argument names which should be validated. * @param array An array of error messages. * * @author Dominik del Bondio <*****@*****.**> * @since 0.11.0 */ public function initialize(AgaviContext $context, array $parameters = array(), array $arguments = array(), array $errors = array()) { $this->context = $context; $this->arguments = $arguments; $this->errorMessages = $errors; if (!isset($parameters['depends']) || !is_array($parameters['depends'])) { $parameters['depends'] = !empty($parameters['depends']) ? explode(' ', $parameters['depends']) : array(); } if (!isset($parameters['provides']) || !is_array($parameters['provides'])) { $parameters['provides'] = !empty($parameters['provides']) ? explode(' ', $parameters['provides']) : array(); } if (!isset($parameters['source'])) { $parameters['source'] = AgaviRequestDataHolder::SOURCE_PARAMETERS; } $this->setParameters($parameters); $this->name = $this->getParameter('name', AgaviToolkit::uniqid()); }
/** * Builds an array of php code strings, each of them creating a validator * * @param AgaviXmlConfigDomElement The value holder of this validator. * @param array The code of old validators (we simply * overwrite "old" validators here). * @param string The name of the parent container. * @param string The severity of the parent container. * @param string The method of the parent container. * @param bool Whether parent container is required. * * @return array PHP code blocks that register the validators * * @author Uwe Mesecke <*****@*****.**> * @author Dominik del Bondio <*****@*****.**> * @author David Zülke <*****@*****.**> * @since 0.11.0 */ protected function getValidatorArray($validator, $code, $parent, $stdSeverity, $stdMethod, $stdRequired = true) { if (!isset($this->classMap[$validator->getAttribute('class')])) { $class = $validator->getAttribute('class'); if (!class_exists($class)) { throw new AgaviValidatorException('unknown validator found: ' . $class); } $this->classMap[$class] = array('class' => $class, 'parameters' => array()); } else { $class = $this->classMap[$validator->getAttribute('class')]['class']; } // setting up parameters $parameters = array('severity' => $validator->getAttribute('severity', $stdSeverity), 'required' => $stdRequired); $arguments = array(); $errors = array(); $stdMethod = $validator->getAttribute('method', $stdMethod); $stdSeverity = $parameters['severity']; if ($validator->hasAttribute('name')) { $name = $validator->getAttribute('name'); } else { $name = AgaviToolkit::uniqid(); $validator->setAttribute('name', $name); } $parameters = array_merge($this->classMap[$validator->getAttribute('class')]['parameters'], $parameters); $parameters = array_merge($parameters, $validator->getAttributes()); $parameters = $validator->getAgaviParameters($parameters); foreach ($validator->get('arguments') as $argument) { if ($argument->hasAttribute('name')) { $arguments[$argument->getAttribute('name')] = $argument->getValue(); } else { $arguments[] = $argument->getValue(); } } if ($validator->hasChild('arguments')) { $parameters['base'] = $validator->getChild('arguments')->getAttribute('base'); if (!$arguments) { // no arguments defined, but there is an <arguments /> element, so we're validating an array there // lets add an empty fake argument for validation to work // must be an empty string, not null $arguments[] = ''; } } foreach ($validator->get('errors') as $error) { if ($error->hasAttribute('for')) { $errors[$error->getAttribute('for')] = $error->getValue(); } else { $errors[''] = $error->getValue(); } } if ($validator->hasAttribute('required')) { $stdRequired = $parameters['required'] = AgaviToolkit::literalize($validator->getAttribute('required')); } $methods = array(''); if (trim($stdMethod)) { $methods = preg_split('/[\\s]+/', $stdMethod); } foreach ($methods as $method) { $code[$method][$name] = implode("\n", array(sprintf('${%s} = new %s();', var_export('_validator_' . $name, true), $class), sprintf('${%s}->initialize($this->getContext(), %s, %s, %s);', var_export('_validator_' . $name, true), var_export($parameters, true), var_export($arguments, true), var_export($errors, true)), sprintf('${%s}->addChild(${%s});', var_export($parent, true), var_export('_validator_' . $name, true)))); } // more <validator> or <validators> children $code = $this->processValidatorElements($validator, $code, '_validator_' . $name, $stdSeverity, $stdMethod, $stdRequired); return $code; }
/** * Adds a route to this routing instance. * * @param string A string with embedded regexp. * @param array An array with options. The array can contain following * items: * <ul> * <li>name</li> * <li>stop</li> * <li>output_type</li> * <li>module</li> * <li>action</li> * <li>parameters</li> * <li>ignores</li> * <li>defaults</li> * <li>childs</li> * <li>callbacks</li> * <li>imply</li> * <li>cut</li> * <li>source</li> * </ul> * @param string The name of the parent route (if any). * * @return string The name of the route. * * @author Dominik del Bondio <*****@*****.**> * @since 0.11.0 */ public function addRoute($route, array $options = array(), $parent = null) { // catch the old options from the route which has to be overwritten if (isset($options['name']) && isset($this->routes[$options['name']])) { $defaultOpts = $this->routes[$options['name']]['opt']; // when the parent is set and differs from the parent of the route to be overwritten bail out if ($parent !== null && $defaultOpts['parent'] != $parent) { throw new AgaviException('You are trying to overwrite a route but are not staying in the same hierarchy'); } if ($parent === null) { $parent = $defaultOpts['parent']; } else { $defaultOpts['parent'] = $parent; } } else { $defaultOpts = array('name' => AgaviToolkit::uniqid(), 'stop' => true, 'output_type' => null, 'module' => null, 'action' => null, 'parameters' => array(), 'ignores' => array(), 'defaults' => array(), 'childs' => array(), 'callbacks' => array(), 'imply' => false, 'cut' => null, 'source' => null, 'method' => null, 'constraint' => array(), 'locale' => null, 'pattern_parameters' => array(), 'optional_parameters' => array(), 'parent' => $parent, 'reverseStr' => '', 'nostops' => array(), 'anchor' => self::ANCHOR_NONE); } // retain backwards compatibility to 0.11 if (isset($options['callback'])) { $options['callbacks'] = array(array('class' => $options['callback'], 'parameters' => array())); unset($options['callback']); } if (isset($options['defaults'])) { foreach ($options['defaults'] as $name => &$value) { $val = $pre = $post = null; if (preg_match('#(.*)\\{(.*)\\}(.*)#', $value, $match)) { $pre = $match[1]; $val = $match[2]; $post = $match[3]; } else { $val = $value; } $value = $this->createValue($val)->setPrefix($pre)->setPostfix($post); } } // set the default options + user opts $options = array_merge($defaultOpts, $options); list($regexp, $options['reverseStr'], $routeParams, $options['anchor']) = $this->parseRouteString($route); $params = array(); // transfer the parameters and fill available automatic defaults foreach ($routeParams as $name => $param) { $params[] = $name; if ($param['is_optional']) { $options['optional_parameters'][$name] = true; } if (!isset($options['defaults'][$name]) && ($param['pre'] || $param['val'] || $param['post'])) { unset($param['is_optional']); $options['defaults'][$name] = $this->createValue($param['val'])->setPrefix($param['pre'])->setPostfix($param['post']); } } $options['pattern_parameters'] = $params; // remove all ignore from the parameters in the route foreach ($options['ignores'] as $ignore) { if (($key = array_search($ignore, $params)) !== false) { unset($params[$key]); } } $routeName = $options['name']; // parse all the setting values for dynamic variables // check if 2 nodes with the same name in the same execution tree exist foreach ($this->routes as $name => $route) { // if a route with this route as parent exist check if its really a child of our route if ($route['opt']['parent'] == $routeName && !in_array($name, $options['childs'])) { throw new AgaviException('The route ' . $routeName . ' specifies a child route with the same name'); } } // direct childs/parents with the same name aren't caught by the above check if ($routeName == $parent) { throw new AgaviException('The route ' . $routeName . ' specifies a child route with the same name'); } // if we are a child route, we need add this route as a child to the parent if ($parent !== null) { foreach ($this->routes[$parent]['opt']['childs'] as $name) { if ($name == $routeName) { // we're overwriting a route, so unlike when first adding the route, there are more routes after this that might also be non-stopping, but we obviously don't want those, so we need to bail out at this point break; } $route = $this->routes[$name]; if (!$route['opt']['stop']) { $options['nostops'][] = $name; } } $this->routes[$parent]['opt']['childs'][] = $routeName; } else { foreach ($this->routes as $name => $route) { if ($name == $routeName) { // we're overwriting a route, so unlike when first adding the route, there are more routes after this that might also be non-stopping, but we obviously don't want those, so we need to bail out at this point break; } if (!$route['opt']['stop'] && !$route['opt']['parent']) { $options['nostops'][] = $name; } } } // make sure we have no duplicates in the nostops (can happen when a route is overwritten) $options['nostops'] = array_unique($options['nostops']); $route = array('rxp' => $regexp, 'par' => $params, 'opt' => $options, 'matches' => array()); $this->routes[$routeName] = $route; return $routeName; }
public function testUniqidWithPrefix() { $id1 = AgaviToolkit::uniqid('001'); $id2 = AgaviToolkit::uniqid('001'); $this->assertNotEquals($id1, $id2); $this->assertContains('001', $id1); }
/** * Lock or unlock the Request so request data can(not) be fetched anymore. * * @param string The key to unlock, if the lock should be removed, or * null if the lock should be set. * * @return mixed The key, if a lock was set, or a boolean value indicating * whether or not the unlocking was successful. * * @author David Zülke <*****@*****.**> * @since 0.11.0 */ public final function toggleLock($key = null) { if (!$this->isLocked() && $key === null) { $this->locked = true; return $this->key = AgaviToolkit::uniqid(); } elseif ($this->isLocked()) { if ($this->key === $key) { $this->key = null; return true; } return false; } }