Wizard
Wizard

Reputation: 11295

Zend framework header data

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

Answers (3)

chrisweb
chrisweb

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

dhavald
dhavald

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

Lucian Depold
Lucian Depold

Reputation: 2017

Define a BaseController, put the things each controller needs to do in there and extend it by your regular controllers...

Upvotes: 2

Related Questions