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:




    
    headTitle() ?>
    headScript() ?>
    headStyle() ?>


    render('header.phtml') ?>

    
layout()->content ?>
render('footer.phtml') ?>

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

Password protect a folder in Apache using .htaccess

mkdir -p /home/secure/
htpasswd -c /home/secure/apasswords developer
chown apache:apache /home/secure/apasswords
chmod 0660 /home/secure/apasswords

then in your htaccess add these:

AuthType Basic
AuthName "Restricted Access"
AuthUserFile /home/secure/apasswords
Require user developer

FIX: Sites not working in IE7, IE8 CO

Recently I had to fix a site that was not being displayed correctly in IE8. Turned out that some of the DOM was written by Javascript, and IE8 on client’s machine was not displaying parts of the page. At first i was not able to replicate the issue on a clean XP SP3, with IE8, but then after i disabled javascript i got the same effect as the client. Thought the solution was easy, assumed the client has JS disabled, but it turns out JS was enabled.

After closer investigation, the only difference between my IE8 and client’s IE8 was a CO, installed using IEAK8 (corporate shit) and it had by default native XMLHTTP disabled. Translated: jQuery was assuming the browser is IE6.

To fix this issue, enable XMLHTTP in IE7, or IE8

1. Open IE8
2. Go to Tools -> Internet Options -> Advanced
3. make sure "Enable native XMLHTTP support" is checked
4. Save

Heroku on Ubuntu

http://devcenter.heroku.com/articles/quickstart

As everything that comes from ruby world, getting heroku running on Ubuntu is not as easy as we’re used to (ie: apt-get install heroku) so there are a few steps that need to be followed. I’ve written this down so i can come back to it later and so that others don’t lose hours trying to figure this out. The data on this article has been scraped from http://www.web2linux.com/05/installing-rails-3-on-ubuntu-10-04-lucid-lynx/ and http://devcenter.heroku.com/articles/quickstart

Installing dependencies

sudo apt-get install curl git-core build-essential zlib1g-dev libssl-dev libreadline5-dev

Install rvm

#for latest, check https://rvm.beginrescueend.com/
bash < 

Install ruby-1.9.2

rvm install 1.9.2 && rvm use 1.9.2 --default

Then add this line as the last line in your .bashrc:

if [[ -s "$HOME/.rvm/scripts/rvm" ]];
        then source "$HOME/.rvm/scripts/rvm";
fi

Install Heroku

Sign-up for a Heroku account if you haven’t already and then install the herokugem.

gem install heroku

You will be asked to enter your Heroku credentials the first time you run a command; after the first time, your email address and an API token will be saved to ~/.heroku/credentials for future use.

It’s generally a good idea to add your public key immediately after installing the heroku gem so that you can use git to push or clone Heroku app repositories:

heroku keys:add
Enter your Heroku credentials.
Email: [email protected]
Password:
Uploading ssh public key /Users/joe/.ssh/id_rsa.pub

Track your application with Git

If you’re already using Git with your application, skip to the next step. If you’re not yet using Git to track your application, run this:

cd PATH/TO/MY_APP
git init
# Initialized empty Git repository in .git/
git add .
git commit -m "new app"
Created initial commit 5df2d09: new app
44 files changed, 8393 insertions(+), 0 deletions(-)

Create your Heroku application

At the command line, run heroku create. The first time you do this, you’ll be asked to enter your Heroku credentials. Once you do, your email address and an API token will be saved to ~/.heroku/credentials, so you won’t have to provide them again.

This first use will also upload your public SSH key so you’ll be able to push and pull code.

heroku create
Enter your Heroku credentials.
Email: [email protected]
Password:
Uploading ssh public key /Users/joe/.ssh/id_rsa.pub
Created http://high-sunrise-58.heroku.com/ | [email protected]:high-sunrise-58.git
Git remote heroku added

The last line shows the name of your new Heroku app; in this case, it’s “high-sunrise-58”, and is available at http://high-sunrise-58.heroku.com. If you were to visit that URL before pushing your application code (either by typing it in or running heroku open), you’d see a standard Heroku welcome page.

On the next to last line, there’s another important piece of information: [email protected]:high-sunrise-58.git. This is the Git repository address for your new Heroku app, and if you check the output of git remote show heroku you can see that the heroku gem added it as a remote for you automatically.

Push your application to Heroku

git push heroku master
Counting objects: 65, done.
Compressing objects: 100% (58/58), done.
Writing objects: 100% (65/65), 80.54 KiB, done.
Total 65 (delta 14), reused 0 (delta 0)

