Example #1
0
 /**
  * Filter data on inner relation or relation chain. Method automatically called by Selector,
  * see with() method. Logic is identical to loader() method.
  *
  * @see Selector::load()
  * @param string $relation Relation name, or chain of relations separated by.
  * @param array  $options  Loader options (will be applied to last chain element only).
  * @return Loader
  * @throws LoaderException
  */
 public function joiner($relation, array $options = [])
 {
     if (empty($options['method'])) {
         //We have to force joining method for full chain
         $options['method'] = self::JOIN;
     }
     if (($position = strpos($relation, '.')) !== false) {
         //Chain of relations provided
         $nested = $this->joiner(substr($relation, 0, $position), []);
         if (empty($nested) || !$nested instanceof self) {
             //todo: DRY
             throw new LoaderException("Only ORM loaders can be used to generate/configure chain of relation joiners.");
         }
         //Recursively (will work only with ORM loaders).
         return $nested->joiner(substr($relation, $position + 1), $options);
     }
     if (!isset($this->schema[ORM::M_RELATIONS][$relation])) {
         $container = $this->container ?: $this->schema[ORM::M_ROLE_NAME];
         throw new LoaderException("Undefined relation '{$relation}' under '{$container}'.");
     }
     if (isset($this->joiners[$relation])) {
         //Updating existed joiner options
         return $this->joiners[$relation]->setOptions($options);
     }
     $relationOptions = $this->schema[ORM::M_RELATIONS][$relation];
     $joiner = $this->orm->loader($relationOptions[ORM::R_TYPE], $relation, $relationOptions[ORM::R_DEFINITION], $this);
     if (!$joiner instanceof self) {
         //todo: DRY
         throw new LoaderException("Only ORM loaders can be used to generate/configure chain of relation joiners.");
     }
     return $this->joiners[$relation] = $joiner->setOptions($options);
 }