Zend Passing variable to PartialLoop inside partial view - php

I have in my view a partial containing a partialLoop.
But when I run the page I have the following error message:
Call to a member function countComments() on a non-object in ...'_loop.phtml'
This is how I call my partial from within my view:
echo $this->partial('_post.phtml',$this->post);
where $this->post is a DB retrieved row
This is my partial's content:
MY simplified Partial!
echo $post->countComments();//the count number is correctly output..
echo $this->partialLoop('_loop.phtml',$this->object);
This is my partialLoop's content:
echo $this->object->countComments();//no output!
In the bootstrap I have set:
$view->partial()->setObjectKey('object');
$view->partialLoop()->setObjectKey('object');
Is this the right way to call partialLoops from within partials??
P.s. I var_dumped $this->object inside my partial and it is a PostRow OBJECT.I var dumped $this->object into _loop.phtml and I have 5 NULLS (standing for id,title,text,author,datetime fields of my post)
thanks
Luca

I think that the reason is that when you pass $this->post into partial view helper like this:
$this->partial('_post.phtml',$this->post);
partial view helper will execute its toArray() method. Hence, your $this->object is an array and you are passing an array to your partialLoop. So, in your partialLoop you are trying to execute countComments() on an array representing your row post object, rather than actual row object.
To avoid this, I would recommend passing variables to partial and partialLoop view helpers using array notation, e.g:
$this->partial('_post.phtml',array('post' => $this->post));
Hope this helps.

This error is caused by the default behaviour of the partial and partialLoop view helpers as Marcin said above.
Although it is confusing the manual does explain this here
Object implementing toArray() method. If an object is passed an has a
toArray() method, the results of toArray() will be assigned to the
view object as view variables.
The solution is to explicitly tell the partial to pass the object. As the manual explains:
// Tell partial to pass objects as 'model' variable
$view->partial()->setObjectKey('model');
// Tell partial to pass objects from partialLoop as 'model' variable
// in final partial view script:
$view->partialLoop()->setObjectKey('model');
This technique is particularly useful when passing
Zend_Db_Table_Rowsets to partialLoop(), as you then have full access
to your row objects within the view scripts, allowing you to call
methods on them (such as retrieving values from parent or dependent
rows).

Related

Can someone explain how Laravel shares variables with view?

In Laravel controller function you can return view with array of variables you like to share with the current view. Something like this:
public function index() {
return view('index')->with(['name' => 'John doe']);
}
Then you can use the name inside the with() function as $name in your view.
Can someone explain how it been done please? I would like to do something similar by myself.
We can pass individual pieces of data to the view using the 'with' method.
When passing information in this manner, the data should be an array with key / value pairs. Inside your view, we can then access each value using its corresponding key, such as
<?php echo $key; ?>
Laravel include the view file inside a function which makes all defining variables scope within a function.
Just before including files laravel calls PHP's builtin function extract(array) which declare all the variable in the scope.
extract create variables out of array making key as variable name and value as variable value.

CakePHP 3 - How to add to an already set view var of type array

I'm building a RESTful API which is returning a JSON response. When setting the view vars in the controller, is there a way to explicitly set elements of an array variable which already exists?
For example, let's say the AppController sets a view var which is an array:
$this->set('myArray', array('foo' => 'bar'));
But then in the child controller MyController I want to add to that array. Something like:
$this->set('myArray.add', 'New Element');
So that the JSON response for the view will be:
{
"myArray": {
"foo": "bar",
"add": "New Element"
}
}
I'm guessing it can be done in a roundabout way by storing the array as a normal PHP property of the AppController class, and then adding to the array in the child controller before finally doing $this->set() once at the end of the controller action.
But I'm curious if there is a way to do this through the Controller::set() method alone.
But I'm curious if there is a way to do this through the Controller::set() method alone.
No. In such a case reading the code is always a good idea. This would have answered your question.
See http://api.cakephp.org/3.2/source-class-Cake.View.ViewVarsTrait.html#129
Implement a method like setMerge() that does what you want or directly array_merge() your data into the viewVars property in your controller.

PHP how to pass array from view to controller and then to a different view from controller?

I have been trying to pass an array that is generated in view to controller.
Say, $abc=array(); How do I sent this array to controller, then process it and sent this array to another view?
Is it even feasible? Not getting any answer after googling! Please help.
I see no point to generate array from inside the view.
It depends how your framework passes the data between the layers.
For example the controller do pass the data to the View object.
I.e.
public function someMethodInController() {
$this->view->varName['arr_key'] = 'something';
}
But talking about view, it might not have a certain controller already instantiated (usually it's against the MVC paradigm)
So I see two major ways:
Instantiate a controller (I would not prefer this)
$controller = MyController();
$controller->abc = $abc;
Or use sessions. This way to transmit data is universal inbetween your domain, and does not care if you are using a certain pattern, or how do you transmit between layers.
$_SESSION['abc'] = $abc;
Once assigned, you can use it in the same session from each of your files.

Laravel4 get section array in Controller/Router layer from a Blade template

I need your help.
I've just found out that the class \Illuminate\View\Environment has a protected array $sections and a method to get it getSections() but it returns an empty array.
Here's how I tried to get it:
$view = View::make('pages');
$env = $view->getEnvironment();
$env->make('pages');
print($env->getSections());
And the result is Array( )
Where did I go wrong? Any suggestion will be appreciated.
That's because when you call $env->make('pages'), the view isn't immediately processed. It's only processed when the render method on the $view object is called, which is done automatically when you return it as a response, via the __toString() method. The problem, though is that just after the page is rendered, still inside the render method, the $sections variable is cleared, using the flushSections method. So you actually never have access to it.
You could try to fool it if you call the incrementRender method before making the view, then make and render the view, get the sections and then finally decrementRender() and flushSections(), but this could bring unexpected results. Something like this:
// Fool it
$env->incrementRender();
$env->make('pages')->render();
$sections = $env->getSections();
// Clear it
$env->decrementRender();
$env->flushSections();

Returning Data with a Zend Framework View Helper

I am creating a view helper to deal with returning some data screen scraped from elsewhere and my question is, what is the best way to gather the collected data and return it for use in the view?
Assume the view helper goes out and successfully grabs a few divs full of data.
Should I return an array of data and iterate over that in the view?
$i = 0
foreach($this->myHelper as $noob) {
echo '<div><h3>'.$noob[$i][0].'</h3>'.$noob[$i][2].'</div>';
$i++;
}
or perhaps build the output in the view helper and return the whole lot as a string?
echo $this->myHelper;
/* giving me something like:
<div><h3>Foo1</h3>bar1</div>
<div><h3>Foo2</h3>bar2</div>
*/
or return an object rather than an array or some other way I am missing (or screwing up in the above examples)? Thanks in advance.
I'd add a view partial argument and pass the data to the nominated partial script, returning the result using the partial or partialLoop helpers (depending on your data), for example
<?php echo $this->myHelper('path/to/partial.phtml') ?>
and in your helper
return $this->partial($partialScript, $data);
Edit If you wanted to simplify things, you could make the partial argument optional and if it was missing, build your HTML string internally.
The basic ideas with view helpers is that they return strings or objects that implement __toString()

Categories