librelist archives

« back to archive

Preconditions for the views

Preconditions for the views

From:
Loic d'Anterroches
Date:
2011-06-23 @ 18:50
Hello,

so, after the dbs, now some questions about the preconditions. At the
moment, Photon does not support preconditions, but I need them.

So, my question is: how? And to which extend.

With a bit of a hack, it is possible to have preconditions with
parameters in Pluf, but implementing this nicely with Photon would not
be easy. The thing is that I want a precondition callable to be a
callable, whatever it is:

    array('\myapp\foo\Bar', 'precondition')
    'function_in_global_scope'

you can put a closure, but you need to define it in the constructor of
the view class:

    $this->method_precond = function (&$req) { return true; };

But to do that, it means, I cannot test on "array or not" to know if the
precondition has some parameters or not. It means that if I want to
support parameters, which would be static anyway, I would need something
like:

    public $theView_precond = array(array(array('\myapp\Foo', 'first'),
                                          'param1', 'param2'),
                                    array('function_in_global_scope')
                                    );

Very hugly in the "common" case where no parameters are in use.

So, I propose a "no parameters" approach, which removes the array and
you are free to dynamically create preconditions in the constructor of
your classes.

What do you think?

loïc

--
Indefero - Project management and code hosting - http://www.indefero.net
Photon - High Performance PHP Framework - http://photon-project.com
Céondo Ltd - Web + Science = Fun - http://www.ceondo.com

Re: [photon.users] Preconditions for the views

From:
Nicolas
Date:
2011-06-23 @ 21:23
Loïc,

I'm not sure I understand what you mean by "preconditions". Can you provide
a use-ca ethat would help me understand what this is about ?

Thanks in advance.
Nicolas

On Thu, Jun 23, 2011 at 8:50 PM, Loic d'Anterroches <loic@ceondo.com> wrote:

> Hello,
>
> so, after the dbs, now some questions about the preconditions. At the
> moment, Photon does not support preconditions, but I need them.
>
> So, my question is: how? And to which extend.
>
> With a bit of a hack, it is possible to have preconditions with
> parameters in Pluf, but implementing this nicely with Photon would not
> be easy. The thing is that I want a precondition callable to be a
> callable, whatever it is:
>
>    array('\myapp\foo\Bar', 'precondition')
>    'function_in_global_scope'
>
> you can put a closure, but you need to define it in the constructor of
> the view class:
>
>    $this->method_precond = function (&$req) { return true; };
>
> But to do that, it means, I cannot test on "array or not" to know if the
> precondition has some parameters or not. It means that if I want to
> support parameters, which would be static anyway, I would need something
> like:
>
>    public $theView_precond = array(array(array('\myapp\Foo', 'first'),
>                                          'param1', 'param2'),
>                                    array('function_in_global_scope')
>                                    );
>
> Very hugly in the "common" case where no parameters are in use.
>
> So, I propose a "no parameters" approach, which removes the array and
> you are free to dynamically create preconditions in the constructor of
> your classes.
>
> What do you think?
>
> loïc
>
> --
> Indefero - Project management and code hosting - http://www.indefero.net
> Photon - High Performance PHP Framework - http://photon-project.com
> Céondo Ltd - Web + Science = Fun - http://www.ceondo.com
>

Re: [photon.users] Preconditions for the views

From:
Loic d'Anterroches
Date:
2011-06-24 @ 06:28
Hello,

> I'm not sure I understand what you mean by "preconditions". Can you
> provide a use-ca ethat would help me understand what this is about ?

You can have a function (or whatever) called before the real view. Here
from the Indefero code:

class IDF_Views_Admin
{
    /**
     * Home page of the administration.
     *
     * It should provide an overview of the forge status.
     */
    public $home_precond = array('Pluf_Precondition::staffRequired');
    public function home($request, $match)
    {
        $title = __('Forge Management');
        return Pluf_Shortcuts_RenderToResponse('idf/gadmin/home.html',
                                               array(
                                                     'page_title' => $title,
                                                     ),
                                               $request);
    }
    ....
}

