Skip to content

Instantly share code, notes, and snippets.

@mattjanssen
Created December 18, 2013 06:48
Show Gist options
  • Save mattjanssen/8018266 to your computer and use it in GitHub Desktop.
Save mattjanssen/8018266 to your computer and use it in GitHub Desktop.
Updated khepin/yaml-fixtures-bundle to query for existing entities before persisting a new one.
<?php
namespace Khepin\YamlFixturesBundle\Fixture;
use Doctrine\Common\Util\Inflector;
use Doctrine\ORM\Mapping\ClassMetadata;
class OrmYamlFixture extends AbstractFixture
{
/**
* @param object $class
* @param array $data
* @param ClassMetadata $metadata
* @param array $options
* @return Object
*/
public function createObject($class, $data, $metadata, $options = array())
{
$object = new $class;
$this->fillObject($object, $data, $metadata, true);
$uniqueFields = array();
$allFields = array();
foreach ($metadata->fieldMappings as $field => $fieldMapping) {
$reflectionProperty = new \ReflectionProperty($object, $field);
$reflectionProperty->setAccessible(true);
$value = $reflectionProperty->getValue($object);
if (null === $value) {
continue;
}
$allFields[$field] = $value;
if (!empty($fieldMapping['unique'])) {
$uniqueFields[$field] = $value;
}
}
$repository = $this->manager->getRepository($class);
$existingEntity = $repository->findOneBy($uniqueFields ? $uniqueFields : $allFields);
if (null !== $existingEntity) {
$object = $existingEntity;
}
$this->fillObject($object, $data, $metadata, false);
return $object;
}
private function fillObject($object, $data, $metadata, $noAssociations) {
$mapping = array_keys($metadata->fieldMappings);
$associations = array_keys($metadata->associationMappings);
foreach ($data as $field => $value) {
// Add the fields defined in the fistures file
$method = Inflector::camelize('set_' . $field);
//
if (in_array($field, $mapping)) {
// Dates need to be converted to DateTime objects
$type = $metadata->fieldMappings[$field]['type'];
if ($type == 'datetime' OR $type == 'date') {
$value = new \DateTime($value);
}
$object->$method($value);
} elseif (in_array($field, $associations)) { // This field is an association
if ($noAssociations) {
continue;
}
if (is_array($value)) { // The field is an array of associations
$referenceArray = array();
foreach ($value as $referenceObject) {
$referenceArray[] = $this->loader->getReference($referenceObject);
}
$object->$method($referenceArray);
} else {
$object->$method($this->loader->getReference($value));
}
} else {
// It's a method call that will set a field named differently
// eg: FOSUserBundle ->setPlainPassword sets the password after
// Encrypting it
$object->$method($value);
}
}
$this->runServiceCalls($object);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment