FAQ
Edit report at http://pear.php.net/bugs/bug.php?id=18435&edit=1

ID: 18435
Updated by: borz_off@cs.msu.su
Reported By: daniel dot oconnor at gmail dot com
Summary: Allow dependency injection/more easily testable code
-Status: Open
+Status: Analyzed
Type: Feature/Change Request
Package: HTML_QuickForm2
Package Version: 0.5.0
PHP Version: Irrelevant
Roadmap Versions:
New Comment:

-Status: Open
+Status: Analyzed
The renderers/plugins setup is a bit convoluted due to shortcomings in
PHP itself: it allows neither to
* add the methods to an object at runtime (without using e.g. runkit)
as possible in other similar languages nor to
* define properties/methods accessible to class and related classes
(e.g. Java's protected modifier allows access from classes of the same
package)

Thus Proxy / Factory which both aggregate methods from several classes
and limit access to them from outside. Until PHP supports at least one
of the above-mentioned features, I am unwilling to change this
architecture.

That being said, it may make sense to pass additional arguments from
factory() call to Renderer constructor, I'll test whether it is possible
with Reflection.


Previous Comments:
------------------------------------------------------------------------

[2011-04-13 03:03:27] doconnor

Description:
------------
With renderers in particular, the protected constructor and
static, final factory method requires me to register my
plugin; which is then stored in private/static variables.

This is a pain if I want to create a renderer with its
dependencies in the constructor - I can never make it work
with the factory; and always have to instantiate it by hand; or
always have to do further setup.

It's also a pain if I just want to instantiate a default renderer,
change one template, and move on - the protected
constructor prevents me from succeeding.

I can see what you are doing by having gone down the path of
having a Proxy which lets you throw new
rendering methods together; but it's added a lot of complexity,
it's rigidly enforced; and for the simple use cases
a fair bit of overkill.

Please consider:
1. Making the constructors of HTML_QuickForm2_Renderer_*
public
2. Removing the 'final' keyword from HTML_QuickForm2
methods; allowing people to extend them
3. Re-using existing, non magic language constructs to
expose public methods.

Test script:
---------------
<?php
require_once 'HTML/QuickForm2/Renderer/Default.php';

$renderer = new HTML_QuickForm2_Renderer_Default();
$renderer->setElementTemplateForGroupClass('html_quickform2_container',
'html_quickform2_element', $checkbox_template);


Expected result:
----------------
I can instantiate the object and manipulate its state with the
appropriate setters/getters

Actual result:
--------------
I have to use the factory, which gives me a proxy, which
evaluates the methods I'm trying to call and adds a layer of
complexity.

------------------------------------------------------------------------