The view method is "home", the preconditions are defined in the property
"$home_precond". It means that the static method "staffRequired" of the
model "Pluf_Precondition" will be called before the home view. It will
get the request object as parameter. It can then either return "true" if
ok to execute the view or a response object to be sent directly to the
client.

This is what I want for Photon too, because one can this way easily have
views marked as "logged in users only" etc.

loïc


> On Thu, Jun 23, 2011 at 8:50 PM, Loic d'Anterroches <loic@ceondo.com
> <mailto:loic@ceondo.com>> wrote:
> 
>     Hello,
> 
>     so, after the dbs, now some questions about the preconditions. At the
>     moment, Photon does not support preconditions, but I need them.
> 
>     So, my question is: how? And to which extend.
> 
>     With a bit of a hack, it is possible to have preconditions with
>     parameters in Pluf, but implementing this nicely with Photon would not
>     be easy. The thing is that I want a precondition callable to be a
>     callable, whatever it is:
> 
>        array('\myapp\foo\Bar', 'precondition')
>        'function_in_global_scope'
> 
>     you can put a closure, but you need to define it in the constructor of
>     the view class:
> 
>        $this->method_precond = function (&$req) { return true; };
> 
>     But to do that, it means, I cannot test on "array or not" to know if the
>     precondition has some parameters or not. It means that if I want to
>     support parameters, which would be static anyway, I would need something
>     like:
> 
>        public $theView_precond = array(array(array('\myapp\Foo', 'first'),
>                                              'param1', 'param2'),
>                                        array('function_in_global_scope')
>                                        );
> 
>     Very hugly in the "common" case where no parameters are in use.
> 
>     So, I propose a "no parameters" approach, which removes the array and
>     you are free to dynamically create preconditions in the constructor of
>     your classes.
> 
>     What do you think?
> 
>     loïc
> 
>     --
>     Indefero - Project management and code hosting - http://www.indefero.net
>     Photon - High Performance PHP Framework - http://photon-project.com
>     Céondo Ltd - Web + Science = Fun - http://www.ceondo.com
> 
> 

Re: [photon.users] Preconditions for the views

From:
Nicolas
Date:
2011-06-24 @ 16:12
On Fri, Jun 24, 2011 at 8:28 AM, Loic d'Anterroches <loic@ceondo.com> wrote:

> Hello,
>
> > I'm not sure I understand what you mean by "preconditions". Can you
> > provide a use-ca ethat would help me understand what this is about ?
>
> You can have a function (or whatever) called before the real view. [...]
>

Thanks, now I get it :)

I don't know how Synfony implements the preExecute and postExecute
mechanism, so I can't tell if it's efficient or clean, but it sure makes
developper's life easier.

I have to agree about the magic variable names being a bad idea. A cleaner
approach would be to provide a method to register a *callable* for execution
when a specific *event* (beforeProcessed, afterProcessed, whatever...) is
fired.

Technically, it could rely on a simple array and a method that would add
references to callables. And in the base views, a method that would be
called in specific places (before/after the view is dealt with, etc...)

This is a bit more complex than the pre/post methods approach, but it is
still pretty simple and could be extended to many *events* in many stages of
the request/response process.

Nicolas

Re: [photon.users] Preconditions for the views

From:
Loic d'Anterroches
Date:
2011-06-25 @ 20:01

On 2011-06-24 18:12, Nicolas wrote:
> 
> 
> On Fri, Jun 24, 2011 at 8:28 AM, Loic d'Anterroches <loic@ceondo.com
> <mailto:loic@ceondo.com>> wrote:
> 
>     Hello,
> 
>     > I'm not sure I understand what you mean by "preconditions". Can you
>     > provide a use-ca ethat would help me understand what this is about ?
> 
>     You can have a function (or whatever) called before the real view. [...]
> 
> 
> Thanks, now I get it :)
>  
> I don't know how Synfony implements the preExecute and postExecute
> mechanism, so I can't tell if it's efficient or clean, but it sure makes
> developper's life easier.
> 
> I have to agree about the magic variable names being a bad idea. A
> cleaner approach would be to provide a method to register a *callable*
> for execution when a specific *event* (beforeProcessed, afterProcessed,
> whatever...) is fired.
> 
> Technically, it could rely on a simple array and a method that would add
> references to callables. And in the base views, a method that would be
> called in specific places (before/after the view is dealt with, etc...)
> 
> This is a bit more complex than the pre/post methods approach, but it is
> still pretty simple and could be extended to many *events* in many
> stages of the request/response process.

