public function validate($data) { if (empty($data)) { $e = new EmptyDataException(); $e->setDefaultValue(array()); throw $e; } $data = json_decode($data, true); if (count($data) == 0) { $e = new EmptyDataException(); $e->setDefaultValue(array()); throw $e; } $rep = $this->em->getRepository($this->entityName); $collection = $rep->findAllByIds($data, $this->idName); // überspringt dies fehlende Ids? // sortieren nach der Data List (da findAllByIds das nicht tut, und das ist auch gut so) $getter = \Psc\Code\Code::castGetter($this->idName); $keys = array_flip($data); usort($collection, function ($entityA, $entityB) use($keys, $getter) { $keyA = $keys[$getter($entityA)]; $keyB = $keys[$getter($entityB)]; if ($keyA === $keyB) { return 0; } return $keyA > $keyB ? 1 : -1; }); if (count($collection) == count($data)) { return $collection; } else { throw new \Psc\Exception('Unexpected: Es wurden: ' . count($collection) . ' IDs hydriert, aber ' . count($data) . ' IDs angegeben.'); } }
/** * @var mixed $print Closure|String wenn ein String wird dies als Attribute gesehen welches mit get$print() vom Objekt geladen werden kann */ public static function listObjects($objectCollection, $sep = ', ', $print = 'Id', $andsep = NULL, Closure $formatter = NULL) { $objectCollection = Code::castArray($objectCollection); $cnt = count($objectCollection); if (isset($andsep) && $cnt > 1) { $last = array_pop($objectCollection); } else { $andsep = NULL; } if (is_string($print) || $print instanceof Closure) { $g = Code::castGetter($print); } else { throw new \InvalidArgumentException('Unbekannter Parameter für $print: ' . Code::varInfo($print)); } $formatter = $formatter ?: function ($item) { return (string) $item; }; $ret = A::implode($objectCollection, $sep, function ($object, $key) use($g, $formatter) { // formatiere das $print-Attribute von $object return $formatter($g($object, $key), $key); }); if (isset($andsep) && $last != NULL) { $ret .= $andsep . $formatter($g($last)); } return $ret; }
protected function generateGetter($property) { return Code::castGetter($property); }
public function sortComponentsBy($property) { Code::value($property, 'formName', 'formValue', 'formLabel', 'componentName'); $getter = Code::castGetter($property); $sorting = function ($c1, $c2) use($getter) { return strcmp($getter($c1), $getter($c2)); }; $this->sortComponents($sorting); return $this; }
/** * Fügt die beiden Collections Ahand der Funktion $getIndex zusammen * * der Array hat als schlüssel die werte von jedem objekt der collection auf das $getIndex angewandt wurde * jedes Element kommt nur einmal vor. * * @see Code::castGetter() */ public static function mergeUnique(array $collection1, array $collection2, $getIndex1, $getIndex2 = NULL) { $getIndex1 = Code::castGetter($getIndex1); if (!isset($getIndex2)) { $getIndex2 = $getIndex1; } else { $getIndex2 = Code::castGetter($getIndex2); } $merge = array(); foreach ($collection1 as $o) { $merge[$getIndex1($o)] = $o; } foreach ($collection2 as $o) { $index = $getIndex2($o); if (!array_key_exists($index, $merge)) { $merge[$index] = $o; } } return $merge; }
/** * Synchronisiert eine Collection eines Entities mit Entities in der Datenbank (deprecated) * * Diese Art der Synchroniserung ist deprecated, weil es mittlerweile ausgelagerte Funktionen dafür gibt * (siehe Psc\Doctrine\*Synchro*) * * also es werden für die bestehenden Objekte in $entity->$collectionProperty die objekte gelöscht * die nicht in newCollection drin sind und die, die in $newCollection drin sind aber nicht in * $entity->$collectionProperty gelöscht * * - Achtung(!): dies führt persist() auf den Entitys der Collection (also quasi andere Seite der Association) aus, wenn $this->entity nicht die Owning-Side der CollectionAssociation ist * - Dies führt persist für items in newCollection, die neu sind * * Die Basis für eine erfolgreiche Synchronization ist eine $newCollection die wirklich die gleichen Objekte enthält, für die Updates gemacht werden sollen. Also vorsicht mit serialisierten Einträgen und clones * * @param string $associationName der Name des Properties der Collection in $entity */ public function synchronizeCollection($associationName, $newCollection) { if (!is_string($associationName)) { throw new \Psc\Exception('string erwartet: ' . Code::varInfo($associationName)); } /* $mapping = $coll->getMapping(); $targetClass = $this->_em->getClassMetadata($mapping['targetEntity']); $sourceClass = $this->_em->getClassMetadata($mapping['sourceEntity']); $id = $this->_em->getUnitOfWork()->getEntityIdentifier($coll->getOwner()); */ if ($this->entity instanceof \Psc\Doctrine\Object) { $entityClass = $this->entity->getDoctrineMetadata(); // Sound } elseif ($this->entity instanceof \Psc\Doctrine\Entity) { $entityClass = $this->em->getClassMetadata($this->entity->getEntityName()); } else { throw new \InvalidArgumentException('$this->entity ist von der Klasse: ' . Code::getClass($this->entity) . ' und diese ist unbekannt'); } $entityAssoc = $entityClass->getAssociationMapping($associationName); // speakers $owning = $entityAssoc['isOwningSide']; // true $targetClass = $this->em->getClassMetadata($entityAssoc['targetEntity']); // Metadata:Speaker if ($owning) { $entityProperty = $entityAssoc['inversedBy']; $collectionProperty = $entityAssoc['fieldName']; } else { $entityProperty = $entityAssoc['mappedBy']; $collectionProperty = $entityAssoc['fieldName']; } // entityProperty = sounds // collectionProperty = speakers $getter = Code::castGetter($collectionProperty); //getSpeakers $collection = $getter($this->entity); // $this->entity->getSpeakers() $collection = Code::castCollection($collection); $newCollection = Code::castCollection($newCollection); $this->log(sprintf("synchronizeCollection '%s'", $associationName)); $this->log('in DBCollection:'); $this->log(DoctrineHelper::debugCollection($collection)); $this->log(NULL); $this->log('in FormCollection:'); $this->log(DoctrineHelper::debugCollection($newCollection)); $this->log(NULL); $this->log('Processing:'); /* Wir synchronisieren hier auf der Owning Side oder Reverse Side jenachdem müssen wir auf der owning oder reverse side die add + remove funktionen aufrufen */ if ($owning) { $remove = 'remove' . ucfirst(Inflector::singular($collectionProperty)); // removeSpeaker $add = 'add' . ucfirst(Inflector::singular($collectionProperty)); // addSpeaker } else { $remove = 'remove' . ucfirst(Inflector::singular($entityProperty)); // removeSound $add = 'add' . ucfirst(Inflector::singular($entityProperty)); // addSound } $logThis = Code::getClassName($entityClass->getName()); // @TODO hier mit reflection prüfen //if (!->hasMethod($remove)) { // throw new \Psc\Exception('Es gibt keine '.$remove.' Methode im Entity: '.$owningEntity); //} //if (!$this->entity->hasMethod($add)) { // throw new \Psc\Exception('Es gibt keine '.$add.' Methode im Entity: '.$owningEntity); //} // foreach ($collection->deleteDiff($newCollection, ArrayCollection::COMPARE_OBJECTS) as $entity) { if ($owning) { $this->entity->{$remove}($entity); // $sound->removeSpeaker($speaker) } else { $this->em->persist($entity); // $speaker persist $entity->{$remove}($this->entity); // $speaker->removeSound($sound) } } foreach ($collection->insertDiff($newCollection, ArrayCollection::COMPARE_OBJECTS) as $entity) { if ($owning) { $this->entity->{$add}($entity); $this->em->persist($entity); } else { $entity->{$add}($this->entity); $this->em->persist($entity); } } }
public function testCastGetter() { $object = new TestingClass('v1', 'v2'); // pre $this->assertEquals('v1', $object->getProp1()); $this->assertEquals('v2', $object->getProp2()); // test $getter = Code::castGetter('prop1'); $this->assertEquals('v1', $getter($object)); $getter = Code::castGetter('prop2'); $this->assertEquals('v2', $getter($object)); // test mit get $getter = Code::castGetter('getProp1'); $this->assertEquals('v1', $getter($object)); $getter = Code::castGetter('getProp2'); $this->assertEquals('v2', $getter($object)); }