Search Discussions

  • Php at Apr 17, 2011 at 4:45 pm
    Edit report at http://pear.php.net/bugs/bug.php?id=18435&edit=1

    ID: 18435
    Updated by: php@mamasam.net
    Reported By: daniel dot oconnor at gmail dot com
    Summary: Allow dependency injection/more easily testable code
    Status: Analyzed
    Type: Feature/Change Request
    Package: HTML_QuickForm2
    Package Version: 0.5.0
    PHP Version: Irrelevant
    Roadmap Versions:
    New Comment:

    Hi Daniel,

    Do you have any suggestions to improve renderers in QF2 ?
    I am personally not totally satisfied with the current implementation,
    which, like
    you, I find not easy enough to extend. I have committed a new renderer,

    HTML_QuickForm2_Renderer_Callback, that accepts a callback to render an

    element or a class of elements, instead of a template. This is not fully
    satisfying
    neither, but it helps in some cases I have and it offers more
    flexibility. If you have
    any ideas, please share.


    Previous Comments:
    ------------------------------------------------------------------------

    [2011-04-13 14:29:27] avb

    -Status: Open
    +Status: Analyzed
    The renderers/plugins setup is a bit convoluted due to shortcomings in
    PHP itself: it allows neither to
    * add the methods to an object at runtime (without using e.g. runkit)
    as possible in other similar languages nor to
    * define properties/methods accessible to class and related classes
    (e.g. Java's protected modifier allows access from classes of the same
    package)

    Thus Proxy / Factory which both aggregate methods from several classes
    and limit access to them from outside. Until PHP supports at least one
    of the above-mentioned features, I am unwilling to change this
    architecture.

    That being said, it may make sense to pass additional arguments from
    factory() call to Renderer constructor, I'll test whether it is possible
    with Reflection.

    ------------------------------------------------------------------------

    [2011-04-13 03:03:27] doconnor

    Description:
    ------------
    With renderers in particular, the protected constructor and
    static, final factory method requires me to register my
    plugin; which is then stored in private/static variables.

    This is a pain if I want to create a renderer with its
    dependencies in the constructor - I can never make it work
    with the factory; and always have to instantiate it by hand; or
    always have to do further setup.

    It's also a pain if I just want to instantiate a default renderer,
    change one template, and move on - the protected
    constructor prevents me from succeeding.

    I can see what you are doing by having gone down the path of
    having a Proxy which lets you throw new
    rendering methods together; but it's added a lot of complexity,
    it's rigidly enforced; and for the simple use cases
    a fair bit of overkill.

    Please consider:
    1. Making the constructors of HTML_QuickForm2_Renderer_*
    public
    2. Removing the 'final' keyword from HTML_QuickForm2
    methods; allowing people to extend them
    3. Re-using existing, non magic language constructs to
    expose public methods.

    Test script:
    ---------------
    <?php
    require_once 'HTML/QuickForm2/Renderer/Default.php';

    $renderer = new HTML_QuickForm2_Renderer_Default();
    $renderer->setElementTemplateForGroupClass('html_quickform2_container',
    'html_quickform2_element', $checkbox_template);


    Expected result:
    ----------------
    I can instantiate the object and manipulate its state with the
    appropriate setters/getters

    Actual result:
    --------------
    I have to use the factory, which gives me a proxy, which
    evaluates the methods I'm trying to call and adds a layer of
    complexity.

    ------------------------------------------------------------------------
  • Borz_off at Apr 17, 2011 at 5:31 pm
    Edit report at http://pear.php.net/bugs/bug.php?id=18435&edit=1

    ID: 18435
    Updated by: borz_off@cs.msu.su
    Reported By: daniel dot oconnor at gmail dot com
    Summary: Allow dependency injection/more easily testable code
    Status: Analyzed
    Type: Feature/Change Request
    Package: HTML_QuickForm2
    Package Version: 0.5.0
    PHP Version: Irrelevant
    Roadmap Versions:
    New Comment:

    Let's lead users by example and move further discussion to pear-dev, OK?


    Previous Comments:
    ------------------------------------------------------------------------

    [2011-04-17 17:46:52] mansion

    Hi Daniel,

    Do you have any suggestions to improve renderers in QF2 ?
    I am personally not totally satisfied with the current implementation,
    which, like
    you, I find not easy enough to extend. I have committed a new renderer,

    HTML_QuickForm2_Renderer_Callback, that accepts a callback to render an

    element or a class of elements, instead of a template. This is not fully
    satisfying
    neither, but it helps in some cases I have and it offers more
    flexibility. If you have
    any ideas, please share.

    ------------------------------------------------------------------------

    [2011-04-13 14:29:27] avb

    -Status: Open
    +Status: Analyzed
    The renderers/plugins setup is a bit convoluted due to shortcomings in
    PHP itself: it allows neither to
    * add the methods to an object at runtime (without using e.g. runkit)
    as possible in other similar languages nor to
    * define properties/methods accessible to class and related classes
    (e.g. Java's protected modifier allows access from classes of the same
    package)

    Thus Proxy / Factory which both aggregate methods from several classes
    and limit access to them from outside. Until PHP supports at least one
    of the above-mentioned features, I am unwilling to change this
    architecture.

    That being said, it may make sense to pass additional arguments from
    factory() call to Renderer constructor, I'll test whether it is possible
    with Reflection.

    ------------------------------------------------------------------------

    [2011-04-13 03:03:27] doconnor

    Description:
    ------------
    With renderers in particular, the protected constructor and
    static, final factory method requires me to register my
    plugin; which is then stored in private/static variables.

    This is a pain if I want to create a renderer with its
    dependencies in the constructor - I can never make it work
    with the factory; and always have to instantiate it by hand; or
    always have to do further setup.

    It's also a pain if I just want to instantiate a default renderer,
    change one template, and move on - the protected
    constructor prevents me from succeeding.

    I can see what you are doing by having gone down the path of
    having a Proxy which lets you throw new
    rendering methods together; but it's added a lot of complexity,
    it's rigidly enforced; and for the simple use cases
    a fair bit of overkill.

    Please consider:
    1. Making the constructors of HTML_QuickForm2_Renderer_*
    public
    2. Removing the 'final' keyword from HTML_QuickForm2
    methods; allowing people to extend them
    3. Re-using existing, non magic language constructs to
    expose public methods.

    Test script:
    ---------------
    <?php
    require_once 'HTML/QuickForm2/Renderer/Default.php';

    $renderer = new HTML_QuickForm2_Renderer_Default();
    $renderer->setElementTemplateForGroupClass('html_quickform2_container',
    'html_quickform2_element', $checkbox_template);


    Expected result:
    ----------------
    I can instantiate the object and manipulate its state with the
    appropriate setters/getters

    Actual result:
    --------------
    I have to use the factory, which gives me a proxy, which
    evaluates the methods I'm trying to call and adds a layer of
    complexity.

    ------------------------------------------------------------------------
  • Borz_off at Apr 28, 2011 at 1:01 pm
    Edit report at http://pear.php.net/bugs/bug.php?id=18435&edit=1

    ID: 18435
    Updated by: borz_off@cs.msu.su
    Reported By: daniel dot oconnor at gmail dot com
    Summary: Allow dependency injection/more easily testable code
    Status: Analyzed
    -Type: Feature/Change Request
    +Type: Documentation Problem
    Package: HTML_QuickForm2
    Package Version: 0.5.0
    PHP Version: Irrelevant
    Roadmap Versions:
    New Comment:

    -Type: Feature/Change Request
    +Type: Documentation Problem
    I checked whether it is possible to pass additional arguments to the
    constructor via ReflectionClass::newInstanceArgs(), but it throws an
    exception for protected constructor even when called from the scope of
    the parent class. Building an eval() string doesn't seem like a good
    idea and ReflectionMethod::setAccessible() only works from PHP 5.3.2

    Anyway, I think it should be documented when you need to use the whole
    Factory / Proxy / Plugin setup and when you can get away with
    subclassing a renderer and declaring its constructor public (note that
    elements' render() methods require just an instance of Renderer, they
    don't care about Proxy).

    I also think that the bug summary is quite a bit misleading, since the
    setup you complain about does not allow only a particular form of
    dependency injection (via constructor) and it only makes your code less
    easily testable if you wish to test renderers and their plugins (somehow
    I doubt that you are testing either of these).


    Previous Comments:
    ------------------------------------------------------------------------

    [2011-04-17 18:32:55] avb

    Let's lead users by example and move further discussion to pear-dev, OK?

    ------------------------------------------------------------------------

    [2011-04-17 17:46:52] mansion

    Hi Daniel,

    Do you have any suggestions to improve renderers in QF2 ?
    I am personally not totally satisfied with the current implementation,
    which, like
    you, I find not easy enough to extend. I have committed a new renderer,

    HTML_QuickForm2_Renderer_Callback, that accepts a callback to render an

    element or a class of elements, instead of a template. This is not fully
    satisfying
    neither, but it helps in some cases I have and it offers more
    flexibility. If you have
    any ideas, please share.

    ------------------------------------------------------------------------

    [2011-04-13 14:29:27] avb

    -Status: Open
    +Status: Analyzed
    The renderers/plugins setup is a bit convoluted due to shortcomings in
    PHP itself: it allows neither to
    * add the methods to an object at runtime (without using e.g. runkit)
    as possible in other similar languages nor to
    * define properties/methods accessible to class and related classes
    (e.g. Java's protected modifier allows access from classes of the same
    package)

    Thus Proxy / Factory which both aggregate methods from several classes
    and limit access to them from outside. Until PHP supports at least one
    of the above-mentioned features, I am unwilling to change this
    architecture.

    That being said, it may make sense to pass additional arguments from
    factory() call to Renderer constructor, I'll test whether it is possible
    with Reflection.

    ------------------------------------------------------------------------

    [2011-04-13 03:03:27] doconnor

    Description:
    ------------
    With renderers in particular, the protected constructor and
    static, final factory method requires me to register my
    plugin; which is then stored in private/static variables.

    This is a pain if I want to create a renderer with its
    dependencies in the constructor - I can never make it work
    with the factory; and always have to instantiate it by hand; or
    always have to do further setup.

    It's also a pain if I just want to instantiate a default renderer,
    change one template, and move on - the protected
    constructor prevents me from succeeding.

    I can see what you are doing by having gone down the path of
    having a Proxy which lets you throw new
    rendering methods together; but it's added a lot of complexity,
    it's rigidly enforced; and for the simple use cases
    a fair bit of overkill.

    Please consider:
    1. Making the constructors of HTML_QuickForm2_Renderer_*
    public
    2. Removing the 'final' keyword from HTML_QuickForm2
    methods; allowing people to extend them
    3. Re-using existing, non magic language constructs to
    expose public methods.

    Test script:
    ---------------
    <?php
    require_once 'HTML/QuickForm2/Renderer/Default.php';

    $renderer = new HTML_QuickForm2_Renderer_Default();
    $renderer->setElementTemplateForGroupClass('html_quickform2_container',
    'html_quickform2_element', $checkbox_template);


    Expected result:
    ----------------
    I can instantiate the object and manipulate its state with the
    appropriate setters/getters

    Actual result:
    --------------
    I have to use the factory, which gives me a proxy, which
    evaluates the methods I'm trying to call and adds a layer of
    complexity.

    ------------------------------------------------------------------------

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
grouppear-bugs @
categoriesphp
postedApr 13, '11 at 1:28p
activeApr 28, '11 at 1:01p
posts4
users2
websitepear.php.net

2 users in discussion

Borz_off: 3 posts Php: 1 post

People

Translate

site design / logo © 2022 Grokbase