Exemplo n.º 1
0
 /**
  * Lazy bind a relation.
  *
  * @param  string    $name   The name of the relation (i.e. field name where it will be binded).
  * @param  array     $config The configuration that should be specified in the relationship.
  *                           See the `chaos\Relationship` class for more information.
  * @return boolean
  * @throws Exception         Throws a `ChaosException` if the config has no type option defined.
  */
 public function bind($name, $config = [])
 {
     $relationship = $this->_classes['relationship'];
     $config += ['type' => 'entity', 'from' => $this->model(), 'to' => null, 'link' => $relationship::LINK_KEY];
     $config['embedded'] = strncmp($config['link'], 'key', 3) !== 0;
     if (!isset($config['relation']) || !isset($this->_classes[$config['relation']])) {
         throw new ChaosException("Unexisting binding relation `{$config['relation']}` for `'{$name}'`.");
     }
     if (!$config['from']) {
         throw new ChaosException("Binding requires `'from'` option to be set.");
     }
     if (!$config['to']) {
         if ($config['relation'] !== 'hasManyThrough') {
             throw new ChaosException("Binding requires `'to'` option to be set.");
         }
     } elseif (($pos = strrpos('\\', $config['to'])) !== false) {
         $from = $config['from'];
         $config['to'] = substr($from, 0, $pos + 1) . $config['to'];
     }
     $config['array'] = !!preg_match('~Many~', $config['relation']);
     $config['type'] = $config['array'] ? 'set' : $config['type'];
     if ($config['relation'] === 'hasManyThrough') {
         if (!isset($config['through'])) {
             throw new ChaosException("Missing `'through'` relation name.");
         }
         $config += ['using' => $this->_conventions->apply('usingName', $name)];
         $config['type'] = 'through';
     }
     $this->_relations[$name] = $config;
     $this->_relationships[$name] = null;
     return true;
 }
Exemplo n.º 2
0
 /**
  * Constructs an object that represents a relationship between two model classes.
  *
  * @param array $config The relationship's configuration, which defines how the two models in
  *                      question are bound. The available options are:
  *                      - `'name'`        _string_ : The field name used for accessing the related data.
  *                                                   For example, in the case of `Post` hasMany `Comment`, the name defaults to `'comments'`.
  *                      - `'keys'`        _mixed_  : Mathing keys definition, where the key is the key in the originating model,
  *                                                   and the value is the key in the target model (i.e. `['fromId' => 'toId']`).
  *                      - `'from'`        _string_ : The fully namespaced class name this relationship originates.
  *                      - `'to'`          _string_ : The fully namespaced class name this relationship targets.
  *                      - `'link'`        _string_ : A constant specifying how the object bound to the originating
  *                                                   model is linked to the object bound to the target model. For relational
  *                                                   databases, the only valid value is `LINK_KEY`, which means a foreign
  *                                                   key in one object matches another key (usually the primary key) in the other.
  *                                                   For document-oriented and other non-relational databases, different types of
  *                                                   linking, including key lists or even embedding.
  *                      - `'fields'`      _mixed_  : An array of the subset of fields that should be selected
  *                                                   from the related object(s) by default. If set to `true` (the default), all
  *                                                   fields are selected.
  *                      - `'conventions'` _object_ : The naming conventions instance to use.
  */
 public function __construct($config = [])
 {
     $defaults = ['name' => null, 'keys' => null, 'from' => null, 'to' => null, 'link' => static::LINK_KEY, 'fields' => true, 'conventions' => null];
     $config += $defaults;
     foreach (['from', 'to'] as $value) {
         if (!$config[$value]) {
             throw new ChaosException("The relationship `'{$value}'` option can't be empty.");
         }
     }
     $this->_conventions = $config['conventions'] ?: new Conventions();
     if (!$config['keys']) {
         $primaryKey = $this->_conventions->apply('primaryKey');
         $config['keys'] = [$primaryKey => $this->_conventions->apply('foreignKey', $config['from'])];
     }
     if (!$config['name']) {
         $config['name'] = $this->_conventions->apply('fieldName', $config['to']);
     }
     $this->_name = $config['name'];
     $this->_from = $config['from'];
     $this->_to = $config['to'];
     $this->_keys = $config['keys'];
     $this->_link = $config['link'];
     $this->_fields = $config['fields'];
     $pos = strrpos(static::class, '\\');
     $this->_type = lcfirst(substr(static::class, $pos !== false ? $pos + 1 : 0));
 }
