Not sure this should be called a 'bug' exactly, but here is
the problem:
I have written a tree tag which needs to write a
function to the compiled template (to recurse through a
tree):
function myfunc(&$root) { ... }
The old behaviour of
ServerDataComponentTag::getDataSourceRefCode()
would return a string like:
$root->children['0010']
which would work find _inside_ the function definition
because '$root' is visible inside the scope of the
function, having been passed in as a parameter (and
given the same name).
Now getDataSourceRefCode returns only a temp variable
(which is assigned/declared in the template during
preGenerate) like:
$G
The problem is if I need to have a {$variable} expanded
inside my function definition as I am generating the tag
output, the following code gets inserted:
$G->get('variable')
But because $G is not visible inside the scope of the
function I get errors like 'call to a method of a non-
object' in the compiled template.
Anyone have any ideas how to get around this, i.e.
properly handle {$variable}, {$^^^othervariable},
{$#rootvariable} within the scope of a function
definition in a compiled template? The only option I can
think of is to pass the desired dataspace, plus _all_
parent dataspaces into the function:
function myfunc(&$root, &$B, &$G, ...) { ... }
but this seems like a pretty ugly hack.
A simple fix of course would be to revert back to the old
behaviour of getDataSpaceRefCode(); however this
would affect (i.e. lengthen) the generated code
everywhere even where this issue is not relevant.
Any other ways to get around this? If any of this is
unclear, please let me know and I'll try to clarify.
Logged In: YES
user_id=555352
I had a similar issue with the cell templates for the
data:table component. I only dealt with the case of
component or root level dataspaces. I explicitly pass them
in as arguments using the same variable names as the render
function would call them. My code would have the same
problem as yours dealing with {$^^^var}
Logged In: YES
user_id=555352
Oh, and one more thought that I did not resort to, that you
might...
Have the parent code always call your function as :
child_function(get_defined_vars());
and do
function child_function($parent_env) {
extract($parent_env);
...
}
Logged In: YES
user_id=604745
>Oh, and one more thought that I did not resort to, that you
might...
>
>Have the parent code always call your function as :
>child_function(get_defined_vars());
>
>and do
>function child_function($parent_env) {
> extract($parent_env);
> ...
>}
Thanks for the idea... so basically this would 'automate' the
generation of the list of dataspace variables ($root, and temp
variables) to be passed into the function. Still seems a little
hackish, but I'm going to go with something like this as I think
it is the best that can be done without changes to WACT
handling of DataBindingExpressions.
One issue: I don't think that 'get_defined_vars' can pass
stuff by reference -- so there would be a lot of overhead
copying dataspaces on each function call -- but I think it
should be possible to find a way to do so.
I was also worried at first that get_defined_vars would also
grab all the PHP internal variables on the first call to the
function, but since WACT templates are defined as functions,
get_defined_vars won't see all these.
Logged In: YES
user_id=604745
Just a quick follow-up:
What I ended up doing to solve this problem is the following. In the function preGenerate, I have:
$dataspace =& $this;
while (!is_null($dataspace)) {
$var = $dataspace->getDataSourceRefCode();
$this->function_params[] = $var;
$dataspace =& $dataspace->getParentDataSource();
}
To generate the code for the function header:
$code->writePHP('function ' . $this->function_name . ' (&' . join(',&',$this->function_params) . ') {');
To generate a function call:
$code->writePHP($this->function_name . '(' . join(',', $this->function_params) . ');');
Works nicely. (As long as getDataSourceRefCode returns a simple variable name, rather than some expression.) Thanks again for the tip!