From: Christian Weiske on
Hello,


Using my own renderer, I wanted to implement ArrayAccess to get easy
access to elements by IDs (see my last mail,
"HTML_QuickForm2_Renderer_Array: Element IDs as array key?") in my
templates.

Unfortunately, the rendering proxy tunnels every method calls and thus
prevents usage of ArrayAccess which gets not tunneled. Does someone
know how I could get array access working despite the proxy?
I cannot instantiate my renderer without the factory since I want to
use renderer plugins.


--
Regards/Mit freundlichen Grüßen
Christian Weiske

-=≡ Geeking around in the name of science since 1982 ≡=-
From: Brett Bieber on
On Mon, May 3, 2010 at 3:38 PM, Christian Weiske <cweiske(a)cweiske.de> wrote:
> Hello,
>
>
> Using my own renderer, I wanted to implement ArrayAccess to get easy
> access to elements by IDs (see my last mail,
> "HTML_QuickForm2_Renderer_Array: Element IDs as array key?") in my
> templates.
>
> Unfortunately, the rendering proxy tunnels every method calls and thus
> prevents usage of ArrayAccess which gets not tunneled. Does someone
> know how I could get array access working despite the proxy?
> I cannot instantiate my renderer without the factory since I want to
> use renderer plugins.

I think the proxy should implement these methods accordingly, so that
these special interfaces such as Traversable, Countable, ArrayAccess,
__toString, etc are handled as expected.

I do something like this in Savant4/Savvy's templating system to
perform automatic output escaping while preserving the object context.
This example is by no means extensive, but accommodates the most-used
interactions.
http://github.com/saltybeagle/Savvy/blob/master/src/Savvy/ObjectProxy.php#L165

--
Brett Bieber
From: Alexey Borzov on
Hi Brett,

On 04.05.2010 3:56, Brett Bieber wrote:
>> Using my own renderer, I wanted to implement ArrayAccess to get easy
>> access to elements by IDs (see my last mail,
>> "HTML_QuickForm2_Renderer_Array: Element IDs as array key?") in my
>> templates.
>>
>> Unfortunately, the rendering proxy tunnels every method calls and thus
>> prevents usage of ArrayAccess which gets not tunneled. Does someone
>> know how I could get array access working despite the proxy?
>> I cannot instantiate my renderer without the factory since I want to
>> use renderer plugins.
>
> I think the proxy should implement these methods accordingly, so that
> these special interfaces such as Traversable, Countable, ArrayAccess,
> __toString, etc are handled as expected.
>
> I do something like this in Savant4/Savvy's templating system to
> perform automatic output escaping while preserving the object context.
> This example is by no means extensive, but accommodates the most-used
> interactions.
> http://github.com/saltybeagle/Savvy/blob/master/src/Savvy/ObjectProxy.php#L165

I don't think implementing all the gazillion SPL interfaces (Iterator,
Countable, etc) makes sense, while proxying __get() / __set() and friends may
indeed be useful.

Of course that means having to write
$renderer->foo
rather than
$renderer['foo']
but I don't see a huge problem here.

Thanks for an example!
From: Alexey Borzov on
Hi,

On 05.05.2010 19:47, Alexey Borzov wrote:
> On 04.05.2010 3:56, Brett Bieber wrote:
>>> Using my own renderer, I wanted to implement ArrayAccess to get easy
>>> access to elements by IDs (see my last mail,
>>> "HTML_QuickForm2_Renderer_Array: Element IDs as array key?") in my
>>> templates.
>>>
>>> Unfortunately, the rendering proxy tunnels every method calls and thus
>>> prevents usage of ArrayAccess which gets not tunneled. Does someone
>>> know how I could get array access working despite the proxy?
>>> I cannot instantiate my renderer without the factory since I want to
>>> use renderer plugins.
>>
>> I think the proxy should implement these methods accordingly, so that
>> these special interfaces such as Traversable, Countable, ArrayAccess,
>> __toString, etc are handled as expected.
>>
>> I do something like this in Savant4/Savvy's templating system to
>> perform automatic output escaping while preserving the object context.
>> This example is by no means extensive, but accommodates the most-used
>> interactions.
>> http://github.com/saltybeagle/Savvy/blob/master/src/Savvy/ObjectProxy.php#L165
>>
>
> I don't think implementing all the gazillion SPL interfaces (Iterator,
> Countable, etc) makes sense, while proxying __get() / __set() and
> friends may indeed be useful.
>
> Of course that means having to write
> $renderer->foo
> rather than
> $renderer['foo']
> but I don't see a huge problem here.
>
> Thanks for an example!
>

Answering to myself: na�ve proxying of __get() / __set() like in the example
above is not a good idea. As most of the Renderer properties are public (so that
they are accessible by plugins) such __get() / __set() methods will allow access
to them from outside, which isn't desirable.

So probably ArrayAccess is the way to go after all:
* offsetSet() and offsetUnset() should throw exceptions, we can't do any
meaningful changes to Renderer;
* offsetExists() and offsetGet() should check whether Renderer implements
ArrayAccess itself and throw exceptions if it doesn't.
From: Alexey Borzov on
Hi Christian,

On 04.05.2010 0:38, Christian Weiske wrote:
> Using my own renderer, I wanted to implement ArrayAccess to get easy
> access to elements by IDs (see my last mail,
> "HTML_QuickForm2_Renderer_Array: Element IDs as array key?") in my
> templates.
>
> Unfortunately, the rendering proxy tunnels every method calls and thus
> prevents usage of ArrayAccess which gets not tunneled. Does someone
> know how I could get array access working despite the proxy?
> I cannot instantiate my renderer without the factory since I want to
> use renderer plugins.

Before we go on implementing proxies and stuff, I'd like to understand what is
the benefit of accessing renderer rather than the result renderer returns?

e.g.

$form->render($renderer);
echo $renderer['foo'];

vs

$result = $form->render($renderer)->toArray();
echo $result['foo'];

?