public function save(
        $updateFields = null,
        $forceInsert = false,
        $forceUpdate = false,
        $connection = null
    ) {
        // Ensure that a model instance without a PK hasn't been assigned to
        // a ForeignKey or OneToOneField on this model. If the field is
        // nullable, allowing the save() would result in silent data loss.
        /* @var $relObject Model */
        /** @var $field Field */
        foreach ($this->getMeta()->getConcreteFields() as $name => $field) {
            if ($field->isRelation) {
                //If the related field isn't cached, then an instance hasn't
                //been assigned and there's no need to worry about this check.
                if ($this->hasProperty($field->getCacheName()) &&
                    $this->{$field->getCacheName()}) {
                    continue;
                }

                $relObject = $this->{$field->getName()};

                if ($relObject && is_null($relObject->getMeta()->primaryKey)) {
                    throw new ValueError(
                        sprintf(
                            'save() prohibited to prevent data loss '.
                            "due to unsaved related object '%s'.",
                            $field->getName()
                        )
                    );
                }
            }
        }

        if ($forceInsert && ($forceInsert || $forceUpdate)) {
            throw new ValueError(
                'Cannot force both insert and updating'.
                ' in model saving.'
            );
        }

        $deferedFields = $this->getDeferredFields();

        // if we got update_fields, ensure we got fields actually exist on
        // the model
        if ($updateFields) {
            $modelFields = $this->getMeta()->getNonM2MForwardFields();
            $fieldsNames = [];
            /** @var $modelField Field */
            foreach ($modelFields as $name => $modelField) {
                if ($modelField->primaryKey) {
                    continue;
                }
                $fieldsNames[] = $modelField->getName();

                // if attribute name and the field name provided arent the same,
                // add also add the attribute name.e.g. in related fields
                if ($modelField->getName() !== $modelField->getAttrName()) {
                    $fieldsNames[] = $modelField->getAttrName();
                }
            }

            $nonModelFields = array_diff($updateFields, $fieldsNames);
            if ($nonModelFields) {
                throw new ValueError(
                    sprintf(
                        'The following fields do not exist in this '.
                        'model or are m2m fields: %s'.implode(
                            ', ',
                            $nonModelFields
                        )
                    )
                );
            }
        } elseif (!$forceInsert && $deferedFields) {
            // if we have some deferred fields, we need to set the fields to
            // update as the onces that were loaded.
            $concreteFields = $this->getMeta()->getConcreteFields();

            $fieldsNames = [];
            /** @var $concreteField Field */
            foreach ($concreteFields as $name => $concreteField) {
                if (!$concreteField->primaryKey &&
                    !$concreteField->hasProperty('through')) {
                    $fieldsNames[] = $concreteField->getName();
                }
            }
            $loadedFields = array_diff($fieldsNames, $deferedFields);

            if ($loadedFields) {
                $updateFields = $loadedFields;
            }
        }

        $this->prepareSave($updateFields);
    }
public function save(
        $updateFields = null,
        $forceInsert = false,
        $forceUpdate = false,
        $connection = null
    ) {
        // Ensure that a model instance without a PK hasn't been assigned to
        // a ForeignKey or OneToOneField on this model. If the field is
        // nullable, allowing the save() would result in silent data loss.
        /* @var $relObject Model */
        /** @var $field Field */
        foreach ($this->getMeta()->getConcreteFields() as $name => $field) {
            if ($field->isRelation) {
                //If the related field isn't cached, then an instance hasn't
                //been assigned and there's no need to worry about this check.
                if ($this->hasProperty($field->getCacheName()) &&
                    $this->{$field->getCacheName()}) {
                    continue;
                }

                $relObject = $this->{$field->getName()};

                if ($relObject && is_null($relObject->getMeta()->primaryKey)) {
                    throw new ValueError(
                        sprintf(
                            'save() prohibited to prevent data loss '.
                            "due to unsaved related object '%s'.",
                            $field->getName()
                        )
                    );
                }
            }
        }

        if ($forceInsert && ($forceInsert || $forceUpdate)) {
            throw new ValueError(
                'Cannot force both insert and updating'.
                ' in model saving.'
            );
        }

        $deferedFields = $this->getDeferredFields();

        // if we got update_fields, ensure we got fields actually exist on
        // the model
        if ($updateFields) {
            $modelFields = $this->getMeta()->getNonM2MForwardFields();
            $fieldsNames = [];
            /** @var $modelField Field */
            foreach ($modelFields as $name => $modelField) {
                if ($modelField->primaryKey) {
                    continue;
                }
                $fieldsNames[] = $modelField->getName();

                // if attribute name and the field name provided arent the same,
                // add also add the attribute name.e.g. in related fields
                if ($modelField->getName() !== $modelField->getAttrName()) {
                    $fieldsNames[] = $modelField->getAttrName();
                }
            }

            $nonModelFields = array_diff($updateFields, $fieldsNames);
            if ($nonModelFields) {
                throw new ValueError(
                    sprintf(
                        'The following fields do not exist in this '.
                        'model or are m2m fields: %s'.implode(
                            ', ',
                            $nonModelFields
                        )
                    )
                );
            }
        } elseif (!$forceInsert && $deferedFields) {
            // if we have some deferred fields, we need to set the fields to
            // update as the onces that were loaded.
            $concreteFields = $this->getMeta()->getConcreteFields();

            $fieldsNames = [];
            /** @var $concreteField Field */
            foreach ($concreteFields as $name => $concreteField) {
                if (!$concreteField->primaryKey &&
                    !$concreteField->hasProperty('through')) {
                    $fieldsNames[] = $concreteField->getName();
                }
            }
            $loadedFields = array_diff($fieldsNames, $deferedFields);

            if ($loadedFields) {
                $updateFields = $loadedFields;
            }
        }

        $this->prepareSave($updateFields);
    }
