refactored bundle management
Before I explain the changes, let's talk about the current state. Before this patch, the registerBundleDirs() method returned an ordered (for resource overloading) list of namespace prefixes and the path to their location. Here are some problems with this approach: * The paths set by this method and the paths configured for the autoloader can be disconnected (leading to unexpected behaviors); * A bundle outside these paths worked, but unexpected behavior can occur; * Choosing a bundle namespace was limited to the registered namespace prefixes, and their number should stay low enough (for performance reasons) -- moreover the current Bundle\ and Application\ top namespaces does not respect the standard rules for namespaces (first segment should be the vendor name); * Developers must understand the concept of "namespace prefixes" to understand the overloading mechanism, which is one more thing to learn, which is Symfony specific; * Each time you want to get a resource that can be overloaded (a template for instance), Symfony would have tried all namespace prefixes one after the other until if finds a matching file. But that can be computed in advance to reduce the overhead. Another topic which was not really well addressed is how you can reference a file/resource from a bundle (and take into account the possibility of overloading). For instance, in the routing, you can import a file from a bundle like this: <import resource="FrameworkBundle/Resources/config/internal.xml" /> Again, this works only because we have a limited number of possible namespace prefixes. This patch addresses these problems and some more. First, the registerBundleDirs() method has been removed. It means that you are now free to use any namespace for your bundles. No need to have specific prefixes anymore. You are also free to store them anywhere, in as many directories as you want. You just need to be sure that they are autoloaded correctly. The bundle "name" is now always the short name of the bundle class (like FrameworkBundle or SensioCasBundle). As the best practice is to prefix the bundle name with the vendor name, it's up to the vendor to ensure that each bundle name is unique. I insist that a bundle name must be unique. This was the opposite before as two bundles with the same name was how Symfony2 found inheritance. A new getParent() method has been added to BundleInterface. It returns the bundle name that the bundle overrides (this is optional of course). That way, there is no ordering problem anymore as the inheritance tree is explicitely defined by the bundle themselves. So, with this system, we can easily have an inheritance tree like the following: FooBundle < MyFooBundle < MyCustomFooBundle MyCustomFooBundle returns MyFooBundle for the getParent() method, and MyFooBundle returns FooBundle. If two bundles override the same bundle, an exception is thrown. Based on the bundle name, you can now reference any resource with this notation: @FooBundle/Resources/config/routing.xml @FooBundle/Controller/FooController.php This notation is the input of the Kernel::locateResource() method, which returns the location of the file (and of course it takes into account overloading). So, in the routing, you can now use the following: <import resource="@FrameworkBundle/Resources/config/internal.xml" /> The template loading mechanism also use this method under the hood. As a bonus, all the code that converts from internal notations to file names (controller names: ControllerNameParser, template names: TemplateNameParser, resource paths, ...) is now contained in several well-defined classes. The same goes for the code that look for templates (TemplateLocator), routing files (FileLocator), ... As a side note, it is really easy to also support multiple-inheritance for a bundle (for instance if a bundle returns an array of bundle names it extends). However, this is not implemented in this patch as I'm not sure we want to support that. How to upgrade: * Each bundle must now implement two new mandatory methods: getPath() and getNamespace(), and optionally the getParent() method if the bundle extends another one. Here is a common implementation for these methods: /** * {@inheritdoc} */ public function getParent() { return 'MyFrameworkBundle'; } /** * {@inheritdoc} */ public function getNamespace() { return __NAMESPACE__; } /** * {@inheritdoc} */ public function getPath() { return strtr(__DIR__, '\\', '/'); } * The registerBundleDirs() can be removed from your Kernel class; * If your code relies on getBundleDirs() or the kernel.bundle_dirs parameter, it should be upgraded to use the new interface (see Doctrine commands for many example of such a change); * When referencing a bundle, you must now always use its name (no more \ or / in bundle names) -- this transition was already done for most things before, and now applies to the routing as well; * Imports in routing files must be changed: Before: <import resource="Sensio/CasBundle/Resources/config/internal.xml" /> After: <import resource="@SensioCasBundle/Resources/config/internal.xml" />
This commit is contained in:
parent
252918beb2
commit
6d1e91a1fa
@ -20,4 +20,19 @@ use Symfony\Component\HttpKernel\Bundle\Bundle;
|
||||
*/
|
||||
class CompatAssetsBundle extends Bundle
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getNamespace()
|
||||
{
|
||||
return __NAMESPACE__;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getPath()
|
||||
{
|
||||
return strtr(__DIR__, '\\', '/');
|
||||
}
|
||||
}
|
||||
|
@ -83,8 +83,20 @@ abstract class AbstractDoctrineExtension extends Extension
|
||||
}
|
||||
|
||||
if ($mappingConfig['is_bundle']) {
|
||||
$namespace = $this->getBundleNamespace($mappingName, $container);
|
||||
$mappingConfig = $this->getMappingDriverBundleConfigDefaults($mappingConfig, $namespace, $mappingName, $container);
|
||||
$bundle = null;
|
||||
foreach ($container->getParameter('kernel.bundles') as $name => $class) {
|
||||
if ($mappingName === $name) {
|
||||
$bundle = new \ReflectionClass($class);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (null === $bundle) {
|
||||
throw new \InvalidArgumentException(sprintf('Bundle "%s" does not exist or it is not enabled.', $mappingName));
|
||||
}
|
||||
|
||||
$mappingConfig = $this->getMappingDriverBundleConfigDefaults($mappingConfig, $bundle, $container);
|
||||
if (!$mappingConfig) {
|
||||
continue;
|
||||
}
|
||||
@ -135,75 +147,25 @@ abstract class AbstractDoctrineExtension extends Extension
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the bundle directory for a namespace.
|
||||
*
|
||||
* If the namespace does not yield a direct match, this method will attempt
|
||||
* to match parent namespaces exhaustively.
|
||||
*
|
||||
* @param string $namespace A bundle namespace omitting the bundle name part
|
||||
* @param ContainerBuilder $container A ContainerBuilder instance
|
||||
*
|
||||
* @return string|false The bundle directory if found, false otherwise
|
||||
*/
|
||||
protected function findBundleDirForNamespace($namespace, $container)
|
||||
{
|
||||
$bundleDirs = $container->getParameter('kernel.bundle_dirs');
|
||||
|
||||
$segment = $namespace;
|
||||
do {
|
||||
if (isset($bundleDirs[$segment])) {
|
||||
return $bundleDirs[$segment] . str_replace('\\', '/', substr($namespace, strlen($segment)));
|
||||
}
|
||||
} while ($segment = substr($segment, 0, ($pos = strrpos($segment, '\\'))));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the namespace a bundle resides into.
|
||||
*
|
||||
* @param string $bundleName
|
||||
* @param ContainerBuilder $container
|
||||
* @return string
|
||||
*/
|
||||
protected function getBundleNamespace($bundleName, $container)
|
||||
{
|
||||
foreach ($container->getParameter('kernel.bundles') AS $bundleClassName) {
|
||||
$tmp = dirname(str_replace('\\', '/', $bundleClassName));
|
||||
$namespace = str_replace('/', '\\', dirname($tmp));
|
||||
$actualBundleName = basename($tmp);
|
||||
|
||||
if ($actualBundleName == $bundleName) {
|
||||
return $namespace;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* If this is a bundle controlled mapping all the missing information can be autodetected by this method.
|
||||
*
|
||||
* Returns false when autodetection failed, an array of the completed information otherwise.
|
||||
*
|
||||
* @param array $bundleConfig
|
||||
* @param string $namespace
|
||||
* @param string $bundleName
|
||||
* @param Container $container
|
||||
* @param array $bundleConfig
|
||||
* @param \ReflectionClass $bundle
|
||||
* @param Container $container
|
||||
*
|
||||
* @return array|false
|
||||
*/
|
||||
protected function getMappingDriverBundleConfigDefaults(array $bundleConfig, $namespace, $bundleName, $container)
|
||||
protected function getMappingDriverBundleConfigDefaults(array $bundleConfig, \ReflectionClass $bundle, $container)
|
||||
{
|
||||
$bundleDir = $this->findBundleDirForNamespace($namespace, $container);
|
||||
|
||||
if (!$bundleDir) {
|
||||
// skip this bundle if we cannot find its location, it must be misspelled or something.
|
||||
return false;
|
||||
}
|
||||
$bundleDir = dirname($bundle->getFilename());
|
||||
|
||||
if (!$bundleConfig['type']) {
|
||||
$bundleConfig['type'] = $this->detectMetadataDriver($bundleDir.'/'.$bundleName, $container);
|
||||
$bundleConfig['type'] = $this->detectMetadataDriver($bundleDir, $container);
|
||||
}
|
||||
|
||||
if (!$bundleConfig['type']) {
|
||||
// skip this bundle, no mapping information was found.
|
||||
return false;
|
||||
@ -211,16 +173,16 @@ abstract class AbstractDoctrineExtension extends Extension
|
||||
|
||||
if (!$bundleConfig['dir']) {
|
||||
if (in_array($bundleConfig['type'], array('annotation', 'static-php'))) {
|
||||
$bundleConfig['dir'] = $bundleDir.'/'.$bundleName.'/' . $this->getMappingObjectDefaultName();
|
||||
$bundleConfig['dir'] = $bundleDir.'/'.$this->getMappingObjectDefaultName();
|
||||
} else {
|
||||
$bundleConfig['dir'] = $bundleDir.'/'.$bundleName.'/' . $this->getMappingResourceConfigDirectory();
|
||||
$bundleConfig['dir'] = $bundleDir.'/'.$this->getMappingResourceConfigDirectory();
|
||||
}
|
||||
} else {
|
||||
$bundleConfig['dir'] = $bundleDir.'/'.$bundleName.'/' . $bundleConfig['dir'];
|
||||
$bundleConfig['dir'] = $bundleDir.'/'.$bundleConfig['dir'];
|
||||
}
|
||||
|
||||
if (!$bundleConfig['prefix']) {
|
||||
$bundleConfig['prefix'] = $namespace.'\\'. $bundleName . '\\' . $this->getMappingObjectDefaultName();
|
||||
$bundleConfig['prefix'] = $bundle->getNamespaceName().'\\'.$this->getMappingObjectDefaultName();
|
||||
}
|
||||
return $bundleConfig;
|
||||
}
|
||||
@ -325,7 +287,7 @@ abstract class AbstractDoctrineExtension extends Extension
|
||||
// add the directory itself as a resource
|
||||
$container->addResource(new FileResource($dir));
|
||||
|
||||
if (is_dir($dir . '/' . $this->getMappingObjectDefaultName())) {
|
||||
if (is_dir($dir.'/'.$this->getMappingObjectDefaultName())) {
|
||||
return 'annotation';
|
||||
}
|
||||
|
||||
|
@ -43,7 +43,7 @@ class ConvertDoctrine1SchemaDoctrineCommand extends DoctrineCommand
|
||||
->setHelp(<<<EOT
|
||||
The <info>doctrine:mapping:convert-d1-schema</info> command converts a Doctrine 1 schema to Doctrine 2 mapping files:
|
||||
|
||||
<info>./app/console doctrine:mapping:convert-d1-schema /path/to/doctrine1schema "Bundle\MyBundle" xml</info>
|
||||
<info>./app/console doctrine:mapping:convert-d1-schema /path/to/doctrine1schema "BundleMyBundle" xml</info>
|
||||
|
||||
Each Doctrine 1 model will have its own XML mapping file located in <info>Bundle/MyBundle/config/doctrine/metadata</info>.
|
||||
EOT
|
||||
@ -55,22 +55,9 @@ EOT
|
||||
*/
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$bundleClass = null;
|
||||
$bundleDirs = $this->container->get('kernel')->getBundleDirs();
|
||||
foreach ($this->container->get('kernel')->getBundles() as $bundle) {
|
||||
if (strpos(get_class($bundle), $input->getArgument('bundle')) !== false) {
|
||||
$tmp = dirname(str_replace('\\', '/', get_class($bundle)));
|
||||
$namespace = str_replace('/', '\\', dirname($tmp));
|
||||
$class = basename($tmp);
|
||||
|
||||
if (isset($bundleDirs[$namespace])) {
|
||||
$destPath = realpath($bundleDirs[$namespace]).'/'.$class;
|
||||
$bundleClass = $class;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
$bundle = $this->application->getKernel()->getBundle($input->getArgument('bundle'));
|
||||
|
||||
$destPath = $bundle->getPath();
|
||||
$type = $input->getArgument('mapping-type') ? $input->getArgument('mapping-type') : 'xml';
|
||||
if ('annotation' === $type) {
|
||||
$destPath .= '/Entity';
|
||||
@ -98,7 +85,7 @@ EOT
|
||||
$output->writeln(sprintf('Converting Doctrine 1 schema "<info>%s</info>"', $input->getArgument('d1-schema')));
|
||||
foreach ($metadata as $class) {
|
||||
$className = $class->name;
|
||||
$class->name = $namespace.'\\'.$bundleClass.'\\Entity\\'.$className;
|
||||
$class->name = $bundle->getNamespace().'\\Entity\\'.$className;
|
||||
if ('annotation' === $type) {
|
||||
$path = $destPath.'/'.$className.'.php';
|
||||
} else {
|
||||
|
@ -62,10 +62,10 @@ EOT
|
||||
}
|
||||
|
||||
$entityGenerator = $this->getEntityGenerator();
|
||||
foreach ($this->container->get('kernel')->getBundles() as $bundle) {
|
||||
foreach ($this->application->getKernel()->getBundles() as $bundle) {
|
||||
|
||||
// retrieve the full bundle classname
|
||||
$class = $bundle->getReflection()->getName();
|
||||
$class = get_class($bundle);
|
||||
|
||||
if ($filterBundle && $filterBundle != $class) {
|
||||
continue;
|
||||
|
@ -40,13 +40,13 @@ class GenerateEntityDoctrineCommand extends DoctrineCommand
|
||||
->setHelp(<<<EOT
|
||||
The <info>doctrine:generate:entity</info> task initializes a new Doctrine entity inside a bundle:
|
||||
|
||||
<info>./app/console doctrine:generate:entity "Bundle\MyCustomBundle" "User\Group"</info>
|
||||
<info>./app/console doctrine:generate:entity "MyCustomBundle" "User\Group"</info>
|
||||
|
||||
The above would initialize a new entity in the following entity namespace <info>Bundle\MyCustomBundle\Entity\User\Group</info>.
|
||||
|
||||
You can also optionally specify the fields you want to generate in the new entity:
|
||||
|
||||
<info>./app/console doctrine:generate:entity "Bundle\MyCustomBundle" "User\Group" --fields="name:string(255) description:text"</info>
|
||||
<info>./app/console doctrine:generate:entity "MyCustomBundle" "User\Group" --fields="name:string(255) description:text"</info>
|
||||
EOT
|
||||
);
|
||||
}
|
||||
@ -56,23 +56,10 @@ EOT
|
||||
*/
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
if (!preg_match('/Bundle$/', $bundle = $input->getArgument('bundle'))) {
|
||||
throw new \InvalidArgumentException('The bundle name must end with Bundle. Example: "Bundle\MySampleBundle".');
|
||||
}
|
||||
|
||||
$dirs = $this->container->get('kernel')->getBundleDirs();
|
||||
|
||||
$tmp = str_replace('\\', '/', $bundle);
|
||||
$namespace = str_replace('/', '\\', dirname($tmp));
|
||||
$bundle = basename($tmp);
|
||||
|
||||
if (!isset($dirs[$namespace])) {
|
||||
throw new \InvalidArgumentException(sprintf('Unable to initialize the bundle entity (%s not defined).', $namespace));
|
||||
}
|
||||
$bundle = $this->application->getKernel()->getBundle($input->getArgument('bundle'));
|
||||
|
||||
$entity = $input->getArgument('entity');
|
||||
$entityNamespace = $namespace.'\\'.$bundle.'\\Entity';
|
||||
$fullEntityClassName = $entityNamespace.'\\'.$entity;
|
||||
$fullEntityClassName = $bundle->getNamespace().'\\Entity\\'.$entity;
|
||||
$mappingType = $input->getOption('mapping-type');
|
||||
|
||||
$class = new ClassMetadataInfo($fullEntityClassName);
|
||||
@ -103,22 +90,21 @@ EOT
|
||||
$exporter = $cme->getExporter($mappingType);
|
||||
|
||||
if ('annotation' === $mappingType) {
|
||||
$path = $dirs[$namespace].'/'.$bundle.'/Entity/'.str_replace($entityNamespace.'\\', null, $fullEntityClassName).'.php';
|
||||
|
||||
$path = $bundle->getPath().'/Entity/'.$entity.'.php';
|
||||
$exporter->setEntityGenerator($this->getEntityGenerator());
|
||||
} else {
|
||||
$mappingType = 'yaml' == $mappingType ? 'yml' : $mappingType;
|
||||
$path = $dirs[$namespace].'/'.$bundle.'/Resources/config/doctrine/metadata/orm/'.str_replace('\\', '.', $fullEntityClassName).'.dcm.'.$mappingType;
|
||||
$path = $bundle->getPath().'/Resources/config/doctrine/metadata/orm/'.str_replace('\\', '.', $fullEntityClassName).'.dcm.'.$mappingType;
|
||||
}
|
||||
|
||||
$code = $exporter->exportClassMetadata($class);
|
||||
|
||||
$output->writeln(sprintf('Generating entity for "<info>%s</info>"', $bundle->getName()));
|
||||
$output->writeln(sprintf(' > generating <comment>%s</comment>', $fullEntityClassName));
|
||||
|
||||
if (!is_dir($dir = dirname($path))) {
|
||||
mkdir($dir, 0777, true);
|
||||
}
|
||||
|
||||
$output->writeln(sprintf('Generating entity for "<info>%s</info>"', $bundle));
|
||||
$output->writeln(sprintf(' > generating <comment>%s</comment>', $fullEntityClassName));
|
||||
file_put_contents($path, $code);
|
||||
}
|
||||
}
|
||||
|
@ -40,22 +40,14 @@ EOT
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$generator = new EntityRepositoryGenerator();
|
||||
$kernel = $this->application->getKernel();
|
||||
$bundleDirs = $kernel->getBundleDirs();
|
||||
foreach ($kernel->getBundles() as $bundle) {
|
||||
$tmp = dirname(str_replace('\\', '/', get_class($bundle)));
|
||||
$namespace = str_replace('/', '\\', dirname($tmp));
|
||||
$class = basename($tmp);
|
||||
|
||||
if (isset($bundleDirs[$namespace])) {
|
||||
$destination = realpath($bundleDirs[$namespace].'/..');
|
||||
if ($metadatas = $this->getBundleMetadatas($bundle)) {
|
||||
$output->writeln(sprintf('Generating entity repositories for "<info>%s</info>"', $class));
|
||||
foreach ($metadatas as $metadata) {
|
||||
if ($metadata->customRepositoryClassName) {
|
||||
$output->writeln(sprintf(' > generating <comment>%s</comment>', $metadata->customRepositoryClassName));
|
||||
$generator->writeEntityRepositoryClass($metadata->customRepositoryClassName, $destination);
|
||||
}
|
||||
foreach ($this->application->getKernel()->getBundles() as $bundle) {
|
||||
$destination = $bundle->getPath();
|
||||
if ($metadatas = $this->getBundleMetadatas($bundle)) {
|
||||
$output->writeln(sprintf('Generating entity repositories for "<info>%s</info>"', get_class($bundle)));
|
||||
foreach ($metadatas as $metadata) {
|
||||
if ($metadata->customRepositoryClassName) {
|
||||
$output->writeln(sprintf(' > generating <comment>%s</comment>', $metadata->customRepositoryClassName));
|
||||
$generator->writeEntityRepositoryClass($metadata->customRepositoryClassName, $destination);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -42,33 +42,20 @@ class ImportMappingDoctrineCommand extends DoctrineCommand
|
||||
->setHelp(<<<EOT
|
||||
The <info>doctrine:mapping:import</info> command imports mapping information from an existing database:
|
||||
|
||||
<info>./app/console doctrine:mapping:import "Bundle\MyCustomBundle" xml</info>
|
||||
<info>./app/console doctrine:mapping:import "MyCustomBundle" xml</info>
|
||||
|
||||
You can also optionally specify which entity manager to import from with the <info>--em</info> option:
|
||||
|
||||
<info>./app/console doctrine:mapping:import "Bundle\MyCustomBundle" xml --em=default</info>
|
||||
<info>./app/console doctrine:mapping:import "MyCustomBundle" xml --em=default</info>
|
||||
EOT
|
||||
);
|
||||
}
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$bundleClass = null;
|
||||
$bundleDirs = $this->container->get('kernel')->getBundleDirs();
|
||||
foreach ($this->container->get('kernel')->getBundles() as $bundle) {
|
||||
if (strpos(get_class($bundle), $input->getArgument('bundle')) !== false) {
|
||||
$tmp = dirname(str_replace('\\', '/', get_class($bundle)));
|
||||
$namespace = str_replace('/', '\\', dirname($tmp));
|
||||
$class = basename($tmp);
|
||||
|
||||
if (isset($bundleDirs[$namespace])) {
|
||||
$destPath = realpath($bundleDirs[$namespace]).'/'.$class;
|
||||
$bundleClass = $class;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
$bundle = $this->application->getKernel()->getBundle($input->getArgument('bundle'));
|
||||
|
||||
$destPath = $bundle->getPath();
|
||||
$type = $input->getArgument('mapping-type') ? $input->getArgument('mapping-type') : 'xml';
|
||||
if ('annotation' === $type) {
|
||||
$destPath .= '/Entity';
|
||||
@ -100,7 +87,7 @@ EOT
|
||||
$output->writeln(sprintf('Importing mapping information from "<info>%s</info>" entity manager', $emName));
|
||||
foreach ($metadata as $class) {
|
||||
$className = $class->name;
|
||||
$class->name = $namespace.'\\'.$bundleClass.'\\Entity\\'.$className;
|
||||
$class->name = $bundle->getNamespace().'\\Entity\\'.$className;
|
||||
if ('annotation' === $type) {
|
||||
$path = $destPath.'/'.$className.'.php';
|
||||
} else {
|
||||
|
@ -67,15 +67,8 @@ EOT
|
||||
$paths = is_array($dirOrFile) ? $dirOrFile : array($dirOrFile);
|
||||
} else {
|
||||
$paths = array();
|
||||
$bundleDirs = $this->container->get('kernel')->getBundleDirs();
|
||||
foreach ($this->container->get('kernel')->getBundles() as $bundle) {
|
||||
$tmp = dirname(str_replace('\\', '/', get_class($bundle)));
|
||||
$namespace = str_replace('/', '\\', dirname($tmp));
|
||||
$class = basename($tmp);
|
||||
|
||||
if (isset($bundleDirs[$namespace]) && is_dir($dir = $bundleDirs[$namespace].'/'.$class.'/DataFixtures/ORM')) {
|
||||
$paths[] = $dir;
|
||||
}
|
||||
foreach ($this->application->getKernel()->getBundles() as $bundle) {
|
||||
$paths[] = $bundle->getPath().'/DataFixtures/ORM';
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -32,4 +32,20 @@ class DoctrineBundle extends Bundle
|
||||
$container->addCompilerPass(new RegisterEventListenersAndSubscribersPass(), PassConfig::TYPE_BEFORE_OPTIMIZATION);
|
||||
$container->addCompilerPass(new CreateProxyDirectoryPass(), PassConfig::TYPE_BEFORE_REMOVING);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getNamespace()
|
||||
{
|
||||
return __NAMESPACE__;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getPath()
|
||||
{
|
||||
return strtr(__DIR__, '\\', '/');
|
||||
}
|
||||
}
|
||||
|
@ -21,13 +21,7 @@ class ContainerTest extends TestCase
|
||||
public function getContainer()
|
||||
{
|
||||
$container = new ContainerBuilder(new ParameterBag(array(
|
||||
'kernel.bundle_dirs' => array(
|
||||
'DoctrineBundle\Tests\DependencyInjection\Fixtures\Bundles' =>
|
||||
__DIR__ . "/DependencyInjection/Fixtures/Bundles"
|
||||
),
|
||||
'kernel.bundles' => array(
|
||||
'DoctrineBundle\Tests\DependencyInjection\Fixtures\Bundles\YamlBundle\YamlBundle',
|
||||
),
|
||||
'kernel.bundles' => array('YamlBundle' => 'DoctrineBundle\Tests\DependencyInjection\Fixtures\Bundles\YamlBundle\YamlBundle'),
|
||||
'kernel.cache_dir' => sys_get_temp_dir(),
|
||||
)));
|
||||
$loader = new DoctrineExtension();
|
||||
|
@ -428,7 +428,7 @@ abstract class AbstractDoctrineExtensionTest extends TestCase
|
||||
|
||||
public function testMultipleOrmLoadCalls()
|
||||
{
|
||||
$container = $this->getContainer('AnnotationsBundle');
|
||||
$container = $this->getContainer(array('XmlBundle', 'AnnotationsBundle'));
|
||||
$loader = new DoctrineExtension();
|
||||
|
||||
$loader->dbalLoad(array(), $container);
|
||||
@ -447,7 +447,7 @@ abstract class AbstractDoctrineExtensionTest extends TestCase
|
||||
'DoctrineBundle\Tests\DependencyInjection\Fixtures\Bundles\AnnotationsBundle\Entity'
|
||||
));
|
||||
$this->assertDICDefinitionMethodCallAt(1, $definition, 'addDriver', array(
|
||||
new Reference('doctrine.orm.default_annotation_metadata_driver'),
|
||||
new Reference('doctrine.orm.default_xml_metadata_driver'),
|
||||
'DoctrineBundle\Tests\DependencyInjection\Fixtures\Bundles\XmlBundle\Entity'
|
||||
));
|
||||
|
||||
@ -625,15 +625,15 @@ abstract class AbstractDoctrineExtensionTest extends TestCase
|
||||
$bundles = array($bundles);
|
||||
}
|
||||
|
||||
foreach ($bundles AS $key => $bundle) {
|
||||
$map = array();
|
||||
foreach ($bundles as $bundle) {
|
||||
require_once __DIR__.'/Fixtures/Bundles/'.($vendor ? $vendor.'/' : '').$bundle.'/'.$bundle.'.php';
|
||||
|
||||
$bundles[$key] = 'DoctrineBundle\\Tests\DependencyInjection\\Fixtures\\Bundles\\'.($vendor ? $vendor.'\\' : '').$bundle.'\\'.$bundle;
|
||||
$map[$bundle] = 'DoctrineBundle\\Tests\DependencyInjection\\Fixtures\\Bundles\\'.($vendor ? $vendor.'\\' : '').$bundle.'\\'.$bundle;
|
||||
}
|
||||
|
||||
return new ContainerBuilder(new ParameterBag(array(
|
||||
'kernel.bundle_dirs' => array('DoctrineBundle\\Tests\\DependencyInjection\\Fixtures\\Bundles' => __DIR__.'/Fixtures/Bundles'),
|
||||
'kernel.bundles' => $bundles,
|
||||
'kernel.bundles' => $map,
|
||||
'kernel.cache_dir' => sys_get_temp_dir(),
|
||||
'kernel.root_dir' => __DIR__ . "/../../../../../" // src dir
|
||||
)));
|
||||
|
@ -6,5 +6,19 @@ use Symfony\Component\HttpKernel\Bundle\Bundle;
|
||||
|
||||
class AnnotationsBundle extends Bundle
|
||||
{
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getNamespace()
|
||||
{
|
||||
return __NAMESPACE__;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getPath()
|
||||
{
|
||||
return strtr(__DIR__, '\\', '/');
|
||||
}
|
||||
}
|
@ -6,5 +6,19 @@ use Symfony\Component\HttpKernel\Bundle\Bundle;
|
||||
|
||||
class AnnotationsBundle extends Bundle
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getNamespace()
|
||||
{
|
||||
return __NAMESPACE__;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getPath()
|
||||
{
|
||||
return strtr(__DIR__, '\\', '/');
|
||||
}
|
||||
}
|
@ -6,5 +6,19 @@ use Symfony\Component\HttpKernel\Bundle\Bundle;
|
||||
|
||||
class XmlBundle extends Bundle
|
||||
{
|
||||
|
||||
}
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getNamespace()
|
||||
{
|
||||
return __NAMESPACE__;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getPath()
|
||||
{
|
||||
return strtr(__DIR__, '\\', '/');
|
||||
}
|
||||
}
|
||||
|
@ -6,5 +6,19 @@ use Symfony\Component\HttpKernel\Bundle\Bundle;
|
||||
|
||||
class YamlBundle extends Bundle
|
||||
{
|
||||
|
||||
}
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getNamespace()
|
||||
{
|
||||
return __NAMESPACE__;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getPath()
|
||||
{
|
||||
return strtr(__DIR__, '\\', '/');
|
||||
}
|
||||
}
|
||||
|
@ -26,17 +26,13 @@ abstract class DoctrineCommand extends BaseCommand
|
||||
public static function configureMigrationsForBundle(Application $application, $bundle, Configuration $configuration)
|
||||
{
|
||||
$configuration->setMigrationsNamespace($bundle.'\DoctrineMigrations');
|
||||
|
||||
$dirs = $application->getKernel()->getBundleDirs();
|
||||
|
||||
$tmp = str_replace('\\', '/', $bundle);
|
||||
$namespace = str_replace('/', '\\', dirname($tmp));
|
||||
$bundle = basename($tmp);
|
||||
|
||||
$dir = $dirs[$namespace].'/'.$bundle.'/DoctrineMigrations';
|
||||
|
||||
$bundle = $this->application->getKernel()->getBundle($input->getArgument('bundle'));
|
||||
$dir = $bundle->getPath().'/DoctrineMigrations';
|
||||
|
||||
$configuration->setMigrationsDirectory($dir);
|
||||
$configuration->registerMigrationsFromDirectory($dir);
|
||||
$configuration->setName($bundle.' Migrations');
|
||||
$configuration->setMigrationsTableName(Inflector::tableize($bundle).'_migration_versions');
|
||||
$configuration->setMigrationsTableName(Inflector::tableize($bundle->getName()).'_migration_versions');
|
||||
}
|
||||
}
|
@ -21,4 +21,19 @@ use Symfony\Component\HttpKernel\Bundle\Bundle;
|
||||
*/
|
||||
class DoctrineMigrationsBundle extends Bundle
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getNamespace()
|
||||
{
|
||||
return __NAMESPACE__;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getPath()
|
||||
{
|
||||
return strtr(__DIR__, '\\', '/');
|
||||
}
|
||||
}
|
||||
|
@ -67,15 +67,8 @@ EOT
|
||||
$paths = is_array($dirOrFile) ? $dirOrFile : array($dirOrFile);
|
||||
} else {
|
||||
$paths = array();
|
||||
$bundleDirs = $this->container->get('kernel')->getBundleDirs();
|
||||
foreach ($this->container->get('kernel')->getBundles() as $bundle) {
|
||||
$tmp = dirname(str_replace('\\', '/', get_class($bundle)));
|
||||
$namespace = str_replace('/', '\\', dirname($tmp));
|
||||
$class = basename($tmp);
|
||||
|
||||
if (isset($bundleDirs[$namespace]) && is_dir($dir = $bundleDirs[$namespace].'/'.$class.'/DataFixtures/MongoDB')) {
|
||||
$paths[] = $dir;
|
||||
}
|
||||
$paths[] = $bundle->getPath().'/DataFixtures/MongoDB';
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -35,4 +35,20 @@ class DoctrineMongoDBBundle extends Bundle
|
||||
$container->addCompilerPass(new CreateProxyDirectoryPass(), PassConfig::TYPE_BEFORE_REMOVING);
|
||||
$container->addCompilerPass(new CreateHydratorDirectoryPass(), PassConfig::TYPE_BEFORE_REMOVING);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getNamespace()
|
||||
{
|
||||
return __NAMESPACE__;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getPath()
|
||||
{
|
||||
return strtr(__DIR__, '\\', '/');
|
||||
}
|
||||
}
|
||||
|
@ -20,9 +20,10 @@ class ContainerTest extends TestCase
|
||||
{
|
||||
public function getContainer()
|
||||
{
|
||||
require_once __DIR__.'/DependencyInjection/Fixtures/Bundles/YamlBundle/YamlBundle.php';
|
||||
|
||||
$container = new ContainerBuilder(new ParameterBag(array(
|
||||
'kernel.bundle_dirs' => array(),
|
||||
'kernel.bundles' => array(),
|
||||
'kernel.bundles' => array('YamlBundle' => 'DoctrineMongoDBBundle\Tests\DependencyInjection\Fixtures\Bundles\YamlBundle\YamlBundle'),
|
||||
'kernel.cache_dir' => sys_get_temp_dir(),
|
||||
)));
|
||||
$loader = new DoctrineMongoDBExtension();
|
||||
|
@ -344,8 +344,7 @@ abstract class AbstractMongoDBExtensionTest extends TestCase
|
||||
require_once __DIR__.'/Fixtures/Bundles/'.$bundle.'/'.$bundle.'.php';
|
||||
|
||||
return new ContainerBuilder(new ParameterBag(array(
|
||||
'kernel.bundle_dirs' => array('DoctrineMongoDBBundle\\Tests\\DependencyInjection\\Fixtures\\Bundles' => __DIR__.'/Fixtures/Bundles'),
|
||||
'kernel.bundles' => array('DoctrineMongoDBBundle\\Tests\\DependencyInjection\\Fixtures\\Bundles\\'.$bundle.'\\'.$bundle),
|
||||
'kernel.bundles' => array($bundle => 'DoctrineMongoDBBundle\\Tests\\DependencyInjection\\Fixtures\\Bundles\\'.$bundle.'\\'.$bundle),
|
||||
'kernel.cache_dir' => sys_get_temp_dir(),
|
||||
)));
|
||||
}
|
||||
|
@ -6,4 +6,19 @@ use Symfony\Component\HttpKernel\Bundle\Bundle;
|
||||
|
||||
class AnnotationsBundle extends Bundle
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getNamespace()
|
||||
{
|
||||
return __NAMESPACE__;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getPath()
|
||||
{
|
||||
return strtr(__DIR__, '\\', '/');
|
||||
}
|
||||
}
|
||||
|
@ -6,5 +6,19 @@ use Symfony\Component\HttpKernel\Bundle\Bundle;
|
||||
|
||||
class XmlBundle extends Bundle
|
||||
{
|
||||
|
||||
}
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getNamespace()
|
||||
{
|
||||
return __NAMESPACE__;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getPath()
|
||||
{
|
||||
return strtr(__DIR__, '\\', '/');
|
||||
}
|
||||
}
|
||||
|
@ -6,5 +6,19 @@ use Symfony\Component\HttpKernel\Bundle\Bundle;
|
||||
|
||||
class YamlBundle extends Bundle
|
||||
{
|
||||
|
||||
}
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getNamespace()
|
||||
{
|
||||
return __NAMESPACE__;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getPath()
|
||||
{
|
||||
return strtr(__DIR__, '\\', '/');
|
||||
}
|
||||
}
|
||||
|
@ -33,6 +33,7 @@ class InitBundleCommand extends Command
|
||||
$this
|
||||
->setDefinition(array(
|
||||
new InputArgument('namespace', InputArgument::REQUIRED, 'The namespace of the bundle to create'),
|
||||
new InputArgument('dir', InputArgument::REQUIRED, 'The directory where to create the bundle'),
|
||||
))
|
||||
->setName('init:bundle')
|
||||
;
|
||||
@ -50,21 +51,8 @@ class InitBundleCommand extends Command
|
||||
throw new \InvalidArgumentException('The namespace must end with Bundle.');
|
||||
}
|
||||
|
||||
$dirs = $this->container->get('kernel')->getBundleDirs();
|
||||
|
||||
$tmp = str_replace('\\', '/', $namespace);
|
||||
$namespace = str_replace('/', '\\', dirname($tmp));
|
||||
$bundle = basename($tmp);
|
||||
|
||||
if (!isset($dirs[$namespace])) {
|
||||
throw new \InvalidArgumentException(sprintf(
|
||||
"Unable to initialize the bundle (%s is not a defined namespace).\n" .
|
||||
"Defined namespaces are: %s",
|
||||
$namespace, implode(', ', array_keys($dirs))));
|
||||
}
|
||||
|
||||
$dir = $dirs[$namespace];
|
||||
$output->writeln(sprintf('Initializing bundle "<info>%s</info>" in "<info>%s</info>"', $bundle, realpath($dir)));
|
||||
$dir = $input->getArgument('dir');
|
||||
$output->writeln(sprintf('Initializing bundle "<info>%s</info>" in "<info>%s</info>"', $bundle, $dir));
|
||||
|
||||
if (file_exists($targetDir = $dir.'/'.$bundle)) {
|
||||
throw new \RuntimeException(sprintf('Bundle "%s" already exists.', $bundle));
|
||||
|
@ -1,143 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Bundle\FrameworkBundle\Controller;
|
||||
|
||||
use Symfony\Component\HttpKernel\Kernel;
|
||||
use Symfony\Component\HttpKernel\Log\LoggerInterface;
|
||||
|
||||
/**
|
||||
* ControllerNameConverter converts controller from the short notation a:b:c
|
||||
* (BlogBundle:Post:index) to a fully-qualified class::method string
|
||||
* (Bundle\BlogBundle\Controller\PostController::indexAction); and the other
|
||||
* way around.
|
||||
*
|
||||
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
*/
|
||||
class ControllerNameConverter
|
||||
{
|
||||
protected $kernel;
|
||||
protected $logger;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param Kernel $kernel A Kernel instance
|
||||
* @param LoggerInterface $logger A LoggerInterface instance
|
||||
*/
|
||||
public function __construct(Kernel $kernel, LoggerInterface $logger = null)
|
||||
{
|
||||
$this->kernel = $kernel;
|
||||
$this->logger = $logger;
|
||||
$this->namespaces = array_keys($kernel->getBundleDirs());
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a class::method string to the short notation a:b:c.
|
||||
*
|
||||
* @param string $controller A controler (class::method)
|
||||
*
|
||||
* @return string A short notation controller (a:b:c)
|
||||
*/
|
||||
public function toShortNotation($controller)
|
||||
{
|
||||
if (2 != count($parts = explode('::', $controller))) {
|
||||
throw new \InvalidArgumentException(sprintf('The "%s" controller is not a valid class::method controller string.', $controller));
|
||||
}
|
||||
|
||||
list($class, $method) = $parts;
|
||||
|
||||
if ('Action' != substr($method, -6)) {
|
||||
throw new \InvalidArgumentException(sprintf('The "%s::%s" method does not look like a controller action (it does not end with Action)', $class, $method));
|
||||
}
|
||||
$action = substr($method, 0, -6);
|
||||
|
||||
if (!preg_match('/Controller\\\(.*)Controller$/', $class, $match)) {
|
||||
throw new \InvalidArgumentException(sprintf('The "%s" class does not look like a controller class (it does not end with Controller)', $class));
|
||||
}
|
||||
$controller = $match[1];
|
||||
|
||||
$bundle = null;
|
||||
$namespace = substr($class, 0, strrpos($class, '\\'));
|
||||
foreach ($this->namespaces as $prefix) {
|
||||
if (0 === $pos = strpos($namespace, $prefix)) {
|
||||
// -11 to remove the \Controller suffix (11 characters)
|
||||
$bundle = substr($namespace, strlen($prefix) + 1, -11);
|
||||
}
|
||||
}
|
||||
|
||||
if (null === $bundle) {
|
||||
throw new \InvalidArgumentException(sprintf('The "%s" class does not belong to a known bundle namespace.', $class));
|
||||
}
|
||||
|
||||
return str_replace('\\', '', $bundle).':'.$controller.':'.$action;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a short notation a:b:c ro a class::method.
|
||||
*
|
||||
* @param string $controller A short notation controller (a:b:c)
|
||||
*
|
||||
* @param string A controler (class::method)
|
||||
*/
|
||||
public function fromShortNotation($controller)
|
||||
{
|
||||
if (3 != count($parts = explode(':', $controller))) {
|
||||
throw new \InvalidArgumentException(sprintf('The "%s" controller is not a valid a:b:c controller string.', $controller));
|
||||
}
|
||||
|
||||
list($bundle, $controller, $action) = $parts;
|
||||
$class = null;
|
||||
$logs = array();
|
||||
|
||||
foreach ($this->namespaces as $namespace) {
|
||||
$prefix = null;
|
||||
foreach ($this->kernel->getBundles() as $b) {
|
||||
if ($bundle === $b->getName() && 0 === strpos($b->getNamespace(), $namespace)) {
|
||||
$prefix = $b->getNamespace();
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (null === $prefix) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$try = $prefix.'\\Controller\\'.$controller.'Controller';
|
||||
if (!class_exists($try)) {
|
||||
if (null !== $this->logger) {
|
||||
$logs[] = sprintf('Failed finding controller "%s:%s" from namespace "%s" (%s)', $bundle, $controller, $namespace, $try);
|
||||
}
|
||||
} else {
|
||||
if (!$this->kernel->isClassInActiveBundle($try)) {
|
||||
throw new \LogicException(sprintf('To use the "%s" controller, you first need to enable the Bundle "%s" in your Kernel class.', $try, $namespace.'\\'.$bundle));
|
||||
}
|
||||
|
||||
$class = $try;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (null === $class) {
|
||||
if (null !== $this->logger) {
|
||||
foreach ($logs as $log) {
|
||||
$this->logger->info($log);
|
||||
}
|
||||
}
|
||||
|
||||
throw new \InvalidArgumentException(sprintf('Unable to find controller "%s:%s".', $bundle, $controller));
|
||||
}
|
||||
|
||||
return $class.'::'.$action.'Action';
|
||||
}
|
||||
}
|
@ -0,0 +1,82 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Bundle\FrameworkBundle\Controller;
|
||||
|
||||
use Symfony\Component\HttpKernel\Kernel;
|
||||
use Symfony\Component\HttpKernel\Log\LoggerInterface;
|
||||
|
||||
/**
|
||||
* ControllerNameParser converts controller from the short notation a:b:c
|
||||
* (BlogBundle:Post:index) to a fully-qualified class::method string
|
||||
* (Bundle\BlogBundle\Controller\PostController::indexAction).
|
||||
*
|
||||
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
*/
|
||||
class ControllerNameParser
|
||||
{
|
||||
protected $kernel;
|
||||
protected $logger;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param Kernel $kernel A Kernel instance
|
||||
* @param LoggerInterface $logger A LoggerInterface instance
|
||||
*/
|
||||
public function __construct(Kernel $kernel, LoggerInterface $logger = null)
|
||||
{
|
||||
$this->kernel = $kernel;
|
||||
$this->logger = $logger;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a short notation a:b:c to a class::method.
|
||||
*
|
||||
* @param string $controller A short notation controller (a:b:c)
|
||||
*
|
||||
* @param string A controler (class::method)
|
||||
*/
|
||||
public function parse($controller)
|
||||
{
|
||||
if (3 != count($parts = explode(':', $controller))) {
|
||||
throw new \InvalidArgumentException(sprintf('The "%s" controller is not a valid a:b:c controller string.', $controller));
|
||||
}
|
||||
|
||||
list($bundle, $controller, $action) = $parts;
|
||||
$class = null;
|
||||
$logs = array();
|
||||
foreach ($this->kernel->getBundle($bundle, false) as $b) {
|
||||
$try = $b->getNamespace().'\\Controller\\'.$controller.'Controller';
|
||||
if (!class_exists($try)) {
|
||||
if (null !== $this->logger) {
|
||||
$logs[] = sprintf('Failed finding controller "%s:%s" from namespace "%s" (%s)', $bundle, $controller, $b->getNamespace(), $try);
|
||||
}
|
||||
} else {
|
||||
$class = $try;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (null === $class) {
|
||||
if (null !== $this->logger) {
|
||||
foreach ($logs as $log) {
|
||||
$this->logger->info($log);
|
||||
}
|
||||
}
|
||||
|
||||
throw new \InvalidArgumentException(sprintf('Unable to find controller "%s:%s".', $bundle, $controller));
|
||||
}
|
||||
|
||||
return $class.'::'.$action.'Action';
|
||||
}
|
||||
}
|
@ -17,7 +17,7 @@ use Symfony\Component\HttpKernel\HttpKernelInterface;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\EventDispatcher\Event;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\ControllerNameConverter;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\ControllerNameParser;
|
||||
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
|
||||
|
||||
/**
|
||||
@ -28,20 +28,20 @@ use Symfony\Component\DependencyInjection\ContainerAwareInterface;
|
||||
class ControllerResolver extends BaseControllerResolver
|
||||
{
|
||||
protected $container;
|
||||
protected $converter;
|
||||
protected $parser;
|
||||
protected $esiSupport;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param ContainerInterface $container A ContainerInterface instance
|
||||
* @param ControllerNameConverter $converter A ControllerNameConverter instance
|
||||
* @param LoggerInterface $logger A LoggerInterface instance
|
||||
* @param ContainerInterface $container A ContainerInterface instance
|
||||
* @param ControllerNameParser $parser A ControllerNameParser instance
|
||||
* @param LoggerInterface $logger A LoggerInterface instance
|
||||
*/
|
||||
public function __construct(ContainerInterface $container, ControllerNameConverter $converter, LoggerInterface $logger = null)
|
||||
public function __construct(ContainerInterface $container, ControllerNameParser $parser, LoggerInterface $logger = null)
|
||||
{
|
||||
$this->container = $container;
|
||||
$this->converter = $converter;
|
||||
$this->parser = $parser;
|
||||
|
||||
parent::__construct($logger);
|
||||
}
|
||||
@ -59,7 +59,7 @@ class ControllerResolver extends BaseControllerResolver
|
||||
$count = substr_count($controller, ':');
|
||||
if (2 == $count) {
|
||||
// controller in the a:b:c notation then
|
||||
$controller = $this->converter->fromShortNotation($controller);
|
||||
$controller = $this->parser->parse($controller);
|
||||
} elseif (1 == $count) {
|
||||
// controller in the service:method notation
|
||||
list($service, $method) = explode(':', $controller);
|
||||
|
@ -153,7 +153,7 @@ class FrameworkExtension extends Extension
|
||||
'Symfony\\Component\\HttpKernel\\Controller\\ControllerResolverInterface',
|
||||
|
||||
'Symfony\\Bundle\\FrameworkBundle\\RequestListener',
|
||||
'Symfony\\Bundle\\FrameworkBundle\\Controller\\ControllerNameConverter',
|
||||
'Symfony\\Bundle\\FrameworkBundle\\Controller\\ControllerNameParser',
|
||||
'Symfony\\Bundle\\FrameworkBundle\\Controller\\ControllerResolver',
|
||||
'Symfony\\Bundle\\FrameworkBundle\\Controller\\Controller',
|
||||
|
||||
@ -213,13 +213,6 @@ class FrameworkExtension extends Extension
|
||||
$container->setParameter('templating.assets.base_urls', $config['assets_base_urls']);
|
||||
}
|
||||
|
||||
// template paths
|
||||
$dirs = array('%kernel.root_dir%/views/%%bundle%%/%%controller%%/%%name%%.%%renderer%%.%%format%%');
|
||||
foreach ($container->getParameter('kernel.bundle_dirs') as $dir) {
|
||||
$dirs[] = $dir.'/%%bundle%%/Resources/views/%%controller%%/%%name%%.%%renderer%%.%%format%%';
|
||||
}
|
||||
$container->setParameter('templating.loader.filesystem.path', $dirs);
|
||||
|
||||
// path for the filesystem loader
|
||||
if (isset($config['path'])) {
|
||||
$container->setParameter('templating.loader.filesystem.path', $config['path']);
|
||||
@ -313,7 +306,7 @@ class FrameworkExtension extends Extension
|
||||
if ($first) {
|
||||
// translation directories
|
||||
$dirs = array();
|
||||
foreach (array_reverse($container->getParameter('kernel.bundles')) as $bundle) {
|
||||
foreach ($container->getParameter('kernel.bundles') as $bundle) {
|
||||
$reflection = new \ReflectionClass($bundle);
|
||||
if (is_dir($dir = dirname($reflection->getFilename()).'/Resources/translations')) {
|
||||
$dirs[] = $dir;
|
||||
|
@ -76,4 +76,20 @@ class FrameworkBundle extends Bundle
|
||||
$container->addCompilerPass(new AddClassesToCachePass());
|
||||
$container->addCompilerPass(new TranslatorPass());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getNamespace()
|
||||
{
|
||||
return __NAMESPACE__;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getPath()
|
||||
{
|
||||
return strtr(__DIR__, '\\', '/');
|
||||
}
|
||||
}
|
||||
|
@ -7,6 +7,7 @@
|
||||
<parameters>
|
||||
<parameter key="router.class">Symfony\Component\Routing\Router</parameter>
|
||||
<parameter key="routing.loader.class">Symfony\Bundle\FrameworkBundle\Routing\DelegatingLoader</parameter>
|
||||
<parameter key="routing.file_locator.class">Symfony\Bundle\FrameworkBundle\Routing\FileLocator</parameter>
|
||||
<parameter key="routing.resolver.class">Symfony\Component\Routing\Loader\LoaderResolver</parameter>
|
||||
<parameter key="routing.loader.xml.class">Symfony\Component\Routing\Loader\XmlFileLoader</parameter>
|
||||
<parameter key="routing.loader.yml.class">Symfony\Component\Routing\Loader\YamlFileLoader</parameter>
|
||||
@ -22,19 +23,23 @@
|
||||
<services>
|
||||
<service id="routing.resolver" class="%routing.resolver.class%" public="false" />
|
||||
|
||||
<service id="routing.file_locator" class="%routing.file_locator.class%" public="false">
|
||||
<argument type="service" id="kernel" />
|
||||
</service>
|
||||
|
||||
<service id="routing.loader.xml" class="%routing.loader.xml.class%" public="false">
|
||||
<tag name="routing.loader" />
|
||||
<argument>%kernel.bundle_dirs%</argument>
|
||||
<argument type="service" id="routing.file_locator" />
|
||||
</service>
|
||||
|
||||
<service id="routing.loader.yml" class="%routing.loader.yml.class%" public="false">
|
||||
<tag name="routing.loader" />
|
||||
<argument>%kernel.bundle_dirs%</argument>
|
||||
<argument type="service" id="routing.file_locator" />
|
||||
</service>
|
||||
|
||||
<service id="routing.loader.php" class="%routing.loader.php.class%" public="false">
|
||||
<tag name="routing.loader" />
|
||||
<argument>%kernel.bundle_dirs%</argument>
|
||||
<argument type="service" id="routing.file_locator" />
|
||||
</service>
|
||||
|
||||
<service id="routing.loader.real" class="%routing.loader.class%">
|
||||
|
@ -7,7 +7,9 @@
|
||||
<parameters>
|
||||
<parameter key="templating.engine.delegating.class">Symfony\Bundle\FrameworkBundle\Templating\DelegatingEngine</parameter>
|
||||
<parameter key="templating.engine.php.class">Symfony\Bundle\FrameworkBundle\Templating\PhpEngine</parameter>
|
||||
<parameter key="templating.loader.filesystem.class">Symfony\Component\Templating\Loader\FilesystemLoader</parameter>
|
||||
<parameter key="templating.name_parser.class">Symfony\Bundle\FrameworkBundle\Templating\Loader\TemplateNameParser</parameter>
|
||||
<parameter key="templating.locator.class">Symfony\Bundle\FrameworkBundle\Templating\Loader\TemplateLocator</parameter>
|
||||
<parameter key="templating.loader.filesystem.class">Symfony\Bundle\FrameworkBundle\Templating\Loader\FilesystemLoader</parameter>
|
||||
<parameter key="templating.loader.cache.class">Symfony\Component\Templating\Loader\CacheLoader</parameter>
|
||||
<parameter key="templating.loader.chain.class">Symfony\Component\Templating\Loader\ChainLoader</parameter>
|
||||
<parameter key="templating.helper.slots.class">Symfony\Component\Templating\Helper\SlotsHelper</parameter>
|
||||
@ -22,7 +24,6 @@
|
||||
<parameter key="templating.helper.form.class">Symfony\Bundle\FrameworkBundle\Templating\Helper\FormHelper</parameter>
|
||||
<parameter key="templating.assets.version">null</parameter>
|
||||
<parameter key="templating.assets.base_urls" type="collection"></parameter>
|
||||
<parameter key="templating.name_parser.class">Symfony\Bundle\FrameworkBundle\Templating\TemplateNameParser</parameter>
|
||||
<parameter key="templating.renderer.php.class">Symfony\Component\Templating\Renderer\PhpRenderer</parameter>
|
||||
<parameter key="debug.file_link_format">null</parameter>
|
||||
</parameters>
|
||||
@ -39,10 +40,18 @@
|
||||
<call method="setCharset"><argument>%kernel.charset%</argument></call>
|
||||
</service>
|
||||
|
||||
<service id="templating.loader.filesystem" class="%templating.loader.filesystem.class%" public="false">
|
||||
<service id="templating.name_parser" class="%templating.name_parser.class%">
|
||||
<argument type="service" id="kernel" />
|
||||
</service>
|
||||
|
||||
<service id="templating.locator" class="%templating.locator.class%" public="false">
|
||||
<argument type="service" id="kernel" />
|
||||
<argument type="service" id="templating.name_parser" />
|
||||
<argument>%templating.loader.filesystem.path%</argument>
|
||||
<call method="setDebugger"><argument type="service" id="templating.debugger" on-invalid="ignore" /></call>
|
||||
<argument>%kernel.root_dir%</argument>
|
||||
</service>
|
||||
|
||||
<service id="templating.loader.filesystem" class="%templating.loader.filesystem.class%" public="false">
|
||||
<argument type="service" id="templating.locator" />
|
||||
</service>
|
||||
|
||||
<service id="templating.loader.cache" class="%templating.loader.cache.class%" public="false">
|
||||
@ -107,10 +116,6 @@
|
||||
<argument type="service" id="templating" />
|
||||
</service>
|
||||
|
||||
<service id="templating.name_parser" class="%templating.name_parser.class%">
|
||||
<argument type="service" id="kernel" />
|
||||
</service>
|
||||
|
||||
<service id="templating.loader" alias="templating.loader.filesystem" />
|
||||
|
||||
<service id="templating" alias="templating.engine.delegating" />
|
||||
|
@ -7,7 +7,7 @@
|
||||
<parameters>
|
||||
<parameter key="request_listener.class">Symfony\Bundle\FrameworkBundle\RequestListener</parameter>
|
||||
<parameter key="controller_resolver.class">Symfony\Bundle\FrameworkBundle\Controller\ControllerResolver</parameter>
|
||||
<parameter key="controller_name_converter.class">Symfony\Bundle\FrameworkBundle\Controller\ControllerNameConverter</parameter>
|
||||
<parameter key="controller_name_converter.class">Symfony\Bundle\FrameworkBundle\Controller\ControllerNameParser</parameter>
|
||||
<parameter key="response_listener.class">Symfony\Component\HttpKernel\ResponseListener</parameter>
|
||||
<parameter key="exception_listener.class">Symfony\Component\HttpKernel\Debug\ExceptionListener</parameter>
|
||||
<parameter key="exception_listener.controller">Symfony\Bundle\FrameworkBundle\Controller\ExceptionController::showAction</parameter>
|
||||
|
@ -11,7 +11,7 @@
|
||||
|
||||
namespace Symfony\Bundle\FrameworkBundle\Routing;
|
||||
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\ControllerNameConverter;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\ControllerNameParser;
|
||||
use Symfony\Component\Routing\Loader\DelegatingLoader as BaseDelegatingLoader;
|
||||
use Symfony\Component\Routing\Loader\LoaderResolverInterface;
|
||||
use Symfony\Component\HttpKernel\Log\LoggerInterface;
|
||||
@ -26,19 +26,19 @@ use Symfony\Component\HttpKernel\Log\LoggerInterface;
|
||||
*/
|
||||
class DelegatingLoader extends BaseDelegatingLoader
|
||||
{
|
||||
protected $converter;
|
||||
protected $parser;
|
||||
protected $logger;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param ControllerNameConverter $converter A ControllerNameConverter instance
|
||||
* @param LoggerInterface $logger A LoggerInterface instance
|
||||
* @param LoaderResolverInterface $resolver A LoaderResolverInterface instance
|
||||
* @param ControllerNameParser $parser A ControllerNameParser instance
|
||||
* @param LoggerInterface $logger A LoggerInterface instance
|
||||
* @param LoaderResolverInterface $resolver A LoaderResolverInterface instance
|
||||
*/
|
||||
public function __construct(ControllerNameConverter $converter, LoggerInterface $logger = null, LoaderResolverInterface $resolver)
|
||||
public function __construct(ControllerNameParser $parser, LoggerInterface $logger = null, LoaderResolverInterface $resolver)
|
||||
{
|
||||
$this->converter = $converter;
|
||||
$this->parser = $parser;
|
||||
$this->logger = $logger;
|
||||
|
||||
parent::__construct($resolver);
|
||||
@ -59,7 +59,7 @@ class DelegatingLoader extends BaseDelegatingLoader
|
||||
foreach ($collection->all() as $name => $route) {
|
||||
if ($controller = $route->getDefault('_controller')) {
|
||||
try {
|
||||
$controller = $this->converter->fromShortNotation($controller);
|
||||
$controller = $this->parser->parse($controller);
|
||||
} catch (\Exception $e) {
|
||||
// unable to optimize unknown notation
|
||||
}
|
||||
|
50
src/Symfony/Bundle/FrameworkBundle/Routing/FileLocator.php
Normal file
50
src/Symfony/Bundle/FrameworkBundle/Routing/FileLocator.php
Normal file
@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Bundle\FrameworkBundle\Routing;
|
||||
|
||||
use Symfony\Component\Routing\Loader\FileLocator as BaseFileLocator;
|
||||
use Symfony\Component\HttpKernel\Kernel;
|
||||
|
||||
/**
|
||||
* FileLocator uses the Kernel to locate resources in bundles.
|
||||
*
|
||||
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
*/
|
||||
class FileLocator extends BaseFileLocator
|
||||
{
|
||||
protected $kernel;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param Kernel $kernel A Kernel instance
|
||||
* @param string|array $paths A path or an array of paths where to look for resources
|
||||
*/
|
||||
public function __construct(Kernel $kernel, array $paths = array())
|
||||
{
|
||||
$this->kernel = $kernel;
|
||||
|
||||
parent::__construct($paths);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function locate($file)
|
||||
{
|
||||
if ('@' === $file[0]) {
|
||||
return $this->kernel->locateResource($file);
|
||||
}
|
||||
|
||||
return parent::locate($file);
|
||||
}
|
||||
}
|
@ -0,0 +1,67 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Bundle\FrameworkBundle\Templating\Loader;
|
||||
|
||||
use Symfony\Component\Templating\Storage\FileStorage;
|
||||
use Symfony\Component\Templating\Loader\LoaderInterface;
|
||||
|
||||
/**
|
||||
* FilesystemLoader is a loader that read templates from the filesystem.
|
||||
*
|
||||
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
*/
|
||||
class FilesystemLoader implements LoaderInterface
|
||||
{
|
||||
protected $locator;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param TemplateNameParserInterface $nameParser A TemplateNameParserInterface instance
|
||||
* @param string $path An overload path
|
||||
*/
|
||||
public function __construct(TemplateLocator $locator)
|
||||
{
|
||||
$this->locator = $locator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads a template.
|
||||
*
|
||||
* @param string $template The logical template name
|
||||
*
|
||||
* @return Storage|Boolean false if the template cannot be loaded, a Storage instance otherwise
|
||||
*/
|
||||
public function load($template)
|
||||
{
|
||||
if (false === $file = $this->locator->locate($template)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return new FileStorage($file);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the template is still fresh.
|
||||
*
|
||||
* @param string $template The template name
|
||||
* @param timestamp $time The last modification time of the cached template
|
||||
*/
|
||||
public function isFresh($template, $time)
|
||||
{
|
||||
if (false === $template = $this->load($template)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return filemtime((string) $template) < $time;
|
||||
}
|
||||
}
|
@ -0,0 +1,73 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Bundle\FrameworkBundle\Templating\Loader;
|
||||
|
||||
use Symfony\Component\Templating\Loader\TemplateNameParserInterface;
|
||||
use Symfony\Component\HttpKernel\Kernel;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
*/
|
||||
class TemplateLocator
|
||||
{
|
||||
protected $kernel;
|
||||
protected $parser;
|
||||
protected $path;
|
||||
protected $cache;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param Kernel $kernel A Kernel instance
|
||||
* @param TemplateNameParserInterface $parser A TemplateNameParserInterface instance
|
||||
* @param string $path A global fallback path
|
||||
*/
|
||||
public function __construct(Kernel $kernel, TemplateNameParserInterface $parser, $path)
|
||||
{
|
||||
$this->kernel = $kernel;
|
||||
$this->path = $path;
|
||||
$this->parser = $parser;
|
||||
$this->cache = array();
|
||||
}
|
||||
|
||||
public function locate($name)
|
||||
{
|
||||
// normalize name
|
||||
$name = str_replace(':/' , ':', preg_replace('#/{2,}#', '/', strtr($name, '\\', '/')));
|
||||
|
||||
if (isset($this->cache[$name])) {
|
||||
return $this->cache[$name];
|
||||
}
|
||||
|
||||
if (false !== strpos($name, '..')) {
|
||||
throw new \RuntimeException(sprintf('Template name "%s" contains invalid characters.', $name));
|
||||
}
|
||||
|
||||
$parameters = $this->parser->parse($name);
|
||||
$resource = $parameters['bundle'].'/Resources/views/'.$parameters['controller'].'/'.$parameters['name'].'.'.$parameters['renderer'].'.'.$parameters['format'];
|
||||
|
||||
if (!$parameters['bundle']) {
|
||||
if (is_file($file = $this->path.'/views/'.$parameters['controller'].'/'.$parameters['name'].'.'.$parameters['renderer'].'.'.$parameters['format'])) {
|
||||
return $this->cache[$name] = $file;
|
||||
}
|
||||
|
||||
throw new \InvalidArgumentException(sprintf('Unable to find template "%s" in "%s".', $name, $this->path));
|
||||
}
|
||||
|
||||
try {
|
||||
return $this->kernel->locateResource('@'.$resource, $this->path);
|
||||
} catch (\Exception $e) {
|
||||
throw new \InvalidArgumentException(sprintf('Unable to find template "%s".', $name, $this->path), 0, $e);
|
||||
}
|
||||
}
|
||||
}
|
@ -9,9 +9,9 @@
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Bundle\FrameworkBundle\Templating;
|
||||
namespace Symfony\Bundle\FrameworkBundle\Templating\Loader;
|
||||
|
||||
use Symfony\Component\Templating\TemplateNameParser as BaseTemplateNameParser;
|
||||
use Symfony\Component\Templating\Loader\TemplateNameParser as BaseTemplateNameParser;
|
||||
use Symfony\Component\HttpKernel\Kernel;
|
||||
|
||||
/**
|
||||
@ -45,41 +45,26 @@ class TemplateNameParser extends BaseTemplateNameParser
|
||||
throw new \InvalidArgumentException(sprintf('Template name "%s" is not valid (format is "bundle:section:template.renderer.format").', $name));
|
||||
}
|
||||
|
||||
$bundle = null;
|
||||
if ($parts[0]) {
|
||||
foreach ($this->kernel->getBundles() as $b) {
|
||||
if ($parts[0] !== $b->getName()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach (array_keys($this->kernel->getBundleDirs()) as $prefix) {
|
||||
if (0 === $pos = strpos($b->getNamespace(), $prefix)) {
|
||||
$bundle = str_replace($prefix.'\\', '', $b->getNamespace());
|
||||
|
||||
break 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (null === $bundle) {
|
||||
throw new \InvalidArgumentException(sprintf('Unable to find a valid bundle name for template "%s".', $name));
|
||||
}
|
||||
}
|
||||
|
||||
$elements = explode('.', $parts[2]);
|
||||
if (3 !== count($elements)) {
|
||||
throw new \InvalidArgumentException(sprintf('Template name "%s" is not valid (format is "bundle:section:template.renderer.format").', $name));
|
||||
}
|
||||
|
||||
$parameters = array(
|
||||
// bundle is used as part of the template path, so we need /
|
||||
'bundle' => str_replace('\\', '/', $bundle),
|
||||
'bundle' => $parts[0],
|
||||
'controller' => $parts[1],
|
||||
'name' => $elements[0],
|
||||
'renderer' => $elements[1],
|
||||
'format' => $elements[2],
|
||||
);
|
||||
|
||||
if ($parameters['bundle']) {
|
||||
try {
|
||||
$this->kernel->getBundle($parameters['bundle']);
|
||||
} catch (\Exception $e) {
|
||||
throw new \InvalidArgumentException(sprintf('Template name "%s" is not valid.', $name), 0, $e);
|
||||
}
|
||||
}
|
||||
|
||||
return $parameters;
|
||||
}
|
@ -1,88 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Bundle\FrameworkBundle\Tests\Controller;
|
||||
|
||||
use Symfony\Bundle\FrameworkBundle\Tests\TestCase;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\ControllerNameConverter;
|
||||
use Symfony\Bundle\FrameworkBundle\Tests\Logger;
|
||||
use Symfony\Bundle\FrameworkBundle\Tests\Kernel;
|
||||
|
||||
require_once __DIR__.'/../Kernel.php';
|
||||
require_once __DIR__.'/../Logger.php';
|
||||
|
||||
class ControllerNameConverterTest extends TestCase
|
||||
{
|
||||
public function testToShortNotation()
|
||||
{
|
||||
$kernel = new Kernel();
|
||||
$kernel->boot();
|
||||
$converter = new ControllerNameConverter($kernel);
|
||||
|
||||
$this->assertEquals('FooBundle:Default:index', $converter->toShortNotation('TestBundle\FooBundle\Controller\DefaultController::indexAction'), '->toShortNotation() converts a class::method string to the short a:b:c notation');
|
||||
$this->assertEquals('SensioFooBundle:Default:index', $converter->toShortNotation('TestBundle\Sensio\FooBundle\Controller\DefaultController::indexAction'), '->toShortNotation() converts a class::method string to the short a:b:c notation');
|
||||
$this->assertEquals('SensioCmsFooBundle:Default:index', $converter->toShortNotation('TestBundle\Sensio\Cms\FooBundle\Controller\DefaultController::indexAction'), '->toShortNotation() converts a class::method string to the short a:b:c notation');
|
||||
|
||||
try {
|
||||
$converter->toShortNotation('foo');
|
||||
$this->fail('->toShortNotation() throws an \InvalidArgumentException if the controller is not a class::method string');
|
||||
} catch (\Exception $e) {
|
||||
$this->assertInstanceOf('\InvalidArgumentException', $e, '->toShortNotation() throws an \InvalidArgumentException if the controller is not a class::method string');
|
||||
}
|
||||
|
||||
try {
|
||||
$converter->toShortNotation('Symfony\Bundle\FooBundle\Controller\FooController::bar');
|
||||
$this->fail('->toShortNotation() throws an \InvalidArgumentException if the method does not end with Action');
|
||||
} catch (\Exception $e) {
|
||||
$this->assertInstanceOf('\InvalidArgumentException', $e, '->toShortNotation() throws an \InvalidArgumentException if the method does not end with Action');
|
||||
}
|
||||
|
||||
try {
|
||||
$converter->toShortNotation('Symfony\Bundle\FooBundle\FooController::barAction');
|
||||
$this->fail('->toShortNotation() throws an \InvalidArgumentException if the class does not end with Controller');
|
||||
} catch (\Exception $e) {
|
||||
$this->assertInstanceOf('\InvalidArgumentException', $e, '->toShortNotation() throws an \InvalidArgumentException if the class does not end with Controller');
|
||||
}
|
||||
|
||||
try {
|
||||
$converter->toShortNotation('FooBar\Bundle\FooBundle\Controller\FooController::barAction');
|
||||
$this->fail('->toShortNotation() throws an \InvalidArgumentException if the class does not belongs to a known namespace');
|
||||
} catch (\Exception $e) {
|
||||
$this->assertInstanceOf('\InvalidArgumentException', $e, '->toShortNotation() throws an \InvalidArgumentException if the class does not belongs to a known namespace');
|
||||
}
|
||||
}
|
||||
|
||||
public function testFromShortNotation()
|
||||
{
|
||||
$kernel = new Kernel();
|
||||
$kernel->boot();
|
||||
$logger = new Logger();
|
||||
$converter = new ControllerNameConverter($kernel, $logger);
|
||||
|
||||
$this->assertEquals('TestBundle\FooBundle\Controller\DefaultController::indexAction', $converter->fromShortNotation('FooBundle:Default:index'), '->fromShortNotation() converts a short a:b:c notation string to a class::method string');
|
||||
$this->assertEquals('TestApplication\Sensio\FooBundle\Controller\DefaultController::indexAction', $converter->fromShortNotation('SensioFooBundle:Default:index'), '->fromShortNotation() converts a short a:b:c notation string to a class::method string');
|
||||
$this->assertEquals('TestBundle\Sensio\Cms\FooBundle\Controller\DefaultController::indexAction', $converter->fromShortNotation('SensioCmsFooBundle:Default:index'), '->fromShortNotation() converts a short a:b:c notation string to a class::method string');
|
||||
|
||||
try {
|
||||
$converter->fromShortNotation('foo:');
|
||||
$this->fail('->fromShortNotation() throws an \InvalidArgumentException if the controller is not an a:b:c string');
|
||||
} catch (\Exception $e) {
|
||||
$this->assertInstanceOf('\InvalidArgumentException', $e, '->fromShortNotation() throws an \InvalidArgumentException if the controller is not an a:b:c string');
|
||||
}
|
||||
|
||||
try {
|
||||
$converter->fromShortNotation('BarBundle:Default:index');
|
||||
$this->fail('->fromShortNotation() throws a \InvalidArgumentException if the class is found but does not exist');
|
||||
} catch (\Exception $e) {
|
||||
$this->assertInstanceOf('\InvalidArgumentException', $e, '->fromShortNotation() throws a \LogicException if the class is found but does not exist');
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Bundle\FrameworkBundle\Tests\Controller;
|
||||
|
||||
use Symfony\Bundle\FrameworkBundle\Tests\TestCase;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\ControllerNameParser;
|
||||
use Symfony\Bundle\FrameworkBundle\Tests\Logger;
|
||||
use Symfony\Bundle\FrameworkBundle\Tests\Kernel;
|
||||
|
||||
require_once __DIR__.'/../Kernel.php';
|
||||
require_once __DIR__.'/../Logger.php';
|
||||
|
||||
class ControllerNameParserTest extends TestCase
|
||||
{
|
||||
public function testParse()
|
||||
{
|
||||
$kernel = new Kernel();
|
||||
$kernel->boot();
|
||||
$logger = new Logger();
|
||||
$parser = new ControllerNameParser($kernel, $logger);
|
||||
|
||||
$this->assertEquals('TestBundle\FooBundle\Controller\DefaultController::indexAction', $parser->parse('FooBundle:Default:index'), '->parse() converts a short a:b:c notation string to a class::method string');
|
||||
$this->assertEquals('TestBundle\FooBundle\Controller\Sub\DefaultController::indexAction', $parser->parse('FooBundle:Sub\Default:index'), '->parse() converts a short a:b:c notation string to a class::method string');
|
||||
$this->assertEquals('TestBundle\Fabpot\FooBundle\Controller\DefaultController::indexAction', $parser->parse('SensioFooBundle:Default:index'), '->parse() converts a short a:b:c notation string to a class::method string');
|
||||
$this->assertEquals('TestBundle\Sensio\Cms\FooBundle\Controller\DefaultController::indexAction', $parser->parse('SensioCmsFooBundle:Default:index'), '->parse() converts a short a:b:c notation string to a class::method string');
|
||||
|
||||
try {
|
||||
$parser->parse('foo:');
|
||||
$this->fail('->parse() throws an \InvalidArgumentException if the controller is not an a:b:c string');
|
||||
} catch (\Exception $e) {
|
||||
$this->assertInstanceOf('\InvalidArgumentException', $e, '->parse() throws an \InvalidArgumentException if the controller is not an a:b:c string');
|
||||
}
|
||||
|
||||
try {
|
||||
$parser->parse('BarBundle:Default:index');
|
||||
$this->fail('->parse() throws a \InvalidArgumentException if the class is found but does not exist');
|
||||
} catch (\Exception $e) {
|
||||
$this->assertInstanceOf('\InvalidArgumentException', $e, '->parse() throws a \LogicException if the class is found but does not exist');
|
||||
}
|
||||
}
|
||||
}
|
@ -49,12 +49,7 @@ class FrameworkExtensionTest extends TestCase
|
||||
protected function getContainer()
|
||||
{
|
||||
return new ContainerBuilder(new ParameterBag(array(
|
||||
'kernel.bundle_dirs' => array(
|
||||
'Symfony\\Framework' => __DIR__ . '/../../../Framework',
|
||||
),
|
||||
'kernel.bundles' => array(
|
||||
'Symfony\\Bundle\\FrameworkBundle\\FrameworkBundle',
|
||||
),
|
||||
'kernel.bundles' => array('FrameworkBundle' => 'Symfony\\Bundle\\FrameworkBundle\\FrameworkBundle'),
|
||||
'kernel.root_dir' => __DIR__,
|
||||
'kernel.debug' => false,
|
||||
'kernel.compiled_classes' => array(),
|
||||
|
@ -1,6 +1,6 @@
|
||||
<?php
|
||||
|
||||
namespace TestApplication\Sensio\FooBundle\Controller;
|
||||
namespace TestBundle\Fabpot\FooBundle\Controller;
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony framework.
|
@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
namespace TestBundle\Fabpot\FooBundle;
|
||||
|
||||
use Symfony\Component\HttpKernel\Bundle\Bundle;
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony framework.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Bundle.
|
||||
*
|
||||
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
*/
|
||||
class FabpotFooBundle extends Bundle
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getParent()
|
||||
{
|
||||
return 'SensioFooBundle';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getNamespace()
|
||||
{
|
||||
return __NAMESPACE__;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getPath()
|
||||
{
|
||||
return strtr(__DIR__, '\\', '/');
|
||||
}
|
||||
}
|
@ -1,8 +1,6 @@
|
||||
<?php
|
||||
|
||||
namespace TestApplication\Sensio\FooBundle;
|
||||
|
||||
use Symfony\Component\HttpKernel\Bundle\Bundle;
|
||||
namespace TestBundle\FooBundle\Controller\Sub;
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony framework.
|
||||
@ -14,10 +12,10 @@ use Symfony\Component\HttpKernel\Bundle\Bundle;
|
||||
*/
|
||||
|
||||
/**
|
||||
* Bundle.
|
||||
* DefaultController.
|
||||
*
|
||||
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
*/
|
||||
class SensioFooBundle extends Bundle
|
||||
class DefaultController
|
||||
{
|
||||
}
|
@ -20,4 +20,19 @@ use Symfony\Component\HttpKernel\Bundle\Bundle;
|
||||
*/
|
||||
class FooBundle extends Bundle
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getNamespace()
|
||||
{
|
||||
return __NAMESPACE__;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getPath()
|
||||
{
|
||||
return strtr(__DIR__, '\\', '/');
|
||||
}
|
||||
}
|
||||
|
@ -20,4 +20,19 @@ use Symfony\Component\HttpKernel\Bundle\Bundle;
|
||||
*/
|
||||
class SensioCmsFooBundle extends Bundle
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getNamespace()
|
||||
{
|
||||
return __NAMESPACE__;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getPath()
|
||||
{
|
||||
return strtr(__DIR__, '\\', '/');
|
||||
}
|
||||
}
|
||||
|
@ -20,4 +20,19 @@ use Symfony\Component\HttpKernel\Bundle\Bundle;
|
||||
*/
|
||||
class SensioFooBundle extends Bundle
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getNamespace()
|
||||
{
|
||||
return __NAMESPACE__;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getPath()
|
||||
{
|
||||
return strtr(__DIR__, '\\', '/');
|
||||
}
|
||||
}
|
||||
|
@ -54,21 +54,10 @@ class Kernel extends BaseKernel
|
||||
{
|
||||
return array(
|
||||
new \Symfony\Bundle\FrameworkBundle\FrameworkBundle(),
|
||||
new \TestBundle\FooBundle\FooBundle(),
|
||||
new \TestBundle\Sensio\FooBundle\SensioFooBundle(),
|
||||
new \TestApplication\Sensio\FooBundle\SensioFooBundle(),
|
||||
new \TestBundle\Sensio\Cms\FooBundle\SensioCmsFooBundle(),
|
||||
);
|
||||
}
|
||||
|
||||
public function registerBundleDirs()
|
||||
{
|
||||
return array(
|
||||
'Application' => __DIR__.'/../src/Application',
|
||||
'Bundle' => __DIR__.'/../src/Bundle',
|
||||
'TestApplication' => __DIR__.'/Fixtures/TestApplication',
|
||||
'TestBundle' => __DIR__.'/Fixtures/TestBundle',
|
||||
'Symfony\\Bundle' => __DIR__.'/../src/vendor/symfony/src/Symfony/Bundle',
|
||||
new \TestBundle\FooBundle\FooBundle(),
|
||||
new \TestBundle\Fabpot\FooBundle\FabpotFooBundle(),
|
||||
);
|
||||
}
|
||||
|
||||
@ -85,9 +74,10 @@ class Kernel extends BaseKernel
|
||||
throw new \LogicException('The kernel is already booted.');
|
||||
}
|
||||
|
||||
$this->bundles = $this->registerBundles();
|
||||
$this->bundleDirs = $this->registerBundleDirs();
|
||||
// init bundles
|
||||
$this->initializeBundles();
|
||||
|
||||
// init container
|
||||
$this->initializeContainer();
|
||||
|
||||
foreach ($this->bundles as $bundle) {
|
||||
|
@ -9,10 +9,10 @@
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Bundle\FrameworkBundle\Tests\Templating;
|
||||
namespace Symfony\Bundle\FrameworkBundle\Tests\Templating\Loader;
|
||||
|
||||
use Symfony\Bundle\FrameworkBundle\Tests\TestCase;
|
||||
use Symfony\Bundle\FrameworkBundle\Templating\TemplateNameParser;
|
||||
use Symfony\Bundle\FrameworkBundle\Templating\Loader\TemplateNameParser;
|
||||
use Symfony\Bundle\FrameworkBundle\Tests\Kernel;
|
||||
|
||||
class TemplateNameParserTest extends TestCase
|
||||
@ -24,9 +24,9 @@ class TemplateNameParserTest extends TestCase
|
||||
{
|
||||
$kernel = new Kernel();
|
||||
$kernel->boot();
|
||||
$converter = new TemplateNameParser($kernel);
|
||||
$parser = new TemplateNameParser($kernel);
|
||||
|
||||
$this->assertEquals($parameters, $converter->parse($name));
|
||||
$this->assertEquals($parameters, $parser->parse($name));
|
||||
}
|
||||
|
||||
public function getParseTests()
|
||||
@ -35,8 +35,8 @@ class TemplateNameParserTest extends TestCase
|
||||
array('FooBundle:Post:index.php.html', array('name' => 'index', 'bundle' => 'FooBundle', 'controller' => 'Post', 'renderer' => 'php', 'format' => 'html')),
|
||||
array('FooBundle:Post:index.twig.html', array('name' => 'index', 'bundle' => 'FooBundle', 'controller' => 'Post', 'renderer' => 'twig', 'format' => 'html')),
|
||||
array('FooBundle:Post:index.php.xml', array('name' => 'index', 'bundle' => 'FooBundle', 'controller' => 'Post', 'renderer' => 'php', 'format' => 'xml')),
|
||||
array('SensioFooBundle:Post:index.php.html', array('name' => 'index', 'bundle' => 'Sensio/FooBundle', 'controller' => 'Post', 'renderer' => 'php', 'format' => 'html')),
|
||||
array('SensioCmsFooBundle:Post:index.php.html', array('name' => 'index', 'bundle' => 'Sensio/Cms/FooBundle', 'controller' => 'Post', 'renderer' => 'php', 'format' => 'html')),
|
||||
array('SensioFooBundle:Post:index.php.html', array('name' => 'index', 'bundle' => 'SensioFooBundle', 'controller' => 'Post', 'renderer' => 'php', 'format' => 'html')),
|
||||
array('SensioCmsFooBundle:Post:index.php.html', array('name' => 'index', 'bundle' => 'SensioCmsFooBundle', 'controller' => 'Post', 'renderer' => 'php', 'format' => 'html')),
|
||||
array(':Post:index.php.html',array('name' => 'index', 'bundle' => '', 'controller' => 'Post', 'renderer' => 'php', 'format' => 'html')),
|
||||
array('::index.php.html', array('name' => 'index', 'bundle' => '', 'controller' => '', 'renderer' => 'php', 'format' => 'html')),
|
||||
);
|
||||
@ -50,9 +50,9 @@ class TemplateNameParserTest extends TestCase
|
||||
{
|
||||
$kernel = new Kernel();
|
||||
$kernel->boot();
|
||||
$converter = new TemplateNameParser($kernel);
|
||||
$parser = new TemplateNameParser($kernel);
|
||||
|
||||
$converter->parse($name);
|
||||
$parser->parse($name);
|
||||
}
|
||||
|
||||
public function getParseInvalidTests()
|
@ -20,4 +20,19 @@ use Symfony\Component\HttpKernel\Bundle\Bundle;
|
||||
*/
|
||||
class SwiftmailerBundle extends Bundle
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getNamespace()
|
||||
{
|
||||
return __NAMESPACE__;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getPath()
|
||||
{
|
||||
return strtr(__DIR__, '\\', '/');
|
||||
}
|
||||
}
|
||||
|
@ -43,7 +43,6 @@ class TwigExtension extends Extension
|
||||
'Twig_Extension_Escaper',
|
||||
'Twig_Extension_Optimizer',
|
||||
'Twig_LoaderInterface',
|
||||
'Twig_Loader_Filesystem',
|
||||
'Twig_Markup',
|
||||
'Twig_TemplateInterface',
|
||||
'Twig_Template',
|
||||
|
@ -11,8 +11,7 @@
|
||||
|
||||
namespace Symfony\Bundle\TwigBundle\Loader;
|
||||
|
||||
use Symfony\Component\Templating\TemplateNameParserInterface;
|
||||
use Symfony\Component\HttpKernel\Log\LoggerInterface;
|
||||
use Symfony\Bundle\FrameworkBundle\Templating\Loader\TemplateLocator;
|
||||
|
||||
/**
|
||||
* FilesystemLoader extends the default Twig filesystem loader
|
||||
@ -20,78 +19,62 @@ use Symfony\Component\HttpKernel\Log\LoggerInterface;
|
||||
*
|
||||
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
*/
|
||||
class FilesystemLoader extends \Twig_Loader_Filesystem
|
||||
class FilesystemLoader implements \Twig_LoaderInterface
|
||||
{
|
||||
protected $nameParser;
|
||||
protected $logger;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param Kernel $kernel A Kernel instance
|
||||
* @param TemplateNameParserInterface $nameParser A TemplateNameParserInterface instance
|
||||
* @param string $path A global fallback path
|
||||
* @param LoggerInterface $logger A LoggerInterface instance
|
||||
*/
|
||||
public function __construct(TemplateNameParserInterface $nameParser, array $paths = array(), LoggerInterface $logger = null)
|
||||
public function __construct(TemplateLocator $locator)
|
||||
{
|
||||
parent::__construct($paths);
|
||||
|
||||
$this->nameParser = $nameParser;
|
||||
$this->logger = $logger;
|
||||
$this->locator = $locator;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* Gets the source code of a template, given its name.
|
||||
*
|
||||
* @param string $name The name of the template to load
|
||||
*
|
||||
* @return string The template source code
|
||||
*/
|
||||
public function setPaths($paths)
|
||||
public function getSource($name)
|
||||
{
|
||||
// invalidate the cache
|
||||
$this->cache = array();
|
||||
return file_get_contents($this->findTemplate($name));
|
||||
}
|
||||
|
||||
// we don't check if the directory exists here as we have path patterns, not paths
|
||||
$this->paths = is_array($paths) ? $paths : array($paths);
|
||||
/**
|
||||
* Gets the cache key to use for the cache for a given template name.
|
||||
*
|
||||
* @param string $name The name of the template to load
|
||||
*
|
||||
* @return string The cache key
|
||||
*/
|
||||
public function getCacheKey($name)
|
||||
{
|
||||
return $this->findTemplate($name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the template is still fresh.
|
||||
*
|
||||
* @param string $name The template name
|
||||
* @param timestamp $time The last modification time of the cached template
|
||||
*/
|
||||
public function isFresh($name, $time)
|
||||
{
|
||||
return filemtime($this->findTemplate($name)) < $time;
|
||||
}
|
||||
|
||||
protected function findTemplate($name)
|
||||
{
|
||||
// normalize name
|
||||
$name = str_replace(':/' , ':', preg_replace('#/{2,}#', '/', strtr($name, '\\', '/')));
|
||||
|
||||
if (isset($this->cache[$name])) {
|
||||
return $this->cache[$name];
|
||||
if (false === $file = $this->locator->locate($name)) {
|
||||
throw new \Twig_Error_Loader(sprintf('Unable to find template "%s".', $name));
|
||||
}
|
||||
|
||||
$parameters = $this->nameParser->parse($name);
|
||||
|
||||
$this->validateName($parameters['name']);
|
||||
$this->validateName($parameters['bundle']);
|
||||
$this->validateName($parameters['controller']);
|
||||
$this->validateName($parameters['format']);
|
||||
|
||||
$replacements = array();
|
||||
foreach ($parameters as $key => $value) {
|
||||
$replacements['%'.$key.'%'] = $value;
|
||||
}
|
||||
|
||||
$logs = array();
|
||||
foreach ($this->paths as $path) {
|
||||
if (is_file($file = strtr($path, $replacements))) {
|
||||
if (null !== $this->logger) {
|
||||
$this->logger->info(sprintf('Loaded template file "%s"', $file));
|
||||
}
|
||||
|
||||
return $this->cache[$name] = $file;
|
||||
}
|
||||
|
||||
if (null !== $this->logger) {
|
||||
$logs[] = sprintf('Failed loading template file "%s"', $file);
|
||||
}
|
||||
}
|
||||
|
||||
if (null !== $this->logger) {
|
||||
foreach ($logs as $log) {
|
||||
$this->logger->debug($log);
|
||||
}
|
||||
}
|
||||
|
||||
throw new \Twig_Error_Loader(sprintf('Unable to find template "%s".', $name));
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
|
@ -26,9 +26,7 @@
|
||||
</service>
|
||||
|
||||
<service id="twig.loader" class="%twig.loader.class%">
|
||||
<argument type="service" id="templating.name_parser" />
|
||||
<argument>%templating.loader.filesystem.path%</argument>
|
||||
<argument type="service" id="logger" on-invalid="ignore" />
|
||||
<argument type="service" id="templating.locator" />
|
||||
</service>
|
||||
|
||||
<service id="templating.engine.twig" class="%templating.engine.twig.class%">
|
||||
|
@ -28,4 +28,20 @@ class TwigBundle extends Bundle
|
||||
|
||||
$container->addCompilerPass(new TwigEnvironmentPass());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getNamespace()
|
||||
{
|
||||
return __NAMESPACE__;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getPath()
|
||||
{
|
||||
return strtr(__DIR__, '\\', '/');
|
||||
}
|
||||
}
|
||||
|
@ -20,4 +20,19 @@ use Symfony\Component\HttpKernel\Bundle\Bundle;
|
||||
*/
|
||||
class WebProfilerBundle extends Bundle
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getNamespace()
|
||||
{
|
||||
return __NAMESPACE__;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getPath()
|
||||
{
|
||||
return strtr(__DIR__, '\\', '/');
|
||||
}
|
||||
}
|
||||
|
@ -28,4 +28,20 @@ class ZendBundle extends Bundle
|
||||
|
||||
$container->addCompilerPass(new ZendLoggerWriterPass());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getNamespace()
|
||||
{
|
||||
return __NAMESPACE__;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getPath()
|
||||
{
|
||||
return strtr(__DIR__, '\\', '/');
|
||||
}
|
||||
}
|
||||
|
@ -18,18 +18,13 @@ use Symfony\Component\Console\Application;
|
||||
use Symfony\Component\Finder\Finder;
|
||||
|
||||
/**
|
||||
* An implementation of the BundleInterface that follows a few conventions
|
||||
* for the DependencyInjection extensions and the Console commands.
|
||||
* An implementation of BundleInterface that adds a few conventions
|
||||
* for DependencyInjection extensions and Console commands.
|
||||
*
|
||||
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
*/
|
||||
abstract class Bundle extends ContainerAware implements BundleInterface
|
||||
{
|
||||
protected $name;
|
||||
protected $namespace;
|
||||
protected $path;
|
||||
protected $reflection;
|
||||
|
||||
/**
|
||||
* Boots the Bundle.
|
||||
*/
|
||||
@ -45,59 +40,13 @@ abstract class Bundle extends ContainerAware implements BundleInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Bundle name.
|
||||
* Returns the bundle parent name.
|
||||
*
|
||||
* @return string The Bundle name
|
||||
* @return string The Bundle parent name it overrides or null if no parent
|
||||
*/
|
||||
public function getName()
|
||||
public function getParent()
|
||||
{
|
||||
if (null === $this->name) {
|
||||
$this->initReflection();
|
||||
}
|
||||
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Bundle namespace.
|
||||
*
|
||||
* @return string The Bundle namespace
|
||||
*/
|
||||
public function getNamespace()
|
||||
{
|
||||
if (null === $this->name) {
|
||||
$this->initReflection();
|
||||
}
|
||||
|
||||
return $this->namespace;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Bundle absolute path.
|
||||
*
|
||||
* @return string The Bundle absolute path
|
||||
*/
|
||||
public function getPath()
|
||||
{
|
||||
if (null === $this->name) {
|
||||
$this->initReflection();
|
||||
}
|
||||
|
||||
return $this->path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Bundle Reflection instance.
|
||||
*
|
||||
* @return \ReflectionObject A \ReflectionObject instance for the Bundle
|
||||
*/
|
||||
public function getReflection()
|
||||
{
|
||||
if (null === $this->name) {
|
||||
$this->initReflection();
|
||||
}
|
||||
|
||||
return $this->reflection;
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -119,7 +68,7 @@ abstract class Bundle extends ContainerAware implements BundleInterface
|
||||
$finder = new Finder();
|
||||
$finder->files()->name('*Extension.php')->in($dir);
|
||||
|
||||
$prefix = $this->namespace.'\\DependencyInjection';
|
||||
$prefix = $this->getNamespace().'\\DependencyInjection';
|
||||
foreach ($finder as $file) {
|
||||
$class = $prefix.strtr($file->getPath(), array($dir => '', '/' => '\\')).'\\'.$file->getBasename('.php');
|
||||
|
||||
@ -146,7 +95,7 @@ abstract class Bundle extends ContainerAware implements BundleInterface
|
||||
$finder = new Finder();
|
||||
$finder->files()->name('*Command.php')->in($dir);
|
||||
|
||||
$prefix = $this->namespace.'\\Command';
|
||||
$prefix = $this->getNamespace().'\\Command';
|
||||
foreach ($finder as $file) {
|
||||
$r = new \ReflectionClass($prefix.strtr($file->getPath(), array($dir => '', '/' => '\\')).'\\'.$file->getBasename('.php'));
|
||||
if ($r->isSubclassOf('Symfony\\Component\\Console\\Command\\Command') && !$r->isAbstract()) {
|
||||
@ -154,16 +103,4 @@ abstract class Bundle extends ContainerAware implements BundleInterface
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the properties on this object that require a reflection
|
||||
* object to have been created.
|
||||
*/
|
||||
protected function initReflection()
|
||||
{
|
||||
$this->reflection = new \ReflectionObject($this);
|
||||
$this->namespace = $this->reflection->getNamespaceName();
|
||||
$this->name = $this->reflection->getShortName();
|
||||
$this->path = str_replace('\\', '/', dirname($this->reflection->getFilename()));
|
||||
}
|
||||
}
|
||||
|
@ -27,4 +27,27 @@ interface BundleInterface
|
||||
* Shutdowns the Bundle.
|
||||
*/
|
||||
function shutdown();
|
||||
|
||||
/**
|
||||
* Returns the bundle parent class.
|
||||
*
|
||||
* @return string The Bundle parent class name it overrides or null if no parent
|
||||
*/
|
||||
function getParent();
|
||||
|
||||
/**
|
||||
* Gets the Bundle namespace.
|
||||
*
|
||||
* @return string The Bundle namespace
|
||||
*/
|
||||
function getNamespace();
|
||||
|
||||
/**
|
||||
* Gets the Bundle directory path.
|
||||
*
|
||||
* The path should always be returned as a Unix path (with /).
|
||||
*
|
||||
* @return string The Bundle absolute path
|
||||
*/
|
||||
function getPath();
|
||||
}
|
||||
|
@ -26,6 +26,7 @@ use Symfony\Component\DependencyInjection\Loader\ClosureLoader;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpKernel\HttpKernelInterface;
|
||||
use Symfony\Component\HttpKernel\ClassCollectionLoader;
|
||||
use Symfony\Component\HttpKernel\Bundle\BundleInterface;
|
||||
|
||||
/**
|
||||
* The Kernel is the heart of the Symfony system. It manages an environment
|
||||
@ -36,7 +37,7 @@ use Symfony\Component\HttpKernel\ClassCollectionLoader;
|
||||
abstract class Kernel implements HttpKernelInterface, \Serializable
|
||||
{
|
||||
protected $bundles;
|
||||
protected $bundleDirs;
|
||||
protected $bundleMap;
|
||||
protected $container;
|
||||
protected $rootDir;
|
||||
protected $environment;
|
||||
@ -97,16 +98,6 @@ abstract class Kernel implements HttpKernelInterface, \Serializable
|
||||
*/
|
||||
abstract public function registerBundles();
|
||||
|
||||
/**
|
||||
* Returns the directories where bundles can be found.
|
||||
*
|
||||
* The order is significant and can be used by the application.
|
||||
* For instance, it can be used to override templates.
|
||||
*
|
||||
* @return array A hash with namespaces as keys and directories as values
|
||||
*/
|
||||
abstract public function registerBundleDirs();
|
||||
|
||||
/**
|
||||
* Loads the container configuration
|
||||
*
|
||||
@ -140,9 +131,10 @@ abstract class Kernel implements HttpKernelInterface, \Serializable
|
||||
|
||||
require_once __DIR__.'/bootstrap.php';
|
||||
|
||||
$this->bundles = $this->registerBundles();
|
||||
$this->bundleDirs = $this->registerBundleDirs();
|
||||
// init bundles
|
||||
$this->initializeBundles();
|
||||
|
||||
// init container
|
||||
$this->initializeContainer();
|
||||
|
||||
// load core classes
|
||||
@ -213,19 +205,9 @@ abstract class Kernel implements HttpKernelInterface, \Serializable
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the directories where bundles can be stored.
|
||||
* Gets the registered bundle instances.
|
||||
*
|
||||
* @return array An array of directories where bundles can be stored
|
||||
*/
|
||||
public function getBundleDirs()
|
||||
{
|
||||
return $this->bundleDirs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the registered bundle names.
|
||||
*
|
||||
* @return array An array of registered bundle names
|
||||
* @return array An array of registered bundle instances
|
||||
*/
|
||||
public function getBundles()
|
||||
{
|
||||
@ -251,6 +233,98 @@ abstract class Kernel implements HttpKernelInterface, \Serializable
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a bundle by its name.
|
||||
*
|
||||
* @param string $name Bundle name
|
||||
* @param Boolean $first Whether to return the first bundle or all bundles matching this name
|
||||
*
|
||||
* @return BundleInterface A BundleInterface instance
|
||||
*
|
||||
* @throws \InvalidArgumentException when the bundle is not enabled
|
||||
*/
|
||||
public function getBundle($name, $first = true)
|
||||
{
|
||||
if (!isset($this->bundleMap[$name])) {
|
||||
throw new \InvalidArgumentException(sprintf('Bundle "%s" does not exist or it is not enabled.', $name));
|
||||
}
|
||||
|
||||
if (true === $first) {
|
||||
return $this->bundleMap[$name][0];
|
||||
} elseif (false === $first) {
|
||||
return $this->bundleMap[$name];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the file path for a given resource.
|
||||
*
|
||||
* The resource name must follow the following pattern:
|
||||
*
|
||||
* @BundleName/path/to/a/file.something
|
||||
*
|
||||
* where BundleName is the name of the bundle
|
||||
* and the remaining part is the relative path in the bundle.
|
||||
*
|
||||
* If $dir is passed, and the first segment of the path is Resources,
|
||||
* this method will look for a file named:
|
||||
*
|
||||
* $dir/BundleName/path/without/Resources
|
||||
*
|
||||
* @param string $name A resource name to locate
|
||||
* @param string $dir A directory where to look for the resource first
|
||||
* @param Boolean $first Whether to return the first path or paths for all matching bundles
|
||||
*
|
||||
* @return string|array The absolute path of the resource or an array if $first is false
|
||||
*
|
||||
* @throws \InvalidArgumentException if the file cannot be found or the name is not valid
|
||||
* @throws \RuntimeException if the name contains invalid/unsafe characters
|
||||
*/
|
||||
public function locateResource($name, $dir = null, $first = true)
|
||||
{
|
||||
if ('@' !== $name[0]) {
|
||||
throw new \InvalidArgumentException(sprintf('A resource name must start with @ ("%s" given).', $name));
|
||||
}
|
||||
|
||||
if (false !== strpos($name, '..')) {
|
||||
throw new \RuntimeException(sprintf('File name "%s" contains invalid characters (..).', $name));
|
||||
}
|
||||
|
||||
$name = substr($name, 1);
|
||||
list($bundle, $path) = explode('/', $name, 2);
|
||||
|
||||
$isResource = 0 === strpos($path, 'Resources');
|
||||
|
||||
// return the first matching one
|
||||
if (true === $first) {
|
||||
if (true === $isResource && null !== $dir && is_file($file = $dir.'/'.$bundle.'/'.substr($path, 10))) {
|
||||
return $file;
|
||||
} elseif (is_file($file = $this->getBundle($bundle)->getPath().'/'.$path)) {
|
||||
return $file;
|
||||
}
|
||||
|
||||
throw new \InvalidArgumentException(sprintf('Unable to find file "@%s".', $name));
|
||||
}
|
||||
|
||||
// return them all
|
||||
$files = array();
|
||||
if (true === $isResource && null !== $dir && is_file($file = $dir.'/'.$bundle.'/'.substr($path, 10))) {
|
||||
$files[] = $file;
|
||||
}
|
||||
|
||||
foreach ($this->getBundle($bundle, false) as $bundle) {
|
||||
if (is_file($file = $bundle->getPath().'/'.$path)) {
|
||||
$files[] = $file;
|
||||
}
|
||||
}
|
||||
|
||||
if ($files) {
|
||||
return $files;
|
||||
}
|
||||
|
||||
throw new \InvalidArgumentException(sprintf('Unable to find file "@%s".', $name));
|
||||
}
|
||||
|
||||
public function getName()
|
||||
{
|
||||
return $this->name;
|
||||
@ -331,6 +405,42 @@ abstract class Kernel implements HttpKernelInterface, \Serializable
|
||||
return $this->rootDir.'/logs';
|
||||
}
|
||||
|
||||
protected function initializeBundles()
|
||||
{
|
||||
// init bundles
|
||||
$this->bundles = array();
|
||||
foreach ($this->registerBundles() as $bundle) {
|
||||
$parts = explode('\\', get_class($bundle));
|
||||
$name = $parts[count($parts) - 1];
|
||||
$this->bundles[$name] = $bundle;
|
||||
if (!isset($this->bundleMap[$name])) {
|
||||
$this->bundleMap[$name] = array();
|
||||
}
|
||||
$this->bundleMap[$name][] = $bundle;
|
||||
}
|
||||
|
||||
// inheritance
|
||||
$extended = array();
|
||||
foreach ($this->bundles as $name => $bundle) {
|
||||
$parent = $bundle;
|
||||
$first = true;
|
||||
while ($parentName = $parent->getParent()) {
|
||||
if (!isset($this->bundles[$parentName])) {
|
||||
throw new \LogicException(sprintf('Bundle "%s" extends bundle "%s", which is not registered.', $name, $parentName));
|
||||
}
|
||||
|
||||
if ($first && isset($extended[$parentName])) {
|
||||
throw new \LogicException(sprintf('Bundle "%s" is directly extended by two bundles "%s" and "%s".', $parentName, $name, $extended[$parentName]));
|
||||
}
|
||||
|
||||
$first = false;
|
||||
$parent = $this->bundles[$parentName];
|
||||
$extended[$parentName] = $name;
|
||||
array_unshift($this->bundleMap[$parentName], $bundle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected function initializeContainer()
|
||||
{
|
||||
$class = $this->getSafeName().ucfirst($this->environment).($this->debug ? 'Debug' : '').'ProjectContainer';
|
||||
@ -351,21 +461,20 @@ abstract class Kernel implements HttpKernelInterface, \Serializable
|
||||
public function getKernelParameters()
|
||||
{
|
||||
$bundles = array();
|
||||
foreach ($this->bundles as $bundle) {
|
||||
$bundles[] = get_class($bundle);
|
||||
foreach ($this->bundles as $name => $bundle) {
|
||||
$bundles[$name] = get_class($bundle);
|
||||
}
|
||||
|
||||
return array_merge(
|
||||
array(
|
||||
'kernel.root_dir' => $this->rootDir,
|
||||
'kernel.environment' => $this->environment,
|
||||
'kernel.debug' => $this->debug,
|
||||
'kernel.name' => $this->name,
|
||||
'kernel.cache_dir' => $this->getCacheDir(),
|
||||
'kernel.logs_dir' => $this->getLogDir(),
|
||||
'kernel.bundle_dirs' => $this->bundleDirs,
|
||||
'kernel.bundles' => $bundles,
|
||||
'kernel.charset' => 'UTF-8',
|
||||
'kernel.root_dir' => $this->rootDir,
|
||||
'kernel.environment' => $this->environment,
|
||||
'kernel.debug' => $this->debug,
|
||||
'kernel.name' => $this->name,
|
||||
'kernel.cache_dir' => $this->getCacheDir(),
|
||||
'kernel.logs_dir' => $this->getLogDir(),
|
||||
'kernel.bundles' => $bundles,
|
||||
'kernel.charset' => 'UTF-8',
|
||||
),
|
||||
$this->getEnvParameters()
|
||||
);
|
||||
@ -453,10 +562,10 @@ abstract class Kernel implements HttpKernelInterface, \Serializable
|
||||
protected function getContainerLoader(ContainerInterface $container)
|
||||
{
|
||||
$resolver = new LoaderResolver(array(
|
||||
new XmlFileLoader($container, $this->getBundleDirs()),
|
||||
new YamlFileLoader($container, $this->getBundleDirs()),
|
||||
new IniFileLoader($container, $this->getBundleDirs()),
|
||||
new PhpFileLoader($container, $this->getBundleDirs()),
|
||||
new XmlFileLoader($container),
|
||||
new YamlFileLoader($container),
|
||||
new IniFileLoader($container),
|
||||
new PhpFileLoader($container),
|
||||
new ClosureLoader($container),
|
||||
));
|
||||
|
||||
|
@ -8,43 +8,15 @@ use Symfony\Component\Console\Application;
|
||||
use Symfony\Component\Finder\Finder;
|
||||
abstract class Bundle extends ContainerAware implements BundleInterface
|
||||
{
|
||||
protected $name;
|
||||
protected $namespace;
|
||||
protected $path;
|
||||
protected $reflection;
|
||||
public function boot()
|
||||
{
|
||||
}
|
||||
public function shutdown()
|
||||
{
|
||||
}
|
||||
public function getName()
|
||||
public function getParent()
|
||||
{
|
||||
if (null === $this->name) {
|
||||
$this->initReflection();
|
||||
}
|
||||
return $this->name;
|
||||
}
|
||||
public function getNamespace()
|
||||
{
|
||||
if (null === $this->name) {
|
||||
$this->initReflection();
|
||||
}
|
||||
return $this->namespace;
|
||||
}
|
||||
public function getPath()
|
||||
{
|
||||
if (null === $this->name) {
|
||||
$this->initReflection();
|
||||
}
|
||||
return $this->path;
|
||||
}
|
||||
public function getReflection()
|
||||
{
|
||||
if (null === $this->name) {
|
||||
$this->initReflection();
|
||||
}
|
||||
return $this->reflection;
|
||||
return null;
|
||||
}
|
||||
public function registerExtensions(ContainerBuilder $container)
|
||||
{
|
||||
@ -53,7 +25,7 @@ abstract class Bundle extends ContainerAware implements BundleInterface
|
||||
}
|
||||
$finder = new Finder();
|
||||
$finder->files()->name('*Extension.php')->in($dir);
|
||||
$prefix = $this->namespace.'\\DependencyInjection';
|
||||
$prefix = $this->getNamespace().'\\DependencyInjection';
|
||||
foreach ($finder as $file) {
|
||||
$class = $prefix.strtr($file->getPath(), array($dir => '', '/' => '\\')).'\\'.$file->getBasename('.php');
|
||||
$container->registerExtension(new $class());
|
||||
@ -66,7 +38,7 @@ abstract class Bundle extends ContainerAware implements BundleInterface
|
||||
}
|
||||
$finder = new Finder();
|
||||
$finder->files()->name('*Command.php')->in($dir);
|
||||
$prefix = $this->namespace.'\\Command';
|
||||
$prefix = $this->getNamespace().'\\Command';
|
||||
foreach ($finder as $file) {
|
||||
$r = new \ReflectionClass($prefix.strtr($file->getPath(), array($dir => '', '/' => '\\')).'\\'.$file->getBasename('.php'));
|
||||
if ($r->isSubclassOf('Symfony\\Component\\Console\\Command\\Command') && !$r->isAbstract()) {
|
||||
@ -74,13 +46,6 @@ abstract class Bundle extends ContainerAware implements BundleInterface
|
||||
}
|
||||
}
|
||||
}
|
||||
protected function initReflection()
|
||||
{
|
||||
$this->reflection = new \ReflectionObject($this);
|
||||
$this->namespace = $this->reflection->getNamespaceName();
|
||||
$this->name = $this->reflection->getShortName();
|
||||
$this->path = str_replace('\\', '/', dirname($this->reflection->getFilename()));
|
||||
}
|
||||
}
|
||||
}
|
||||
namespace Symfony\Component\HttpKernel\Bundle
|
||||
@ -89,6 +54,9 @@ interface BundleInterface
|
||||
{
|
||||
function boot();
|
||||
function shutdown();
|
||||
function getParent();
|
||||
function getNamespace();
|
||||
function getPath();
|
||||
}
|
||||
}
|
||||
namespace Symfony\Component\HttpKernel\Debug
|
||||
|
@ -33,7 +33,7 @@ class AnnotationDirectoryLoader extends AnnotationFileLoader
|
||||
*/
|
||||
public function load($path, $type = null)
|
||||
{
|
||||
$dir = $this->getAbsolutePath($path);
|
||||
$dir = $this->locator->getAbsolutePath($path);
|
||||
if (!file_exists($dir)) {
|
||||
throw new \InvalidArgumentException(sprintf('The directory "%s" does not exist (in: %s).', $dir, implode(', ', $this->paths)));
|
||||
}
|
||||
@ -62,6 +62,6 @@ class AnnotationDirectoryLoader extends AnnotationFileLoader
|
||||
*/
|
||||
public function supports($resource, $type = null)
|
||||
{
|
||||
return is_string($resource) && is_dir($this->getAbsolutePath($resource)) && (!$type || 'annotation' === $type);
|
||||
return is_string($resource) && is_dir($this->locator->getAbsolutePath($resource)) && (!$type || 'annotation' === $type);
|
||||
}
|
||||
}
|
||||
|
@ -30,13 +30,13 @@ class AnnotationFileLoader extends FileLoader
|
||||
* @param AnnotationClassLoader $loader An AnnotationClassLoader instance
|
||||
* @param string|array $paths A path or an array of paths where to look for resources
|
||||
*/
|
||||
public function __construct(AnnotationClassLoader $loader, $paths = array())
|
||||
public function __construct(FileLocator $locator, AnnotationClassLoader $loader, $paths = array())
|
||||
{
|
||||
if (!function_exists('token_get_all')) {
|
||||
throw new \RuntimeException('The Tokenizer extension is required for the routing annotation loaders.');
|
||||
}
|
||||
|
||||
parent::__construct($paths);
|
||||
parent::__construct($locator, $paths);
|
||||
|
||||
$this->loader = $loader;
|
||||
}
|
||||
@ -53,7 +53,7 @@ class AnnotationFileLoader extends FileLoader
|
||||
*/
|
||||
public function load($file, $type = null)
|
||||
{
|
||||
$path = $this->getAbsolutePath($file);
|
||||
$path = $this->locator->getAbsolutePath($file);
|
||||
if (!file_exists($path)) {
|
||||
throw new \InvalidArgumentException(sprintf('The file "%s" cannot be found (in: %s).', $file, implode(', ', $this->paths)));
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ class AnnotationGlobLoader extends AnnotationDirectoryLoader
|
||||
public function load($glob, $type = null)
|
||||
{
|
||||
$collection = new RouteCollection();
|
||||
foreach ($this->getAbsolutePaths($glob) as $path) {
|
||||
foreach ($this->locator->getAbsolutePaths($glob) as $path) {
|
||||
$collection->addCollection(parent::load($path, $type));
|
||||
}
|
||||
|
||||
|
@ -20,20 +20,17 @@ use Symfony\Component\Routing\RouteCollection;
|
||||
*/
|
||||
abstract class FileLoader extends Loader
|
||||
{
|
||||
protected $locator;
|
||||
protected $currentDir;
|
||||
protected $paths;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string|array $paths A path or an array of paths where to look for resources
|
||||
*/
|
||||
public function __construct($paths = array())
|
||||
public function __construct(FileLocator $locator)
|
||||
{
|
||||
if (!is_array($paths)) {
|
||||
$paths = array($paths);
|
||||
}
|
||||
$this->paths = $paths;
|
||||
$this->locator = $locator;
|
||||
}
|
||||
|
||||
public function getLocator()
|
||||
{
|
||||
return $this->locator;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -49,74 +46,9 @@ abstract class FileLoader extends Loader
|
||||
$loader = $this->resolve($resource, $type);
|
||||
|
||||
if ($loader instanceof FileLoader && null !== $this->currentDir) {
|
||||
$resource = $this->getAbsolutePath($resource, $this->currentDir);
|
||||
$resource = $this->locator->getAbsolutePath($resource, $this->currentDir);
|
||||
}
|
||||
|
||||
return $loader->load($resource, $type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a full path for a given file.
|
||||
*
|
||||
* @param string $file A file path
|
||||
*
|
||||
* @return string The full path for the file
|
||||
*
|
||||
* @throws \InvalidArgumentException When file is not found
|
||||
*/
|
||||
protected function findFile($file)
|
||||
{
|
||||
$path = $this->getAbsolutePath($file);
|
||||
if (!file_exists($path)) {
|
||||
throw new \InvalidArgumentException(sprintf('The file "%s" does not exist (in: %s).', $file, implode(', ', $this->paths)));
|
||||
}
|
||||
|
||||
return $path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the absolute path for the file path if possible.
|
||||
*
|
||||
* @param string $file A file path
|
||||
* @param string $currentPath The current path
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getAbsolutePath($file, $currentPath = null)
|
||||
{
|
||||
if (self::isAbsolutePath($file)) {
|
||||
return $file;
|
||||
} else if (null !== $currentPath && file_exists($currentPath.DIRECTORY_SEPARATOR.$file)) {
|
||||
return $currentPath.DIRECTORY_SEPARATOR.$file;
|
||||
} else {
|
||||
foreach ($this->paths as $path) {
|
||||
if (file_exists($path.DIRECTORY_SEPARATOR.$file)) {
|
||||
return $path.DIRECTORY_SEPARATOR.$file;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $file;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the file path is an absolute path.
|
||||
*
|
||||
* @param string $file A file path
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
static protected function isAbsolutePath($file)
|
||||
{
|
||||
if ($file[0] == '/' || $file[0] == '\\'
|
||||
|| (strlen($file) > 3 && ctype_alpha($file[0])
|
||||
&& $file[1] == ':'
|
||||
&& ($file[2] == '\\' || $file[2] == '/')
|
||||
)
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
100
src/Symfony/Component/Routing/Loader/FileLocator.php
Normal file
100
src/Symfony/Component/Routing/Loader/FileLocator.php
Normal file
@ -0,0 +1,100 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Routing\Loader;
|
||||
|
||||
/**
|
||||
* FileLocator uses an array of pre-defined paths to find files.
|
||||
*
|
||||
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
*/
|
||||
class FileLocator
|
||||
{
|
||||
protected $paths;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string|array $paths A path or an array of paths where to look for resources
|
||||
*/
|
||||
public function __construct($paths = array())
|
||||
{
|
||||
if (!is_array($paths)) {
|
||||
$paths = array($paths);
|
||||
}
|
||||
$this->paths = $paths;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a full path for a given file.
|
||||
*
|
||||
* @param string $file A file path
|
||||
*
|
||||
* @return string The full path for the file
|
||||
*
|
||||
* @throws \InvalidArgumentException When file is not found
|
||||
*/
|
||||
public function locate($file)
|
||||
{
|
||||
$path = $this->getAbsolutePath($file);
|
||||
if (!file_exists($path)) {
|
||||
throw new \InvalidArgumentException(sprintf('The file "%s" does not exist (in: %s).', $file, implode(', ', $this->paths)));
|
||||
}
|
||||
|
||||
return $path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the absolute path for the file path if possible.
|
||||
*
|
||||
* @param string $file A file path
|
||||
* @param string $currentPath The current path
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getAbsolutePath($file, $currentPath = null)
|
||||
{
|
||||
if ($this->isAbsolutePath($file)) {
|
||||
return $file;
|
||||
} else if (null !== $currentPath && file_exists($currentPath.DIRECTORY_SEPARATOR.$file)) {
|
||||
return $currentPath.DIRECTORY_SEPARATOR.$file;
|
||||
} else {
|
||||
foreach ($this->paths as $path) {
|
||||
if (file_exists($path.DIRECTORY_SEPARATOR.$file)) {
|
||||
return $path.DIRECTORY_SEPARATOR.$file;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $file;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the file path is an absolute path.
|
||||
*
|
||||
* @param string $file A file path
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function isAbsolutePath($file)
|
||||
{
|
||||
if ($file[0] == '/' || $file[0] == '\\'
|
||||
|| (strlen($file) > 3 && ctype_alpha($file[0])
|
||||
&& $file[1] == ':'
|
||||
&& ($file[2] == '\\' || $file[2] == '/')
|
||||
)
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
@ -32,7 +32,7 @@ class PhpFileLoader extends FileLoader
|
||||
{
|
||||
$loader = $this;
|
||||
|
||||
$path = $this->findFile($file);
|
||||
$path = $this->locator->locate($file);
|
||||
|
||||
$collection = include $path;
|
||||
$this->currentDir = dirname($path);
|
||||
|
@ -34,7 +34,7 @@ class XmlFileLoader extends FileLoader
|
||||
*/
|
||||
public function load($file, $type = null)
|
||||
{
|
||||
$path = $this->findFile($file);
|
||||
$path = $this->locator->locate($file);
|
||||
|
||||
$xml = $this->loadFile($path);
|
||||
|
||||
@ -56,7 +56,8 @@ class XmlFileLoader extends FileLoader
|
||||
$type = (string) $node->getAttribute('type');
|
||||
$prefix = (string) $node->getAttribute('prefix');
|
||||
$this->currentDir = dirname($path);
|
||||
$collection->addCollection($this->import($resource, $type), $prefix);
|
||||
$file = $this->locator->locate($resource);
|
||||
$collection->addCollection($this->import($file, $type), $prefix);
|
||||
break;
|
||||
default:
|
||||
throw new \InvalidArgumentException(sprintf('Unable to parse tag "%s"', $node->tagName));
|
||||
|
@ -35,7 +35,7 @@ class YamlFileLoader extends FileLoader
|
||||
*/
|
||||
public function load($file, $type = null)
|
||||
{
|
||||
$path = $this->findFile($file);
|
||||
$path = $this->locator->locate($file);
|
||||
|
||||
$config = $this->loadFile($path);
|
||||
|
||||
@ -57,7 +57,8 @@ class YamlFileLoader extends FileLoader
|
||||
$type = isset($config['type']) ? $config['type'] : null;
|
||||
$prefix = isset($config['prefix']) ? $config['prefix'] : null;
|
||||
$this->currentDir = dirname($path);
|
||||
$collection->addCollection($this->import($config['resource'], $type), $prefix);
|
||||
$file = $this->locator->locate($config['resource']);
|
||||
$collection->addCollection($this->import($file, $type), $prefix);
|
||||
} elseif (isset($config['pattern'])) {
|
||||
$this->parseRoute($collection, $name, $config, $path);
|
||||
} else {
|
||||
|
@ -13,7 +13,6 @@ namespace Symfony\Component\Templating\Loader;
|
||||
|
||||
use Symfony\Component\Templating\Storage\Storage;
|
||||
use Symfony\Component\Templating\Storage\FileStorage;
|
||||
use Symfony\Component\Templating\TemplateNameParserInterface;
|
||||
|
||||
/**
|
||||
* FilesystemLoader is a loader that read templates from the filesystem.
|
||||
|
@ -12,7 +12,6 @@
|
||||
namespace Symfony\Component\Templating\Loader;
|
||||
|
||||
use Symfony\Component\Templating\DebuggerInterface;
|
||||
use Symfony\Component\Templating\TemplateNameParserInterface;
|
||||
|
||||
/**
|
||||
* Loader is the base class for all template loader classes.
|
||||
|
@ -9,7 +9,7 @@
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Templating;
|
||||
namespace Symfony\Component\Templating\Loader;
|
||||
|
||||
/**
|
||||
* TemplateNameParser is the default implementation of TemplateNameParserInterface.
|
@ -9,7 +9,7 @@
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Templating;
|
||||
namespace Symfony\Component\Templating\Loader;
|
||||
|
||||
/**
|
||||
* TemplateNameParserInterface parses template name to a template name and an array of options.
|
@ -22,6 +22,218 @@ class KernelTest extends \PHPUnit_Framework_TestCase
|
||||
|
||||
$this->assertEquals('foo', $kernel->getSafeName());
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \InvalidArgumentException
|
||||
*/
|
||||
public function testLocateResourceThrowsExceptionWhenNameIsNotValid()
|
||||
{
|
||||
$this->getKernelForInvalidLocateResource()->locateResource('foo');
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \RuntimeException
|
||||
*/
|
||||
public function testLocateResourceThrowsExceptionWhenNameIsUnsafe()
|
||||
{
|
||||
$this->getKernelForInvalidLocateResource()->locateResource('@foo/../bar');
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \InvalidArgumentException
|
||||
*/
|
||||
public function testLocateResourceThrowsExceptionWhenBundleDoesNotExist()
|
||||
{
|
||||
$this->getKernelForInvalidLocateResource()->locateResource('@foo/config/routing.xml');
|
||||
}
|
||||
|
||||
public function testLocateResourceReturnsTheFirstThatMatches()
|
||||
{
|
||||
$kernel = $this->getKernel();
|
||||
$kernel
|
||||
->expects($this->once())
|
||||
->method('getBundle')
|
||||
->will($this->returnValue($this->getBundle(__DIR__.'/Fixtures/Bundle1')))
|
||||
;
|
||||
|
||||
$this->assertEquals(__DIR__.'/Fixtures/Bundle1/foo.txt', $kernel->locateResource('@foo/foo.txt'));
|
||||
}
|
||||
|
||||
public function testLocateResourceReturnsTheAllMatches()
|
||||
{
|
||||
$kernel = $this->getKernel();
|
||||
$kernel
|
||||
->expects($this->once())
|
||||
->method('getBundle')
|
||||
->with($this->anything(), $this->equalTo(false))
|
||||
->will($this->returnValue(array($this->getBundle(__DIR__.'/Fixtures/Bundle1'), $this->getBundle(__DIR__.'/Fixtures/Bundle2'))))
|
||||
;
|
||||
|
||||
$this->assertEquals(array(__DIR__.'/Fixtures/Bundle1/foo.txt', __DIR__.'/Fixtures/Bundle2/foo.txt'), $kernel->locateResource('@foo/foo.txt', null, false));
|
||||
}
|
||||
|
||||
public function testLocateResourceReturnsAllMatchesBis()
|
||||
{
|
||||
$kernel = $this->getKernel();
|
||||
$kernel
|
||||
->expects($this->once())
|
||||
->method('getBundle')
|
||||
->with($this->anything(), $this->equalTo(false))
|
||||
->will($this->returnValue(array($this->getBundle(__DIR__.'/Fixtures/Bundle1'), $this->getBundle(__DIR__.'/foobar'))))
|
||||
;
|
||||
|
||||
$this->assertEquals(array(__DIR__.'/Fixtures/Bundle1/foo.txt'), $kernel->locateResource('@foo/foo.txt', null, false));
|
||||
}
|
||||
|
||||
public function testLocateResourceIgnoresDirOnNonResource()
|
||||
{
|
||||
$kernel = $this->getKernel();
|
||||
$kernel
|
||||
->expects($this->once())
|
||||
->method('getBundle')
|
||||
->will($this->returnValue($this->getBundle(__DIR__.'/Fixtures/Bundle1')))
|
||||
;
|
||||
|
||||
$this->assertEquals(__DIR__.'/Fixtures/Bundle1/foo.txt', $kernel->locateResource('@foo/foo.txt', __DIR__.'/Fixtures'));
|
||||
}
|
||||
|
||||
public function testLocateResourceReturnsTheDirOneForResources()
|
||||
{
|
||||
$kernel = $this->getKernel();
|
||||
|
||||
$this->assertEquals(__DIR__.'/Fixtures/foo/foo.txt', $kernel->locateResource('@foo/Resources/foo.txt', __DIR__.'/Fixtures'));
|
||||
}
|
||||
|
||||
public function testLocateResourceReturnsTheDirOneForResourcesAndBundleOnes()
|
||||
{
|
||||
$kernel = $this->getKernel();
|
||||
$kernel
|
||||
->expects($this->once())
|
||||
->method('getBundle')
|
||||
->will($this->returnValue(array($this->getBundle(__DIR__.'/Fixtures/Bundle1'))))
|
||||
;
|
||||
|
||||
$this->assertEquals(array(__DIR__.'/Fixtures/foo/foo.txt', __DIR__.'/Fixtures/Bundle1/Resources/foo.txt'), $kernel->locateResource('@foo/Resources/foo.txt', __DIR__.'/Fixtures', false));
|
||||
}
|
||||
|
||||
public function testInitializeBundles()
|
||||
{
|
||||
$parent = $this->getBundle(null, '', 'ParentABundle');
|
||||
$child = $this->getBundle(null, 'ParentABundle', 'ChildABundle');
|
||||
|
||||
$kernel = $this->getKernel();
|
||||
$kernel
|
||||
->expects($this->once())
|
||||
->method('registerBundles')
|
||||
->will($this->returnValue(array($parent, $child)))
|
||||
;
|
||||
$kernel->initializeBundles();
|
||||
|
||||
$map = $kernel->getBundleMap();
|
||||
$this->assertEquals(array($child, $parent), $map['ParentABundle']);
|
||||
}
|
||||
|
||||
public function testInitializeBundlesSupportInheritanceCascade()
|
||||
{
|
||||
$grandparent = $this->getBundle(null, '', 'GrandParentBBundle');
|
||||
$parent = $this->getBundle(null, 'GrandParentBBundle', 'ParentBBundle');
|
||||
$child = $this->getBundle(null, 'ParentBBundle', 'ChildBBundle');
|
||||
|
||||
$kernel = $this->getKernel();
|
||||
$kernel
|
||||
->expects($this->once())
|
||||
->method('registerBundles')
|
||||
->will($this->returnValue(array($parent, $grandparent, $child)))
|
||||
;
|
||||
$kernel->initializeBundles();
|
||||
|
||||
$map = $kernel->getBundleMap();
|
||||
$this->assertEquals(array($child, $parent, $grandparent), $map['GrandParentBBundle']);
|
||||
$this->assertEquals(array($child, $parent), $map['ParentBBundle']);
|
||||
$this->assertEquals(array($child), $map['ChildBBundle']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \LogicException
|
||||
*/
|
||||
public function testInitializeBundlesThrowsExceptionWhenAParentDoesNotExists()
|
||||
{
|
||||
$child = $this->getBundle(null, 'FooBar', 'ChildCBundle');
|
||||
|
||||
$kernel = $this->getKernel();
|
||||
$kernel
|
||||
->expects($this->once())
|
||||
->method('registerBundles')
|
||||
->will($this->returnValue(array($child)))
|
||||
;
|
||||
$kernel->initializeBundles();
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \LogicException
|
||||
*/
|
||||
public function testInitializeBundlesThrowsExceptionWhenABundleIsDirectlyExtendedByTwoBundles()
|
||||
{
|
||||
$parent = $this->getBundle(null, '', 'ParentCBundle');
|
||||
$child1 = $this->getBundle(null, 'ParentCBundle', 'ChildC1Bundle');
|
||||
$child2 = $this->getBundle(null, 'ParentCBundle', 'ChildC2Bundle');
|
||||
|
||||
$kernel = $this->getKernel();
|
||||
$kernel
|
||||
->expects($this->once())
|
||||
->method('registerBundles')
|
||||
->will($this->returnValue(array($parent, $child1, $child2)))
|
||||
;
|
||||
$kernel->initializeBundles();
|
||||
}
|
||||
|
||||
protected function getBundle($dir = null, $parent = null, $className = null)
|
||||
{
|
||||
$bundle = $this->getMockBuilder('Symfony\Component\HttpKernel\Bundle\BundleInterface');
|
||||
|
||||
if ($className) {
|
||||
$bundle->setMockClassName($className);
|
||||
}
|
||||
|
||||
$bundle = $bundle->getMock();
|
||||
|
||||
if (null !== $dir) {
|
||||
$bundle
|
||||
->expects($this->any())
|
||||
->method('getPath')
|
||||
->will($this->returnValue($dir))
|
||||
;
|
||||
}
|
||||
|
||||
if (null !== $parent) {
|
||||
$bundle
|
||||
->expects($this->any())
|
||||
->method('getParent')
|
||||
->will($this->returnValue($parent))
|
||||
;
|
||||
}
|
||||
|
||||
return $bundle;
|
||||
}
|
||||
|
||||
protected function getKernel()
|
||||
{
|
||||
return $this
|
||||
->getMockBuilder('Symfony\Tests\Component\HttpKernel\KernelForTest')
|
||||
->setMethods(array('getBundle', 'registerBundles'))
|
||||
->disableOriginalConstructor()
|
||||
->getMock()
|
||||
;
|
||||
}
|
||||
|
||||
protected function getKernelForInvalidLocateResource()
|
||||
{
|
||||
return $this
|
||||
->getMockBuilder('Symfony\Component\HttpKernel\Kernel')
|
||||
->disableOriginalConstructor()
|
||||
->getMockForAbstractClass()
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
class KernelForTest extends Kernel
|
||||
@ -33,6 +245,11 @@ class KernelForTest extends Kernel
|
||||
$this->name = $name;
|
||||
}
|
||||
|
||||
public function getBundleMap()
|
||||
{
|
||||
return $this->bundleMap;
|
||||
}
|
||||
|
||||
public function registerRootDir()
|
||||
{
|
||||
}
|
||||
@ -48,4 +265,9 @@ class KernelForTest extends Kernel
|
||||
public function registerContainerConfiguration(LoaderInterface $loader)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public function initializeBundles()
|
||||
{
|
||||
parent::initializeBundles();
|
||||
}
|
||||
}
|
||||
|
@ -15,6 +15,7 @@ use Symfony\Component\Routing\Loader\LoaderResolver;
|
||||
use Symfony\Component\Routing\Loader\AnnotationDirectoryLoader;
|
||||
use Symfony\Component\Routing\Route;
|
||||
use Symfony\Component\Routing\RouteCollection;
|
||||
use Symfony\Component\Routing\Loader\FileLocator;
|
||||
|
||||
class AnnotationDirectoryLoaderTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
@ -27,7 +28,7 @@ class AnnotationDirectoryLoaderTest extends \PHPUnit_Framework_TestCase
|
||||
->disableOriginalConstructor()
|
||||
->getMockForAbstractClass();
|
||||
|
||||
$loader = new AnnotationDirectoryLoader($annotationClassLoader);
|
||||
$loader = new AnnotationDirectoryLoader(new FileLocator(), $annotationClassLoader);
|
||||
|
||||
$fixturesDir = __DIR__.'/../Fixtures';
|
||||
|
||||
|
@ -27,7 +27,7 @@ class AnnotationFileLoaderTest extends \PHPUnit_Framework_TestCase
|
||||
->disableOriginalConstructor()
|
||||
->getMockForAbstractClass();
|
||||
|
||||
$loader = new AnnotationFileLoader($annotationClassLoader);
|
||||
$loader = new AnnotationFileLoader($this->getMock('Symfony\Component\Routing\Loader\FileLocator'), $annotationClassLoader);
|
||||
|
||||
$fixture = __DIR__.'/../Fixtures/annotated.php';
|
||||
|
||||
|
@ -27,7 +27,7 @@ class AnnotationGlobLoaderTest extends \PHPUnit_Framework_TestCase
|
||||
->disableOriginalConstructor()
|
||||
->getMockForAbstractClass();
|
||||
|
||||
$loader = new AnnotationGlobLoader($annotationClassLoader);
|
||||
$loader = new AnnotationGlobLoader($this->getMock('Symfony\Component\Routing\Loader\FileLocator'), $annotationClassLoader);
|
||||
|
||||
$this->assertTrue($loader->supports('*'), '->supports() returns true if the resource is loadable');
|
||||
$this->assertFalse($loader->supports('foo.foo'), '->supports() returns true if the resource is loadable');
|
||||
|
@ -49,7 +49,7 @@ class DelegatingLoaderTest extends \PHPUnit_Framework_TestCase
|
||||
public function testSupports()
|
||||
{
|
||||
$resolver = new LoaderResolver(array(
|
||||
$ini = new XmlFileLoader(array()),
|
||||
$ini = new XmlFileLoader($this->getMock('Symfony\Component\Routing\Loader\FileLocator')),
|
||||
));
|
||||
$loader = new DelegatingLoader($resolver);
|
||||
|
||||
|
@ -11,61 +11,26 @@
|
||||
|
||||
namespace Symfony\Tests\Component\Routing\Loader;
|
||||
|
||||
use Symfony\Component\Routing\Loader\FileLoader;
|
||||
use Symfony\Component\Routing\Loader\FileLocator;
|
||||
|
||||
class FileLoaderTest extends \PHPUnit_Framework_TestCase
|
||||
class FileLocatorTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
/**
|
||||
* @covers Symfony\Component\Routing\Loader\FileLoader::__construct
|
||||
*/
|
||||
public function testConstructor()
|
||||
{
|
||||
$loader = new ProjectLoader(__DIR__);
|
||||
$this->assertEquals(array(__DIR__), $loader->paths, '__construct() takes a path as its second argument');
|
||||
|
||||
$loader = new ProjectLoader(array(__DIR__, __DIR__));
|
||||
$this->assertEquals(array(__DIR__, __DIR__), $loader->paths, '__construct() takes an array of paths as its second argument');
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers Symfony\Component\Routing\Loader\FileLoader::GetAbsolutePath
|
||||
* @covers Symfony\Component\Routing\Loader\FileLoader::isAbsolutePath
|
||||
* @covers Symfony\Component\Routing\Loader\FileLocator::GetAbsolutePath
|
||||
* @covers Symfony\Component\Routing\Loader\FileLocator::isAbsolutePath
|
||||
*/
|
||||
public function testGetAbsolutePath()
|
||||
{
|
||||
$loader = new ProjectLoader(array(__DIR__.'/../Fixtures'));
|
||||
$loader = new FileLocator(array(__DIR__.'/../Fixtures'));
|
||||
$this->assertEquals('/foo.xml', $loader->getAbsolutePath('/foo.xml'), '->getAbsolutePath() return the path unmodified if it is already an absolute path');
|
||||
$this->assertEquals('c:\\\\foo.xml', $loader->getAbsolutePath('c:\\\\foo.xml'), '->getAbsolutePath() return the path unmodified if it is already an absolute path');
|
||||
$this->assertEquals('c:/foo.xml', $loader->getAbsolutePath('c:/foo.xml'), '->getAbsolutePath() return the path unmodified if it is already an absolute path');
|
||||
$this->assertEquals('\\server\\foo.xml', $loader->getAbsolutePath('\\server\\foo.xml'), '->getAbsolutePath() return the path unmodified if it is already an absolute path');
|
||||
|
||||
$this->assertEquals(__DIR__.DIRECTORY_SEPARATOR.'FileLoaderTest.php', $loader->getAbsolutePath('FileLoaderTest.php', __DIR__), '->getAbsolutePath() returns an absolute filename if the file exists in the current path');
|
||||
$this->assertEquals(__DIR__.DIRECTORY_SEPARATOR.'FileLocatorTest.php', $loader->getAbsolutePath('FileLocatorTest.php', __DIR__), '->getAbsolutePath() returns an absolute filename if the file exists in the current path');
|
||||
|
||||
$this->assertEquals(__DIR__.'/../Fixtures'.DIRECTORY_SEPARATOR.'foo.xml', $loader->getAbsolutePath('foo.xml', __DIR__), '->getAbsolutePath() returns an absolute filename if the file exists in one of the paths given in the constructor');
|
||||
|
||||
$this->assertEquals('foobar.xml', $loader->getAbsolutePath('foobar.xml', __DIR__), '->getAbsolutePath() returns the path unmodified if it is unable to find it in the given paths');
|
||||
}
|
||||
}
|
||||
|
||||
class ProjectLoader extends FileLoader
|
||||
{
|
||||
public $paths;
|
||||
|
||||
public function load($resource, $type = null)
|
||||
{
|
||||
}
|
||||
|
||||
public function supports($resource, $type = null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getType()
|
||||
{
|
||||
}
|
||||
|
||||
public function getAbsolutePath($file, $currentPath = null)
|
||||
{
|
||||
return parent::getAbsolutePath($file, $currentPath);
|
||||
}
|
||||
}
|
@ -35,7 +35,7 @@ class LoaderTest extends \PHPUnit_Framework_TestCase
|
||||
public function testResolve()
|
||||
{
|
||||
$resolver = new LoaderResolver(array(
|
||||
$ini = new XmlFileLoader(array()),
|
||||
$ini = new XmlFileLoader($this->getMock('Symfony\Component\Routing\Loader\FileLocator')),
|
||||
));
|
||||
$loader = new ProjectLoader1();
|
||||
$loader->setResolver($resolver);
|
||||
|
@ -23,7 +23,7 @@ class PhpFileLoaderTest extends \PHPUnit_Framework_TestCase
|
||||
*/
|
||||
public function testSupports()
|
||||
{
|
||||
$loader = new PhpFileLoader();
|
||||
$loader = new PhpFileLoader($this->getMock('Symfony\Component\Routing\Loader\FileLocator'));
|
||||
|
||||
$this->assertTrue($loader->supports('foo.php'), '->supports() returns true if the resource is loadable');
|
||||
$this->assertFalse($loader->supports('foo.foo'), '->supports() returns true if the resource is loadable');
|
||||
|
@ -23,7 +23,7 @@ class XmlFileLoaderTest extends \PHPUnit_Framework_TestCase
|
||||
*/
|
||||
public function testSupports()
|
||||
{
|
||||
$loader = new XmlFileLoader();
|
||||
$loader = new XmlFileLoader($this->getMock('Symfony\Component\Routing\Loader\FileLocator'));
|
||||
|
||||
$this->assertTrue($loader->supports('foo.xml'), '->supports() returns true if the resource is loadable');
|
||||
$this->assertFalse($loader->supports('foo.foo'), '->supports() returns true if the resource is loadable');
|
||||
|
@ -16,6 +16,7 @@ use Symfony\Component\Routing\Loader\YamlFileLoader;
|
||||
use Symfony\Component\Routing\Route;
|
||||
use Symfony\Component\Routing\RouteCollection;
|
||||
use Symfony\Component\Routing\Resource\FileResource;
|
||||
use Symfony\Component\Routing\Loader\FileLocator;
|
||||
|
||||
class YamlFileLoaderTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
@ -24,7 +25,7 @@ class YamlFileLoaderTest extends \PHPUnit_Framework_TestCase
|
||||
*/
|
||||
public function testSupports()
|
||||
{
|
||||
$loader = new YamlFileLoader();
|
||||
$loader = new YamlFileLoader($this->getMock('Symfony\Component\Routing\Loader\FileLocator'));
|
||||
|
||||
$this->assertTrue($loader->supports('foo.yml'), '->supports() returns true if the resource is loadable');
|
||||
$this->assertFalse($loader->supports('foo.foo'), '->supports() returns true if the resource is loadable');
|
||||
@ -35,7 +36,7 @@ class YamlFileLoaderTest extends \PHPUnit_Framework_TestCase
|
||||
|
||||
public function testLoadDoesNothingIfEmpty()
|
||||
{
|
||||
$loader = new YamlFileLoader(array(__DIR__.'/../Fixtures'));
|
||||
$loader = new YamlFileLoader(new FileLocator(array(__DIR__.'/../Fixtures')));
|
||||
$collection = $loader->load('empty.yml');
|
||||
|
||||
$this->assertEquals(array(), $collection->all());
|
||||
@ -47,7 +48,7 @@ class YamlFileLoaderTest extends \PHPUnit_Framework_TestCase
|
||||
*/
|
||||
public function testLoadThrowsExceptionIfNotAnArray()
|
||||
{
|
||||
$loader = new YamlFileLoader(array(__DIR__.'/../Fixtures'));
|
||||
$loader = new YamlFileLoader(new FileLocator(array(__DIR__.'/../Fixtures')));
|
||||
$loader->load('nonvalid.yml');
|
||||
}
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ require_once __DIR__.'/../Fixtures/ProjectTemplateDebugger.php';
|
||||
use Symfony\Component\Templating\Loader\Loader;
|
||||
use Symfony\Component\Templating\Loader\CacheLoader;
|
||||
use Symfony\Component\Templating\Storage\StringStorage;
|
||||
use Symfony\Component\Templating\TemplateNameParser;
|
||||
use Symfony\Component\Templating\Loader\TemplateNameParser;
|
||||
|
||||
class CacheLoaderTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
|
@ -16,7 +16,7 @@ require_once __DIR__.'/../Fixtures/ProjectTemplateDebugger.php';
|
||||
use Symfony\Component\Templating\Loader\ChainLoader;
|
||||
use Symfony\Component\Templating\Loader\FilesystemLoader;
|
||||
use Symfony\Component\Templating\Storage\FileStorage;
|
||||
use Symfony\Component\Templating\TemplateNameParser;
|
||||
use Symfony\Component\Templating\Loader\TemplateNameParser;
|
||||
|
||||
class ChainLoaderTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
|
@ -15,7 +15,7 @@ require_once __DIR__.'/../Fixtures/ProjectTemplateDebugger.php';
|
||||
|
||||
use Symfony\Component\Templating\Loader\FilesystemLoader;
|
||||
use Symfony\Component\Templating\Storage\FileStorage;
|
||||
use Symfony\Component\Templating\TemplateNameParser;
|
||||
use Symfony\Component\Templating\Loader\TemplateNameParser;
|
||||
|
||||
class FilesystemLoaderTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
|
@ -14,7 +14,7 @@ namespace Symfony\Tests\Component\Templating\Loader;
|
||||
require_once __DIR__.'/../Fixtures/ProjectTemplateDebugger.php';
|
||||
|
||||
use Symfony\Component\Templating\Loader\Loader;
|
||||
use Symfony\Component\Templating\TemplateNameParser;
|
||||
use Symfony\Component\Templating\Loader\TemplateNameParser;
|
||||
|
||||
class LoaderTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
|
@ -18,7 +18,7 @@ use Symfony\Component\Templating\Loader\Loader;
|
||||
use Symfony\Component\Templating\Storage\Storage;
|
||||
use Symfony\Component\Templating\Storage\StringStorage;
|
||||
use Symfony\Component\Templating\Helper\SlotsHelper;
|
||||
use Symfony\Component\Templating\TemplateNameParser;
|
||||
use Symfony\Component\Templating\Loader\TemplateNameParser;
|
||||
|
||||
class PhpEngineTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
|
Reference in New Issue
Block a user