Saturday
27
February
2010

New features for Zend_Filter_Encrypt

Hy folks,

today I added 2 new features for all who do encryption and decryption with Zend Framework.

* Compression
You can now automatically use compression within the encrypted content. This can become handy when you are encrypting very large content or files.

$filter = new Zend_Filter_Encrypt(array(
    'adapter'     => 'openssl',
    'private'     => '/path/to/mykey/private.pem',
    'public'      => '/public/key/path/public.pem',
    'compression' => 'bz2'
));

Internally it uses Zend_Filter_Compress to reduce the encrypted value.
You can also set other compression options when you define them as array like:

'compression' => array(
    'adapter' => 'zip',
    'target' => 'C:\temp\test.zip'
)

For decryption you must simply set the same compression options as for encryption.
This option works with both encryption adapters.

* Simplified usage
For Openssl I added a simplified usage.

You can now set the package option.
When it is set to true then the envelope keys will be packed to the encrypted values.

So the old usage was:

$filter = new Zend_Filter_Encrypt(array(
    'adapter' => 'openssl',
    'private' => '/path/to/mykey/private.pem',
    'public' => '/public/key/path/public.pem',
));
	
$encrypted = $filter->filter('text_to_be_encoded');
$envelope  = $filter->getEnvelopeKey();
	
---------------------------------
$filter = new Zend_Filter_Decrypt(array(
    'adapter' => 'openssl',
    'private' => '/path/to/mykey/private.pem',
    'public' => '/public/key/path/public.pem',
    'envelope' => $envelope
));
	
$content = $filter->filter($encrypted);

and now you can simplify this by omiting the envelope keys:

$filter = new Zend_Filter_Encrypt(array(
    'adapter' => 'openssl',
    'private' => '/path/to/mykey/private.pem',
    'public' => '/public/key/path/public.pem',
    'package' => true
));
	
$encrypted = $filter->filter('text_to_be_encoded');
	
---------------------------------
$filter = new Zend_Filter_Decrypt(array(
    'adapter' => 'openssl',
    'private' => '/path/to/mykey/private.pem',
    'public' => '/public/key/path/public.pem',
    'package' => true
));
	
$content = $filter->filter($encrypted);

So you need no longer to provide the envelope keys to be able to decrypt the content.
This simplifies the decryption.

Possible negative aspects of this behaviour are:
* A lowering of security by integrating the envelope key into the encrypted value
* The encrypted string will be longer as all envelope keys are integrated

I hope that you find both features usefull for your work.

Greetings
Thomas Weidner
I18N Team Leader, Zend Framework

Zend Framework Advisory Board Member
Zend Certified Engineer for Zend Framework

Back to top
Wednesday
13
January
2010

Boolean filtering

Hy fellows,

another one of my new components has been moved to core…

Zend_Filter_Boolean

You say that you don’t need this filter? You can simply cast to boolean?
Let me describe you why you are wrong.

As you can imagine Zend_Filter_Boolean is a filter. Like all other filters it can be used in combination with other components which allow to add filters on themself. For example Zend_Form, Zend_File, Zend_Dojo and so on…

So far so good.
But what’s the benefit of Zend_Filter_Boolean?

Let’s take a look into examples:

$form->addFilter('Boolean');

Not very exciting…

You think this could also be done by using the following?

$value = (boolean) $form->element->getValue();

Doesn’t look as nice as the above ;-)

Now let’s try something which is not possible by a simple cast. Expect that we’re reading data from database. Our table could could look like this:

Col User | Col Info
---------+---------
patric   | 0
ralph    | 1
thomas   | -1
fred     | false
bruno    | unknown

So 0 would mean “FALSE”, other integers would mean “TRUE”, and anything different would mean “NOT SET”. Still, default is true, so -1 would also point to true. Now the filter within your model would look like this:

$filter = new Zend_Filter_Boolean(Zend_Filter_Boolean::INTEGER);

This would work like a cast, but only on integer values. You may note the “unknown” string in our table.
Now the filtered data would be returned like this:

Col User | Col Info
---------+---------
patric   | FALSE
ralph    | TRUE
thomas   | TRUE
fred     | TRUE
bruno    | unknown

Nice isn’t it? Note the TRUE for fred because we filtered only integers and said that all other types have to be seen as true.

Ok… your model can not act on “unknown”? Also no problem for us. Let’s cast to boolean:

$filter = new Zend_Filter_Boolean(array('type' => Zend_Filter_Boolean::INTEGER, 'casting' => true));

Now our above data would would be returned like this:

Col User | Col Info
---------+---------
patric   | FALSE
ralph    | TRUE
thomas   | TRUE
fred     | TRUE
bruno    | TRUE

