1
0
mirror of synced 2025-02-20 22:23:14 +03:00

Merge pull request #1089 from encoder32/EntityRepositoryGeneratorDefaultRepository

EntityRepositoryGenerator default repository
This commit is contained in:
Marco Pivetta 2014-11-11 16:22:51 +01:00
commit ab62914f87
9 changed files with 511 additions and 9 deletions

View File

@ -73,6 +73,8 @@ EOT
$metadatas = $em->getMetadataFactory()->getAllMetadata();
$metadatas = MetadataFilter::filter($metadatas, $input->getOption('filter'));
$repositoryName = $em->getConfiguration()->getDefaultRepositoryClassName();
// Process destination directory
$destPath = realpath($input->getArgument('dest-path'));
@ -92,6 +94,8 @@ EOT
$numRepositories = 0;
$generator = new EntityRepositoryGenerator();
$generator->setDefaultRepositoryName($repositoryName);
foreach ($metadatas as $metadata) {
if ($metadata->customRepositoryClassName) {
$output->writeln(

View File

@ -32,20 +32,20 @@ namespace Doctrine\ORM\Tools;
*/
class EntityRepositoryGenerator
{
private $repositoryName;
protected static $_template =
'<?php
<namespace>
use Doctrine\ORM\EntityRepository;
/**
* <className>
*
* This class was generated by the Doctrine ORM. Add your own custom
* repository methods below.
*/
class <className> extends EntityRepository
class <className> extends <repositoryName>
{
}
';
@ -57,16 +57,49 @@ class <className> extends EntityRepository
*/
public function generateEntityRepositoryClass($fullClassName)
{
$className = substr($fullClassName, strrpos($fullClassName, '\\') + 1, strlen($fullClassName));
$variables = array(
'<namespace>' => $this->generateEntityRepositoryNamespace($fullClassName),
'<className>' => $className
'<namespace>' => $this->generateEntityRepositoryNamespace($fullClassName),
'<repositoryName>' => $this->generateEntityRepositoryName($fullClassName),
'<className>' => $this->generateClassName($fullClassName)
);
return str_replace(array_keys($variables), array_values($variables), self::$_template);
}
/**
* Generates the namespace, if class do not have namespace, return empty string instead.
*
* @param string $fullClassName
*
* @return string $namespace
*/
private function getClassNamespace($fullClassName)
{
$namespace = substr($fullClassName, 0, strrpos($fullClassName, '\\'));
return $namespace;
}
/**
* Generates the class name
*
* @param string $fullClassName
*
* @return string
*/
private function generateClassName($fullClassName)
{
$namespace = $this->getClassNamespace($fullClassName);
$className = $fullClassName;
if ($namespace) {
$className = substr($fullClassName, strrpos($fullClassName, '\\') + 1, strlen($fullClassName));
}
return $className;
}
/**
* Generates the namespace statement, if class do not have namespace, return empty string instead.
*
@ -76,11 +109,29 @@ class <className> extends EntityRepository
*/
private function generateEntityRepositoryNamespace($fullClassName)
{
$namespace = substr($fullClassName, 0, strrpos($fullClassName, '\\'));
$namespace = $this->getClassNamespace($fullClassName);
return $namespace ? 'namespace ' . $namespace . ';' : '';
}
/**
* @param string $fullClassName
*
* @return string $repositoryName
*/
private function generateEntityRepositoryName($fullClassName)
{
$namespace = $this->getClassNamespace($fullClassName);
$repositoryName = $this->repositoryName ?: 'Doctrine\ORM\EntityRepository';
if ($namespace && $repositoryName[0] !== '\\') {
$repositoryName = '\\' . $repositoryName;
}
return $repositoryName;
}
/**
* @param string $fullClassName
* @param string $outputDirectory
@ -103,4 +154,17 @@ class <className> extends EntityRepository
file_put_contents($path, $code);
}
}
/**
* @param string $repositoryName
*
* @return \Doctrine\ORM\Tools\EntityRepositoryGenerator
*/
public function setDefaultRepositoryName($repositoryName)
{
$this->repositoryName = $repositoryName;
return $this;
}
}

View File

@ -0,0 +1,7 @@
<?php
namespace Doctrine\Tests\Models\DDC3231;
class DDC3231EntityRepository extends \Doctrine\ORM\EntityRepository
{
}

View File

@ -0,0 +1,23 @@
<?php
namespace Doctrine\Tests\Models\DDC3231;
/**
* @Entity(repositoryClass="DDC3231User1Repository")
* @Table(name="users")
*/
class DDC3231User1
{
/**
* @Id
* @Column(type="integer")
* @GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @Column(type="string", length=255)
*/
protected $name;
}

View File

@ -0,0 +1,21 @@
<?php
/**
* @Entity(repositoryClass="DDC3231User1NoNamespaceRepository")
* @Table(name="no_namespace_users")
*/
class DDC3231User1NoNamespace
{
/**
* @Id
* @Column(type="integer")
* @GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @Column(type="string", length=255)
*/
protected $name;
}

View File

@ -0,0 +1,23 @@
<?php
namespace Doctrine\Tests\Models\DDC3231;
/**
* @Entity(repositoryClass="DDC3231User2Repository")
* @Table(name="users2")
*/
class DDC3231User2
{
/**
* @Id
* @Column(type="integer")
* @GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @Column(type="string", length=255)
*/
protected $name;
}

View File

@ -0,0 +1,21 @@
<?php
/**
* @Entity(repositoryClass="DDC3231User2NoNamespaceRepository")
* @Table(name="no_namespace_users2")
*/
class DDC3231User2NoNamespace
{
/**
* @Id
* @Column(type="integer")
* @GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @Column(type="string", length=255)
*/
protected $name;
}

View File

@ -0,0 +1,143 @@
<?php
namespace Doctrine\Tests\ORM\Tools\Console\Command;
use Doctrine\ORM\Tools\Console\Command\GenerateRepositoriesCommand;
use Doctrine\ORM\Tools\Console\Helper\EntityManagerHelper;
use Symfony\Component\Console\Tester\CommandTester;
use Symfony\Component\Console\Helper\HelperSet;
use Symfony\Component\Console\Application;
use Doctrine\Tests\OrmFunctionalTestCase;
/**
* GenerateRepositoriesCommandTest
*/
class GenerateRepositoriesCommandTest extends OrmFunctionalTestCase
{
/**
* @var \Symfony\Component\Console\Application
*/
private $application;
private $path;
/**
* @inheritdoc
*/
protected function setUp()
{
parent::setUp();
$this->path = \sys_get_temp_dir() . DIRECTORY_SEPARATOR . uniqid('doctrine_');
\mkdir($this->path);
$metadataDriver = $this->_em->getConfiguration()->getMetadataDriverImpl();
$metadataDriver->addPaths(array(
__DIR__ . '/../../../../Models/DDC3231/'
));
$this->application = new Application();
$this->application->setHelperSet(new HelperSet(array(
'em' => new EntityManagerHelper($this->_em)
)));
$this->application->add(new GenerateRepositoriesCommand());
}
/**
* @inheritdoc
*/
public function tearDown()
{
$dirs = array();
$ri = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($this->path));
foreach ($ri AS $file) {
/* @var $file \SplFileInfo */
if ($file->isFile()) {
\unlink($file->getPathname());
} elseif ($file->getBasename() === '.') {
$dirs[] = $file->getRealpath();
}
}
arsort($dirs);
foreach ($dirs as $dir) {
\rmdir($dir);
}
parent::tearDown();
}
public function testGenerateRepositories()
{
$this->generateRepositories('DDC3231User1');
$cname = 'Doctrine\Tests\Models\DDC3231\DDC3231User1Repository';
$fname = str_replace('\\', DIRECTORY_SEPARATOR, $cname) . '.php';
$this->assertFileExists($this->path . DIRECTORY_SEPARATOR . $fname);
$this->assertFileExists($this->path . DIRECTORY_SEPARATOR . 'DDC3231User1NoNamespaceRepository.php');
require $this->path . DIRECTORY_SEPARATOR . $fname;
require $this->path . DIRECTORY_SEPARATOR . 'DDC3231User1NoNamespaceRepository.php';
$this->assertTrue(class_exists($cname));
$this->assertTrue(class_exists('DDC3231User1NoNamespaceRepository'));
$repo1 = new \ReflectionClass($cname);
$repo2 = new \ReflectionClass('DDC3231User1NoNamespaceRepository');
$this->assertSame('Doctrine\ORM\EntityRepository', $repo1->getParentClass()->getName());
$this->assertSame('Doctrine\ORM\EntityRepository', $repo2->getParentClass()->getName());
}
public function testGenerateRepositoriesCustomDefaultRepository()
{
$this->generateRepositories('DDC3231User2', 'Doctrine\Tests\Models\DDC3231\DDC3231EntityRepository');
$cname = 'Doctrine\Tests\Models\DDC3231\DDC3231User2Repository';
$fname = str_replace('\\', DIRECTORY_SEPARATOR, $cname) . '.php';
$this->assertFileExists($this->path . DIRECTORY_SEPARATOR . $fname);
$this->assertFileExists($this->path . DIRECTORY_SEPARATOR . 'DDC3231User2NoNamespaceRepository.php');
require $this->path . DIRECTORY_SEPARATOR . $fname;
require $this->path . DIRECTORY_SEPARATOR . 'DDC3231User2NoNamespaceRepository.php';
$this->assertTrue(class_exists($cname));
$this->assertTrue(class_exists('DDC3231User2NoNamespaceRepository'));
$repo1 = new \ReflectionClass($cname);
$repo2 = new \ReflectionClass('DDC3231User2NoNamespaceRepository');
$this->assertSame('Doctrine\Tests\Models\DDC3231\DDC3231EntityRepository', $repo1->getParentClass()->getName());
$this->assertSame('Doctrine\Tests\Models\DDC3231\DDC3231EntityRepository', $repo2->getParentClass()->getName());
}
/**
* @param string $filter
* @param string $defaultRepository
*/
private function generateRepositories($filter, $defaultRepository = null)
{
if ($defaultRepository) {
$this->_em->getConfiguration()->setDefaultRepositoryClassName($defaultRepository);
}
$command = $this->application->find('orm:generate-repositories');
$tester = new CommandTester($command);
$tester->execute(array(
'command' => $command->getName(),
'dest-path' => $this->path,
'--filter' => $filter,
));
}
}

View File

@ -0,0 +1,196 @@
<?php
namespace Doctrine\Tests\ORM\Tools;
use Doctrine\ORM\Tools\EntityGenerator;
use Doctrine\ORM\Tools\EntityRepositoryGenerator;
use Doctrine\ORM\Mapping\ClassMetadataFactory;
class EntityRepositoryGeneratorTest extends \Doctrine\Tests\OrmTestCase
{
/**
* @var EntityGenerator
*/
private $_generator;
/**
* @var EntityRepositoryGenerator
*/
private $_repositoryGenerator;
private $_tmpDir;
private $_namespace;
/**
* @inheritdoc
*/
public function setUp()
{
$this->_namespace = uniqid('doctrine_');
$this->_tmpDir = \sys_get_temp_dir() . DIRECTORY_SEPARATOR . $this->_namespace;
\mkdir($this->_tmpDir);
$this->_generator = new EntityGenerator();
$this->_generator->setAnnotationPrefix("");
$this->_generator->setGenerateAnnotations(true);
$this->_generator->setGenerateStubMethods(true);
$this->_generator->setRegenerateEntityIfExists(false);
$this->_generator->setUpdateEntityIfExists(true);
$this->_generator->setFieldVisibility(EntityGenerator::FIELD_VISIBLE_PROTECTED);
$this->_repositoryGenerator = new EntityRepositoryGenerator();
}
/**
* @inheritdoc
*/
public function tearDown()
{
$dirs = array();
$ri = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($this->_tmpDir));
foreach ($ri AS $file) {
/* @var $file \SplFileInfo */
if ($file->isFile()) {
\unlink($file->getPathname());
} elseif ($file->getBasename() === '.') {
$dirs[] = $file->getRealpath();
}
}
arsort($dirs);
foreach ($dirs as $dir) {
\rmdir($dir);
}
}
/**
* @group DDC-3231
*/
public function testGeneratedEntityRepositoryClass()
{
$em = $this->_getTestEntityManager();
$ns = $this->_namespace;
require_once __DIR__ . '/../../Models/DDC3231/DDC3231User1.php';
$className = $ns . '\DDC3231User1Tmp';
$this->writeEntityClass('Doctrine\Tests\Models\DDC3231\DDC3231User1', $className);
$rpath = $this->writeRepositoryClass($className);
$this->assertFileExists($rpath);
require $rpath;
$repo = new \ReflectionClass($em->getRepository($className));
$this->assertTrue($repo->inNamespace());
$this->assertSame($className . 'Repository', $repo->getName());
$this->assertSame('Doctrine\ORM\EntityRepository', $repo->getParentClass()->getName());
require_once __DIR__ . '/../../Models/DDC3231/DDC3231User1NoNamespace.php';
$className2 = 'DDC3231User1NoNamespaceTmp';
$this->writeEntityClass('DDC3231User1NoNamespace', $className2);
$rpath2 = $this->writeRepositoryClass($className2);
$this->assertFileExists($rpath2);
require $rpath2;
$repo2 = new \ReflectionClass($em->getRepository($className2));
$this->assertFalse($repo2->inNamespace());
$this->assertSame($className2 . 'Repository', $repo2->getName());
$this->assertSame('Doctrine\ORM\EntityRepository', $repo2->getParentClass()->getName());
}
/**
* @group DDC-3231
*/
public function testGeneratedEntityRepositoryClassCustomDefaultRepository()
{
$em = $this->_getTestEntityManager();
$ns = $this->_namespace;
require_once __DIR__ . '/../../Models/DDC3231/DDC3231User2.php';
$className = $ns . '\DDC3231User2Tmp';
$this->writeEntityClass('Doctrine\Tests\Models\DDC3231\DDC3231User2', $className);
$rpath = $this->writeRepositoryClass($className, 'Doctrine\Tests\Models\DDC3231\DDC3231EntityRepository');
$this->assertNotNull($rpath);
$this->assertFileExists($rpath);
require $rpath;
$repo = new \ReflectionClass($em->getRepository($className));
$this->assertTrue($repo->inNamespace());
$this->assertSame($className . 'Repository', $repo->getName());
$this->assertSame('Doctrine\Tests\Models\DDC3231\DDC3231EntityRepository', $repo->getParentClass()->getName());
require_once __DIR__ . '/../../Models/DDC3231/DDC3231User2NoNamespace.php';
$className2 = 'DDC3231User2NoNamespaceTmp';
$this->writeEntityClass('DDC3231User2NoNamespace', $className2);
$rpath2 = $this->writeRepositoryClass($className2, 'Doctrine\Tests\Models\DDC3231\DDC3231EntityRepository');
$this->assertNotNull($rpath2);
$this->assertFileExists($rpath2);
require $rpath2;
$repo2 = new \ReflectionClass($em->getRepository($className2));
$this->assertFalse($repo2->inNamespace());
$this->assertSame($className2 . 'Repository', $repo2->getName());
$this->assertSame('Doctrine\Tests\Models\DDC3231\DDC3231EntityRepository', $repo2->getParentClass()->getName());
}
/**
* @param string $className
* @param string $newClassName
* @return string
*/
private function writeEntityClass($className, $newClassName)
{
$cmf = new ClassMetadataFactory();
$em = $this->_getTestEntityManager();
$cmf->setEntityManager($em);
$metadata = $cmf->getMetadataFor($className);
$metadata->namespace = $this->_namespace;
$metadata->name = $newClassName;
$metadata->customRepositoryClassName = $newClassName . "Repository";
$this->_generator->writeEntityClass($metadata, $this->_tmpDir);
require $this->_tmpDir . DIRECTORY_SEPARATOR . str_replace('\\', DIRECTORY_SEPARATOR, $newClassName) . ".php";
}
/**
* @param string $className
* @param string $defaultRepository
* @return string
*/
private function writeRepositoryClass($className, $defaultRepository = null)
{
$this->_repositoryGenerator->setDefaultRepositoryName($defaultRepository);
$this->_repositoryGenerator->writeEntityRepositoryClass($className . 'Repository', $this->_tmpDir);
return $this->_tmpDir . DIRECTORY_SEPARATOR . str_replace('\\', DIRECTORY_SEPARATOR, $className) . 'Repository.php';
}
}