HTTP response headers in Zend Framework
I needed to display a Zend Framework generated PDF using the browser plugins and after a bit of looking around it turns out that some headers need to be set in order to achieve that.
$this->getResponse()
->setHeader('Content-Disposition', 'inline; filename=invoice.pdf')
->setHeader('Content-type', 'application/x-pdf');
If you'd want to automatically download the PDF instead of displaying it using the browser plugins, you need to change the 'Content-Disposition' as follows:
$this->getResponse()
->setHeader('Content-Disposition', 'attachment; filename=invoice.pdf')
->setHeader('Content-type', 'application/x-pdf');
Switch layouts in Zend Framework
If you have a larger Zend Framework application, you probably want to you use a layout for more of your pages. For instance you'd need at least two layouts: one for a backend and another one for frontend. In order to tell ZF to use layouts, you'll need to set the layout paths in your application.ini
In order to store the layouts in /application/layouts/scripts, add the following to /application/configs/application.ini
resources.layout.layoutpath = APPLICATION_PATH "/layouts/scripts"
You can now create several layouts, something around this model:
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<?php echo $this->headTitle() ?>
<?php echo $this->headScript() ?>
<?php echo $this->headStyle() ?>
</head>
<body>
<?php echo $this->render('header.phtml') ?>
<div id="content"><?php echo $this->layout()->content ?></div>
<?php echo $this->render('footer.phtml') ?>
</body>
</html>
By default, your application will use the layout in /application/layouts/scripts/layout.phtml, but if you want some pages to be rendered using another layout you can tell ZF to do so like this:
// Within controller
// note that the file that's going to be rendered is /application/layouts/scripts/backend.phtml
$this->_helper->_layout->setLayout('backend')
//Within view script
$this->layout()->setLayout('other-layout'); ?>
More info on using Zend_Layout: http://framework.zend.com/manual/en/zend.layout.quickstart.html
Zend Framework disable layout and view rendering
When using Zend Framework, sometimes you need to create a controller action which just does something, doesn't need to display anything to the user. To disable the layout and the view rendering add the following in your action:
// disable layout $this -> _helper -> layout() -> disableLayout(); // disable view rendering $this -> _helper -> viewRenderer -> setNoRender();
Zend_Auth and subdomains
I was working today on an user authentication system that redirects the users to their own sub-domain after a successful login. It should work like this: user comes to www.exmple.com, fills in his credentials and after successful login he/she should be redirected to username.example.com. All fine and dandy except the session is not persistent between sub-domains of example.com. After a bit of google and some help from eXcuvator on #zftalk, i found the solution:
Just put the following in your Bootstrap.php and everything should just work:
protected function _initSession()
{
Zend_Session::setOptions( array('cookie_domain' => '.example.com', 'use_only_cookies' => true, 'name' => 'yourSessionName'));
}
Fix Zend Framework 404 routes on HTTPS
I've been working on a web project that required some of the pages to be loaded via HTTPS.
I've got the certificate, installed accessed homepage via HTTPS and seems to work. That was not the case for the rest of the routes. After a lot of searching i was able to find a post which proposes a fix for this. Namely, you have to add what's on your app's main .htaccess into your SSL virtualhost.
Add the following just before tag closes and you should be fine:
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} -s [OR]
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} -l [OR]
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]
RewriteRule ^.*$ /index.php [NC,L]
</IfModule>
Another one of my requirements was to redirect some pages to HTTPS (ie a login page). To do that add the following to your .htaccess:
RewriteCond %{HTTPS} !=on
RewriteRule ^login(.*) https://%{SERVER_NAME}/login$1 [R,L]
Setup ZF using svn externals
After you create a project with zf tool, put it on SVN, you might want to include inside /library the ZF, but you want to have the bleeding edge all the time. You can include it as a svn external like this:
cd library/ svn propset svn:externals 'Zend http://framework.zend.com/svn/framework/standard/trunk/library/Zend/' .
Next time when you run svn up, your project will fetch the latest ZF from it's repo.
Setup controllers and actions inside a module using zf tool
I've been trying to move some old code into separate modules for easier use later on. I installed zend framework and zend tool and created a new project:
zf create project myproject
Adding a new module is easy as pie:
zf create module mymodule
This creates the /application/modules/mymodule folder with complete MVC structure inside (controllers, models and views folders).
My module was not working so after a bit of looking around i've found Akrabat's post that some light on the subject. You have to add to /application/configs.ini the following inside the [production] section:
# enabling modules resources.frontController.moduleDirectory = APPLICATION_PATH "/modules" resources.modules[] = ""
Good, now we should have a working module, except we don't have any controllers. Trying to create a controller proved a bit tricky as zf tool would not pleace them in the right place, inside the modules/mymodule/controllers but in the default /application/controllers. The same applies for actions. With a bit of help from TheAshMan on #zftalk i found the right answer:
# create controller Photos_IndexController at /application/modules/controllers/Photos_IndexController.php zf create controller Photos_Index 1 mymodule # create the action view inside the Photos_IndexController zf create action view Photos_Index 1 mymodule
Hope this helps someone as it took me a few hours to figure it out
How to update your Twitter status using Zend Framework
After reading the NetTuts tutorial on how to update your Twitter status using CodeIgniter, I wanted to show how to update your Twitter status using Zend Framework.
For this tutorial you need to install Zend Framework and Zend_Tool first.
Step 1: setup apache vhost by creating the /etc/apache2/sites-available/twitter as follows:
<VirtualHost *:80>
ServerAdmin romeo.cioaba@spotonearth.com
DocumentRoot /home/mimir/Zend/workspaces/DefaultWorkspace7/twitter
ServerName twitter.dev
ServerAlias www.twitter.dev
ErrorLog /home/mimir/Zend/workspaces/DefaultWorkspace7/logs/twitter_error_log
CustomLog /home/mimir/Zend/workspaces/DefaultWorkspace7/logs/twitter_access_log combined
<Directory "/home/mimir/Zend/workspaces/DefaultWorkspace7/twitter/">
Options Indexes FollowSymLinks
AllowOverride All
Order allow,deny
Allow from all
</Directory>
</VirtualHost>
You will need to change the DocumentRoot and Directory directives to match your configuration.
Step 2: add twitter.dev to your hosts file:
127.0.0.1 twitter.dev www.twitter.dev
Step 3: create the Zend Framework project
# i switch to my Zend Studio workspace, where apache is reading his sites from: # cd Zend/workspaces/DefaultWorkspace7/ zf create project twitter
Step 4: restart apache
sudo /etc/init.d/apache2 restart
At this point you should have a default Zend Framework project that you can browse at http://twitter.dev/public/. How let's change our status
Replace the content of IndexController with the following:
<?php
class IndexController extends Zend_Controller_Action
{
public function init()
{
/* Initialize action controller here */
}
public function indexAction()
{
// we create the form
$updateForm = new Zend_Form();
$status = new Zend_Form_Element_Text('status');
$status->setLabel('New Twitter Status')
->setRequired(true)
->addFilter('StripTags')
->addFilter('StringTrim')
->addValidator('NotEmpty');
$submit = new Zend_Form_Element_Submit('submit');
$submit->setLabel('Update');
$updateForm->addElements(array($status, $submit));
// we send the form to the view
$this->view->updateForm = $updateForm;
// we check if there was any POST
if ($this->getRequest()->isPost()){
$formData = $this->_request->getPost();
// checking if the form data is valid (if we have a new status or not)
if ($this->view->updateForm->isValid($formData)){
// our form is valid, we can update our status
$twitterStatus = $formData['status'];
$twitter = new Zend_Service_Twitter('myusername', 'mypassword');
$response = $twitter->status->update($twitterStatus);
}
}
}
}
Also replace the view for the index action of IndexController with:
<h1>Welcome to the Twitter Update Tutorial</h1> <?php echo $this->updateForm?>
TADA! You can now check your twitter account and see that twitter status is updated every time you submit the form -:)
Install Zend Framework and Zend_Tool using PEAR on Ubuntu
I work every day with Zend Framework and the easiest way i find to install it is by using the PEAR packages offered by the betta channel ZF Campus
Here is what you have to do install Zend Framework and Zend_Tool using PEAR on Ubuntu:
sudo pear channel-discover pear.zfcampus.org sudo pear install zfcampus/zf # for some reason the installer does not correctly link the zf.php and Zend_Tool won't work # so we need to setup a symlink sudo ln -s /usr/share/php/zf.php /usr/bin/zf.php
That's it! You can now test your install:
zf show version
In my care the output was this one:
mimir@orion:~$ zf show version Zend Framework Version: 1.9.2
Zend Framework tutorials – RFC
After a talk on #zftalk I'm thinking to start witting a site that would allow the Zend Framework community to submit learning material.
The site is going to be called Zend Framework Tips
I have a few ideas of my own, but i want to hear more from you.