As you can see our “unknown” value is casted. But different to a simple case also the value “false” from fred is filtered to “true” because it’s not an integer value.

What could this also used for?
Expect we have an form element with 3 states (3 radiobuttons): “1”, “0” and “don’t know”. And we want to have these 3 states also within our model as “true”, “false” and “-1”. On “-1” we want take another action like opening a subform to show other questions. To make our model simple you could add a boolean filter:

$filter = new Zend_Filter_Boolean(array('type' => Zend_Filter_Boolean::BOOLEAN));

Now we will receive “true”, “false” and “-1” from our form.

Still not fancy enough for you?
Let’s expect you have an online agreement… and your user must enter “yes” and “no” instead of just clicking on a button.
Even this can be done with a single line:

$filter = new Zend_Filter_Boolean(array('type' => Zend_Filter_Boolean::YES));

Now what happens?
Our user enters “Yes” and the filter will then return “true” for your model. And what’s really fancy about this, is that it works on any language:

$filter = new Zend_Filter_Boolean(array('type' => Zend_Filter_Boolean::YES, 'locale' => 'de'));

Now it would work on “Ja” and “Nein”.

Isn’t that cool? ;-)
Ok… now which types are recognised and can be differed by this filter:

Type         |  true  | false   | examples for unrecognised values
             |  when  |  when   | (or true on casting)
-------------+--------+---------+---------------------------------
BOOLEAN      |   TRUE |   FALSE | 1, 0, 'false'
INTEGER      |      1 |       0 | FALSE, 'true', 0.0, 1.2
FLOAT        |    1.0 |     0.0 | TRUE, 1, 0
STRING       |    --- |      '' | TRUE, 0, 1.2, 'false'
ZERO         |    '1' |     '0' | 0, 1, FALSE, 'true'
EMPTY_ARRAY  |    --- | array() | 0, 1.0, TRUE
NULL         |    --- |    NULL | FALSE, 'true', 0
FALSE_STRING | 'true' | 'false' | TRUE, FALSE, 0, '0'
YES          |  'Yes' |    'No' | TRUE, 'false', 0 (localized!)

Note that the last constant YES works on the language you’ve set. ‘Ja’ for german, ‘Si’ for italic and so on.
I am sure that you will find a useful scenario for this feature in your environment ;-)
The benefit to seperate between different types on casting can sometimes be really useful.

For further informations take a look into the manual.
I hope you find my new component for Zend Framework useful in your own application.

Greetings
Thomas Weidner
I18N Team Leader, Zend Framework

Zend Framework Advisory Board Member
Zend Certified Engineer for Zend Framework

Back to top
Sunday
20
September
2009

Compression and Decompression for ZF

With Zend Framework Release 1.10 there will be a way to handle compression and decompression.

The new components Zend_Filter_Compress and Zend_Filter_Decompress provide a unified API for several compression formats.

Actually the formats BZ2, GZ, LZF, RAR, TAR and ZIP are implemented:

You can not only work with Strings, but also with Files and also with complete Directories.
Each format is provided as standalone Adapter. This way we can easily add support for a new compression format by adding a new Adapter.

So let’s go a little bit into details…
To compress a string with BZ2 we would code the following lines:

$filter = new Zend_Filter_Compress('bz2');
$input  = "Uncompressed content";
$output = $filter->filter($input);

$output will have stored the compressed string.
To reverse the output and get the uncompressed string simply do the following:

$filter = new Zend_Filter_Decompress('bz2');
$result = $filter->filter($output);

As you can see compression and decompression is really very simple.

Now when you want to compress and decompress files, it is as simple as compressing strings.
Simply give the filename instead of a string and tell the adapter where to store the archive.

$filter = new Zend_Filter_Compress(array(
    'adapter' => 'bz2'
    'options' => array(
        'archive' => 'myarchive.bz2'
    )
);
$result = $filter->filter('\\path\to\myfile.ext');

The file myfile.ext will be compressed and stored into myarchive.bz2.
You can even compress complete directories. But be aware, that when you do this on the base directory of your server, your server will be stressed for a very long time.

As you can attach this filters to any component which accepts filters, you could very easily compress any given input to store it anywhere else.

Let’s expect you have a textarea element where your costumer provides a book review. To save space you could easily attach this filter to the element and store the compressed string into the database. When you want to display the content to your user again simply decompress it before rendering.

$element = new Zend_Form_Element_TextArea('myarea');
$element->addFilter('Compress', array('zip'));

There are many places where compression or decompression can be useful. In all this cases you can now use Zend_Filter_Compress.

When you find this component useful feel free to use it within your own application.
Have fun with Zend Framework

Greetings
Thomas Weidner
I18N Team Leader, Zend Framework

Zend Framework Advisory Board Member
Zend Certified Engineer for Zend Framework

Back to top