When setting your Zend Form with Select field you don’t always wish to have label on that filed but rather “Select one” as a first option.

Setting the required flag on Zend Select, or adding notEmpty validator won’t always work especially if your box is being populated dynamically.

Let’s say you have something like this:

<select name="example">
    <option value="Select one">Select one</option>
    <option value="value1">value1</option>
    <option value="value2">value2</option>
    <option value="value3">value3</option>
</select>

You could easily validate this by adding Zend_Validate_Regex and passing any pattern to it
as follows in snippet:

$select->addValidator(new Zend_Validate_Regex( '/[^Select\sone]/' ))
    ->addErrorMessage('You need to select one value');

This one will check if the value is not “Select one” and let your user pass validation only in that case.

PHP fluent interface

In: PHP

23 Nov 2011

PHP fluent interfaces have been around for quite some time. They are often used just for chaining methods of an object so that we get nice readable code.

Good fluent interface takes a while to build, and will take some planning to make object methods work seamlessly. However, if you still haven’t experienced the PHP fluent interface, there is a good way to start, just check out the following snippet.

class Php_Fluent_Interface_Demo {
    protected $_first;
    protected $_second;
    protected $_third;
 
    public function setFirst($firstVal) {
        $this->_first = $firstVal;
        return $this;
    }
 
    public function setSecond($secondVal) {
        $this->_second = $secondVal;
        return $this;
    }
 
    public function setThird($thirdVal) {
        $this->_third = $thirdVal;
        return $this;
    }
}

You have noticed that all setters have one line in common return $this; and this is how you set your methods to be able to chain. Example of usage follows in next snippet:

$phpFluentInterface = new Php_Fluent_Interface_Demo();
$phpFluentInterface->setFirst(1)
    ->setSecond(2)
    ->setThird(3);

I hope that this simple example is enough to get you started if you still haven’t tried PHP fluent interface. Good luck!

CSRF or Cross-Site Request Forgery is basically a way of requesting an unauthorized commands from a website by using an authorised user.

For example: Let’s assume that you are logged in on your blog and I know that. I could then send you an e-mail with following content: <img src=”http://yoursite.com/?action=delete-article&id=12″ />.

Although you wouldn’t see the image – request for deleting article with id 12 would be sent. This can be prevented by setting up a hidden input in your Zend Framework form with a value that will be posted with your request and validated when request is sent in order to prevent possible CSRF attack.

It is quite easy in Zend Framework to set CSRF protection and here is the snippet:

$form->addElement('hash', 'csrf_token',
            array('salt' => get_class($this) . 'stunt@c0d3rs~!'));

In order to see a full example of Zend Framework CSRF protection I have prepared an example of simple form with no elements on it.

Zend Framework CSRF protection

class Stunt_Form extends Zend_Form
{
    public function init()
    {
        parent::init();
        $this->addElement('hash', 'csrf_token',
                    array('salt' => get_class($this) . 'stunt@c0d3rs~!'));
    }
}

CSS horizontal menu

In: CSS

22 Jun 2011

This is a snippet of simple CSS horizontal menu. First of all – we’re going to create a HTML structure for our CSS horizontal menu. Here it is:

<ul id="nav">
    <li><a href="#">Magazine</a></li>
    <li class="active"><a href="#">Snippets</a></li>
    <li><a href="#">Portfolio</a></li>
    <li><a href="#">Contact</a></li>
</ul>

Now – our CSS horizontal menu it looks like a regular list so let’s style it with some CSS:

#nav {
    min-height:48px;
    box-shadow:0 0 5px #0099cc;
    background: #eee;
    display:block;
    margin:15px 0;
    padding:0 10px;
}
#nav li {
    float: left;
    padding: 15px 20px;
    list-style: none;
    background: transparent;
}
#nav li:hover {
    background: #f8f8f8;
}
#nav li.active {
    background: #f8f8f8;
}
#nav a {
    font-size: 16px;
}

Finally – we got ourselves one nice CSS horizontal menu which we can implement easily to our website. Here is the demo:

CSS3 inner shadow

In: CSS

19 Apr 2011

Ever wondered how to make CSS3 inner shadow? Quite easy actually! Take a look at this CSS3 inner shadow snippet, and example below it.

-moz-box-shadow: inset 0 4px 6px rgba(0,0,0,.4);
-webkit-box-shadow: inset 0 4px 6px rgba(0,0,0,.4);
 box-shadow: inset 0 4px 6px rgba(0,0,0,.24);

Example of CSS3 inner shadow

CSS3 inner shadow

I hope you’ll enjoy using this snippet to make nice effects with CSS3 inner shadow on your website.

Have you ever wondered if you could let user see his website visits on his own admin page without having to leave backend of his system? I have…

Actually – the CMS I made for my clients (written in Zend Framework) has this option for quite some time, and users love it.

So – in order to implement this function on your own website (written in Zend Framework) I have shared following code. First – copy model:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
class Default_Model_Analytics
{ 
 
	public function auth()
	{
		$email = "your_email@domain.com";
		$passwd = "your_password";
 
		try {
			$client = Zend_Gdata_ClientLogin::getHttpClient($email, $passwd, "analytics");
		}catch (Zend_Gdata_App_CaptchaRequiredException $cre) {
			echo 'URL of CAPTCHA image: ' . $cre->getCaptchaUrl() . "\n";
			echo 'Token ID: ' . $cre->getCaptchaToken() . "\n";
			return null;
		} catch (Zend_Gdata_App_AuthException $ae) {
			echo 'Problem authenticating: ' . $ae->exception() . "\n";
			return null;
		}
 
		return new Zend_Gdata($client);
	}
 
