Robert Basic's blog

Archives for December, 2008

Styling the default Zend_Form layout

by Robert Basic on December 22, 2008.
Heads-up! You're reading an old post and the information in it is quite probably outdated.

Here’s an example for styling Zend_Form’s default layout. The default layout is using definition lists. While there’s an option for changing the default layout, the wrapper tags and stuff, I see no reason for it. Create the form, add some CSS and your good to go :)

Note: Be sure to provide a Document Type in your view scripts like this:

<?php
<?= $this->doctype('XHTML1_STRICT') ?>

because when the form is generated, ZF is looking at the doctype to see how to create the form elements. Forgetting the doctype will probably generate invalid markup. I learned the hard way. Don’t do the same mistake, k? :)

The generated markup

So, here’s what Zend_Form makes for us (this markup is after submitting the form, but whit generated error, to show the error markup, too):

<form enctype="application/x-www-form-urlencoded" method="post" action="">
<dl class="zend_form">
    <dt>
        <label for="input1" class="required">Input field #1:</label>
    </dt>
    <dd>
        <input type="text" name="input1" id="input1" value="" />
        <ul class="errors">
            <li>Value is empty, but a non-empty value is required</li>
        </ul>
        <p class="description">Description? Yes, please.</p>
    </dd>
    <dt>
         
    </dt>
    <dd>
        <input type="submit" name="submit" id="submit" value="Submit form" />
    </dd>
</dl>
</form>

The PHP code which generates this form (without the error, of course) goes like this:

<?php
$input1 = new Zend_Form_Element_Text('input1');
$input1->setLabel('Input field #1:')
          ->setDescription('Description? Yes, please.')
          ->setRequired(true);

$submit = new Zend_Form_Element_Submit('submit');
$submit->setLabel('Submit form')

$form = new Zend_Form();
$form->setMethod('post')
       ->addElement($input1)
       ->addElement($submit);

Now, the generated form looks kinda good with no styling (which is good, if some maniac comes to visit with CSS support disabled).

OK, I lie: there’s a minimum of CSS for setting the background to white and the width to 460 pixels.

As you can see I’ve shortened the HTML and the PHP in the example codes…

The styling

I like my forms a bit different: form elements and their labels side by side with element descriptions and eventual errors showing up under the element. Here’s the CSS to achieve this:

.zend_form{
background:#fff;
width:460px;
margin:5px auto;
padding:0;
overflow:auto;
}

.zend_form dt{
padding:0;
clear:both;
width:30%;
float:left;
text-align:right;
margin:5px 5px 5px 0;
}

.zend_form dd{
padding:0;
float:left;
width:68%;
margin:5px 2px 5px 0;
}

.zend_form p{
padding:0;
margin:0;
}

.zend_form input, .zend_form textarea{
margin:0 0 2px 0;
padding:0;
}

.submit{
float:right;
}

.required:before{content:'* '}

.optional:before{content:'+ '}

Of course, this CSS takes care only of the layout; things like font types and sizes, colors, borders, backgrounds, etc. are not essential for this.

So, with this CSS applied to the generated Zend_Form, you can see on the image what will come up. And you know what’s the best part? It’s good for Firefox, Internet Explorer 6, Chrome and Opera, both under Windows and GNU/Linux (sorry, not tested for Internet Explorer 7 and Safari, but they should play along as well).

I almost forgot: I added a class=“submit” to the submit button, to be able to float it right. I first tried to do that with input[type=submit], but IE doesn’t know that, and as I wanted to make a styling that looks (almost) the same in all browsers with no hacks, I decided to add the class attribute.

So there, this little CSS code snippet should get you started with styling your Zend Form’s.

Cheers!

Tags: css, example, form, framework, layout, style, styling, zend.
Categories: Development, Programming.

Data filtering with PHP's Filter extension

by Robert Basic on December 15, 2008.
Heads-up! You're reading an old post and the information in it is quite probably outdated.

Today I was catching up on feeds and one of the articles lead me to GoPHP5.org, where I spent some time lurking. In the FAQ section of that site one sentence made me curios:

The Filter extension is a new security component in PHP.

Filter extension? Maybe it’s nothing new for some of you, but it is for me. I’ve never heard of it before. So I quickly hopped over to PHP.net and the Filter chapter of the manual.

The filter extension is an extension that comes by default in PHP 5.2. It is here to help us to “validate and filter data that comes from insecure sources, such as user input”. It can validate integers, booleans, floats, regular expressions, URLs, E-Mails and IPs. It can sanitize strings, integers, floats, URLs, E-Mails…

