public function testResolution() { $r = new NamespacedItemResolver(); $this->assertEquals(array('foo', 'bar', 'baz'), $r->parseKey('foo::bar.baz')); $this->assertEquals(array('foo', 'bar', null), $r->parseKey('foo::bar')); $this->assertEquals(array(null, 'bar', 'baz'), $r->parseKey('bar.baz')); $this->assertEquals(array(null, 'bar', null), $r->parseKey('bar')); }
/** * Get the fullly qualified location of the view. * * @param string $name * @return string * @throws \InvalidArgumentException */ public function find($name) { $name = str_replace('.', '/', $name); // If the theme bag instance has not been set, we will just let // the default handler take control of loading the views. if (!isset($this->themeBag)) { return parent::find($name); } // Parse the name $resolver = new NamespacedItemResolver(); list($section, $view) = $resolver->parseKey($name); try { // If we have a package listed, let's just check firstly // if it's actually referring to a hard-coded namespace. // Namespaces override packages in Themes, as they do in views. if (isset($section)) { if (isset($this->hints[$section])) { $sectionType = 'namespaces'; $paths = $this->themeBag->getCascadedNamespaceViewPaths($section); } else { $sectionType = 'packages'; $paths = $this->themeBag->getCascadedPackageViewPaths($section); } $view = $this->findInPaths($view, $paths); } else { $paths = $this->themeBag->getCascadedViewPaths(); $view = $this->findInPaths($view, $paths); } } catch (InvalidArgumentException $e) { // Let's fallback to the normal view system. try { return parent::find($name); } catch (InvalidArgumentException $e) { // Grab the relevent themes from the theme bag $active = $this->themeBag->getActive(); $fallback = $this->themeBag->getFallback(); // If we had a section, throw an Exception that's more aimed at // debugging why the package does not exist. if (isset($section)) { $message = sprintf('Theme [%s] view [%s] could not be found in theme [%s]', $sectionType, $name, $active->getSlug()); } else { $message = sprintf('Theme view [%s] could not be found in theme [%s]', $name, $active->getSlug()); } $message .= $active->getParentSlug() ? ' or any of it\'s parent themes' : ''; $message .= ($fallback and $fallback != $active) ? " or the fallback theme [{$fallback->getSlug()}]." : '.'; $message .= ' The standard view finder has also failed to find the view.'; throw new InvalidArgumentException($message); } } return $view; }
/** * Parse a key into namespace, group, and item. * * @param string $key * @return array */ public function parseKey($key) { $segments = parent::parseKey($key); if (is_null($segments[0])) { $segments[0] = '*'; } return $segments; }
/** * Parse the segments of a package namespace. * * @param string $key * @param string $namespace * @param string $item * @return array */ protected function parsePackageSegments($key, $namespace, $item) { $itemSegments = explode('.', $item); // If the configuration file doesn't exist for the given package group we can // assume that we should implicitly use the config file matching the name // of the namespace. Generally packages should use one type or another. if (!$this->loader->exists($itemSegments[0], $namespace)) { return array($namespace, 'config', $item); } return parent::parseNamespacedSegments($key); }
/** * Loads the Theme Info JSON file for the theme. * * @return void */ protected function loadInfoFile() { $file = "{$this->path}/theme.json"; $json = $this->themeBag->getFilesystem()->get($file); $data = json_decode($json); if (is_null($data) and !is_null($json)) { $this->validateSyntax($json, $file); } $this->validateSchema($data, $file); $data = json_decode($json, true); $resolver = new NamespacedItemResolver(); list($this->area, $this->key) = $resolver->parseKey($data['slug']); unset($data['slug']); $this->setAttributes($data); }
/** * Locates a theme using the given slug in the * registered paths and registers it. * * @param string $slug * @return \Cartalyst\Themes\ThemeInterface * @throws \RuntimeException */ public function locateAndRegister($slug) { $resolver = new NamespacedItemResolver(); list($area, $key) = $resolver->parseKey($slug); foreach ($this->paths as $path) { $themePath = $this->getThemePath($path, $key, $area); if ($this->filesystem->isDirectory($themePath)) { $theme = $this->createTheme($themePath); return $this->register($theme); } } throw new RuntimeException("Could not resolve theme [{$slug}]."); }