The problem is "locality". The pre/post processing of the view must
respect it. That is, if you put in an event far away of the view —
registered in another file or something like that — which will affect
only the given view, it does not make sense and makes the code very hard
to read.

The $viewname_precond property approach has the wonderful advantage of
being close to the view declaration (just the line above).
Then it makes sense to put at the start of the class, in __construct()
the definition of the preconditions affecting all the views of the given
class.
Then for all the views of all the classes you simply have the middleware.

So more specific the closer you are to the view code, the less specific
the farther away you are. This approach is intuitive.

I will start this way but I welcome a proof of concept to do
differently/better. The current Photon code base is small, it is time to
make it really the best.

loïc

Re: [photon.users] Preconditions for the views

From:
William Martin
Date:
2011-06-24 @ 07:52
What i like with precondition in indefero is they are just near the
view function, and not in another file, or 500 lines upper in the
file.

William

On Fri, Jun 24, 2011 at 8:28 AM, Loic d'Anterroches <loic@ceondo.com> wrote:
> Hello,
>
>> I'm not sure I understand what you mean by "preconditions". Can you
>> provide a use-ca ethat would help me understand what this is about ?
>
> You can have a function (or whatever) called before the real view. Here
> from the Indefero code:
>
> class IDF_Views_Admin
> {
>    /**
>     * Home page of the administration.
>     *
>     * It should provide an overview of the forge status.
>     */
>    public $home_precond = array('Pluf_Precondition::staffRequired');
>    public function home($request, $match)
>    {
>        $title = __('Forge Management');
>        return Pluf_Shortcuts_RenderToResponse('idf/gadmin/home.html',
>                                               array(
>                                                     'page_title' => $title,
>                                                     ),
>                                               $request);
>    }
>    ....
> }
>
> The view method is "home", the preconditions are defined in the property
> "$home_precond". It means that the static method "staffRequired" of the
> model "Pluf_Precondition" will be called before the home view. It will
> get the request object as parameter. It can then either return "true" if
> ok to execute the view or a response object to be sent directly to the
> client.
>
> This is what I want for Photon too, because one can this way easily have
> views marked as "logged in users only" etc.
>
> loïc
>
>
>> On Thu, Jun 23, 2011 at 8:50 PM, Loic d'Anterroches <loic@ceondo.com
>> <mailto:loic@ceondo.com>> wrote:
>>
>>     Hello,
>>
>>     so, after the dbs, now some questions about the preconditions. At the
>>     moment, Photon does not support preconditions, but I need them.
>>
>>     So, my question is: how? And to which extend.
>>
>>     With a bit of a hack, it is possible to have preconditions with
>>     parameters in Pluf, but implementing this nicely with Photon would not
>>     be easy. The thing is that I want a precondition callable to be a
>>     callable, whatever it is:
>>
>>        array('\myapp\foo\Bar', 'precondition')
>>        'function_in_global_scope'
>>
>>     you can put a closure, but you need to define it in the constructor of
>>     the view class:
>>
>>        $this->method_precond = function (&$req) { return true; };
>>
>>     But to do that, it means, I cannot test on "array or not" to know if the
>>     precondition has some parameters or not. It means that if I want to
>>     support parameters, which would be static anyway, I would need something
>>     like:
>>
>>        public $theView_precond = array(array(array('\myapp\Foo', 'first'),
>>                                              'param1', 'param2'),
>>                                        array('function_in_global_scope')
>>                                        );
>>
>>     Very hugly in the "common" case where no parameters are in use.
>>
>>     So, I propose a "no parameters" approach, which removes the array and
>>     you are free to dynamically create preconditions in the constructor of
>>     your classes.
>>
>>     What do you think?
>>
>>     loïc
>>
>>     --
>>     Indefero - Project management and code hosting - http://www.indefero.net
>>     Photon - High Performance PHP Framework - http://photon-project.com
>>     Céondo Ltd - Web + Science = Fun - http://www.ceondo.com
>>
>>
>