public function save ( $ updateFields = null , $ forceInsert = false , $ forceUpdate = false , $ connection = null ) { // Ensure that a model instance without a PK hasn't been assigned to // a ForeignKey or OneToOneField on this model. If the field is // nullable, allowing the save() would result in silent data loss. /* @var $relObject Model */ /** @var $field Field */ foreach ( $ this -> getMeta ( ) -> getConcreteFields ( ) as $ name => $ field ) { if ( $ field -> isRelation ) { //If the related field isn't cached, then an instance hasn't //been assigned and there's no need to worry about this check. if ( $ this -> hasProperty ( $ field -> getCacheName ( ) ) && $ this -> { $ field -> getCacheName ( ) } ) { continue ; } $ relObject = $ this -> { $ field -> getName ( ) } ; if ( $ relObject && is_null ( $ relObject -> getMeta ( ) -> primaryKey ) ) { throw new ValueError ( sprintf ( 'save() prohibited to prevent data loss ' . "due to unsaved related object '%s'." , $ field -> getName ( ) ) ) ; } } } if ( $ forceInsert && ( $ forceInsert || $ forceUpdate ) ) { throw new ValueError ( 'Cannot force both insert and updating' . ' in model saving.' ) ; } $ deferedFields = $ this -> getDeferredFields ( ) ; // if we got update_fields, ensure we got fields actually exist on // the model if ( $ updateFields ) { $ modelFields = $ this -> getMeta ( ) -> getNonM2MForwardFields ( ) ; $ fieldsNames = [ ] ; /** @var $modelField Field */ foreach ( $ modelFields as $ name => $ modelField ) { if ( $ modelField -> primaryKey ) { continue ; } $ fieldsNames [ ] = $ modelField -> getName ( ) ; // if attribute name and the field name provided arent the same, // add also add the attribute name.e.g. in related fields if ( $ modelField -> getName ( ) !== $ modelField -> getAttrName ( ) ) { $ fieldsNames [ ] = $ modelField -> getAttrName ( ) ; } } $ nonModelFields = array_diff ( $ updateFields , $ fieldsNames ) ; if ( $ nonModelFields ) { throw new ValueError ( sprintf ( 'The following fields do not exist in this ' . 'model or are m2m fields: %s' . implode ( ', ' , $ nonModelFields ) ) ) ; } } elseif ( ! $ forceInsert && $ deferedFields ) { // if we have some deferred fields, we need to set the fields to // update as the onces that were loaded. $ concreteFields = $ this -> getMeta ( ) -> getConcreteFields ( ) ; $ fieldsNames = [ ] ; /** @var $concreteField Field */ foreach ( $ concreteFields as $ name => $ concreteField ) { if ( ! $ concreteField -> primaryKey && ! $ concreteField -> hasProperty ( 'through' ) ) { $ fieldsNames [ ] = $ concreteField -> getName ( ) ; } } $ loadedFields = array_diff ( $ fieldsNames , $ deferedFields ) ; if ( $ loadedFields ) { $ updateFields = $ loadedFields ; } } $ this -> prepareSave ( $ updateFields ) ; }
Saves the current instance. Override this in a subclass if you want to
control the saving process.

The 'force_insert' and 'force_update' parameters can be used to insist
that the "save" must be an SQL
insert or update (or equivalent for on-SQL backends), respectively.
Normally, they should not be set.

@param bool|false $forceInsert
@param bool|false $forceUpdate
@param null       $connection
@param null       $updateField

@throws ValueError

@since  1.1.0

@author Eddilbert Macharia (http://eddmash.com) <edd.cowan@gmail.com>
Saves the current instance . Override this in a subclass if you want to control the saving process .