TODO

@param $nameInFile
@param $nameInModel
@param null $fn
@return Association|null
438812
public function field($nameInFile, $nameInModel, $fn = null)
    {
        if ($association = $this->getAssociation($nameInModel)) {
            $association->addNameInFile($nameInFile);
        } else {
            $association = new Association();
            $association->addNameInFile($nameInFile);
            $association->setNameInModel($nameInModel);
            $association->setParser($fn);
            $this->association[] = $association;
        }
        return $association;
    }
269304
public function manipulator($manipulator, $nameInModel, $nameInManipulator, $fn = null)
    {
        if ($association = $this->getAssociation($nameInModel)) {
            $association->setManipulator($manipulator);
            $association->setNameInManipulator($nameInManipulator);
        } else {
            $association = new Association();
            $association->setManipulator($manipulator);
            $association->setNameInModel($nameInModel);
            $association->setNameInManipulator($nameInManipulator);
            $association->setManipulatorParser($fn);
            $this->association[] = $association;
        }
    }
1191184
private function getAssociation($nameInModel)
    {
        foreach ($this->association as $association) {
            if ($association->getNameInModel() == $nameInModel) {
                return $association;
            }
        }
        return null;
    }
1279723
public function belongs($name, $foreignKeyOrCallback = null, $callback = null, $storeKey = null)
    {
        $foreignKey = null;
        if (func_num_args() < 4 && is_callable($foreignKeyOrCallback)) {
            $storeKey = $callback;
            $callback = $foreignKeyOrCallback;
        } else {
            $foreignKey = $foreignKeyOrCallback;
        }
        $foreignKey = $foreignKey ? : $this->rows
            ->getTable()
            ->getStructure()
            ->foreignKey($name, $this->getRows()->getTable()->getTableName());
        $relations = $this->getRows()->loadBelongRelations($name, $foreignKey, $callback, $storeKey);
        $this->loadedRelations[] = [
            $storeKey ? : $name, 'belongs', $foreignKey
        ];
        return $relations->find($this->$foreignKey);
    }
1359580
public function build($name, Collection $fields = null)
    {
        $path = $this->getClassFilePath($name);
        $tableName = source_table_name($name);

        $contents = view('_hierarchy::entities.model', [
            'tableName'        => $tableName,
            'name'             => $this->getClassName($name),
            'fields'           => $this->makeFields($fields),
            'searchableFields' => $this->makeSearchableFields($fields, $tableName),
            'mutatables'       => $this->makeMutatableFields($fields)
        ])->render();

        $this->write($path, $contents);
    }
387828
protected function normalizeAssociation($association, $name, $format = null, array $context = array())
    {
        if ($association === null) {
            return;
        }

        $hint = $this->getHintFromObject($association);
        $ids = $this->getIdentifierFromObject($association);
        $id = $this->getIdentifiersAsString($ids);
        $data = array_merge($hint, $ids);
        $objectId = current($hint).'#'.$id;

        if (isset($context['@references'][$objectId])) {
            return $data;
        }

        $context['@references'][$objectId] = false;
        if ($association instanceof Proxy and !$association->__isInitialized()) {
            return $data;
        }

        $normalized = $this->serializer->normalize($association, $format, $context);

        $context['@references'][$objectId] = $normalized;

        return $data;
    }
234452
public function findFunctionariesByAssociation($association, $functionariesFilter = null)
    {
        $xmlQuery = $this->associationsApiService->getFunctionariesFromAssociation($association->getID(), $functionariesFilter);

        $functionaries = new Functionaries();

        $mapper = new \RGU\Dvoconnector\Mapper\Functionaries($xmlQuery);
        $mapper->mapToAbstractEntity($functionaries);

        return $this->completeEntity($functionaries);
    }
552656
public function getSchemaExtension($name, ConnectionInterface $conn)
    {
        if (isset($this->extensions[$name])) {
            return call_user_func($this->extensions[$name], $conn);
        }

        return null;
    }
586032
protected function loadRelation(array $models, $name, Closure $constraints)
    {
        $relation = $this->getRelation($name);

        $relation->addEagerConstraints($models);

        call_user_func($constraints, $relation);

        $models = $relation->initRelation($models, $name);

        $results = $relation->getEager();

        return $relation->match($models, $results, $name);
    }
