Ejemplo n.º 1
0
 /**
  * Saves a foreign relationship where a property on the supplied object references an id for another object.
  *
  * Can be used to save a one-to-one relationship or the "one" side of a one-to-many relationship.
  *
  * @param DataObjectInterface[] $objects
  * @param string $foreignIdColumn Property on this object that relates to the foreign tables id
  */
 public function saveOne(array $objects, $foreignIdColumn)
 {
     $getter = 'get' . $this->inflector->methodNameFromColumn($foreignIdColumn);
     /** @var DataObjectInterface[] $foreignObjectsByObjectId */
     $foreignObjectsByObjectId = [];
     foreach ($objects as $object) {
         if (!method_exists($object, $getter)) {
             throw new MethodNotImplementedException("{$getter} must be defined on {$object->getClassName()} to save relationship");
         }
         $objectIdSetter = 'set' . $this->inflector->idColumnFromClass(get_class($object));
         $foreignObject = $object->{$getter}();
         if ($foreignObject) {
             $foreignObjectsByObjectId[$object->getId()] = $foreignObject;
             if (method_exists($foreignObject, $objectIdSetter)) {
                 // for true one-to-one relationships
                 $foreignObject->{$objectIdSetter}($object->getId());
             }
         }
     }
     $this->objectMapper->saveAll($foreignObjectsByObjectId);
     $idSetter = 'set' . ucfirst($foreignIdColumn);
     $idGetter = 'get' . ucfirst($foreignIdColumn);
     $objectsToUpdate = [];
     foreach ($objects as $object) {
         if (!method_exists($object, $idSetter)) {
             throw new MethodNotImplementedException("{$idSetter} must be defined on {$object->getClassName()} to save relationship");
         }
         if (!method_exists($object, $idGetter)) {
             throw new MethodNotImplementedException("{$idGetter} must be defined on {$object->getClassName()} to save relationship");
         }
         if (isset($foreignObjectsByObjectId[$object->getId()])) {
             $foreignObject = $foreignObjectsByObjectId[$object->getId()];
             if ($object->{$idGetter}() != $foreignObject->getId()) {
                 $object->{$idSetter}($foreignObject->getId());
                 $objectsToUpdate[] = $object;
             }
         }
     }
     $this->objectMapper->saveAll($objectsToUpdate);
 }
Ejemplo n.º 2
0
 /**
  * Loads objects of the foreign class onto the supplied objects linked by a link table containing the id's of both objects
  *
  * @param DataObjectInterface[] $objects
  * @param string $className Class name of foreign objects to load
  * @param string $linkTable Table that links two objects together
  * @param string $idColumn Column on link table = the id on this object
  * @param string $foreignIdColumn Column on link table = the id on the foreign object table
  * @return DataObjectInterface[] Loaded objects keyed by id
  */
 public function loadManyToMany(array $objects, $className, $linkTable, $idColumn = null, $foreignIdColumn = null)
 {
     if (empty($objects)) {
         return [];
     }
     $ids = DataObject::getIds($objects);
     $queryHelper = $this->objectMapper->getQueryHelper();
     $db = $queryHelper->getConnection();
     $qb = $queryHelper->buildSelectQuery($linkTable, [$db->quoteIdentifier($idColumn) . ' AS id', $db->quoteIdentifier($foreignIdColumn) . ' AS ' . $db->quoteIdentifier('foreignId')], [$idColumn => $ids]);
     $foreignIdsById = [];
     $foreignIds = [];
     $linkRows = $qb->execute();
     $linkRows->setFetchMode(\PDO::FETCH_OBJ);
     foreach ($linkRows as $linkRow) {
         $foreignIdsById[$linkRow->id][] = $linkRow->foreignId;
         $foreignIds[$linkRow->foreignId] = true;
     }
     $foreignObjects = $this->objectMapper->findByIds($className, array_keys($foreignIds));
     unset($foreignIds);
     $foreignObjectsById = [];
     foreach ($foreignObjects as $foreignObject) {
         $foreignObjectsById[$foreignObject->getId()] = $foreignObject;
     }
     unset($foreignObjects);
     $setter = 'set' . $this->inflector->methodNameFromColumn($foreignIdColumn, true);
     foreach ($objects as $object) {
         if (method_exists($object, $setter)) {
             $foreignObjects = [];
             if (isset($foreignIdsById[$object->getId()])) {
                 $foreignIds = $foreignIdsById[$object->getId()];
                 foreach ($foreignIds as $foreignId) {
                     $foreignObjects[] = $foreignObjectsById[$foreignId];
                 }
             }
             $object->{$setter}($foreignObjects);
         } else {
             throw new MethodNotImplementedException("{$setter} must be defined on {$object->getClassName()} to load many-to-many relationship with {$className}");
         }
     }
     return $foreignObjectsById;
 }