Jarves\Storage\Propel::mapValues PHP Method

mapValues() public method

public mapValues ( &$item, array &$values, boolean $ignoreNotExistingValues = false )
$item propel object
$values array
$ignoreNotExistingValues boolean
    public function mapValues(&$item, &$values, $ignoreNotExistingValues = false)
    {
        $setted = [];
        $applyColumn = function ($name) use(&$item, &$values, &$setted, &$ignoreNotExistingValues) {
            $fieldName = lcfirst($name);
            $setted[] = $fieldName;
            $fieldValue = @$values[$fieldName];
            if (!isset($values[$fieldName]) && $ignoreNotExistingValues) {
                return;
            }
            $fieldName = ucfirst($fieldName);
            $set = 'set' . $fieldName;
            $methodExist = method_exists($item, $set);
            if ($methodExist) {
                $item->{$set}($fieldValue);
            }
        };
        $pluralizer = new StandardEnglishPluralizer();
        $self = $this;
        /**
         * @param RelationDefinition $relation
         *
         * @throws ObjectNotFoundException
         * @throws \Exception
         */
        $applyRelation = function ($relation) use($self, $pluralizer, &$item, &$values, &$setted, &$ignoreNotExistingValues) {
            $fieldName = lcfirst($relation->getName());
            $fieldValue = isset($values[$fieldName]) ? $values[$fieldName] : null;
            if (!isset($values[$fieldName]) && $ignoreNotExistingValues) {
                return;
            }
            if ($relation->getType() == AbstractStorage::MANY_TO_MANY || $relation->getType() == AbstractStorage::ONE_TO_MANY) {
                $name = $pluralizer->getPluralForm($pluralizer->getSingularForm(Tools::underscore2Camelcase($fieldName)));
                $setItems = 'set' . $name;
                $clearItems = 'clear' . $name;
                if (is_array($fieldValue)) {
                    $foreignQuery = $self->getQueryClass($relation->getForeignObjectKey());
                    $foreignClass = $self->getPhpName($relation->getForeignObjectKey());
                    $foreignObjClass = $self->objects->getStorageController($relation->getForeignObjectKey());
                    if ($relation->getType() == AbstractStorage::ONE_TO_MANY) {
                        $coll = new ObjectCollection();
                        $coll->setModel(ucfirst($foreignClass));
                        if (!is_array($fieldValue)) {
                            throw new \LogicException(sprintf('Relation `%s` on object %s requires array value, not %s', $relation->getName(), $this->getObjectKey(), gettype($fieldValue)));
                        }
                        foreach ($fieldValue as $foreignItem) {
                            $pk = $self->objects->getObjectPk($relation->getForeignObjectKey(), $foreignItem);
                            $item2 = null;
                            if ($pk) {
                                $propelPk = $self->getPropelPk($pk, $relation->getForeignObjectKey());
                                $item2 = $foreignQuery->findPk($propelPk);
                            }
                            if (!$item2) {
                                $item2 = new $foreignClass();
                            }
                            $item2->fromArray($foreignItem, TableMap::TYPE_CAMELNAME);
                            $coll[] = $item2;
                        }
                        $item->{$setItems}($coll);
                    } else {
                        $primaryKeys = array();
                        if (is_array($fieldValue)) {
                            foreach ($fieldValue as $value) {
                                $primaryKeys[] = $foreignObjClass->normalizePrimaryKey($value);
                            }
                        }
                        $propelPks = array();
                        foreach ($primaryKeys as $primaryKey) {
                            $propelPks[] = $self->getPropelPk($primaryKey, $relation->getForeignObjectKey());
                        }
                        $collItems = $foreignQuery->findPks($propelPks);
                        $item->{$setItems}($collItems);
                    }
                } elseif ($ignoreNotExistingValues) {
                    $item->{$clearItems}();
                }
            }
            if ($relation->getType() == AbstractStorage::MANY_TO_ONE || $relation->getType() == AbstractStorage::ONE_TO_ONE) {
                if (!$self->tableMap->hasRelation(ucfirst($fieldName))) {
                    throw new \Exception(sprintf('Relation %s not found in propel object %s (%s)', ucfirst($fieldName), $self->getObjectKey(), $self->getPhpName()));
                }
                //try to set the local column of the relation directly, when we get only primary keys
                $propelRelation = $self->tableMap->getRelation(ucfirst($fieldName));
                $localColumns = $propelRelation->getLocalColumns();
                $firstColumn = current($localColumns);
                $hasPrimaryKey = false;
                if (is_array($fieldValue)) {
                    $foreignColumns = $propelRelation->getForeignColumns();
                    $firstForeignColumn = current($foreignColumns);
                    $key = lcfirst($firstForeignColumn->getPhpName());
                    if (isset($fieldValue[$key])) {
                        $fieldValue = $fieldValue[$key];
                        $hasPrimaryKey = true;
                    }
                } else {
                    $hasPrimaryKey = true;
                }
                if ($hasPrimaryKey) {
                    //set local column of foreign key directly
                    $setter = 'set' . ucfirst($firstColumn->getPhpName());
                    $item->{$setter}($fieldValue);
                } else {
                    //we got no primary key, so set values at the object directly
                    $getter = 'get' . ucfirst($relation->getName());
                    $relatedItem = $item->{$getter}();
                    if (!$relatedItem) {
                        $class = $propelRelation->getForeignTable()->getClassName();
                        $relatedItem = new $class();
                        $setter = 'set' . ucfirst($relation->getName());
                        $item->{$setter}($relatedItem);
                    }
                    foreach ($fieldValue as $k => $v) {
                        $relatedItem->{'set' . ucfirst($k)}($v);
                    }
                }
            }
        };
        foreach ($this->getDefinition()->getFields(true) as $field) {
            if ($field->isPrimaryKey() && $field->isAutoIncrement()) {
                continue;
            }
            foreach ($field->getFieldType()->getColumns() as $column) {
                $applyColumn($column->getName());
            }
        }
        foreach ($this->getDefinition()->getRelations() as $relation) {
            $applyRelation($relation);
        }
        //        /*
        //         * all virtual fields which are not present in the object.
        //         * Virtual fields are all methods in the model which have a setter.
        //         * Examples:
        //         *
        //         *   setPassword => 'password'
        //         */
        //        foreach ($values as $fieldName => $fieldValue) {
        //            $fieldName = lcfirst($fieldName);
        //            if (in_array($fieldName, $setted)) {
        //                continue;
        //            }
        //
        //            $fieldName = ucfirst($fieldName);
        //            $set = 'set' . $fieldName;
        //            $methodExist = method_exists($item, $set);
        //
        //            if ($methodExist) {
        //                $item->$set($fieldValue);
        //            }
        //        }
    }