	public function fetch($gdClient, $startDate = '2010-07-01', $endDate = null, $dimensions = array("ga:region", "ga:city"), $metrics = array("ga:visits", "ga:pageviews"))
	{
		if(empty($gdClient)) return false;
		if(empty($endDate)) $endDate = date('Y-m-d');
 
		try {
			$reportURL	=	"https://www.google.com/analytics/feeds/data?ids=ga:" . $yourAccountNumber . "&" .
							"dimensions=" . @implode(",", $dimensions) . "&" .
							"metrics=" . @implode(",", $metrics) . "&" .
							"start-date={$startDate}&" .
							"end-date={$endDate}&" .
							"sort=-ga:visits";
 
			$results = $gdClient->getFeed($reportURL);
			$titleRow = 1; // To output a row of column labels
			echo '<table>';
			foreach ($results as $rep) {
				if ($titleRow) {
					foreach ($rep->extensionElements as $elem) {
						$titles[] = $elem->extensionAttributes["name"]["value"];
					}
					echo "<tr><td>" . implode("</td><td>", $titles) . "</td></tr>\n";
					$titleRow = 0;
				}
				$row = array();
				foreach ($rep->extensionElements as $elem) {
					$row[] = $elem->extensionAttributes["value"]["value"];
				}
				echo "\t<tr>\n\t\t<td>" . implode("</td><td>", $row) . "</td>\n\t</tr>\n";
			}
			echo '</table>';
		} catch (Zend_Exception $e) {
			echo "Caught exception: " . get_class($e) . "\n";
			echo "Message: " . $e->getMessage() . "\n";
		}
	}
}

Then – run following code in your controller so user can see Analytics results:

1
2
3
4
5
6
7
8
$analyticsModel = new Default_Model_Analytics();
//get: date start and date end of Analytics results
$postParams = $this->getRequest()->getParams();
 
if($this->getRequest()->isPost()) {
    $gdata = $analyticsModel->auth();
    $analyticsModel->fetch($gdata, $postParams['year1'] . '-' . $postParams['month1'] . '-01', $postParams['year2'] . '-' . $postParams['month2'] . '-31');
}

Notice: This is not the proper way to write code in Zend Framework, but is used as an example.

When making a multilingual application programmers usually find themselves in a bit of a problem when having need to translate things in JavaScript as those JavaScript files are usually separated from PHP so they can’t call translate function for this purpose. To solve this problem I have created JavaScript translate class, so please check following snippet to find how to define JavaScript translate class:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var javaScriptTranslate = function() {
    var translations = {};
 
    return {
        translate: function(text) {
            if(typeof translations[text] === 'undefined') {
                return text;
            } else {
                return translations[text];
            }
        },
        init: function(translationArray) {
            translations = translationArray;
        }
    };
}();

After you have defined your JavaScript translate class you need to load list of translations (usually saved as PHP array, and if not – convert it to PHP array):

1
javaScriptTranslate.init(<?php echo json_encode($translation); ?>);

Now – all you have to do is call function translate from javaScriptTranslate class and you’ll find it really easy. See for yourself in following snippet:

1
alert(javaScriptTranslate.translate('Hello dear friend - I am JavaScript translate class'));

Notice: Your PHP value of variable $translation should be an associative array where key is value you are translating and value is translation of desired value. Example for German translation in this snippet would be following:

1
2
3
4
$translation = array(
   'Hello dear friend - I am JavaScript translate class' => 
      'Hallo lieber Freund - ich bin JavaScript übersetzen Klasse'
);

So, there is a simple way to access the running Magento session from outside the installation folder. The magic happens here:

1
2
3
4
5
6
7
8
9
10
11
12
$mageFilename = realpath(‘mymagentoshop/app/Mage.php’);
require_once( $mageFilename );
umask(0);
 
Mage::app();
Mage::getSingleton(‘core/session’, array(‘name’ => ‘frontend’));
$session = Mage::getSingleton(‘customer/session’);
 
if($session->isLoggedIn())
   echo ‘LOGGED IN’;
else
   echo ‘NOT LOGGED IN’;

The line 5 presents the Magento initialization, and from there you can call any Magento core API functions and procedures. In order for session to work properly (as one) in both sites, you need to retrieve it, and that is exactly what is done on the lines 6 (for the core session) and 7 (for the customer session). Later in our example we’re checking whether the customer is logged in or not, but you can do whatever you want!

Oh yes, on more thing – Use SID on Frontend setting in the Magento admin (System -> Configuration -> Web -> Session Validation Settings) MUST be set to YES, otherwise it won’t work.

Sometimes you really want to refresh page when using jQuery events. So – in order to refresh page on event (in this case click) use following snippet and reload current page.

1
2
3
jQuery('#refresh-link').click(function() {
        location.reload();
});

Suppose you have to access your Magento session from outside the Magento system (and it’s folders), and also, you want to put some relevant data into session and retrieve it on the other side. The following procedure on the Magento side will allow you to do that:

1
Mage::getSingleton('core/session')->setMyData('exampleString');

where MyData is the name of your attribute, and you will retrieve it with getMyData. Here, you can use any name you wish, but try to avoid names which can collide with the existing API and reserved words.

On the other side you can access the session and get the data with the following code:

1
2
3
4
5
6
7
$mageFilename = realpath('MageShop/app/Mage.php');
require_once( $mageFilename );
umask(0);
 
Mage::app();
$session = Mage::getSingleton('core/session', array('name' => 'frontend'));
$data= $session ->getMyData(true);

On the line 1 the access to the main Magento folder is required, so here you either specify relative or absolute path to the Mage.php. The parameter true on the line 7 function call is the flag for “retrieve and remove from session” .