Reputation: 11295
In views\scripts
I have header.phtml
file, there is placed infomation about user: Name, Surname, photo
Now I must in each controller constructor get this data from db, maybe is better solution to use abstract class or something else ?
Because it hard to place same code in each controller constructor.
Upvotes: 0
Views: 174
Reputation: 1509
Yes there are two recommended solutions, first one is to make a plugin (http://framework.zend.com/manual/1.12/en/zend.controller.plugins.html) that gets loaded for example in your bootstrap and will do something for each request, if what you want to do applies only to a few actions you could create an action helper (http://framework.zend.com/manual/1.12/en/zend.controller.actionhelpers.html).
In your case i would create a frontController plugin for example on dispatchLoopStartup that stores the user data in the registry, then in your view you retrieve that data from the registry and echo it. To reduce the amount of db requests, the plugin could use the user session to store the informations, so only the first request to your site would trigger a db query, or put the user data in the session upon login.
I dont recommend using a baseController as it is not a best practice and you would have to edit all your controllers to tell them to extend the baseController, i will also not use the init function of all your controllers for the same reason, by using the plugin all you need to do is initialize it in your boostrap and then retrieve the data from registry in your header view partial
the name of the plugin starts with the name of your library directory, followed by any subfolders that you may have and after the last underscore is the name of your class, this is why the autoloader finds your plugin by replacing the underscores with slahes or backslashes depending on your OS to get the correct path
header.phtml:
<?php
// test if userData is there
Zend_Debug::dump($userData);
Bootstrap.php:
<?php
// add the namespace of your library directory
$autoloader = Zend_Loader_Autoloader::getInstance();
$autoloader->registerNamespace('MyLibrary_');
// register header plugin
$front = Zend_Controller_Front::getInstance();
$front->registerPlugin(new headerUserDataPlugin());
Put the following plugin into the correct folder and adapt the plugin class name if your directories structure differs from this one, for example your Library folder is maybe not called "myLibrary":
application/
configs/
application.ini
forms/
layouts/
modules/
views/
Bootstrap.php
library/
Zend/
MyLibrary/
Controller/
Plugin/
HeaderUserDataPlugin.php
public/
index.php
HeaderUserDataPlugin.php:
<?php
/**
* header user data plugin
*
**/
class MyLibrary_Controller_Plugin_HeaderUserDataPlugin extends Zend_Controller_Plugin_Abstract {
public function routeShutdown(Zend_Controller_Request_Abstract $request) {
// at this point you can retrieve the user id from session
$mysession = new Zend_Session_Namespace('mysession');
// is there a userId in the session
if (!isset($mysession->userId)) {
$userId = $mysession->userId;
// get userData from user model
$userModel = new UserModel();
$userData = UserModel->getUserData($mysession->userId);
Zend_Registry::set('user_data', $userData);
}
}
}
I did not test the code, there may be some typos :S
Upvotes: 2
Reputation: 554
If I understood this question correctly, you want to call DB with same query in each controller construct, assign view variables with returned result and print them in header.phtml. If that's what you want, read along.
If memory is not an issue, the easier way to do this is to store a json encoded array with required data in a registry with Zend_Registry in bootstrap. This way, you only need to make only 1 query to DB.
Bootstrap.php
$row = $db->fetchRow("SELECT name, surname, url FROM people WHERE id = '127'");
$userData = array('name' => $row ['name'], 'surname' => $row ['surname'], 'photo' => $row ['url']);
Zend_Registry::set('user_data', json_encode($userData));
Now, you dont need to put this code in any controller. Just make a view helper which reads from Zend_Registry
and returns required property. You can call it from your header.phtml
directly.
/views/helpers/User.php
class Zend_View_Helper_User
{
public function user($property)
{
$userData = Zend_Registry::get('user_data');
$userData = json_decode($userData, true);
return $userData[$property];
}
}
header.phtml
<p><?=$this->user('name')?> <?=$this->user('surname')?></p>
<img src="<?=$this->user('photo')?>"/>
Upvotes: 1
Reputation: 2017
Define a BaseController, put the things each controller needs to do in there and extend it by your regular controllers...
Upvotes: 2