Example #1
0
 /**
  * returns rendered content
  *
  * @param string $content input content
  * @param string $data field to retrieve from configuration
  * @param array $options an array with additional options
  * @return string content as given
  * @filter
  */
 public function get($content, $data = null, array $options = array())
 {
     $defaults = array('default' => array(), 'flat' => false);
     $options += $defaults;
     $params = compact('content', 'data', 'options');
     return $this->_filter(__METHOD__, $params, function ($self, $params) {
         extract($params);
         try {
             $config = NeonFormatter::decode($content);
         } catch (NeonException $e) {
             return $options['default'];
         } catch (Exception $e) {
             return $options['default'];
         }
         if (!empty($data) && is_scalar($data)) {
             if (array_key_exists($data, (array) $config)) {
                 return $config[$data];
             }
         }
         if ($data) {
             $data = '/' . str_replace('.', '/', $data) . '/.';
             $result = current(Set::extract((array) $config, $data));
             return !empty($result) ? $result : null;
         }
         return $options['flat'] ? Set::flatten($config) : $config;
     });
 }
Example #2
0
 /**
  * Renders a group of navigations defined as Configurations.
  *
  * A Configuration with a type ´navigation´ must follow this naming conventions:
  * nav.{name of navigation group}.{name of navigation}
  * e.g. nav.sidebar.main, nav.sidebar.mailplugin, ...
  *
  * $this->Navigation->group('sidebar') will render all Configurations with a slug starting with
  * ´nav.sidebar.´ that are of type `navigation`. In addition it renders all navigations based
  * on files from all loaded libraries, that have files at {:library}/data/nav/{:name}.foo.neon
  *
  * @param string $name part of a navigation slug
  * @param array $options additional options:
  *        - `pattern`: pattern of slug to search configurations of, defaults to `nav.{:name}.`
  *        - `seperator`: glue-character to implode all navigations together with
  *        - `db`: set to false to avoid database-based rendering of navigations (configurations)
  *        - `files`: set to false to avoid file-based rendering of navigations
  * @return string all navigations
  */
 public function group($name, array $options = array())
 {
     $defaults = array('pattern' => 'nav.{:name}.', 'seperator' => "\n", 'files' => true, 'db' => true);
     $options += $defaults;
     $search = String::insert($options['pattern'], compact('name'));
     $result = array();
     if ($options['db']) {
         $configs = Configurations::search($search);
         if ($configs) {
             foreach ($configs as $nav) {
                 $result[] = $this->render($nav);
             }
         }
     }
     if (!$options['files']) {
         return implode($options['seperator'], $result);
     }
     $conditions = array('slug' => $name);
     $files = Neon::find(array('source' => 'nav', 'key' => 'slug'), 'all', compact('conditions'));
     if ($files) {
         foreach ($files as $file => $nav) {
             $caption = Inflector::humanize(str_replace(sprintf('%s.', $name), '', $file));
             $result[] = $this->render($nav, compact('caption'));
         }
     }
     return implode($options['seperator'], $result);
 }
Example #3
0
 /**
  * allows for data-retrieval of entities via file-based access
  *
  * In case you want to provide default file-data without inserting them into the database, you
  * would need to create files based on model-name in a path like that
  * `{:library}/data/{:class}/{:id}.neon` or `{:library}/data/{:class}/{:slug}.neon`
  *
  * In that case, an entity requested by id or slug would be loaded from file instead. Please pay
  * attention, though that not all options are implemented, such as extended conditions, order,
  * limit or page. This is meant to enable basic loading of id- or slug-based entity lookups.
  *
  * @see radium\util\Neon::file()
  * @see radium\util\File::contents()
  * @param string $type The find type, which is looked up in `Model::$_finders`. By default it
  *        accepts `all`, `first`, `list` and `count`,
  * @param array $options Options for the query. By default, accepts:
  *        - `conditions`: The conditional query elements, e.g.
  *                 `'conditions' => array('published' => true)`
  *        - `fields`: The fields that should be retrieved. When set to `null`, defaults to
  *             all fields.
  *        - `order`: The order in which the data will be returned, e.g. `'order' => 'ASC'`.
  *        - `limit`: The maximum number of records to return.
  *        - `page`: For pagination of data.
  * @return mixed
  */
 public static function find($type, array $options = array())
 {
     $result = parent::find($type, $options);
     $neon = static::meta('neon');
     if ($neon && (!$result || !count($result))) {
         return Neon::find(get_called_class(), $type, $options);
     }
     return $result;
 }
