zend, access app without loading controllers? - zend-framework

if i wanted to have my app load profile names, like this: www.mydomain.com/simon where simon isnt a controller, its the username of the user to bring up the profile, is this possible?
class ProfileController extends Zend_Controller_Action {
public function init() {
}
public function indexAction(){
echo $this->_request->getParam('profileuser');
this is where i can display the user.
}
or something...

You might use Zend_Route for this purpose.
Just add the following to your application Bootstrap:
protected function _initRoutes()
{
$frontController = Zend_Controller_Front::getInstance();
$router = $frontController->getRouter();
$router->addRoute('profile', new Zend_Controller_Router_Route(
':profileuser',
array('module' => 'default', 'controller' => 'profile', 'action' => 'index')
));
}
More information on using Zend_Controller_Router here.

Presuming ProfileController is your default Controller, so you will get there by default, you can use
$profileName = ltrim($this->getRequest()->getRequestUri(), "/");
in indexAction to get 'simon' from your url.

Related

Pass a form with post method to another controller

I have a simple Zend Form that contains a textbox with setRequired(TRUE) and other validators and a simple submit button in IndexController.
My question is, is it possible another controller will process and validate my post form?
Login.php
<?php
class Application_Form_Login extends Zend_Form
{
public function init()
{
$username = $this->createElement('text', 'username');
$username->setLabel('Username:');
$username->setRequired(TRUE);
$username->addValidator(new Zend_Validate_StringLength(array('min' => 3, 'max' => 10)));
$username->addFilters(array(
new Zend_Filter_StringTrim(),
new Zend_Filter_StringToLower()
)
);
$this->addElement($username);
// create submit button
$this->addElement('submit', 'login',
array('required' => false,
'ignore' => true,
'label' => 'Login'));
}}
IndexController.php
<?php
class AttendantController extends Zend_Controller_Action
{
public function indexAction()
{
$loginForm = new Application_Form_Login();
$loginForm->setAction('/Auth/process');
$loginForm->setMethod('post');
$this->view->loginForm = $loginForm;
}
}
AuthController.php
class AuthController extends Zend_Controller_Action
{
public function processAction()
{
// How to validate the form posted here in this action function?
// I have this simple code but I'm stacked here validating the form
// Get the request
$request = $this->getRequest();
// Create a login form
$loginForm = new Application_Form_Login();
// Checks the request if it is a POST action
if($request->isPost()) {
$loginForm->populate($request->getPost());
// This is where I don't know how validate the posted form
if($loginForm->isValid($_POST)) {
// codes here
}
}
}
}
You're pretty close. In the process action you create a new instance of the login form (which you are doing), and you pass the POST data to the isValid() method of that form in order to validate. So:
public function processAction()
{
$request = $this->getRequest();
$loginForm = new Application_Form_Login();
if($request->isPost()) {
if($loginForm->isValid($request->getPost)) {
// codes here
} else {
// assign the login form back to the view so errors can be displayed
$this->view->loginForm = $loginForm;
}
}
}
Generally it is easier to display and process the form within the same action, and redirect when the submission is successful. This is the Post/Redirect/Get pattern - see http://en.wikipedia.org/wiki/Post/Redirect/Get. This saves you having to create an instance of the same form in two different actions and makes it easier to redisplay the form in case of errors.
Are you using ' ?
change $loginForm->setAction(/Auth/process); to $loginForm->setAction('/auth/process');
from processAction you may remove $login->populate($request->getPost());

Class Not Found in Zend Framework

I have installed a fresh copy of zend framework 1.11.11 on my local workstation (Windows). For my admin module I have created "Login.php" form under /application/modules/admin/models/Form/Login.php I have also set up autoloader in Bootstrap.php Like
protected function _initAutoloader()
{
$autoloader = Zend_Loader_Autoloader::getInstance();
$autoloader->registerNamespace('My_');
new Zend_Application_Module_Autoloader(array(
'basePath' => APPLICATION_PATH,
'namespace' => 'Default')
);
$loader = new Zend_Loader_Autoloader_Resource(array(
'basePath' => APPLICATION_PATH.'/models/',
'namespace' => '')
);
$loader->addResourceType('forms', 'Form/', 'Form');
return $autoloader;
}
on my loginAction() method of IndexController.php file of admin module, i am using
$form = new Admin_Model_Form_Login();
But Getting below error:-
Fatal error: Class 'Admin_Model_Form_Login' not found in
C:\wamp\www\ztest\application\modules\admin\controllers\IndexController.php
Here is the code of Login.php
class Admin_Model_Form_Login extends Zend_Form
{
public function init()
{
parent::init();
$this->setAction('/admin/index/login')->setMethod('post');
$account = new Zend_Form_Element_Text('account');
$account->setLabel('Username')->setRequired(true);
$account->setOrder(1);
$this->addElement($account);
$password = new Zend_Form_Element_Password('password');
$password->setLabel('Password');
$password->setOrder(2);
$this->addElement($password);
$submit = new Zend_Form_Element_Submit('login');
$submit->setLabel('Login');
$submit->setOrder(3);
$this->addElement($submit);
}
}
Have you added a Bootstrap.php file to your module's path?
The file should be found in /application/modules/admin/Bootstrap.php
Similar to this:
class Admin_Bootstrap extends Zend_Application_Module_Bootstrap
{
//Can be left blank
}

Zend Framework - How does a controller point to a model?

This is a problem that I cannot figure out after hours of googling, the Zend Framework documentation didn't explain what i needed to know.
I have a file: /application/controllers/RegisterController.php
class RegisterController extends Zend_Controller_Action
{
}
How do I point this file to use classes from: /application/models/User.php
class Application_Model_User
{
}
The code works great when the file is named Register.php
What configurations do i need to make to point a controller to a specific model?
In your bootstrap, you can start by declaring your namespace:
protected function _initAutoload() {
//Autoloader
$autoLoader = Zend_Loader_Autoloader::getInstance();
$resourceLoader = new Zend_Loader_Autoloader_Resource(array(
'basePath' => APPLICATION_PATH,
'namespace' => '',
'resourceTypes' => array(
//Tells the application where to find the models
'model' => array(
'path' => 'models/',
'namespace' => 'Model_'
)
)
));
return $autoLoader;
}
Your model: /application/models/User.php
class Model_User extends Zend_Db_Table_Abstract
{
}
Then in you controller: /application/controllers/RegisterController.php
class RegisterController extends Zend_Controller_Action
{
public function indexAction() {
$model = new Model_User();
}
}

Change Layout in Bootstrap

I am new with zend and I have a problem changing my layout in the bootstrap. I want to change my layout when the user is logged in.
My function to change the layout in the bootstrap is like this:
protected function _initAuthState()
{
$layout = new Zend_Layout;
$layout->setLayoutPath('/layouts/scripts');
if (Zend_Auth::getInstance()->hasIdentity()):
// Logged in.
$layout->setLayout(layout2);
else:
// Not Logged in.
$layout->setLayout(‘layout’);
endif;
}
This code doesn't work, the layout is always the same ... help!
You are modifying a new layout instance, not the instance that is being used by the system.
I assume you are specifying your layout params in application.ini. So you need:
$this->bootstrap('layout');
$layout = $this->getResource('layout');
Then perform your check/modification on this layout instance.
BTW, changing layout is often done using a front-controller plugin. Still runs early enough to do the job, but is often more configurable and re-usable. See here and here for two examples.
I found the answer!!
this is my final result, and is working!!
Bootstrap.php:
<?php
class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{
public function _initLoader(){
$resourceLoader = new Zend_Loader_Autoloader_Resource(array(
'basePath' => '../application/',
'namespace' => 'My',
));
$resourceLoader->addResourceTypes(array(
'plugin' => array(
'path' => 'plugins/',
'namespace' => 'Plugin',
)
));
}
public function _initPlugins()
{
$front = Zend_Controller_Front::getInstance();
$front->registerPlugin(new My_Plugin_Layout());
}
}
application/plugins/Layout.php:
<?php
class My_Plugin_Layout extends Zend_Controller_Plugin_Abstract
{
public function preDispatch()
{
$user = Zend_Auth::getInstance();
$role = $user->getIdentity()->role;
$layout = Zend_Layout::getMvcInstance();
switch ($role) {
case 'admin':
$layout->setLayout('layout2');
break;
case 'normal':
$layout->setLayout('layout');
break;
default:
$layout->setLayout('layout');
break;
}
}
}
?>

Zend Framework: How to 301 redirect old routes to new custom routes?

I have a large list of old routes that I need to redirect to new routes.
I am already defining my custom routes in the Bootstrap:
protected function _initRoutes()
{
$router = Zend_Controller_Front::getInstance()->getRouter();
$oldRoute = 'old/route.html';
$newRoute = 'new/route/*';
//how do I add a 301 redirect to the new route?
$router->addRoute('new_route',
new Zend_Controller_Router_Route($newRoute,
array('controller' =>'fancy', 'action' => 'route')
));
}
How can I add routes that redirect the old routes using a 301 redirect to the new routes?
I've done it like this
Add a Zend_Route_Regexp route as the old route
Add Controller and action for the old route
Add logic to parse old route
Add $this->_redirect($url, array('code' => 301)) for this logic
Zend Framework does not have this type of functionality built in. So I have created a custom Route object in order to handle this:
class Zend_Controller_Router_Route_Redirect extends Zend_Controller_Router_Route
{
public function match($path, $partial = false)
{
if ($route = parent::match($path, $partial)) {
$helper = new Zend_Controller_Action_Helper_Redirector();
$helper->setCode(301);
$helper->gotoRoute($route);
}
}
}
Then you can use it when defining your routes:
class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{
protected function _initCustomRoutes()
{
$router = Zend_Controller_Front::getInstance()->getRouter();
$route = new Zend_Controller_Router_Route_Redirect('old/route/*', array('controller'=>'content', 'action'=>'index'));
$router->addRoute('old_route', $route);
}
}
In controller, try this way:
$this->getHelper('redirector')->setCode(301);
$this->_redirect(...);
There are a few approaches to solve this issue.
The easiest is probably to just use your .htaccess file to do a RewriteRule pattern substitution [R=301]
You could also detect what route was used in the controller and redirect based on that:
public function preDispatch() {
$router = $this->getFrontController()->getRouter();
if ($router->getCurrentRouteName() != 'default') {
return $this->_redirect($url, array('code'=>301));
}
}
The way I used to do it was to redirect to a controller that only handled redirects. Now I use the custom class mentioned in my other answer.
class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{
protected function _initRoutes()
{
$router = Zend_Controller_Front::getInstance()->getRouter();
//new routes
$router->addRoute('myroute',
new Zend_Controller_Router_Route_Static('/new/route/1234',
array('controller' =>'brands', 'action' => 'view', 'id' => '4')
));
//old routes
$oldRoutes = array(
'/old/route/number/1' => '/new/route/1234',
}
foreach ($oldRoutes as $oldRoute => $newRoute) {
$router->addRoute($oldRoute, new Zend_Controller_Router_Route_Static($oldRoute, array('controller' =>'old-routes', 'action' => 'redirect', 'new-route' => $newRoute)));
}
}
}
And the controller:
class OldRoutesController extends Zend_Controller_Action
{
public function redirectAction()
{
$newRoute = $this->_getParam('new-route');
return $this->_redirect($newRoute, array('code' => 301));
}
}