On 11/30/10 9:01 AM, Henrik Bjornskov wrote:
We have in our own systems used the resourceName: which have worked
out quite well.
Instead of always specifying the resource to use, cant we fallback to
file if theres no prefix?
Yes, this is the proposition number 2.
But this is not possible with "something:resource". How do you
differentiate between a path and a resource with a prefix?
annotations:foobar
c:\...
Fabien
On Nov 30, 8:42 am, Fabien Potencier<fabien.potenc...@symfony-
project.com> wrote:
Hi all,
Time for another RFC. Today, I want your opinion on custom loader
resources notation.
As you might know, the Dependency Injection and Routing components have
the notion of loaders. A loader is able to load "resource"s. A resource
can be anything; write a loader that knows how to load the resource and
you're good to go. Both components comes with built-in file loaders for
XML, YAML, and PHP:
# config.yml
imports:
- { resource: security.yml }
# routing.yml
imports
- { resource: BlogBundle/Resources/config/routing.xml, prefix: /blog }
The interesting part is that a resource is not necessarily a file. Of
course, most of the time, this is part of a file path, but it does not
need to.
For instance, if you have a look at the Routing component and the
FrameworkExtraBundle documentation, you will see that there is a special
"annotation" loader. For this annotation loader, the resource is not a
file path but it can be a glob or a directory of files to parse for
annotations:
imports:
- { resource: annotations:BlogBundle/Controller/AnnotController.php }
As you can see, the current convention is to to prefix the "real"
resource by a word followed by a colon, here "annotations:".
Symfony2 determines the loader to use via a LoaderResolverInterface
instance. Here is the default implementation of this interface:
public function resolve($resource)
{
foreach ($this->loaders as $loader) {
if ($loader->supports($resource)) {
return $loader;
}
}
return false;
}
So, each loader has a supports() method that must return true if it is
able to load the resource. Here is for instance the supports() method
for the PHP and XML loader:
// PHP
public function supports($resource)
{
return is_string($resource)
&& 'php' === pathinfo($resource, PATHINFO_EXTENSION)
&& is_file($this->getAbsolutePath($resource));
}
// XML
public function supports($resource)
{
return is_string($resource)
&& 'xml' === pathinfo($resource, PATHINFO_EXTENSION);
}
As you can see, for the annotation loader to work, the PHP loader checks
if the resource is actually an existing file; which is not the case for
XML loader.
I had to do that because of the registration order. If you remove the
'is_file' check in the PHP loader and register the annotation loader
after the PHP one, the PHP loader will always "win" but won't be able to
do anything useful with the resource.
So, we need a way to clearly identify which loader need to be used. The
current implementation of the PHP loader is a "hack" as you won't have a
proper exception if you want to load a PHP resource and if you make a
typo in the file path because the loader will tell the resolver that it
does not support the resource. So, you will have an exception saying
that there is no loader able to load your resource, which is not the
real problem (you have a typo in the file path).
everzet had the same problem and came up with a
patch:https://github.com/fabpot/symfony/pull/178
In this pull request, we talked about the prefix to use, and one
proposal (the one implemented in the patch) was to use (), as they
cannot be used at the beginning of a real file path. So, to create a
custom loader, you need prefix the resource like this:
imports:
- { resource: (annotations) BlogBundle/Controller/AnnotController.php }
I was about to merge the change and then I step back and found this
convention quite ugly (I was the one to propose that).
I thought about that more and here are some proposals:
1/ Always prefix the path with something, even for file resources (like
a DSN):
imports:
- { resource: file:BlogBundle/Controller/AnnotController.php }
- { resource: annotations:BlogBundle/Controller/AnnotController.php }
* This is explicit, no ambiguity possible, simple supports()
implementation, clear error messages;
* But when using a file as a resource, which is what you will do most
of the time, you will have to use the 'file:' prefix.
2/ Use a prefix for everything except file loaders
For this one, we need to come up with a convention that can be easily
checked and cannot be part of a file name:
(annotations) BlogBundle/Controller/AnnotController.php
annotations::BlogBundle/Controller/AnnotController.php
[annotations]BlogBundle/Controller/AnnotController.php
...
3/ You own idea here ;)
Fabien
--
Fabien Potencier
Sensio CEO - symfony lead developer
sensiolabs.com | symfony-project.org | fabien.potencier.org
Tél: +33 1 40 99 80 80
--
If you want to report a vulnerability issue on symfony, please send it to
security at symfony-project.com
You received this message because you are subscribed to the Google
Groups "symfony developers" group.
To post to this group, send email to symfony-devs@googlegroups.com
To unsubscribe from this group, send email to
symfony-devs+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/symfony-devs?hl=en