-----> Heroku receiving push
-----> Rails app detected
       Compiled slug size is 0.1MB
-----> Launching....... done
       App deployed to Heroku

To [email protected]:high-sunrise-58.git
 * [new branch]      master -> master

Bootstrap your database

Your app is now running on Heroku with an empty database. Depending on your framework, run the appropriate command to set up your DB. For Ruby on Rails, run:

heroku rake db:migrate
(in /mnt/home/slugs/41913_b81cc1e5813c58c443e4120aff984d006f36ef20/mnt)
== 20081118092504 CreateWidgets: migrating ====================================
-- create_table(:widgets)
   -> 0.0519s
== 20081118092504 CreateWidgets: migrated (0.0520s) ===========================

That’s it, your app is now running on Heroku! You can take a look at it in your default web browser by running heroku open.

Next Steps

Now that your application is running, it’s easy to push updates:

Develop and test changes locally.
Commit code to git.
Push your changes to Heroku with git push heroku.

Remove MS Word formatting using PHP regular expressions

Recently i’ve had a client which would only paste into the CMS text from MS Word. Normally a JS should have been in place to automatically strip the crazy tags Word adds, but on this project this was not the case. Here’s hos to remove MS Word formatting using PHP regular expressions:

// it will remove all  comments
preg_replace('//i', '', $string);

or 

// it will remove all  comments
preg_replace('//i', '', $string);

Redirect entire site to another domain, excluding folder

A site i’ve built for a campaign needed to be redirected to another site as the campaign expired, but one folder in the domain needed still to be accessible. htaccess to the rescue:

RewriteEngine on
RewriteRule !^uploads($|/) http://example.com%{REQUEST_URI} [L,R=301]

This rule does match any URL path that does not begin with either /uploads or /uploads/ (leading / is missing in the pattern due to the path prefix removal when used in .htaccess files) and redirects the request to the corresponding path at example.com.

Install native 64bit Flash Player 11 on Linux

Update 3 [30 10 2011]: The script was updated to install of Flash Player 11.2 Beta
Update 2 [7 09 2011]: The script was updated to install rc1 of Flash Player 11
Update 1 [13 08 2011]: The script was updated to install b2 of Flash Player 11

Abobe released yesterday the first beta of Flash Player 11 for Linux 64 bit.

I’ve put together a small script that takes care of installing it on Ubuntu:

#!/bin/bash
# Script  created by
# Romeo-Adrian Cioaba [email protected]

echo "Stopping any Firefox that might be running"
sudo killall -9 firefox

