currently i have a zend framework application, i integrate it with wurfl user agent, so i can switch between mobile and desktop version, my plugin reside in library
<?php
class Zc_Controller_Plugin_TemplatePicker extends Zend_Controller_Plugin_Abstract
{
protected $useragent;
public function postDispatch(Zend_Controller_Request_Abstract $request)
{
$bootstrap = Zend_Controller_Front::getInstance()->getParam('bootstrap');
$this->useragent = $bootstrap->getResource('useragent');
if($this->useragent->getDevice()->getType() == 'mobile')
{
Zend_Layout::getMvcInstance()->setLayout('mobile');
}
}
}
and now i have 2 layouts in script file mobile.phtml and layout.phtml, hw can i use some of the controller function so that it can be use for mobile layout, also i have layout loader in bootstrap
protected function _initLayoutHelper()
{
// $front = Zend_Controller_Front::getInstance();
// $front->registerPlugin(new Zc_Controller_Plugin_TemplatePicker());
if(!stristr($_SERVER['REQUEST_URI'], '/admin')){
$this->bootstrap('frontController');
}
$layout = Zend_Controller_Action_HelperBroker::addHelper(new Zc_Controller_Action_Helper_LayoutLoader());
}
and the layoutloader code is
<?php
class Zc_Controller_Action_Helper_LayoutLoader extends
Zend_Controller_Action_Helper_Abstract
{
public function preDispatch(){
$bootstrap = $this->getActionController()->getInvokeArg('bootstrap');
$config = $bootstrap->getOptions();
Zend_Registry::set('config', $config);
$module = $this->getRequest()->getModuleName();
$controller = $this->getRequest()->getControllerName();
$action = $this->getRequest()->getActionName();
$layoutScript = "layout";
if (isset($config[$module]['resources']['layout']['layout'])) {
$layoutScript = $config[$module]['resources']['layout']['layout'];
}
$this->getActionController()->getHelper('layout')->setLayout($layoutScript);
}
}
where should i tweak now so that i can have 1 controller class with 2 separate layout.Thanks!!
If you wish to set some certain layout for the certain controller, you can use the following code:
class Custom_Plugin_Layout extends Zend_Controller_Plugin_Abstract
{
public function preDispatch()
{
$front = Zend_Controller_Front::getInstance();
$layout = Zend_Layout::getMvcInstance();
switch ($front->getRequest()->getControllerName()) {
case "index":
$layout->setLayout('home');
break;
case "login":
$layout->setLayout('login');
break;
default:
$layout->setLayout('default');
}
}
}
Related
i have two class, one(controller class) extend from another, then in the controller class, I define a variable "load" (in the construct), but when i extend from another class i can't invoke this variable from the constructor, any ideas? (Apologies for my bad english).
Class Controller:
<?php
class Controller {
protected $load;
public function __construct() {
$this->load = new Loader();
if($_GET && isset($_GET['action']))
{
$action = $_GET['action'];
if(method_exists($this, $action))
$this->$action();
else
die('Method not found.');
} else {
if(method_exists($this, 'index'))
$this->index();
else
die('Index method not found.');
}
}
}
Class home ( Where does it extend):
<?php
class Home extends Controller
{
function __construct() {
parent::__construct();
$this->load->model("HomeModel");// this line doesn't work
}
public function index() {
$articles = new HomeModel();
$articles = $articles->getData();
$nombres = ['jona', 'juan', 'jose'];
$view = new Views('home/home', compact("nombres", "articles"));
}
}
Loader Class:
<?php
class Loader
{
function __construct() {
}
public function model($model) {
require('./models/'.$model.'.php');
}
}
The error "'HomeModel' not found" would lead me to believe that you are not requiring the file that contains the 'HomeModel' class in the 'Home' class file.
Well, is there something like before() method in kostache module? For example, if I have a couple of PHP lines inside of the view file, I'd like to execute them separately inside of the view class, without echoing anything in the template itself. How can I handle that?
You can put this type of code in the constructor of your View class. When the view is instantiated, the code will run.
Here is a (slightly modified) example from a working application. This example illustrates a ViewModel that lets you change which mustache file is being used as the site's main layout. In the constructor, it chooses a default layout, which you can override if needed.
Controller:
class Controller_Pages extends Controller
{
public function action_show()
{
$current_page = Model_Page::factory($this->request->param('name'));
if ($current_page == NULL) {
throw new HTTP_Exception_404('Page not found: :page',
array(':page' => $this->request->param('name')));
}
$view = new View_Page;
$view->page_content = $current_page->Content;
$view->title = $current_page->Title;
if (isset($current_page->Layout) && $current_page->Layout !== 'default') {
$view->setLayout($current_page->Layout);
}
$this->response->body($view->render());
}
}
ViewModel:
class View_Page
{
public $title;
public $page_content;
public static $default_layout = 'mytemplate';
private $_layout;
public function __construct()
{
$this->_layout = self::$default_layout;
}
public function setLayout($layout)
{
$this->_layout = $layout;
}
public function render($template = null)
{
if ($this->_layout != null)
{
$renderer = Kostache_Layout::factory($this->_layout);
$this->template_init();
}
else
{
$renderer = Kostache::factory();
}
return $renderer->render($this, $template);
}
}
I followed this great article http://weierophinney.net/matthew/archives/246-Using-Action-Helpers-To-Implement-Re-Usable-Widgets.html, but currently i can't get work my simplified example.
PROBLEM The preDispatch does not get loaded.
I created new module user (there is also controller UserController, i hope this wont mess up the loading).
I have added two files in user.
Bootstrap.php - under module user
class User_Bootstrap extends Zend_Application_Module_Bootstrap {
public function initResourceLoader() {
$loader = $this->getResourceLoader();
$loader->addResourceType('helper', 'helpers', 'Helper');
}
protected function _initHelpers() {
Zend_Controller_Action_HelperBroker::addHelper(
new User_Helper_HandleLogin()
);
}
New folder under /user/helpers and class HandleLogin.
class User_Helper_HandleLogin extends Zend_Controller_Action_Helper_Abstract {
protected $view;
public function preDispatch() {
echo 'called';
if (($controller = $this->getActionController()) === null) {
return;
}
$this->createProfileWidget();
}
public function createProfileWidget() {
if (!$view = $this->getView()) {
return;
}
$view->user = '<h2>HELLO WORLD</h2>';
}
public function createLoginForm() {
}
public function getView() {
if ($this->view !== null) {
return $this->view;
}
$controller = $this->getActionController();
$view = $controller->view;
if (!$view instanceof Zend_View_Abstract) {
return;
}
//$view->addScriptPath(dirname(__FILE__) .'/../views/scripts');
$this->view = $view;
return $view;
}
}
And lastly added into layout.phtml the output.
<?php echo $this->user ?>
is init() function of User_Helper_HandleLogin works? is User_Bootstrap works? :) maybe you forget resources.modules[] = in config.ini?
I am a newbie to the Zend framework.
I am getting an error while loading my index controller:
Fatal error: Class 'Places' not found in C:\xampp\htdocs\zend\book\application\controllers\IndexController.php on line 36
My bootstrapper code is
<?php
class Bootstrap
{
public function __construct($configSection)
{
$rootDir = dirname(dirname(__FILE__));
define('ROOT_DIR', $rootDir);
set_include_path(get_include_path(). PATH_SEPARATOR . ROOT_DIR . '/library/'. PATH_SEPARATOR . ROOT_DIR .
'/application/models/');
require_once 'Zend/Loader/Autoloader.php';
$loader = Zend_Loader_Autoloader::getInstance();
// Load configuration
Zend_Registry::set('configSection',$configSection);
$config = new Zend_Config_Ini(ROOT_DIR.'/application/config.ini',$configSection);
Zend_Registry::set('config', $config);
date_default_timezone_set($config->date_default_timezone);
// configure database and store to the registry
$db = Zend_Db::factory($config->db);
Zend_Db_Table_Abstract::setDefaultAdapter($db);
Zend_Registry::set('db', $db);
}
public function configureFrontController()
{
$frontController = Zend_Controller_Front::getInstance();
$frontController->setControllerDirectory(ROOT_DIR .'/application/controllers');
}
public function runApp()
{
$this->configureFrontController();
// run!
$frontController = Zend_Controller_Front::getInstance();
$frontController->dispatch();
}
}
I have a model:
<?php
class Places extends Zend_Db_Table
{
protected $_name = 'places'; //table name
function fetchLatest($count = 10)
{
return $this->fetchAll(null,'date_created DESC', $count);
}
}
My index controller code is:
class IndexController extends Zend_Controller_Action
{
public function indexAction()
{
$this->view->title = 'Welcome';
$placesFinder = new Places();
$this->view->places = $places->fetchLatest();
}
}
I am using ZF version 1.10.4
There is a good chance you are missing somethign in your class declaration
try:
<?php
class Models_Places extends Zend_Db_Table
{
protected $_name = 'places'; //table name
function fetchLatest($count = 10)
{
return $this->fetchAll(null,'date_created DESC', $count);
}
}
The Zend autoloader class will look into Models/places.php for your class.
Also you could initialise the models and default module in bootstrap with:
protected function _initAutoload() {
$autoloader = new Zend_Application_Module_Autoloader(array(
'namespace' => '',
'basePath' => dirname(__FILE__),
));
$autoloader->addResourceType('models', 'models/', 'Models');
return $autoloader;
}
After having done that your class should be named Models_Places.
Check out the docs about autoloading.
Well, personally, I use extended controllers which contain few util methods I use very often. Here is a snippet of my extended controller:
<?php
class My_MyController extends Zend_Controller_Action
{
protected $_tables = array();
protected function _getTable($table)
{
if (false === array_key_exists($table, $this->_tables)) {
include APPLICATION_PATH . '/modules/'
. $this->_request->getModuleName() . '/models/' . $table . '.php';
$this->_tables[$table] = new $table();
}
return $this->_tables[$table];
}
}
You just need to define the APPLICATION_PATH in index.php. Then your controller could look like this:
<?php
class IndexController extends My_MyController
{
public function indexAction()
{
// get model
$model = $this->_getTable('ModelName');
}
}
Path where you store the My_Controller must also be in your include path.
i wrote a small plugin, so i will be able to get the name of the controller in each view.
but idk how to "pass" a parameter to the view (do sumth like $this->view->foo =...;).
class Zend_Extension_Controller_Plugin_GetControllerName extends Zend_Controller_Plugin_Abstract
{
public function __construct()
{
}
public function preDispatch(Zend_Controller_Request_Abstract $request)
{
$this->view->controllerName = $request->getControllerName();
}
}
what can i write instead of $this->view->controllerName so it will work?
Try this:
$view = Zend_Layout::getMvcInstance()->getView();
$view->controllerName = $request->getControllerName();
You can use the helper broker to get an instance of the view. Something like this should work:
Zend_Controller_Action_HelperBroker::getExistingHelper('ViewRenderer')->view->foo = 'bar';
Take this example as basis:
class Plugin_Sidebar extends Zend_Controller_Plugin_Abstract {
public function postDispatch(Zend_Controller_Request_Abstract $request)
{
if($request->getModuleName() == 'admin')
{
return;
}
$viewRenderer = Zend_Controller_Action_HelperBroker::getStaticHelper('viewRenderer');
if (null === $viewRenderer->view) {
$viewRenderer->initView();
}
$view = $viewRenderer->view;
$Categories = new Model_DbTable_Categories();
$view->menuItens = $Categories->getMenu();
}
}