Exemplo n.º 1
0
 /**
  * {@inheritDoc}
  */
 public function save($entity, array $options = [])
 {
     $query = $this->queryBuilder->save($this->entityMetadata, $options)->entity($entity);
     try {
         $saveResult = $this->doQuery($query, ["output" => "raw"]);
     } catch (\PDOException $e) {
         $pkMetadata = $this->entityMetadata->getPrimaryKeyMetadata();
         // if this entity has an auto incrementing PK, or the error is not about PK conflicts, re-throw the error
         if ($pkMetadata[EntityMetadata::METADATA_FIELD_AUTO_INCREMENTING] == true || $e->errorInfo[0] != self::ANSI_DUPLICATE_KEY_ERROR_CODE) {
             throw $e;
         }
         // this is a duplicate key on a collection with a PK that does not auto increment.
         // force the save to be an update
         $query->setOption("saveType", "update");
         $saveResult = $this->doQuery($query, ["output" => "raw"]);
     }
     // get the primary key value, if there is one, and save it on the entity
     if (isset($saveResult[StorageInterface::NEW_INSERT_ID_RETURN_FIELD])) {
         $pkValue = $saveResult[StorageInterface::NEW_INSERT_ID_RETURN_FIELD];
         $this->entityMetadata->setEntityValue($entity, $this->entityMetadata->getPrimaryKey(), $pkValue);
     } else {
         $pkValue = null;
     }
     // save "* to many" relationships
     foreach ($this->entityMetadata->getRelationships() as $alias => $relationship) {
         $type = $relationship[EntityMetadata::METADATA_RELATIONSHIP_TYPE];
         $property = $relationship[EntityMetadata::METADATA_RELATIONSHIP_PROPERTY];
         $childValue = $this->entityMetadata->getEntityValue($entity, $property);
         if ($type == EntityMetadata::RELATIONSHIP_TYPE_ONE_TO_ONE) {
             // This covers "many to one" as well
             if (!empty($this->relationshipCascade[$alias])) {
                 /** @var RepositoryInterface $childRepo */
                 $childRepo = $this->relationshipCascade[$alias];
                 $childRepo->save($childValue);
             }
             // nothing more to do for One to One / Many to One
             continue;
         }
         /* We need to know the following:
          * Which child entities have been added and removed
          * The field names used on both sides of the relationship
          * The corresponding values for both the parent and child entities
          */
         if (!$childValue instanceof Collection) {
             // if this isn't a collection object we can't process this relationship
             continue;
         }
         // get the field used on the child entity
         $childMetadata = $this->metadataProvider->getEntityMetadata($relationship[EntityMetadata::METADATA_ENTITY]);
         $theirField = !empty($relationship[EntityMetadata::METADATA_RELATIONSHIP_THEIR_FIELD]) ? $relationship[EntityMetadata::METADATA_RELATIONSHIP_THEIR_FIELD] : $childMetadata->getPrimaryKey();
         // get the field and value used on the parent entity
         $ourValue = null;
         $ourField = null;
         // if we haven't specified a field for the parent, use the primary key
         if (empty($relationship[EntityMetadata::METADATA_RELATIONSHIP_OUR_FIELD])) {
             // using the PK
             if ($pkValue !== null) {
                 // This was a new record and we already have the value for the parent PK, so set it now
                 $ourValue = $pkValue;
             }
             $ourField = $this->entityMetadata->getPrimaryKey();
         } else {
             $ourField = $relationship[EntityMetadata::METADATA_RELATIONSHIP_OUR_FIELD];
         }
         // get the parent value if it isn't set already
         if ($ourValue === null) {
             $ourValue = $this->entityMetadata->getEntityValue($entity, $ourField);
         }
         // update the relationship
         if ($type == EntityMetadata::RELATIONSHIP_TYPE_ONE_TO_MANY) {
             $this->saveOneToMany($alias, $childValue, $childMetadata, $ourValue, $theirField);
         } elseif ($type == EntityMetadata::RELATIONSHIP_TYPE_MANY_TO_MANY) {
             $this->saveManyToMany($relationship, $alias, $childValue, $childMetadata, $ourValue, $ourField, $theirField);
         }
     }
     return $saveResult;
 }
Exemplo n.º 2
0
 /**
  * @dataProvider pkMetadataProvider
  *
  * @param $fieldMetadata
  * @param $expectedMetadata
  */
 public function testPublicKeyMetadata($fieldMetadata, $expectedMetadata)
 {
     $pk = "id";
     $metadata = new EntityMetadata("blah");
     $metadata->setPrimaryKey($pk);
     if (!is_null($fieldMetadata)) {
         $metadata->addFieldMetadata($pk, $fieldMetadata);
     }
     $pkMetadata = $metadata->getPrimaryKeyMetadata();
     foreach ($expectedMetadata as $field => $value) {
         $this->assertEquals($value, $pkMetadata[$field]);
     }
 }