Examples

Here are some examples about what this extension is capable of. Lets assume that we get some data from a form with POST method. The 3 input fields are name, email and age (I’m not creating a real validator, but var_dump-ing the results of the filtering, to show what filter gives what kind of output).

<?php
// $_POST['name'] = "Robert <b>hello</b>";
var_dump(filter_input(INPUT_POST, 'name', FILTER_SANITIZE_STRING));
// Output: string(12) "Robert hello"

// $_POST['email'] = "mail@example.com";
var_dump(filter_input(INPUT_POST, 'name', FILTER_VALIDATE_EMAIL));
// Output: string(16) "mail@example.com"

// $_POST['age'] = "22";
var_dump(filter_input(INPUT_POST, 'age', FILTER_VALIDATE_INT,
                        array('options' => array('min_range' => 18,
                                                'max_range' => 28)
                        )));
// Output: int(22)

With the first filter I’m using the FILTER_SANITIZE_STRING which strips down all tags and unwanted characters from our string. The second filter validates the provided E-mail address: pass it a malformed E-mail address and it will result with a boolean false. The third filter validates the age: it must be an integer and in the range between 18 and 28 (the min and max ranges are optional, I added them just for the example).

Besides input filtering it can filter variables, too:

<?php
$string = "Some funky string with <b>html</b> code and 'quotes'";
var_dump(filter_var($string, FILTER_SANITIZE_STRING));
// Output: string(53) "Some funky string with html code and 'quotes'"
// NOTE: the single quotes in the output are encoded as &#39;

var_dump(filter_var($string, FILTER_SANITIZE_MAGIC_QUOTES));
// Output: string(54) "Some funky string with html code and \'quotes\'"
// NOTE: the <b></b> html tags are NOT stripped in the output

var_dump(filter_var($string, FILTER_SANITIZE_ENCODED));
// Output: string(80) "Some%20funky%20string%20with%20%3Cb%3Ehtml%3C%2Fb%3E%20code%20and%20%27quotes%27"

Play around with it, get familiar, cause this is one nice extension that will help you make more secure web sites and web apps.

Cheers!

Tags: data, example, filter, input, php, secure.
Categories: Development, Programming.

MyUrl view helper for Zend Framework

by Robert Basic on December 02, 2008.
Heads-up! You're reading an old post and the information in it is quite probably outdated.

I started writing some boring introduction but I’ll just skip to the point.

The problem

Zend Framework’s built in URL view helper — Zend_View_Helper_Url — is discarding the query string of the URL, thus breaking some links.

Example: If I’m on a page like:
http://project/foo/bar/?param1=value1
and in the bar.phtml I use the Url helper like this:

<?php
<?= $this->url(array('param2' => 'value2')); ?>

I expect this:
http://project/foo/bar/param2/value2/?param1=value1
or something similar to this. This would be just perfect:
http://project/foo/bar/param1/value1/param2/value2
But no, it gives:
http://project/foo/bar/param2/value2/

The solution

After working on several workarounds, currently this is the best one I can think of — take the link that is created by the built-in Url helper and add the query string on that link:

<?php

// Usage:
// <?= $this->myUrl($this->url(array('param2' => 'value2'))); ?>
// Output:
// http://project/controller/action/param2/value2/?param1=value1
class Zend_View_Helper_MyUrl
{
    public function myUrl(&$url, &$toAdd = array())
    {
        $requestUri = Zend_Controller_Front::getInstance()->getRequest()->getRequestUri();
        $query = parse_url($requestUri, PHP_URL_QUERY);
        if($query == '')
        {
            return $url;
        }
        else if(empty($toAdd))
        {
            return $url . '/?' . $query;
        }
        else
        {
            $toAdd = (array)$toAdd;
            $query = explode("&", $query);

            $add = '/?';

            foreach($toAdd as $addPart)
            {
                foreach($query as $queryPart)
                {
                    if(strpos($queryPart, $addPart) !== False)
                    {
                        $add .= '&' . $queryPart;
                    }
                }
            }
            return $url . $add;
        }
    }
}

The second parameter, $toAdd, should be an array of parameters that we want to add to the URL. Say, if I have a query string like:
?param1=value1&someotherparam=anditsvalue
but want only to add the param1=value1 to the URL, I would pass “param1” as the second parameter. Not passing anything as the second parameter will result in adding the complete query string to the URL.

This is an ugly hack to make ugly links work, but it works. Thoughts?

Cheers!

Tags: example, framework, helper, link, php, url, view, zend.
Categories: Development, Programming.