/** * Compiles URL addressing current script of current application. * * @param array|false $parameters set of parameters to pass in query, false * to drop all current parameters (e.g. on creating GET form), * provide special parameter '*' in array to start fresh set of parameters * @param mixed $selector first of multiple optional selectors to include * @return string URL of addressed script including optional parameters */ public function selfURL($parameters = array(), $selector = null) { $selectors = func_get_args(); $selectors = array_slice($selectors, 1); if (!count($selectors)) { $selectors = application::current()->selectors; } /* * merge current script's input parameters with provided one */ if ($parameters === false) { $parameters = array(); } else { // find all non-persistent input parameters of current script $currentVolatileParameters = array(); if (!array_key_exists('*', $parameters)) { $get = input::source(input::SOURCE_ACTUAL_GET); foreach ($get->listNames() as $name) { if (data::isKeyword($name) && !input::isPersistent($name)) { $currentVolatileParameters[$name] = $get->getValue($name); } } } unset($parameters['*']); // merge volatile input with given parameters, but drop all those // finally set NULL (to support removal per $parameters) $parameters = array_filter(array_merge($currentVolatileParameters, $parameters), function ($item) { return $item !== null; }); } /* * utilize scriptURL() for referring to current script */ array_unshift($selectors, $parameters); array_unshift($selectors, $this->script); return call_user_func_array(array(&$this, 'scriptURL'), $selectors); }
/** * @param integer $itemCount number of records to be paged * @param boolean $isVolatile if true, offset/items per page must be always found in actual input * if false, both are retrieved from cache unless contained in actual input * if null, offset is expected in actual input while size is not * @param string $offsetName name of input selecting offset * @param string $sizeName name of input selecting count of items per page */ public function __construct($itemCount, $isVolatile = null, $offsetName = 'skip', $sizeName = 'count') { if (!ctype_digit(trim($itemCount))) { throw new \InvalidArgumentException('invalid item count'); } if (!data::isKeyword($offsetName)) { throw new \InvalidArgumentException('invalid offset selector'); } if (!data::isKeyword($sizeName)) { throw new \InvalidArgumentException('invalid size selector'); } $this->offsetName = $offsetName; $this->sizeName = $sizeName; $this->itemCount = $itemCount; $this->isVolatile = is_null($isVolatile) ? null : !!$isVolatile; }
/** * Iterates over given or configured list of user database providers invoking * provided callback on every provider until first callback is returning * properly without throwing exception. * * @param callable $callback callback to invoke per iterated user database provider * @param array|string $explicitSource set of provider names to iterate or name of first provider in a sequence to test * @return mixed|null result return from callback, null if all callbacks threw exception * @throws \RuntimeException on missing valid set of providers to iterate * @throws unauthorized_exception if callback is throwing in other case than "user isn't found" * @throws \InvalidArgumentException on missing callback */ public static final function findProvider($callback, $explicitSource = null) { if (!is_callable($callback)) { throw new \InvalidArgumentException('invalid callback on finding user provider'); } // get list of sources to look up for requested user if (is_array($explicitSource)) { $sources = $explicitSource; } else { $sources = func_get_args(); array_shift($sources); } if (!count($sources)) { $sources = config::getList('user.sources.enabled'); } if (!count($sources)) { throw new \RuntimeException('missing/invalid user sources configuration'); } // traverse list of sources ... foreach ($sources as $source) { if (trim($source) !== '' && ctype_alnum($source)) { // read its configuration $definition = config::get('user.sources.setup.' . $source); if (is_array($definition)) { // read name of class for managing user source from configuration $class = array_key_exists('class', $definition) ? data::isKeyword($definition['class']) : null; if (!$class) { $class = data::isKeyword($definition['type'] . '_user'); } if (txf::import($class)) { try { // create instance of managing class $factory = new \ReflectionClass($class); $user = $factory->newInstance(); if ($user instanceof self) { $user->configure($definition); return call_user_func($callback, $user); } } catch (unauthorized_exception $e) { if (!$e->isUserNotFound()) { throw $e; } } catch (\Exception $e) { log::warning('failed to search user source: ' . $e); } } } } } return null; }
/** * Reads named input variable. * * Support for $default requires related source manager to be included in * queue of enabled input sources. * * @param string $name name of value to read, must be keyword * @param mixed $default value to return by default * @param boolean $checkPersistents if true, check persistent sources as well * @param mixed $format format definition used to filter values * @param boolean $optional set true to suppress exception on missing valid input from any enabled source * @return mixed|null available input value, null on missing any */ protected final function readValue($name, $default = null, $checkPersistents = true, $format = null, $optional = false) { $name = data::isKeyword($name); if (!$name) { throw new \InvalidArgumentException('invalid input variable name'); } // normalize format once to be used in normalized form $format = self::normalizeFormat($format); foreach ($this->sources as $source) { if ($source['enabled']) { if ($checkPersistents || $source['volatile']) { if ($source['manager']->hasValue($name, $default)) { // current source provides value --> validate $value = $source['manager']->getValue($name, $default); if (is_array($value)) { // got an array // --> its elements are validated separately foreach ($value as $key => $element) { if ($this->valueIsValid($element, $format)) { $value[$key] = $this->convertValue($element, $format); } else { unset($value[$key]); } } if (count($value)) { // (real subset of) array is valid -> return that return $checkPersistents ? $this->persistValue($name, $value) : $value; } } else { if ($this->valueIsValid($value, $format)) { // value is valid -> return if ($checkPersistents) { $this->persistValue($name, $value); } return $this->convertValue($value, $format); } } } } } } // throw exception if missing any input isn't considered valid input // according to provided format definition if (!$optional && !$this->valueIsValid(null, $format)) { throw new \RuntimeException('invalid input'); } return null; }