-- 
---------------------------------------------------------
William MARTIN
wysman @NoSpAm@ gmail @DoT@ com

Re: [photon.users] Preconditions for the views

From:
Loic d'Anterroches
Date:
2011-06-24 @ 08:01

On 2011-06-24 09:52, William MARTIN wrote:
> What i like with precondition in indefero is they are just near the
> view function, and not in another file, or 500 lines upper in the
> file.

Yes, this is something I *really* like too. So, do not worry, I will
keep this approach.

loïc

--
Indefero - Project management and code hosting - http://www.indefero.net
Photon - High Performance PHP Framework - http://photon-project.com
Céondo Ltd - Web + Science = Fun - http://www.ceondo.com

> On Fri, Jun 24, 2011 at 8:28 AM, Loic d'Anterroches <loic@ceondo.com> wrote:
>> Hello,
>>
>>> I'm not sure I understand what you mean by "preconditions". Can you
>>> provide a use-ca ethat would help me understand what this is about ?
>>
>> You can have a function (or whatever) called before the real view. Here
>> from the Indefero code:
>>
>> class IDF_Views_Admin
>> {
>>    /**
>>     * Home page of the administration.
>>     *
>>     * It should provide an overview of the forge status.
>>     */
>>    public $home_precond = array('Pluf_Precondition::staffRequired');
>>    public function home($request, $match)
>>    {
>>        $title = __('Forge Management');
>>        return Pluf_Shortcuts_RenderToResponse('idf/gadmin/home.html',
>>                                               array(
>>                                                     'page_title' => $title,
>>                                                     ),
>>                                               $request);
>>    }
>>    ....
>> }
>>
>> The view method is "home", the preconditions are defined in the property
>> "$home_precond". It means that the static method "staffRequired" of the
>> model "Pluf_Precondition" will be called before the home view. It will
>> get the request object as parameter. It can then either return "true" if
>> ok to execute the view or a response object to be sent directly to the
>> client.
>>
>> This is what I want for Photon too, because one can this way easily have
>> views marked as "logged in users only" etc.
>>
>> loïc
>>
>>
>>> On Thu, Jun 23, 2011 at 8:50 PM, Loic d'Anterroches <loic@ceondo.com
>>> <mailto:loic@ceondo.com>> wrote:
>>>
>>>     Hello,
>>>
>>>     so, after the dbs, now some questions about the preconditions. At the
>>>     moment, Photon does not support preconditions, but I need them.
>>>
>>>     So, my question is: how? And to which extend.
>>>
>>>     With a bit of a hack, it is possible to have preconditions with
>>>     parameters in Pluf, but implementing this nicely with Photon would not
>>>     be easy. The thing is that I want a precondition callable to be a
>>>     callable, whatever it is:
>>>
>>>        array('\myapp\foo\Bar', 'precondition')
>>>        'function_in_global_scope'
>>>
>>>     you can put a closure, but you need to define it in the constructor of
>>>     the view class:
>>>
>>>        $this->method_precond = function (&$req) { return true; };
>>>
>>>     But to do that, it means, I cannot test on "array or not" to know if the
>>>     precondition has some parameters or not. It means that if I want to
>>>     support parameters, which would be static anyway, I would need something
>>>     like:
>>>
>>>        public $theView_precond = array(array(array('\myapp\Foo', 'first'),
>>>                                              'param1', 'param2'),
>>>                                        array('function_in_global_scope')
>>>                                        );
>>>
>>>     Very hugly in the "common" case where no parameters are in use.
>>>
>>>     So, I propose a "no parameters" approach, which removes the array and
>>>     you are free to dynamically create preconditions in the constructor of
>>>     your classes.
>>>
>>>     What do you think?
>>>
>>>     loïc
>>>
>>>     --
>>>     Indefero - Project management and code hosting - http://www.indefero.net
>>>     Photon - High Performance PHP Framework - http://photon-project.com
>>>     Céondo Ltd - Web + Science = Fun - http://www.ceondo.com
>>>
>>>
>>
> 
> 
> 

