FOF30\Model\DataModel::save PHP Method

save() public method

Special note if you are using a custom buildQuery with JOINs or field aliases: You will need to override the recordDataToDatabaseData method. Make sure that you _remove_ or rename any fields which do not exist in the table defined in $this->tableName. Otherwise Joomla! will not know how to insert / update the data on the table and will throw an Exception denoting a database error. It is generally a BAD idea using JOINs instead of relations. If unsure, use relations.
public save ( null | array $data = null, string $orderingFilter = '', array $ignore = null, $resetRelations = true ) : DataModel
$data null | array [Optional] Data to bind
$orderingFilter string A WHERE clause used to apply table item reordering
$ignore array A list of fields to ignore when binding $data
return DataModel Self, for chaining
    public function save($data = null, $orderingFilter = '', $ignore = null, $resetRelations = true)
    {
        // Stash the primary key
        $oldPKValue = $this->getId();
        // Call the onBeforeSave event
        $this->triggerEvent('onBeforeSave', array(&$data));
        // Get the relation to local field map and initialise the relationsAffected array
        $relationImportantFields = $this->getRelationFields();
        $dataBeforeBind = array();
        // If we have relations we keep a copy of the data before bind.
        if (count($relationImportantFields)) {
            $dataBeforeBind = array_merge($this->recordData);
        }
        // Bind any (optional) data. If no data is provided, the current record data is used
        if (!is_null($data)) {
            $this->bind($data, $ignore);
        }
        // Is this a new record?
        if (empty($oldPKValue)) {
            $isNewRecord = true;
        } else {
            $isNewRecord = $oldPKValue != $this->getId();
        }
        // Check the validity of the data
        $this->check();
        // Get the database object
        $db = $this->getDbo();
        // Insert or update the record. Note that the object we use for insertion / update is the a copy holding
        // the transformed data.
        $dataObject = $this->recordDataToDatabaseData();
        $dataObject = (object) $dataObject;
        if ($isNewRecord) {
            $this->triggerEvent('onBeforeCreate', array(&$dataObject));
            // Insert the new record
            $db->insertObject($this->tableName, $dataObject, $this->idFieldName);
            // Update ourselves with the new ID field's value
            $this->{$this->idFieldName} = $db->insertid();
            // Rebase the relations with the newly created model
            if ($resetRelations) {
                $this->relationManager->rebase($this);
            }
            $this->triggerEvent('onAfterCreate');
        } else {
            $this->triggerEvent('onBeforeUpdate', array(&$dataObject));
            $db->updateObject($this->tableName, $dataObject, $this->idFieldName, true);
            $this->triggerEvent('onAfterUpdate');
        }
        // If an ordering filter is set, attempt reorder the rows in the table based on the filter and value.
        if ($orderingFilter) {
            $filterValue = $this->{$orderingFilter};
            $this->reorder($orderingFilter ? $db->qn($orderingFilter) . ' = ' . $db->q($filterValue) : '');
        }
        // One more thing... Touch all relations in the $touches array
        if (!empty($this->touches)) {
            foreach ($this->touches as $relation) {
                $records = $this->getRelations()->getData($relation);
                if (!empty($records)) {
                    if ($records instanceof DataModel) {
                        $records = array($records);
                    }
                    /** @var DataModel $record */
                    foreach ($records as $record) {
                        $record->touch();
                    }
                }
            }
        }
        // If we have relations we compare the data to the copy of the data before bind.
        if (count($relationImportantFields) && $resetRelations) {
            // Since array_diff_assoc doesn't work recursively we have to do it the EXCRUCIATINGLY SLOW WAY. Sad panda :(
            $keysRecord = is_array($this->recordData) && !empty($this->recordData) ? array_keys($this->recordData) : array();
            $keysBefore = is_array($dataBeforeBind) && !empty($dataBeforeBind) ? array_keys($dataBeforeBind) : array();
            $keysAll = array_merge($keysRecord, $keysBefore);
            $keysAll = array_unique($keysAll);
            $modifiedFields = array();
            foreach ($keysAll as $key) {
                if (!isset($dataBeforeBind[$key]) || !isset($this->recordData[$key])) {
                    $modifiedFields[] = $key;
                } elseif ($dataBeforeBind[$key] != $this->recordData[$key]) {
                    $modifiedFields[] = $key;
                }
            }
            unset($dataBeforeBind);
            if (count($modifiedFields)) {
                $relationsAffected = array();
                unset($modifiedData);
                foreach ($relationImportantFields as $relationName => $fieldName) {
                    if (in_array($fieldName, $modifiedFields)) {
                        $relationsAffected[] = $relationName;
                    }
                }
                // Reset the relations which are affected by the save. This will force-reload the relations when you try to
                // access them again.
                $this->relationManager->resetRelationData($relationsAffected);
            }
        }
        // Finally, call the onAfterSave event
        $this->triggerEvent('onAfterSave');
        return $this;
    }

Usage Example

コード例 #1
0
 /**
  * Publish or unpublish a DataModel item based on its publish_up / publish_down fields
  *
  * @param   DataModel  $row  The DataModel to publish/unpublish
  *
  * @return  void
  */
 protected function publishByDate(DataModel $row)
 {
     static $uNow = null;
     \JLoader::import('joomla.utilities.date');
     if (is_null($uNow)) {
         $jNow = new \JDate();
         $uNow = $jNow->toUnix();
     }
     $db = $this->container->db;
     $triggered = false;
     if ($row->publish_down && $row->publish_down != $db->getNullDate()) {
         $publish_down = $this->normaliseDate($row->publish_down, '2038-01-18 00:00:00');
         $publish_up = $this->normaliseDate($row->publish_up, '2001-01-01 00:00:00');
         $jDown = new \JDate($publish_down);
         $jUp = new \JDate($publish_up);
         if ($uNow >= $jDown->toUnix() && $row->enabled) {
             $row->enabled = 0;
             $triggered = true;
         } elseif ($uNow >= $jUp->toUnix() && !$row->enabled && $uNow < $jDown->toUnix()) {
             $row->enabled = 1;
             $triggered = true;
         }
     }
     if ($triggered) {
         $row->save();
     }
 }