Joakim Nygård Archive Linked About

Zend Framework Validator for Danish VAT Numbers

17 Mar 2009 -

Working on an as of yet unpublished startup, I needed a validator for the Danish CVR numbers issued as part of VAT registration. As the project is written in Zend Framework, I decided to implement the code as an extension of the Zend_Validate_Abstract and share it here.

The validation is based on the specification located at cvr.dk and involves a modulus 11 check on the 8th digit based on a weighted sum of the previous seven. Not particularly interesting but nice to have when working with Danish companies.

<?php
/**
 * Scienta Zend Additions
 *
 * @category   Scienta
 * @package    Scienta_Validate
 * @copyright  Copyright (c) 2008-2009 Joakim Nygård (http://jokke.dk)
 * @version    $Id$
 */

/** Zend_Validate_Abstract */
require_once 'Zend/Validate/Abstract.php';

/** Zend_Filter_Digits */
require_once 'Zend/Filter/Digits.php';

/**
 * A class for validating Danish CVR numbers based on modulo 11
 * @see http://www.cvr.dk/Site/Forms/CMS/DisplayPage.aspx?pageid=60
 * @category   Scienta
 * @package    Scienta_Validate
 * @copyright  Copyright (c) 2008-2009 Joakim Nygård (http://jokke.dk)
 */
class Scienta_Validate_Cvr extends Zend_Validate_Abstract
{
    const INVALID          = 'cvrInvalid';
    const INCORRECT_LENGTH = 'stringLengthNotRight';
    const NOT_DIGITS       = 'notDigits';

    protected $_messageTemplates = array(
        self::INVALID          => "'%value%' is not a valid CVR number",
        self::INCORRECT_LENGTH => "'%value%' does not contain 8 digits",
        self::NOT_DIGITS       => "'%value%' does not contain only digits",
    );

    protected $_cvrWeights = array(2, 7, 6, 5, 4, 3, 2);

    public function isValid($value)
    {
        $valueString = (string) $value;
        $this->_setValue($valueString);
    
        $filter = new Zend_Filter_Digits();
        if ($valueString !== $filter->filter($valueString)) {
            $this->_error(self::NOT_DIGITS);
            return false;
        }
        if (8 != strlen($valueString)) {
            $this->_error(self::INCORRECT_LENGTH);
            return false;
        }
    
        $sum = 0;
        foreach ($this->_cvrWeights as $i => $weight) {
            $sum += $valueString[$i] * $weight;
        }
        $remainder = $sum % 11;
		if($remainder==1){
		    $this->_error(self::INVALID);
		    return false;            
		}
		if($remainder==0)
		    $lastDigit = 0;
		else
		    $lastDigit = 11 - $remainder;
		
        $valid = ($valueString[7] == $lastDigit);

        if ($valid) {
            return true;
        } else {
            $this->_error(self::INVALID);
            return false;
        }
    }
}

Save the above to the file library/Scienta/Validate/Cvr.php with library being the directory containing the Zend framework. The class can then be used to test a number as follows:

$cvrValidator = new Scienta_Validate_Cvr();
if ($cvrValidator->isValid($proposedCvrNumber)) {
    ...
}

One case where testing is needed might be a Zend_Form, in which case the class is easily added as a validator on the appropriate element.

Forever's Not So Long

13 Mar 2009 -

Remarkable new short film by Shawn Morrison and Garrett Murray. Beautiful shots and great acting.

So amazing, so illegal. What are we going to do with you, future?

12 Mar 2009 -

Merlin Mann comments on Kutiman’s amazing Youtube video remixes

…this is what your new Elvis looks like, gang. And, eventually somebody will figure out (and publicly admit) that Kutiman, and any number of his peers on the “To-Sue” list, should be passed from Legal down to A&R.

The Future Is Already Here

5 Mar 2009 -

Great pictures, as always, of robots around the world (many are from Japan) from the Boston Globe’s The Big Picture section.

ToyRacers public beta

3 Mar 2009 -

My brother Stein Nygård just released a public beta of his upcoming toy themed racing game ToyRacers. He has previously developed NapkinRace and the renowned KartingRace. Though still in beta, the game looks impressive. (Windows only at this time)

Impressive Webapp Version of Interface Builder

26 Feb 2009 -