396267
protected function _inferRelation($model, $name)
    {
        if (in_array($name . '_id', $model->getFields(), true)) {
            $referenceName = $this->_inferClassName($model, $name);
            return $referenceName ? [$referenceName, Relation::TYPE_HAS_ONE] : false;
        }

        if (preg_match('#^(.+[a-z\d])Of([A-Z].*)$#', $name, $match)) {
            if (!$singular = $this->_pluralToSingular($match[1])) {
                return false;
            }

            if (!$referenceName = $this->_inferClassName($model, $singular)) {
                return false;
            }

            $valueField = lcfirst($match[2]) . '_id';
            if (in_array($valueField, $model->getForeignKeys(), true)) {
                /** @var \ManaPHP\Model $reference */
                $reference = new $referenceName;
                return [$referenceName, Relation::TYPE_HAS_MANY_TO_MANY, $reference->getPrimaryKey(), $valueField];
            } else {
                return false;
            }
        }

        if ($singular = $this->_pluralToSingular($name)) {
            if (!$referenceName = $this->_inferClassName($model, $singular)) {
                return false;
            }

            /** @var \ManaPHP\Model $reference */
            $reference = new $referenceName;

            $keys = $model->getForeignKeys();
            if (count($keys) === 2) {
                $foreignKey = $singular . '_id';
                if (in_array($foreignKey, $keys, true)) {
                    $keys = array_flip($keys);
                    unset($keys[$foreignKey]);
                    return [$referenceName, Relation::TYPE_HAS_MANY_TO_MANY, $reference->getPrimaryKey(), key($keys)];
                }
            }
            if (in_array($model->getPrimaryKey(), $reference->getFields(), true)) {
                return [$referenceName, Relation::TYPE_HAS_MANY];
            } else {
                $r1Name = substr($referenceName, strrpos($referenceName, '\\') + 1);

                $modelName = get_class($model);
                $pos = strrpos($modelName, '\\');
                $baseName = substr($modelName, 0, $pos + 1);
                $r2Name = substr($modelName, $pos + 1);

                $tryViaName = $baseName . $r1Name . $r2Name;
                if (class_exists($tryViaName)) {
                    return [$referenceName, Relation::TYPE_HAS_MANY_VIA, $tryViaName, $model->getPrimaryKey()];
                } else {
                    $tryViaName = $baseName . $r2Name . $r1Name;
                    if (!class_exists($tryViaName)) {
                        throw new RuntimeException(['infer `:relation` relation failed', 'relation' => $name]);
                    }

                    return [$referenceName, Relation::TYPE_HAS_MANY_VIA, $tryViaName, $model->getPrimaryKey()];
                }
            }
        }

        return false;
    }
63140
protected function nullableRelationship(string $name, bool $cascadeDelete = false): Closure
    {
        return $this->relationshipImpl($name, false, $cascadeDelete);
    }
612976
public static function set(string $namespace, string $name = null, $object = null)
    {
        $name = $name ?: 'default';

        self::$container[$namespace][$name] = $object;

        return $object;
    }
1320430
protected function tryToGetJoinColumnAnnotationOfMappedBy($annotation){
        $result = null;
        if($annotation->targetEntity && $annotation->mappedBy) {
            $result = $this->getAnnotation(
                $annotation->targetEntity,
                $annotation->mappedBy,
                'Doctrine\ORM\Mapping\JoinColumn'
            );
            if ($result === null) {
                $result = $this->getAnnotation(
                    $annotation->targetEntity,
                    $annotation->mappedBy,
                    'Doctrine\ORM\Mapping\JoinColumns'
                );
            }
        }
        return $result;
    }
221369
public function addAttachment($file, $name = null, $fileInfo = []) {
		$fileInfo['file'] = $file;
		if (!empty($name)) {
			$fileInfo = [$name => $fileInfo];
		} else {
			$fileInfo = [$fileInfo];
		}
		return $this->addAttachments($fileInfo);
	}
1346455
public function importerFileHasFilename($importerFile, $filenameToImport)
    {
        if (!file_exists($importerFile)) {
            return false;
        }

        $data = Yaml::parse(file_get_contents($importerFile));

        return $this->dataContainsImportFile($data, $filenameToImport);
    }
470633
public function withAttr($name, $callback = null)
    {
        $this->each(function ($model) use ($name, $callback) {
            /** @var Model $model */
            $model && $model->withAttribute($name, $callback);
        });

        return $this;
    }
1072243
public function setupJoins($names, Meta $meta, $alias)
    {
        if (is_null($alias)) {
            $alias = $this->getInitialAlias();
        }
        $joins = [$alias];

        $namesPaths = $this->getNamesPath($names, $meta, true);

        $pathInfos = $namesPaths['paths'];

        /* @var $meta Meta */
        foreach ($pathInfos as $pathInfo) {
            $meta = $pathInfo['toMeta'];

            if ($pathInfo['direct']) {
                $nullable = $this->isNullable($pathInfo['joinField']);
            } else {
                $nullable = true;
            }
            $join = new Join();
            $join->setTableName($meta->getDbTable());
            $join->setParentAlias($alias);
            $join->setJoinType(INNER);
            $join->setJoinField($pathInfo['joinField']);
            $join->setNullable($nullable);

            $alias = $this->join($join);

            $joins[] = $alias;
        }

        return [
            $namesPaths['finalField'],
            $namesPaths['targets'],
            $joins,
            $pathInfos,
            $meta,
        ];
    }