/**
  * Build class methods.
  *
  * @param StructureInterface $structure
  * @param TypeInterface      $source_type
  * @param TypeInterface      $target_type
  * @param array              $result
  */
 public function buildClassMethods(StructureInterface $structure, TypeInterface $source_type, TypeInterface $target_type, array &$result)
 {
     $namespace = $structure->getNamespace();
     if ($namespace) {
         $namespace = '\\' . ltrim($namespace, '\\');
     }
     $this->buildGetFinderMethod($structure, $source_type, $target_type, $namespace, $result);
     $result[] = '';
     $result[] = '    /**';
     $result[] = '     * Return ' . Inflector::singularize($source_type->getName()) . ' ' . $this->getName() . '.';
     $result[] = '     *';
     $result[] = '     * @return ' . $this->getInstanceClassFrom($namespace, $target_type) . '[]';
     $result[] = '     */';
     $result[] = "    public function get{$this->getClassifiedAssociationName()}()";
     $result[] = '    {';
     $result[] = '        return $this->' . $this->getFinderMethodName() . '()->all();';
     $result[] = '    }';
     $result[] = '';
     $result[] = '    /**';
     $result[] = '     * Return ' . Inflector::singularize($source_type->getName()) . ' ' . Inflector::singularize($this->getName()) . ' ID-s.';
     $result[] = '     *';
     $result[] = '     * @return int[]';
     $result[] = '     */';
     $result[] = '    public function get' . Inflector::classify(Inflector::singularize($this->getName())) . 'Ids()';
     $result[] = '    {';
     $result[] = '        return $this->' . $this->getFinderMethodName() . '()->ids();';
     $result[] = '    }';
     $result[] = '';
     $result[] = '    /**';
     $result[] = '     * Return number of ' . Inflector::singularize($source_type->getName()) . ' ' . $this->getName() . '.';
     $result[] = '     *';
     $result[] = '     * @return int';
     $result[] = '     */';
     $result[] = "    public function count{$this->getClassifiedAssociationName()}()";
     $result[] = '    {';
     $result[] = '        return $this->' . $this->getFinderMethodName() . '()->count();';
     $result[] = '    }';
     $this->buildAddRelatedObjectMethod($structure, $source_type, $target_type, $namespace, $result);
     $this->buildRemoveRelatedObjectMethod($structure, $source_type, $target_type, $namespace, $result);
     $this->buildClearRelatedObjectsMethod($structure, $source_type, $target_type, $namespace, $result);
 }
 /**
  * Build class methods.
  *
  * @param StructureInterface $structure
  * @param TypeInterface      $source_type
  * @param TypeInterface      $target_type
  * @param array              $result
  */
 public function buildClassMethods(StructureInterface $structure, TypeInterface $source_type, TypeInterface $target_type, array &$result)
 {
     $namespace = $structure->getNamespace();
     if ($namespace) {
         $namespace = '\\' . ltrim($namespace, '\\');
     }
     $target_instance_class = $namespace . '\\' . Inflector::classify(Inflector::singularize($target_type->getName()));
     $classified_association_name = Inflector::classify($this->getName());
     $getter_name = "get{$classified_association_name}";
     $setter_name = "set{$classified_association_name}";
     $fk_getter_name = "get{$classified_association_name}Id";
     $fk_setter_name = "set{$classified_association_name}Id";
     $result[] = '';
     $result[] = '    /**';
     $result[] = '     * Return ' . Inflector::singularize($source_type->getName()) . ' ' . $this->getName() . '.';
     $result[] = '     *';
     $result[] = '     * @return ' . $target_instance_class;
     $result[] = '     */';
     $result[] = '    public function ' . $getter_name . '()';
     $result[] = '    {';
     $result[] = '        return $this->pool->getById(' . var_export($target_instance_class, true) . ', $this->' . $fk_getter_name . '());';
     $result[] = '    }';
     $setter_access_level = $this->getProtectSetter() ? 'protected' : 'public';
     $result[] = '';
     $result[] = '    /**';
     $result[] = '     * Set ' . Inflector::singularize($source_type->getName()) . ' ' . $this->getName() . '.';
     $result[] = '     *';
     $result[] = '     * @param  ' . $target_instance_class . ' $value';
     $result[] = '     * @return $this';
     $result[] = '     */';
     $result[] = '    ' . $setter_access_level . ' function &' . $setter_name . '(' . $target_instance_class . ' $value' . ($this->isRequired() ? '' : ' = null') . ')';
     $result[] = '    {';
     if ($this->isRequired()) {
         $result[] = '        if (empty($value) || !$value->isLoaded()) {';
         $result[] = '            throw new \\InvalidArgumentException(\'Valid related instance is required\');';
         $result[] = '        }';
         $result[] = '';
         $result[] = '        $this->' . $fk_setter_name . '($value->getId());';
         $result[] = '';
         $result[] = '        return $this;';
     } else {
         $result[] = '        if (empty($value)) {';
         $result[] = '            $this->' . $fk_setter_name . '(0);';
         $result[] = '        } else {';
         $result[] = '            $this->' . $fk_setter_name . '($value->getId());';
         $result[] = '        }';
         $result[] = '';
         $result[] = '        return $this;';
     }
     $result[] = '    }';
 }
 /**
  * {@inheritdoc}
  */
 public function buildClearRelatedObjectsMethod(StructureInterface $structure, TypeInterface $source_type, TypeInterface $target_type, $namespace, array &$result)
 {
     $intermediary_type = $structure->getType($this->intermediary_type_name);
     $intermediary_instance_class = $this->getInstanceClassFrom($namespace, $intermediary_type);
     $result[] = '';
     $result[] = '    /**';
     $result[] = '     * Drop all connections between ' . str_replace('_', ' ', $target_type->getName()) . ' and this ' . Inflector::singularize($source_type->getName()) . '.';
     $result[] = '     *';
     $result[] = '     * @return $this';
     $result[] = '     */';
     $result[] = "    public function &clear{$this->getClassifiedAssociationName()}()";
     $result[] = '    {';
     $result[] = '        if ($objects = $this->get' . $this->getClassifiedAssociationName() . '()) {';
     $result[] = '            $object_ids = [];';
     $result[] = '';
     $result[] = '            $this->connection->transact(function () use ($objects, &$object_ids) {';
     $result[] = '                foreach ($objects as $object) {';
     $result[] = '                    $object_ids[] = $object->getId();';
     $result[] = '                    $object->delete(true);';
     $result[] = '                }';
     $result[] = '            });';
     $result[] = '';
     $result[] = '            $this->pool->forget(' . var_export($intermediary_instance_class, true) . ', $object_ids);';
     $result[] = '        }';
     $result[] = '';
     $result[] = '        return $this;';
     $result[] = '    }';
 }