Though I am not convinced that converting every desktop app to a webapp in the cloud is such a clever idea, the work done by 280 North is impressive. This Atlas is the online equivalent of Interface Builder for developing GUIs on the Mac and appears very well done.

Bucket With A View

25 Feb 2009 -

Some weeks ago I linked to a post by Alex Payne called The Case Against Everything Buckets in which he argues that organizational applications such as Yojimbo, Evernote, Together, etc. are a bad idea because they recreate the structuring features of the filesystem. I linked to it because I agree that applications should refrain from recreating existing functionality. Rather they should expand on what is already there.

It has become painfully obvious that the old desktop metaphor just doesn’t cut it for the tens of thousands of photos, thousands of songs and hundreds of documents we all store. They are not practically manageble through the standard interface to the filesystem, Finder (or Explorer on Windows). They are not and should not be clever enough to handle every organizational idea. The Finder, despite critisism, handles hierarchies of files and folder rather well. It should not be extended to make it a photo browser and media player (though I am tremendously happy with Quicklook). So what would work?

As Alex Payne writes:

use software that does one thing well.

This rhymes perfectly with traditional Unix philosophy and to some extent Apple’s approach to software. It makes for simpler applications and with inter-application communication (AppleScript, Automator, Unix pipes, et al.), powerful tasks can be accomplished without reinventing the wheel.

I’ve previously written about my thoughts on extending the file system in One Application to Rule Your Files and the idea fits perfectly with organizational software. Don’t recreate the filesystem – provide a better view to the files thrown in there. Applications like iTunes, Together and Tagbot all provide alternate views to files in this way.

John Gruber wrote a piece on how one problem with saving new documents is that you’re forced to deal with the organizational aspect while you’re still working out the contents. Applications that do away with the traditional save dialog (which I believe to be horribly outdated) encourage the user to create more content.

I think no one would argue against the use of a mail client (be it Thunderbird, Mail.app or mutt) to manage emails. That’s how it has always been and we tend to think of mails not as files on the harddrive but something that belongs inside the client. Yet every mail is stored somewhere on the computer (not webmail obviously).

The point is not to do everything by hand or to manually place every file in relevant folders. Instead we should have applications that do this for us in a way that is both compatible with the underlying filesystem and reveals information on the files that would otherwise be hard to find.

A Validator for URIs in Zend Framework

20 Feb 2009 -

Working with forms in Zend Framework is incredibly easy with the Zend_Form component. In some cases user input from forms contain URIs, e.g. for homepages. Though there is a Zend_Uri class, the corresponding Validator is missing. Here’s a validator I wrote some time ago:

<?php
/**
 * Scienta Zend Additions
 *
 * @category   Scienta
 * @package    Scienta_Validate
 * @copyright  Copyright (c) 2008-2009 Joakim Nygård (http://jokke.dk)
 * @version    $Id$
 */

/** Zend_Validate_Abstract */
require_once 'Zend/Validate/Abstract.php';

/** Zend_Uri */
require_once 'Zend/Uri.php';

/**
 * @category   Scienta
 * @package    Scienta_Validate
 * @copyright  Copyright (c) 2008-2009 Joakim Nygård (http://jokke.dk)
 */
class Scienta_Validate_Uri extends Zend_Validate_Abstract
{
    const INVALID = 'uriInvalid';

    protected $_messageTemplates = array(
        self::INVALID => "'%value%' is not a valid uri",
    );

    public function isValid($value)
    {
        $this->_setValue($value);
    
        $valid = Zend_Uri::check($value);
    
        if ($valid) {
            return true;
        } else {
            $this->_error(self::INVALID);
            return false;
        }
    }
}

Save the above to the file library/Scienta/Validate/Uri.php with library being the directory with the Zend framework. It can then be used on a form element as follows:

$element->addValidator(new Scienta_Validate_Uri());

The Crisis of Credit Visualized

20 Feb 2009 -

Excellent video by Jonathan Jarvis explaining the credit crisis and why it happened in clear terms.

Webgrind 1.0 Released

20 Feb 2009 -

The PHP Xdebug profiling tool I wrote with Jacob Oettinger has been bumped to version 1.0. There’s a new ability to click on function names in the call info list, very useful for backtracing expensive calls.

Archive