/** * @inheritdoc */ public function upload($selector) { LoggerRegistry::debug('FileModule::upload({selector})', array('selector' => TypeUtilities::describe($selector))); $filename = sprintf('%s/%s', $this->getEngine()->getSiteInfo()->getSiteRoot(), ltrim($selector, '/')); mkdir(dirname($filename), 0777, true); // TODO Implement me }
/** * @inheritdoc */ public function register($key, $decorator) { if ($this->isRegistered($key)) { throw new \LogicException(sprintf('The given decorator key "%s" cannot be registered because it already exists.', $key)); } $this->decorators[$key] = TypeUtilities::buildTypeCheckedObject($decorator, 'decorator', null, '\\Sitegear\\View\\Decorator\\DecoratorInterface'); }
/** * @param \Sitegear\Engine\SitegearEngine $engine * @param string|null $filename */ public function __construct(SitegearEngine $engine, $filename = null) { LoggerRegistry::debug('new SitegearApplicationInfoProvider({engine}, {filename})', array('engine' => TypeUtilities::describe($engine), 'filename' => TypeUtilities::describe($filename))); $this->engine = $engine; $filename = $filename ?: sprintf('%s/%s', dirname($this->getSitegearRoot()), $filename ?: 'composer.json'); $this->data = file_exists($filename) ? json_decode(file_get_contents($filename), true) : array(); }
/** * Display the breadcrumbs navigation helper component. * * @param \Sitegear\View\ViewInterface $view * @param \Symfony\Component\HttpFoundation\Request $request * @param string|null $url Allows breadcrumb to be displayed for a different page; if null, the URL is taken from * the passed-in Request object. * * @return null|boolean */ public function breadcrumbsComponent(ViewInterface $view, Request $request, $url = null) { LoggerRegistry::debug('NavigationModule::breadcrumbsComponent([view], [request], {url})', array('url' => TypeUtilities::describe($url))); $url = trim(!is_null($url) ? $url : $request->getPathInfo(), '/'); if (empty($url) && !$this->config('components.breadcrumbs.show-on-homepage')) { // This is the home page, and we are configured not to show the breadcrumbs here. return false; } $data = $this->getData(MountableModuleInterface::NAVIGATION_DATA_MODE_EXPANDED); $path = $this->getNavigationPath($url, $data); if (is_null($path)) { // The URL cannot be found in the navigation, don't show the breadcrumb because there is nothing to show. return false; } $trail = array(); $breadcrumbKeys = array('url' => true, 'label' => true); if (strlen($url) > 0 && $this->config('components.breadcrumbs.prepend-homepage')) { $trail[] = array_intersect_key($this->getNavigationItem('', $data), $breadcrumbKeys); } foreach ($path as $pathItem) { $trail[] = array_intersect_key($data[$pathItem], $breadcrumbKeys); $data = isset($data[$pathItem]['children']) ? $data[$pathItem]['children'] : array(); } $view['trail'] = $trail; return null; }
/** * @inheritdoc */ public function load($args) { LoggerRegistry::debug('JsonFileLoader::load({args})', array('args' => TypeUtilities::describe($args))); if (!$this->supports($args)) { throw new \InvalidArgumentException(sprintf('JsonFileLoader attempting to load unsupported config file "%s".', $args)); } return json_decode(file_get_contents($args), true); }
/** * @inheritdoc */ public function load($args) { LoggerRegistry::debug('PhpFileLoader::load({args})', array('args' => TypeUtilities::describe($args))); if (!$this->supports($args)) { throw new \InvalidArgumentException(sprintf('PhpFileLoader attempting to load unsupported config file "%s".', $args)); } /** @noinspection PhpIncludeInspection */ return require $args; }
/** * @inheritdoc */ public function deleteUser($email) { LoggerRegistry::debug('JsonFileUserStorage::deleteUser({email})', array('email' => TypeUtilities::describe($email))); if (!array_key_exists($email, $this->users)) { throw new \InvalidArgumentException(sprintf('JsonFileUserStorage cannot delete user with email address "%s", that email address is not registered.', $email)); } unset($this->users[$email]); $this->store(); }
/** * @inheritdoc */ public function login($email, array $credentials) { LoggerRegistry::debug('SitegearUserManager::login({email}, [credentials])', array(TypeUtilities::describe($email))); $result = false; if (!is_null($this->getAuthenticator()->checkCredentials($email, $credentials))) { $this->session->set(self::SESSION_KEY_USER_EMAIL, $email); $this->session->remove(self::SESSION_KEY_USER_IS_GUEST); $result = true; } return $result; }
/** * @inheritdoc */ public function render($path, ViewInterface $view) { LoggerRegistry::debug('RendererRegistry::render({path}, [view])', array('path' => TypeUtilities::describe($path))); $result = null; foreach ($this->registry as $renderer) { /** @var \Sitegear\View\Renderer\RendererInterface $renderer */ if (is_null($result) && $renderer->supports($path)) { $result = $renderer->render($path, $view); } } return $result; }
/** * Render a string containing class names that can be assigned to a high-level page element (e.g. <html> or <body>) * to identify sections and pages to CSS rules based on URL. The home page is given the special class given by * the $indexName argument. * * @param \Sitegear\View\ViewInterface $view * @param \Symfony\Component\HttpFoundation\Request $request * @param null|int $maxElements Maximum number of path levels to include in the result, starting from the start. * For example if the relative URL is "/foo/bar/baz" then by default the page this method would return * "foo foo-bar foo-bar-baz", but if $maxDepth is 2, then it will return "foo foo-bar". */ public function bodyClassesComponent(ViewInterface $view, Request $request, $maxElements = null) { LoggerRegistry::debug('ContentModule::bodyClassesComponent([view], [request], {maxElements})', array('maxElements' => TypeUtilities::describe($maxElements))); $url = ltrim($request->getPathInfo(), '/'); $path = !empty($url) ? explode('/', $url) : array($this->config('body-classes.index')); $maxElements = $maxElements ?: sizeof($path); $classNames = array(); for ($i = 0; $i < $maxElements; $i++) { $classNames[] = implode('-', array_slice($path, 0, $i + 1)); } $view['class-names'] = $classNames; }
/** * @inheritdoc */ public function render($path, ViewInterface $view) { LoggerRegistry::debug('PhpRenderer::render({path}, [view])', array('path' => TypeUtilities::describe($path))); $renderPath = null; foreach ($this->getExtensions() as $extension) { if (is_null($renderPath) && file_exists($path . $extension)) { $renderPath = $path . $extension; } } if (is_null($renderPath)) { throw new \InvalidArgumentException(sprintf('The path "%s" cannot be rendered by PhpRenderer', $path)); } return PhpRendererEvaluationSandbox::render($renderPath, $view); }
/** * @inheritdoc */ public function checkCredentials($email, array $credentials) { LoggerRegistry::debug('PlainTextPasswordAuthenticator::checkCredentials({email}, [credentials])', array('email' => TypeUtilities::describe($email))); if (!isset($credentials['password'])) { throw new \InvalidArgumentException('PlainTextPasswordAuthenticator expects "password" credential key, insufficient credentials supplied.'); } $result = null; if ($this->getStorage()->hasUser($email)) { $data = $this->getStorage()->getData($email); if (isset($data['password']) && $data['password'] === $credentials['password']) { $result = $email; } } return $result; }
/** * @inheritdoc */ public function guess($path) { LoggerRegistry::debug('ExtensionMimeTypeGuesser::guess({path})', array('path' => TypeUtilities::describe($path))); if (!is_file($path)) { throw new FileNotFoundException($path); } if (!is_readable($path)) { throw new AccessDeniedException($path); } if (empty($this->data)) { throw new \LogicException('The data file could not be loaded or contains no data'); } $extension = pathinfo($path, PATHINFO_EXTENSION); return is_string($extension) && isset($this->data[$extension]) ? $this->data[$extension] : null; }
/** * @param string|null $environment */ public function __construct($environment = null) { LoggerRegistry::debug('new SitegearEnvironmentInfoProvider({environment})', array('environment' => TypeUtilities::describe($environment))); $this->environment = $environment; }
/** * Normalise the given configuration into an array, or throw an exception if it cannot be normalised. * * @param array|string|\ArrayObject|\Sitegear\Config\Configuration $config Data to normalise. * * @return array Normalised data. * * @throws \InvalidArgumentException If the argument is of unknown type. */ private function normalise($config) { if (is_string($config)) { $config = $this->loadFile($config); } elseif ($config instanceof \ArrayObject) { $config = $config->getArrayCopy(); } elseif ($config instanceof Configuration) { $config = $config->all(); } elseif (!is_array($config)) { throw new \InvalidArgumentException(sprintf('Unhandled configuration type cannot be normalised [%s]', TypeUtilities::describe($config))); } return $config; }
/** * @inheritdoc */ public function applyViewDefaults(ViewInterface $view, $viewType, $viewName) { LoggerRegistry::debug('{class}::applyViewDefaults([view], {viewType}, {viewName})', array('class' => (new \ReflectionClass($this))->getShortName(), 'viewType' => TypeUtilities::describe($viewType), 'viewName' => TypeUtilities::describe($viewName))); $this->applyConfigToView('common', $view); $this->applyConfigToView(sprintf('%s.%s', NameUtilities::convertToDashedLower($viewType), NameUtilities::convertToDashedLower($viewName)), $view); }
/** * @inheritdoc */ public function render() { LoggerRegistry::debug('View::render()'); $content = null; $this->rendering = true; if ($this->getTargetCount() === 2) { $request = $this->getRequest(); // The arguments to the module definition are decorators, set them now call_user_func_array(array($this, 'activateDecorators'), $this->getTargetArguments(self::TARGET_LEVEL_MODULE)); // Create a relevant context $context = $this->getEngine()->getViewFactory()->buildViewContext($this, $this->getRequest()); // Check for and execute a target controller $targetController = $context->getTargetController($this, $request); $targetControllerResult = null; if (!is_null($targetController) && is_callable($targetController)) { $targetControllerResult = TypeUtilities::invokeCallable($targetController, null, array($this, $request), $this->getTargetArguments(self::TARGET_LEVEL_METHOD) ?: array()); } // A result of false means don't render anything. if ($targetControllerResult !== false) { // Use the context to render the result $content = $context->render($this->getEngine()->getViewFactory()->getRendererRegistry(), $targetControllerResult) ?: ''; // Decorate using active decorators foreach ($this->getActiveDecorators() as $active) { $decorator = $this->getEngine()->getViewFactory()->getDecoratorRegistry()->getDecorator($active['name']); $content = TypeUtilities::invokeCallable(array($decorator, 'decorate'), array($content), array($this, $request), $active['arguments']); } } } else { // Incorrect number of targets; exactly 2 expected $targets = $this->getTargetCount() === 1 ? 'target' : 'targets'; throw new \LogicException(sprintf('Error in view script; exactly 2 targets expected ("$view->module()->method()"); %d %s encountered', $this->getTargetCount(), $targets)); } // Ensure we are returning a string value $this->rendering = false; return $content ?: ''; }
/** * The location search form. * * @param ViewInterface $view * @param string|null $query Previous query, to populate the value. * @param string|null $radius Previous radius selection, to populate the selected option. */ public function searchFormComponent(ViewInterface $view, $query = null, $radius = null) { LoggerRegistry::debug('LocationsModule::searchFormComponent([view], {query}, {radius})', array('query' => TypeUtilities::describe($query), 'radius' => TypeUtilities::describe($radius))); $view['action-url'] = $this->getRouteUrl('search'); if (!is_null($query)) { $view['query'] = $query; } if (!is_null($radius)) { $view['radius'] = $radius; } }
/** * @inheritdoc */ public function checkCredentials($email, array $credentials) { LoggerRegistry::debug('SaltedPasswordAuthenticator::checkCredentials({email}, [credentials])', array('email' => TypeUtilities::describe($email))); // TODO Implement me throw new \InvalidArgumentException('Not implemented'); }
/** * @inheritdoc */ public function save($selector, $value) { LoggerRegistry::debug('DoctrineModule::save({selector}, {value})', array('selector' => TypeUtilities::describe($selector), 'value' => TypeUtilities::describe($value))); $selector = $this->parseSelector($selector); $query = $this->getEntityManager()->createQuery(sprintf('update %s%s item set item.%s = :value where item.%s = :match', $selector['entity-alias'], $selector['entity-name'], $selector['value-field-name'], $selector['match-field-name'])); $query->setParameter('value', $value); $query->setParameter('match', $selector['match-field-value']); return $query->execute() !== false; }
/** * Show a componentised view of the latest headlines. * * @param \Sitegear\View\ViewInterface $view * @param int|null $itemLimit Number of items to display, or null to use the value from the configuration. * @param int|null $excerptLength Number of characters of the news item text to display in each preview, or null to * use the value from the configuration. * @param string|null $readMore Text to use for "read more" links */ public function latestHeadlinesComponent(ViewInterface $view, $itemLimit = null, $excerptLength = null, $readMore = null) { LoggerRegistry::debug('NewsModule::latestHeadlinesComponent([view], %d, %d, %s)', array('itemLimit' => TypeUtilities::describe($itemLimit), 'excerptLength' => TypeUtilities::describe($excerptLength), 'readMore' => TypeUtilities::describe($readMore))); $itemLimit = intval(!is_null($itemLimit) ? $itemLimit : $this->config('component.latest-headlines.item-limit')); $view['items'] = $this->getRepository('Item')->findLatestItems($itemLimit); $view['date-format'] = $this->config('component.latest-headlines.date-format'); $view['excerpt-length'] = !is_null($excerptLength) ? $excerptLength : $this->config('component.latest-headlines.excerpt-length'); if ($readMore) { $view['read-more'] = $readMore; } }
/** * Apply all children of the given config key from this module, as values stored in the given view. This is a * handy shortcut for making all the top-level configuration items available to the view without requiring an * additional parent key. * * @param string $configKey * @param \Sitegear\View\ViewInterface $view */ protected function applyConfigToView($configKey, ViewInterface $view) { LoggerRegistry::debug('AbstractConfigurableModule::applyConfigToView({configKey}, [view])', array('configKey' => TypeUtilities::describe($configKey))); if (is_array($config = $this->config($configKey))) { foreach ($config as $key => $value) { $view[$key] = $value; } } }
/** * Remove all current values, error messages and progress from the specified form. * * @param string $formKey */ public function resetForm($formKey) { LoggerRegistry::debug('FormRegistry::resetForm({formKey})', array('formKey' => TypeUtilities::describe($formKey))); $this->clearProgress($formKey); $this->clearValues($formKey); $this->clearErrors($formKey); }
/** * @expectedException \ReflectionException */ public function testParametersInvalidType() { TypeUtilities::getParameters(42); }
/** * Instantiate a module instance for this engine. * * @param string $name Module to load. * * @return \Sitegear\Module\ModuleInterface * * @throws \InvalidArgumentException If the named module does not exist. * @throws \DomainException If the named module does not implement ModuleInterface. */ protected function createModule($name) { LoggerRegistry::debug('AbstractEngine::createModule({name})', array('name' => TypeUtilities::describe($name))); try { return TypeUtilities::buildTypeCheckedObject($this->getModuleClassName($name) ?: '', 'module', null, '\\Sitegear\\Module\\ModuleInterface', array($this)); } catch (\DomainException $e) { throw new \InvalidArgumentException(sprintf('AbstractEngine cannot create module "%s" because it does not exist', $name), 0, $e); } }
/** * Create a RendererFactoryInterface implementation as determined by configuration. * * @return RendererFactoryInterface */ protected function createRendererFactory() { $factoryClassName = $this->config('form-renderer-factory.class-name'); $factoryConstructorArguments = $this->config('form-renderer-factory.constructor-arguments'); return TypeUtilities::buildTypeCheckedObject($factoryClassName, 'form renderer factory', null, array('\\Sitegear\\Form\\Renderer\\Factory\\RendererFactoryInterface'), $factoryConstructorArguments); }
/** * @inheritdoc */ public function activateDecorators() { foreach (func_get_args() as $arg) { if (is_array($arg) && ArrayUtilities::isIndexed($arg)) { // An indexed array, recurse with each element of the array as a separate argument. call_user_func_array(array($this, 'activateDecorators'), $arg); } elseif (is_array($arg)) { // An associative array, ensure it has an 'arguments' key. $this->activeDecorators[] = array_merge(array('arguments' => array()), $arg); } elseif (is_string($arg)) { // A string, use the parseFunctionCall() utility method. $this->activeDecorators[] = PhpSourceUtilities::parseFunctionCall($arg); } else { // Unhandled type. throw new \InvalidArgumentException(sprintf('Cannot use [%s] as decorator specification', TypeUtilities::describe($arg))); } } return $this; }
/** * @inheritdoc */ public function mount($mountedUrl = null, RequestContext $context) { LoggerRegistry::debug('{class}::mount({mountedUrl})', array('class' => (new \ReflectionClass($this))->getShortName(), 'mountedUrl' => TypeUtilities::describe($mountedUrl))); $this->mountedUrl = trim($mountedUrl, '/'); $this->routes = $this->buildRoutes(); }
/** * Retrieve a textual description of the given Exception, or FlattenException (as passed by Symfony HttpKernel). * * @param \Symfony\Component\HttpKernel\Exception\FlattenException|\Exception $exception * @param string|null $adminName * @param string|null $adminEmail * @param string $heading * @param null $stackTraceHeading * * @return string */ public static function exception($exception, $adminName = null, $adminEmail = null, $heading = null, $stackTraceHeading = null) { // Generate the error message. ob_start(); echo $heading ?: '<h1>Error</h1>', PHP_EOL; echo '<p><strong>', $exception->getMessage(), '</strong></p>', PHP_EOL; echo '<p>Error occurred at ', date('Y-m-d H:i:s'), ', code: ', $exception->getCode(), ', ', TypeUtilities::describe($exception), '</p>', PHP_EOL; echo '<p>Please contact your system administrator for assistance.</p>' . PHP_EOL; if (!empty($adminName) || !empty($adminEmail)) { echo '<ul>', PHP_EOL; if (!empty($adminName)) { echo '<li>Name: ', $adminName, '</li>', PHP_EOL; } if (!empty($adminEmail)) { echo '<li>Email Address: ', $adminEmail, '</li>', PHP_EOL; } echo '</ul>', PHP_EOL; } echo '<hr/>', PHP_EOL; echo $stackTraceHeading ?: '<h2>Stack Trace</h2>', PHP_EOL; echo '<ol>', PHP_EOL; foreach (array_reverse($exception->getTrace()) as $traceItem) { $file = isset($traceItem['file']) ? $traceItem['file'] : ''; $line = isset($traceItem['line']) ? sprintf('(%s)', $traceItem['line']) : ''; $function = isset($traceItem['function']) ? isset($traceItem['class']) && !empty($traceItem['class']) ? sprintf('%s->%s', $traceItem['class'], $traceItem['function']) : $traceItem['function'] : ''; echo '<li>', $file, $line, ': ', $function, '()</li>', PHP_EOL; } echo '</ol>'; return ob_get_clean(); }
/** * Create a single condition for a single processor. * * @param array $conditionDefinition * * @return ConditionInterface * * @throws \InvalidArgumentException */ public function buildCondition(array $conditionDefinition) { $conditionClass = TypeUtilities::firstExistingClass($this->getFormsModule()->registry()->getConditionNamespaces(), NameUtilities::convertToStudlyCaps($conditionDefinition['condition']) . 'Condition'); if (is_null($conditionClass)) { throw new \InvalidArgumentException(sprintf('FormBuilder could not find a condition class for the name "%s"', $conditionDefinition['condition'])); } return $conditionClass->newInstance($conditionDefinition['options']); }