Exemplo n.º 3
0
 /**
  * Configures the meta for use.
  *
  * @param array $config Possible options are:
  *                      - `'connection'`  _object_ : The connection instance (defaults to `null`).
  *                      - `'source'`      _string_ : The source name (defaults to `null`).
  *                      - `'model'`       _string_ : The fully namespaced model class name (defaults to `null`).
  *                      - `'locked'`      _boolean_: set the ability to dynamically add/remove fields (defaults to `false`).
  *                      - `'key'`         _string_ : The primary key value (defaults to `id`).
  *                      - `'columns'      _array_  : array of field definition where keys are field names and values are arrays
  *                                                   with the following keys. All properties are optionnal except the `'type'`:
  *                                                   - `'type'`      _string_ : the type of the field.
  *                                                   - `'default'`   _mixed_  : the default value (default to '`null`').
  *                                                   - `'null'`      _boolean_: allow null value (default to `'null'`).
  *                                                   - `'length'`    _integer_: the length of the data (default to `'null'`).
  *                                                   - `'precision'` _integer_: the precision (for decimals) (default to `'null'`).
  *                                                   - `'use'`       _string_ : the database type to override the associated type for
  *                                                                              this type (default to `'null'`).
  *                                                   - `'serial'`    _string_ : autoincremented field (default to `'null'`).
  *                                                   - `'primary'`   _boolead_: primary key (default to `'null'`).
  *                                                   - `'unique'`    _boolead_: unique key (default to `'null'`).
  *                                                   - `'reference'` _string_ : foreign key (default to `'null'`).
  *                      - `'meta'`        _array_  : array of meta definitions for the schema. The definitions are related to
  *                                                   the datasource. For the MySQL adapter the following options are available:
  *                                                   - `'charset'`    _string_: the charset value to use for the table.
  *                                                   - `'collate'`    _string_: the collate value to use for the table.
  *                                                   - `'engine'`     _stirng_: the engine value to use for the table.
  *                                                   - `'tablespace'` _string_: the tablespace value to use for the table.
  *                      - `'handlers'`    _array_  : casting handlers.
  *                      - `'conventions'` _object_ : The naming conventions instance.
  *                      - `'classes'`     _array_  : The class dependencies.
  */
 public function __construct($config = [])
 {
     $defaults = ['connection' => null, 'source' => null, 'model' => Document::class, 'locked' => true, 'columns' => [], 'meta' => [], 'handlers' => [], 'conventions' => null, 'classes' => $this->_classes];
     $config = Set::merge($defaults, $config);
     $this->_classes = $config['classes'];
     $this->_connection = $config['connection'];
     $this->_locked = $config['locked'];
     $this->_meta = $config['meta'];
     $this->_handlers = Set::merge($config['handlers'], $this->_handlers());
     $this->_conventions = $config['conventions'] ?: new Conventions();
     $config += ['key' => $this->_conventions->apply('key')];
     $this->_columns = $config['columns'];
     $this->_source = $config['source'];
     $this->_model = $config['model'];
     $this->_key = $config['key'];
     foreach ($config['columns'] as $key => $value) {
         $this->_columns[$key] = $this->_initColumn($value);
     }
     if ($this->_connection) {
         $this->_formatters = $this->_connection->formatters();
     }
     $handlers = $this->_handlers;
     $this->formatter('array', 'id', $handlers['array']['integer']);
     $this->formatter('array', 'serial', $handlers['array']['integer']);
     $this->formatter('array', 'integer', $handlers['array']['integer']);
     $this->formatter('array', 'float', $handlers['array']['float']);
     $this->formatter('array', 'decimal', $handlers['array']['string']);
     $this->formatter('array', 'date', $handlers['array']['date']);
     $this->formatter('array', 'datetime', $handlers['array']['datetime']);
     $this->formatter('array', 'boolean', $handlers['array']['boolean']);
     $this->formatter('array', 'null', $handlers['array']['null']);
     $this->formatter('array', '_default_', $handlers['array']['string']);
     $this->formatter('cast', 'integer', $handlers['cast']['integer']);
     $this->formatter('cast', 'float', $handlers['cast']['float']);
     $this->formatter('cast', 'decimal', $handlers['cast']['decimal']);
     $this->formatter('cast', 'date', $handlers['cast']['datetime']);
     $this->formatter('cast', 'datetime', $handlers['cast']['datetime']);
     $this->formatter('cast', 'boolean', $handlers['cast']['boolean']);
     $this->formatter('cast', 'null', $handlers['cast']['null']);
     $this->formatter('cast', 'string', $handlers['cast']['string']);
     if ($this->_connection) {
         $this->_formatters = Set::merge($this->_formatters, $this->_connection->formatters());
     }
 }
Exemplo n.º 4
0
 /**
  * Loads the Channel module and runs its entries() method
  *
  * @access      private
  * @return      void
  */
 private function _channel_entries()
 {
     // --------------------------------------
     // Make sure the following params are set
     // --------------------------------------
     $set_params = array('dynamic' => 'no', 'paginate' => 'bottom');
     foreach ($set_params as $key => $val) {
         if (!ee()->TMPL->fetch_param($key)) {
             $this->params->apply($key, $val);
         }
     }
     // --------------------------------------
     // Take care of related entries
     // --------------------------------------
     if (version_compare(APP_VER, '2.6.0', '<')) {
         // We must do this, 'cause the template engine only does it for
         // channel:entries or search:search_results. The bastard.
         ee()->TMPL->tagdata = ee()->TMPL->assign_relationship_data(ee()->TMPL->tagdata);
         // Add related markers to single vars to trigger replacement
         foreach (ee()->TMPL->related_markers as $var) {
             ee()->TMPL->var_single[$var] = $var;
         }
     }
     // --------------------------------------
     // Get channel module
     // --------------------------------------
     $this->_log('Calling the channel module');
     if (!class_exists('channel')) {
         require_once PATH_MOD . 'channel/mod.channel' . EXT;
     }
     // --------------------------------------
     // Create new Channel instance
     // --------------------------------------
     $channel = new Channel();
     // --------------------------------------
     // Let the Channel module do all the heavy lifting
     // --------------------------------------
     return $channel->entries();
 }