Example #4
0
 /**
  * Loads entities and records from file-based structure
  *
  * Trys to implement a similar method to load datasets not from database, but rather from
  * a file that holds all relevant model data and is laid into the filesystem of each library.
  * This allows for easy default-data to be loaded without using a database as backend.
  *
  * Put your files into `{:library}\data\{:class}\{:name}.neon` and let the content be found
  * with loading just the id or slug of that file.
  *
  * Attention: This feature is considered experimental and should be used with care. It might
  *            not work as expected. Also, not all features are implemented.
  *
  * If nothing is found, it just returns null or an empty array to ensure a falsey value.
  *
  * @param string|array $model fully namespaced model class, e.g. `radium\models\Contents`
  *                     can also be an array, in which case `key` and `source` must be given
  *                     according to the internal structure of `Model::meta()`.
  * @param string $type The find type, which is looked up in `Model::$_finders`. By default it
  *        accepts `all`, `first`, `list` and `count`. Later two are not implement, yet.
  * @param array $options Options for the query. By default, accepts:
  *        - `conditions`: The conditional query elements, e.g.
  *                 `'conditions' => array('published' => true)`
  *        - `fields`: The fields that should be retrieved. When set to `null`, defaults to
  *             all fields.
  *        - `order`: The order in which the data will be returned, e.g. `'order' => 'ASC'`.
  *        - `limit`: The maximum number of records to return.
  *        - `page`: For pagination of data.
  * @return mixed returns null or an empty array if nothing is found
  *               If `$type` is `first` returns null or the correct entity with given data
  *               If `$type` is `all` returns null or a DocumentSet object with loaded entities
  */
 public static function find($model, $type, array $options = array())
 {
     $defaults = array('conditions' => null, 'fields' => null);
     $options += $defaults;
     $paths = self::$_paths;
     Libraries::paths($paths);
     $meta = is_array($model) ? $model : $model::meta();
     $locate = sprintf('neons.%s', $meta['source']);
     $data = Libraries::locate($locate, null, array('namespaces' => true));
     $files = new Collection(compact('data'));
     unset($data);
     $files->each(function ($file) {
         return str_replace('\\', '/', $file) . 'neon';
     });
     extract($options);
     if (isset($conditions['slug'])) {
         $field = 'slug';
     }
     if (isset($conditions[$meta['key']])) {
         $field = $meta['key'];
     }
     if (!isset($field)) {
         $field = 'all';
         // var_dump($field);
         // return array();
     }
     $value = $conditions[$field];
     switch (true) {
         case is_string($value):
             $pattern = sprintf('/%s/', $value);
             break;
         case isset($value['like']):
             $pattern = $value['like'];
             break;
     }
     if (isset($pattern)) {
         $filter = function ($file) use($pattern) {
             return (bool) preg_match($pattern, $file);
         };
     }
     if (isset($filter)) {
         $files = $files->find($filter);
     }
     if (isset($order)) {
         // TODO: add sort
     }
     if ($type == 'count') {
         return count($files);
     }
     if ($type == 'list') {
         // TODO: implement me
     }
     if ($type == 'first' && count($files)) {
         $data = self::file($files->first());
         $data[$field] = $value;
         if ($model === 'radium\\models\\Configurations') {
             $data['value'] = Neon::encode($data['value']);
         }
         return $model::create($data);
     }
     // we found one (!) file with name 'all.neon', this is the entire set
     if ($type == 'all' && count($files) == 1 && substr($files->first(), -strlen('all.neon')) === 'all.neon') {
         $rows = self::file($files->first());
         $data = array();
         foreach ($rows as $row) {
             $data[] = $model::create($row);
         }
         if (is_array($model)) {
             return new Collection(compact('data'));
         }
         $model = $meta['class'];
         return new DocumentSet(compact('data', 'model'));
     }
     if ($type == 'all' && count($files)) {
         $data = array();
         foreach ($files as $file) {
             $current = self::file($file);
             if (is_array($model)) {
                 $filename = File::name($file);
                 $data[$filename] = $current;
                 continue;
             }
             if ($model === 'radium\\models\\Configurations') {
                 $current['value'] = Neon::encode($current['value']);
             }
             $data[] = $model::create($current);
         }
         if (is_array($model)) {
             return new Collection(compact('data'));
         }
         $model = $meta['class'];
         return new DocumentSet(compact('data', 'model'));
     }
     return false;
 }