Re: [photon.users] Preconditions for the views

From:
Thomas Keller
Date:
2011-06-24 @ 10:18
Am 24.06.2011 10:01, schrieb Loic d'Anterroches:
> 
> 
> On 2011-06-24 09:52, William MARTIN wrote:
>> What i like with precondition in indefero is they are just near the
>> view function, and not in another file, or 500 lines upper in the
>> file.
> 
> Yes, this is something I *really* like too. So, do not worry, I will
> keep this approach.

I'd argue that we could improve and yet generalize "preconditions":

1) Allow preconditions on a module (view) level as well, so you don't
have to secure each and every single view handler, but all at once.
Ideally something like Symfony 1's preExecute() and postExecute()
methods could be used for that - if they exist, they'd be called before
the actual view handler and they could be annotated with preconditions
as well.

2) Personally I always found it a bit clumsy to have to define an
attribute that shares the prefix with the view handler. Maybe using some
kind of annotation syntax could be used here (see e.g.
http://code.google.com/p/addendum/). Upside is we don't have to fear
parsing of these annotations over and over again, since classes are only
loaded once in Photon, right? And, a big upside would also be that we
could actually create custom annotation types for our custom
preconditions, i.e. have an @access(role = "staff") for access-based
preconditions, a @exists(model = "IDF_Commit", id = FROM_REQUEST) to
check for 404's in a generic way or even an @scmAvailable.
One could also try to extend this model and add an alternative view as
"target" in case a precondition does not evaluate to "true", i.e. not
default to 404 under all circumstances.

Thomas.

-- 
GPG-Key 0x160D1092 | tommyd3mdi@jabber.ccc.de | http://thomaskeller.biz
Please note that according to the EU law on data retention, information
on every electronic information exchange might be retained for a period
of six months or longer: http://www.vorratsdatenspeicherung.de/?lang=en

Re: [photon.users] Preconditions for the views

From:
Loic d'Anterroches
Date:
2011-06-24 @ 10:45
Hello,

On 2011-06-24 12:18, Thomas Keller wrote:
> Am 24.06.2011 10:01, schrieb Loic d'Anterroches:
>>
>>
>> On 2011-06-24 09:52, William MARTIN wrote:
>>> What i like with precondition in indefero is they are just near the
>>> view function, and not in another file, or 500 lines upper in the
>>> file.
>>
>> Yes, this is something I *really* like too. So, do not worry, I will
>> keep this approach.
> 
> I'd argue that we could improve and yet generalize "preconditions":
> 
> 1) Allow preconditions on a module (view) level as well, so you don't
> have to secure each and every single view handler, but all at once.
> Ideally something like Symfony 1's preExecute() and postExecute()
> methods could be used for that - if they exist, they'd be called before
> the actual view handler and they could be annotated with preconditions
> as well.

Why not, something at the class level for all the views defined in the
class. Sounds good for me.