echo "Removing any other flash plugin previously installed:"
sudo apt-get remove -y --purge flashplugin-nonfree gnash gnash-common mozilla-plugin-gnash swfdec-mozilla libflashsupport nspluginwrapper
sudo rm -f /usr/lib/mozilla/plugins/*flash*
sudo rm -f ~/.mozilla/plugins/*flash*
sudo rm -f /usr/lib/firefox/plugins/*flash*
sudo rm -f /usr/lib/firefox-addons/plugins/*flash*
sudo rm -rfd /usr/lib/nspluginwrapper


echo "Installing Flash Player 11"
cd ~
wget 'http://download.macromedia.com/pub/labs/flashplatformruntimes/flashplayer11-2/flashplayer11-2_p1_install_lin_64_102611.tar.gz'
tar zxvf flashplayer11-2_p1_install_lin_64_102611.tar.gz
sudo cp libflashplayer.so /usr/lib/mozilla/plugins/ 
sudo cp -r usr/ /usr

echo "Linking the libraries so Firefox and apps depending on XULRunner (vuze, liferea, rsswol) can find it."
sudo ln -sf /usr/lib/mozilla/plugins/libflashplayer.so /usr/lib/firefox-addons/plugins/
sudo ln -sf /usr/lib/mozilla/plugins/libflashplayer.so  /usr/lib/xulrunner-addons/plugins/

# now doing some cleaning up:
sudo rm -rf libflashplayer.so 
sudo rm -rf usr/
sudo rm -rf flashplayer11-2_p1_install_lin_64_102611.tar.gz

A very interesting application that comes bundled in this release is the “flash-player-properties” app which allows us to finally be able to set permissions to mic/camera on websites.

Magento top navigation show products in category

I had a structure like this in admin

– Category
– – SubCategory1
– – – Product 1
– – – Product 2
– – – Product 3
– – SubCategory2
– – – Product 1
– – – Product 2
– – – Product 3

but the default magento navigation would only list my categories and subcategories, not the products. after a bit of tweaking around i noticed that both SubCategory1 and SubCategory2 are level 1 so i only needed to find a way to display products for those categories. That is done easily by extending /core/Mage/Catalog/Block/Navigation.php into your local (/local/Mage/Catalog/Block/Navigation.php) and replacing the function _renderCategoryMenuItemHtml with the one below:

    protected function _renderCategoryMenuItemHtml($category, $level = 0, $isLast = false, $isFirst = false,
        $isOutermost = false, $outermostItemClass = '', $childrenWrapClass = '', $noEventAttributes = false)
    {
        if (!$category->getIsActive()) {
            return '';
        }
        $html = array();

        // get all children
        if (Mage::helper('catalog/category_flat')->isEnabled()) {
            $children = (array)$category->getChildrenNodes();
            $childrenCount = count($children);
        } else {
            $children = $category->getChildren();
            $childrenCount = $children->count();
        }
        $hasChildren = ($children && $childrenCount);

        // select active children
        $activeChildren = array();
        foreach ($children as $child) {
            if ($child->getIsActive()) {
                $activeChildren[] = $child;
            }
        }
        $activeChildrenCount = count($activeChildren);
        $hasActiveChildren = ($activeChildrenCount > 0);

        // prepare list item html classes
        $classes = array();
        $classes[] = 'level' . $level;
        $classes[] = 'nav-' . $this->_getItemPosition($level);
        if ($this->isCategoryActive($category)) {
            $classes[] = 'active';
        }
        $linkClass = '';
        if ($isOutermost && $outermostItemClass) {
            $classes[] = $outermostItemClass;
            $linkClass = ' class="'.$outermostItemClass.'"';
        }
        if ($isFirst) {
            $classes[] = 'first';
        }
        if ($isLast) {
            $classes[] = 'last';
        }
        if ($hasActiveChildren) {
            $classes[] = 'parent';
        }

        // prepare list item attributes
        $attributes = array();
        if (count($classes) > 0) {
            $attributes['class'] = implode(' ', $classes);
        }
        if ($hasActiveChildren && !$noEventAttributes) {
             $attributes['onmouseover'] = 'toggleMenu(this,1)';
             $attributes['onmouseout'] = 'toggleMenu(this,0)';
        }

        // assemble list item with attributes
        $htmlLi = ' $attrValue) {
            $htmlLi .= ' ' . $attrName . '="' . str_replace('"', '\"', $attrValue) . '"';
        }
        $htmlLi .= '>';
        $html[] = $htmlLi;

        $html[] = '';
        $html[] = '' . $this->escapeHtml($category->getName()) . '';
        $html[] = '';


		// Grabbing the products for the category if it's level is 1
		if ($level == 1) {
		
			$catId = $category->getId();
			$categorie = new Mage_Catalog_Model_Category();
			$categorie->load($catId); // this is category id
			$collection = $categorie->getProductCollection()->addAttributeToSort('name', 'asc');
			$html[] = '
    '; foreach ($collection as $pc) { $p = new Mage_Catalog_Model_Product(); $p->load($pc->getId()); $data = $p->_data; $html[] = '
  • '.$data['name'] .'
  • '; } $html[] = "
\n"; } // Done // render children $htmlChildren = ''; $j = 0; foreach ($activeChildren as $child) { $htmlChildren .= $this->_renderCategoryMenuItemHtml( $child, ($level + 1), ($j == $activeChildrenCount - 1), ($j == 0), false, $outermostItemClass, $childrenWrapClass, $noEventAttributes ); $j++; } if (!empty($htmlChildren)) { if ($childrenWrapClass) { $html[] = '
'; } $html[] = '
    '; $html[] = $htmlChildren; $html[] = '
'; if ($childrenWrapClass) { $html[] = '
'; } } $html[] = ''; $html = implode("\n", $html); return $html; }

The rest of the file stays the same. Note this works on magento > 1.4

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();

Delete test orders in magento 1.4.x

– Reset Magento TEST Data
SET FOREIGN_KEY_CHECKS=0;
– reset dashboard search queries
TRUNCATE `catalogsearch_query`;
ALTER TABLE `catalogsearch_query` AUTO_INCREMENT=1;
– reset sales order info
TRUNCATE `sales_flat_creditmemo`;
TRUNCATE `sales_flat_creditmemo_comment`;
TRUNCATE `sales_flat_creditmemo_grid`;
TRUNCATE `sales_flat_creditmemo_item`;
TRUNCATE `sales_flat_invoice`;
TRUNCATE `sales_flat_invoice_comment`;
TRUNCATE `sales_flat_invoice_grid`;
TRUNCATE `sales_flat_invoice_item`;
TRUNCATE `sales_flat_order`;
TRUNCATE `sales_flat_order_address`;
TRUNCATE `sales_flat_order_grid`;
TRUNCATE `sales_flat_order_item`;
TRUNCATE `sales_flat_order_payment`;
TRUNCATE `sales_flat_order_status_history`;
TRUNCATE `sales_flat_quote`;
TRUNCATE `sales_flat_quote_address`;
TRUNCATE `sales_flat_quote_address_item`;
TRUNCATE `sales_flat_quote_item`;
TRUNCATE `sales_flat_quote_item_option`;
TRUNCATE `sales_flat_quote_payment`;
TRUNCATE `sales_flat_quote_shipping_rate`;
TRUNCATE `sales_flat_shipment`;
TRUNCATE `sales_flat_shipment_comment`;
TRUNCATE `sales_flat_shipment_grid`;
TRUNCATE `sales_flat_shipment_item`;
TRUNCATE `sales_flat_shipment_track`;
TRUNCATE `sales_invoiced_aggregated`;
TRUNCATE `sales_invoiced_aggregated_order`;
TRUNCATE `sales_order_aggregated_created`;
TRUNCATE `sendfriend_log`;
TRUNCATE `tag`;
TRUNCATE `tag_relation`;
TRUNCATE `tag_summary`;
TRUNCATE `wishlist`;
TRUNCATE `log_quote`;
TRUNCATE `report_event`;
ALTER TABLE `sales_flat_creditmemo` AUTO_INCREMENT=1;
ALTER TABLE `sales_flat_creditmemo_comment` AUTO_INCREMENT=1;
ALTER TABLE `sales_flat_creditmemo_grid` AUTO_INCREMENT=1;
ALTER TABLE `sales_flat_creditmemo_item` AUTO_INCREMENT=1;
ALTER TABLE `sales_flat_invoice` AUTO_INCREMENT=1;
ALTER TABLE `sales_flat_invoice_comment` AUTO_INCREMENT=1;
ALTER TABLE `sales_flat_invoice_grid` AUTO_INCREMENT=1;
ALTER TABLE `sales_flat_invoice_item` AUTO_INCREMENT=1;
ALTER TABLE `sales_flat_order` AUTO_INCREMENT=1;
ALTER TABLE `sales_flat_order_address` AUTO_INCREMENT=1;
ALTER TABLE `sales_flat_order_grid` AUTO_INCREMENT=1;
ALTER TABLE `sales_flat_order_item` AUTO_INCREMENT=1;
ALTER TABLE `sales_flat_order_payment` AUTO_INCREMENT=1;
ALTER TABLE `sales_flat_order_status_history` AUTO_INCREMENT=1;
ALTER TABLE `sales_flat_quote` AUTO_INCREMENT=1;
ALTER TABLE `sales_flat_quote_address` AUTO_INCREMENT=1;
ALTER TABLE `sales_flat_quote_address_item` AUTO_INCREMENT=1;
ALTER TABLE `sales_flat_quote_item` AUTO_INCREMENT=1;
ALTER TABLE `sales_flat_quote_item_option` AUTO_INCREMENT=1;
ALTER TABLE `sales_flat_quote_payment` AUTO_INCREMENT=1;
ALTER TABLE `sales_flat_quote_shipping_rate` AUTO_INCREMENT=1;
ALTER TABLE `sales_flat_shipment` AUTO_INCREMENT=1;
ALTER TABLE `sales_flat_shipment_comment` AUTO_INCREMENT=1;
ALTER TABLE `sales_flat_shipment_grid` AUTO_INCREMENT=1;
ALTER TABLE `sales_flat_shipment_item` AUTO_INCREMENT=1;
ALTER TABLE `sales_flat_shipment_track` AUTO_INCREMENT=1;
ALTER TABLE `sales_invoiced_aggregated` AUTO_INCREMENT=1;
ALTER TABLE `sales_invoiced_aggregated_order` AUTO_INCREMENT=1;
ALTER TABLE `sales_order_aggregated_created` AUTO_INCREMENT=1;
ALTER TABLE `sendfriend_log` AUTO_INCREMENT=1;
ALTER TABLE `tag` AUTO_INCREMENT=1;
ALTER TABLE `tag_relation` AUTO_INCREMENT=1;
ALTER TABLE `tag_summary` AUTO_INCREMENT=1;
ALTER TABLE `wishlist` AUTO_INCREMENT=1;
ALTER TABLE `log_quote` AUTO_INCREMENT=1;
ALTER TABLE `report_event` AUTO_INCREMENT=1;
SET FOREIGN_KEY_CHECKS=1;