protected function setUp() { parent::setUp(); $this->targetDir = '../data/' . self::TARGET_DIR_NAME; $this->fullDirPath = static::getContainer()->getParameter('kernel.root_dir') . '/' . $this->targetDir; EntityHelper::buildDBSchema($this->em); (new FixturesLoader())->withManager($this->em)->fromDir(__DIR__ . '/../data/alice_fixtures_for_loading')->load(); }
public function testRun() { $app = new Application(self::$kernel); $app->addCommands([new LoadFixturesCommand()]); $command = $app->find('amstaffix:fixtures:load'); $commandTester = new CommandTester($command); $commandTester->execute(['command' => $command->getName(), 'dir-with-fixtures' => $this->dirWithFixtures], ['interactive' => false]); $this->assertEquals(4, EntityHelper::getCountOfEntities($this->em, 'CoreTestFixture\\TestBundle\\Entity\\Article')); $this->assertEquals(3, EntityHelper::getCountOfEntities($this->em, 'CoreTestFixture\\TestBundle\\Entity\\Author')); $this->assertEquals(8, EntityHelper::getCountOfEntities($this->em, 'CoreTestFixture\\TestBundle\\Entity\\Book')); }
/** * Метод осуществляет выборку сущностей из менеджера сущностей, создает контент и записывает в файл * * @param \Doctrine\ORM\EntityManager $em * @param string $dirForGeneratedFixtures директория, в которой будут созданы файлы с фикстурами * @param string $className полное имя класса для создания фикстур * @param int $entitiesPerClass кол-во сущностей на один класс * @param int $entitiesPerFile кол-во сущностей в одном файле */ private function generateFixtureForEntityClass(EntityManager $em, $dirForGeneratedFixtures, $className, $entitiesPerClass = self::DEFAULT_MAX_ENTITIES_COUNT, $entitiesPerFile = self::DEFAULT_ENTITIES_PER_FILE) { $metadata = $em->getClassMetadata($className); $countEntitiesInDB = EntityHelper::getCountOfEntities($em, $className); $howManyEntitiesShouldBe = min($entitiesPerClass, $countEntitiesInDB); $countOfFiles = ceil($howManyEntitiesShouldBe / $entitiesPerFile); $shortClassName = Helper::getClassNameWithoutNamespace($className); for ($fileNo = 0; $fileNo < $countOfFiles; $fileNo++) { $entities = $em->getRepository($className)->findBy([], null, $entitiesPerFile, $entitiesPerFile * $fileNo); $content = "{$className}:\n"; foreach ($entities as &$entity) { $id = $metadata->getSingleIdReflectionProperty()->getValue($entity); $content .= " entity_{$id}:\n"; $fieldNames = $metadata->getFieldNames(); foreach ($fieldNames as $fieldName) { $fieldValue = $metadata->getFieldValue($entity, $fieldName); if ($fieldValue instanceof \DateTime) { $fieldValue = "'" . $fieldValue->format(self::DATETIME_FORMAT) . "'"; } elseif (is_string($fieldValue)) { $fieldValue = str_replace("\n", '', $fieldValue); /* * Этот кусок написан из-за того, что кавычки (" и ') являются частью YAML, и неожиданное их появление * в строковых значение рушит парсер, так что там где встречаются кавычки, мы их обрамляем на "противоположенные", т.е. * если есть ", то обрамим в '; * если есть ', то обрамим в "; * * насчет появления обоих этих кавычек пока ничего сказать не могу... */ if (strpos($fieldValue, '"') !== false) { $fieldValue = "'{$fieldValue}'"; } elseif (strpos($fieldValue, "'") !== false) { $fieldValue = sprintf('"%s"', $fieldValue); } /* * Вот я не знаю что это за знак такой ... но вроде так работает... */ $fieldValue = str_replace("\n", ' ', $fieldValue); } /* * Т.к. true и false не записываются в текстовой файл, то для них сделаем такую штуку. */ if (is_bool($fieldValue)) { $fieldValue = $fieldValue ? 'true' : 'false'; } $content .= " {$fieldName}: {$fieldValue}\n"; } } $filePath = $dirForGeneratedFixtures . "/{$shortClassName}_{$fileNo}." . self::FILE_EXTENSION; file_put_contents($filePath, $content); $em->clear(); } }
/** * Возвращает рандомную сущность из всех возможных * * @param EntityManager $em менеджер сущностей * @param string $entityFullClassName наименование сущности, которое поймет менеджер * * @throws \Doctrine\ORM\ORMException выкидывается, если не была найдена ни одна сущность * @return object сущность полученная из БД */ public static function getOneRandomEntity(EntityManager $em, $entityFullClassName) { $primaryKeyData = EntityHelper::getOneRandomEntityId($em, $entityFullClassName); // Сделал исключение, т.к. вызывая этот метод клиент должен быть уверен в том, что вернется какая-то сущность if ($primaryKeyData === null) { throw new ORMException("Случайная сущность {$entityFullClassName} не была найдена, скорее всего таблица пустая"); } if (is_array($primaryKeyData)) { $entity = $em->getRepository($entityFullClassName)->findOneBy($primaryKeyData); } else { $entity = $em->getRepository($entityFullClassName)->find($primaryKeyData); } return $entity; }
/** * [ВНИМАНИЕ] * Если у сущности генератор первичного ключа отсутствует, т.е. необходимо задать вручную ключ, то необходимо удалить * первичный ключ из структуры, чтобы не было попыток найти эту сущность. Ошибка описана в ссылке ниже * @link https://github.com/jamesmoey/extjs-bundle/issues/17 * @inheritdoc */ public function run() { $this->checkIsInit(); $obj = json_decode($this->requestContent, false, 512, JSON_BIGINT_AS_STRING); $response = new RestResponse(); $savedPKValueFromRequestData = null; $PKFieldName = $this->getPKFieldName(); $entityNotHaveIdGenerator = $this->classMetadata->generatorType == ClassMetadata::GENERATOR_TYPE_NONE; if ($entityNotHaveIdGenerator) { if (!$this->isObjectHasPKField($obj) && !$this->isObjectHasNewPKField($obj)) { $response->setSuccess(false)->setStatusCode(RestResponse::STATUS_CODE_WRONG_INPUT_DATA)->setMessage(sprintf("Не указан первичный ключ (%s)", $PKFieldName)); return $response; } elseif (!$this->isObjectHasPKField($obj) && $this->isObjectHasNewPKField($obj)) { $savedPKValueFromRequestData = $this->getNewPKValueFromObject($obj); unset($obj->{$this->getNewPKValueFromObject($obj)}); } elseif ($this->isObjectHasPKField($obj) && !$this->isObjectHasNewPKField($obj)) { $savedPKValueFromRequestData = $obj->{$PKFieldName}; unset($obj->{$PKFieldName}); } } $serializedObj = json_encode($obj); $entity = $this->serializer->deserialize($serializedObj, $this->classMetadata->getName(), 'json', DeserializationContext::create()->setGroups([Action::GROUP_DEFAULT, Action::GROUP_POST])); if ($entityNotHaveIdGenerator) { EntityHelper::changePKValue($this->em, $entity, $savedPKValueFromRequestData); } $validator = $this->validator; /** @var ConstraintViolationList $validations */ $validations = $validator->validate($entity); if (sizeof($validations) === 0) { try { $this->em->persist($entity); $this->em->flush(); $this->em->refresh($entity); $response->setSuccess(true)->setData($entity)->setStatusCode(RestResponse::STATUS_CODE_OK); } catch (DBALException $e) { $response->setSuccess(false)->setMessage($e->getMessage())->setStatusCode(RestResponse::STATUS_CODE_WRONG_INPUT_DATA); } } else { $response->setSuccess(false)->setStatusCode(RestResponse::STATUS_CODE_WRONG_INPUT_DATA)->setErrors($validations); } return $response; }
/** * @expectedException \LogicException * @expectedExceptionMessage Одно из названий ключа (soe) не было найдено среди ключей в сущности (id,ownerId) */ public function testThrowExceptionIfUseChangePKValueWithArrayWithNotEnoughItemsWhenEntityWithCompositeKeys2() { /** @var Client $book */ $book = $this->em->getRepository($this->bookFullClassName)->findOneBy(['id' => 1, 'ownerId' => 1]); EntityHelper::changePKValueAndSave($this->em, $book, ['soe' => 2, 'sad' => 3]); }
protected function getOneRandomEntity($shortEntityName = '') { if (empty($shortEntityName)) { $shortEntityName = self::$shortEntityName; } return EntityHelper::getOneRandomEntity(static::getEntityManager(), $shortEntityName); }
/** * * @param Object $content Обработанные данные из запроса * @return mixed */ protected function mergeDataFromRequestWithEntity($content) { $dContext = DeserializationContext::create()->setGroups($this->serializationContextGroups); $dContext->attributes->set('related_action', 'merge'); $entity = $this->serializer->deserialize(json_encode($content), $this->classMetadata->getName(), 'json', $dContext); if ($this->newPrimaryKeyValue !== null) { EntityHelper::changePKValue($this->em, $entity, $this->newPrimaryKeyValue); } return $entity; }
/** * Метод, который проверяет возможность изменения первичного ключа (обычно 'id') * P.S. * Сделал без префикса test, т.к. данная возможность необходима не всем сущностям * P.P.S. * Метод получился довольно большой, но разобраться вроде возможно. В переносе в другой класс пока нет необходимости */ public function patchWithNewPKValue() { $oldEntity = $this->getOneRandomEntity(); $oldEntityAsObj = $this->convertEntityToObj($oldEntity, [\Amstaffix\RestActions\Action::GROUP_GET]); // пришлось сделать тут, т.к. иначе не "инициализируется" TZone $oldPKValue = $this->getEntityPKValue($oldEntity); $newPKValue = EntityHelper::findNextFreeEntityId($this->em, self::$shortEntityName); $pkFieldName = $this->em->getClassMetadata(self::$shortEntityName)->getSingleIdentifierFieldName(); $newPKFieldName = 'new_' . $pkFieldName; $requestDataAlterer = function ($object) use($newPKValue, $newPKFieldName) { $object->{$newPKFieldName} = $newPKValue; return $object; }; $responseDataAsserter = function ($responseData) use($oldPKValue, $oldEntity, $newPKValue, $pkFieldName, $oldEntityAsObj) { $this->assertResponseData($responseData); $this->assertResponseObjectForSuccess($responseData, true); $this->assertResponseObjectForDataAttribute($responseData); $this->em->clear(); /* Теперь по старому идентификатору нельзя найти сущность */ $entityWithOldId = $this->em->getRepository(self::$shortEntityName)->find($oldPKValue); $this->assertNull($entityWithOldId); /* А вот по новому - можно */ $entityWithNewId = $this->em->getRepository(self::$shortEntityName)->find($newPKValue); $this->assertNotNull($entityWithNewId); $newEntityAsObj = $this->convertEntityToObj($entityWithNewId, [\Amstaffix\RestActions\Action::GROUP_GET]); /* т.к. первичные ключи теперь отличаются, уберем их из обоих объектов. */ unset($oldEntityAsObj->{$pkFieldName}); unset($newEntityAsObj->{$pkFieldName}); $this->assertTwoObjects($oldEntityAsObj, $newEntityAsObj); $this->assertTwoObjects($newEntityAsObj, $responseData->data); }; $action = (new PatchAction())->setDataAltererCallback($requestDataAlterer)->setEntityPKValue($oldPKValue)->addResponseDataAsserterCallback($responseDataAsserter); $this->initAction($action); $action->run(); }
public function testRun() { (new FixturesFromDBGenerator())->generateFixtures($this->em, self::$dir, self::$fullClassNames, 10, 2); /** @var $loader */ $loader = new Yaml(); $this->assertEquals(2, (new Finder())->files()->name("Author_*.yml")->in(self::$dir)->count()); $this->assertEquals(5, (new Finder())->files()->name("Book_*.yml")->in(self::$dir)->count()); $finder = (new Finder())->files()->name('*.yml')->in(self::$dir); foreach ($finder as $file) { /** @var SplFileInfo $file */ $objects = $loader->load($file->getPathname()); if (count($objects) > 0) { $className = get_class($objects[array_keys($objects)[0]]); $this->assertTrue(in_array($className, self::$fullClassNames)); foreach ($objects as $obj) { $id = EntityHelper::getPrimaryKey($this->em, $obj); $this->assertNotNull($this->em->getRepository($className)->find($id)); } } } }
private function getCountOfEntities($className) { return EntityHelper::getCountOfEntities($this->em, $className); }