> 2) Personally I always found it a bit clumsy to have to define an
> attribute that shares the prefix with the view handler. Maybe using some
> kind of annotation syntax could be used here (see e.g.
> http://code.google.com/p/addendum/). Upside is we don't have to fear
> parsing of these annotations over and over again, since classes are only
> loaded once in Photon, right? And, a big upside would also be that we
> could actually create custom annotation types for our custom
> preconditions, i.e. have an @access(role = "staff") for access-based
> preconditions, a @exists(model = "IDF_Commit", id = FROM_REQUEST) to
> check for 404's in a generic way or even an @scmAvailable.
> One could also try to extend this model and add an alternative view as
> "target" in case a precondition does not evaluate to "true", i.e. not
> default to 404 under all circumstances.

Here not. I do not want to have functionalities of the application
depending on comments in the code. The concept is not bad, the problem
is the implementation. Too fragile and very hard to test. But it looks
like that it may come to the core of PHP, at this point it could make
sense to use this approach.

The discussion is good. Let me try to push it a bit further, more at the
concept level than the implementation level.

At the moment we have middleware and preconditions. This means that we
have the following flow:

Req -> Middleware -> dispatch -> precond -> view -> middleware -> client

The request comes in, goes through the middlewares, then is dispatched
to the right view. Before the view is called, the preconditions are run.
The response pass through the middleware in reverse order and then is
rendered for the client.

Middleware are good. We keep them.

Now, the "precond -> view -> ? " could be improved. But here we need to
pay attention, too many layers and we kill performance.

Suggestions:

1. keep like that
2. precond -> view -> postcond ->
3. class level precond -> precond -> view -> postcond -> class postcond

Thomas, is it what you think about? For example, for the admin area, you
would just put one class level "staffRequired" precondition?

I do not want to enter into the details of the implementations, more
what we need to write clean, efficient and elegant code.

loïc

Re: [photon.users] Preconditions for the views

From:
Thomas Keller
Date:
2011-06-24 @ 11:15
Am 24.06.2011 12:45, schrieb Loic d'Anterroches:
> On 2011-06-24 12:18, Thomas Keller wrote:
>> 2) Personally I always found it a bit clumsy to have to define an
>> attribute that shares the prefix with the view handler. Maybe using some
>> kind of annotation syntax could be used here (see e.g.
>> http://code.google.com/p/addendum/). Upside is we don't have to fear
>> parsing of these annotations over and over again, since classes are only
>> loaded once in Photon, right? And, a big upside would also be that we
>> could actually create custom annotation types for our custom
>> preconditions, i.e. have an @access(role = "staff") for access-based
>> preconditions, a @exists(model = "IDF_Commit", id = FROM_REQUEST) to
>> check for 404's in a generic way or even an @scmAvailable.
>> One could also try to extend this model and add an alternative view as
>> "target" in case a precondition does not evaluate to "true", i.e. not
>> default to 404 under all circumstances.
> 
> Here not. I do not want to have functionalities of the application
> depending on comments in the code. The concept is not bad, the problem
> is the implementation. Too fragile and very hard to test. But it looks
> like that it may come to the core of PHP, at this point it could make
> sense to use this approach.

I think the rfc was declined: <https://wiki.php.net/rfc/annotations>

> The discussion is good. Let me try to push it a bit further, more at the
> concept level than the implementation level.
> 
> At the moment we have middleware and preconditions. This means that we
> have the following flow:
> 
> Req -> Middleware -> dispatch -> precond -> view -> middleware -> client
> 
> The request comes in, goes through the middlewares, then is dispatched
> to the right view. Before the view is called, the preconditions are run.
> The response pass through the middleware in reverse order and then is
> rendered for the client.
> 
> Middleware are good. We keep them.
> 
> Now, the "precond -> view -> ? " could be improved. But here we need to
> pay attention, too many layers and we kill performance.
> 
> Suggestions:
> 
> 1. keep like that
> 2. precond -> view -> postcond ->
> 3. class level precond -> precond -> view -> postcond -> class postcond
> 
> Thomas, is it what you think about? For example, for the admin area, you
> would just put one class level "staffRequired" precondition?

Right, that one would go in the class level precondition. The reason why
pre- and postExecute are so useful in Symfony is also because a Symfony
controller has a special overload for member variables. That means
whenever you define $this->foo somewhere, $foo will be available in the
template you're about to render. Also, common resources can be aquired
in preExecute and be released in postExecute, or simple initializations
can happen as well.

The template part is not applicable for Photon, because template vars
need to be given explicitely to the response object that is returned,
but for the other use cases these magic methods would be useful.

> I do not want to enter into the details of the implementations, more
> what we need to write clean, efficient and elegant code.

Well, in my very humble opinion the current precondition implementation
of Pluf only satisfies "efficient", but not neccessarily "clean" or
"elegant". But maybe this is also just me; if you don't like the
annotation syntax then I have to admit I'm also a bit clueless how to
configure these kind of things _inside_ the view controller without
additional configuration files or magic methods.

Thomas.
-- 
GPG-Key 0x160D1092 | tommyd3mdi@jabber.ccc.de | http://thomaskeller.biz
Please note that according to the EU law on data retention, information
on every electronic information exchange might be retained for a period
of six months or longer: http://www.vorratsdatenspeicherung.de/?lang=en