/** * Handle writes, save the entity * @param \Spot\Entity\EntityInterface $entity * @param bool $insert, use insert if true, or use update * @return bool * @todo - UPDATE operation should only update modified data */ public function saveEntity(EntityInterface $entity, $insert = true) { // Run beforeInsert to know whether or not we can continue $resultAfter = null; #if (false === $this->eventsManager->triggerInstanceHook($entity, 'beforeInsert', $this)) { # return false; #} // Get the entity class name $entityName = $entity->toString(); // Get field options for primary key, merge with overrides (if any) passed $columns = $this->entityManager->getColumns($entityName); // Get identity/sequence columns $exceptColumns = []; foreach ($columns as $column) { ($column->isIdentity() || $column->isSequence() || $column->isRelation()) && ($exceptColumns[] = $column->getName()); } // If the primary key is a sequence, serial or identity column, exclude the PK from the array of columns to insert if ($insert) { $data = !empty($exceptColumns) ? $entity->getDataExcept($exceptColumns) : $entity->getData(); } else { $data = !empty($exceptColumns) ? $entity->getModifiedExcept($exceptColumns) : $entity->getModified(); } if (count($data) <= 0) { return false; } // Save only known, defined fields $data = array_intersect_key($data, $columns); // Initialize options array $options = ['identity' => false, 'sequence' => false, 'primaryKey' => false]; // Get meta data $metaData = $entityName::getMetaData(); // Loop through each $exceptColumns (which will be identity or sequence columns) foreach ($exceptColumns as $column) { if ($metaData->getColumn($column)->isSequence()) { $options['primaryKey'] = $column; $options['sequence'] = !empty($metaData->getSequence()) ? $metaData->getSequence() : $metaData->getTable() . "_{$column}_seq"; } } // Create binds from data $binds = []; foreach ($data as $key => $value) { $binds[$key] = ['value' => $value, 'bindType' => $metaData->getColumn($key)->getBindType()]; } // Send to adapter if ($insert === true) { $result = $this->getAdapter()->createEntity($this->entityManager->getTable($entityName), $binds, $options); // Update primary key on entity object if ($result !== false) { $primaryKeys = $this->entityManager->getPrimaryKeys($entityName); $entity->{$primaryKeys[0]} = $result; } // Load relations on new entity $this->relationManager->loadRelations($entity, $this); } else { // Return false if nothing to update if (!count($data)) { return true; } // Build conditions using PK $conditions = []; foreach ($this->entityManager->getPrimaryKeyValues($entity) as $key => $value) { $conditions[] = ['conditions' => [$key . ' :eq' => $value]]; } $result = $this->getAdapter()->updateEntity($this->entityManager->getTable($entityName), $binds, $conditions, $options); } // Run afterInsert # $resultAfter = $this->eventsManager->triggerInstanceHook($entity, 'afterInsert', [$this, $result]); $resultAfter = null; return null !== $resultAfter ? $resultAfter : $result; }