View Source

<ac:macro ac:name="unmigrated-inline-wiki-markup"><ac:plain-text-body><![CDATA[{zone-template-instance:ZFPROP:Proposal Zone Template}

{zone-data:component-name}
Zend_Validate_Uuid
{zone-data}

{zone-data:proposer-list}
[Stephan Wentz|mailto:swentz@brainbits.net]
{zone-data}

{zone-data:liaison}
TBD
{zone-data}

{zone-data:revision}
1.0 - 2 February 2010: Initial Draft.
{zone-data}

{zone-data:overview}
Zend_Validate_Uuid is a component that validates 36-character UUIDs (Universally Unique Identifiers).
{zone-data}

{zone-data:references}
* [UUID Wikipedia Entry|http://en.wikipedia.org/wiki/UUID]
* [RFC 4122|http://tools.ietf.org/html/rfc4122]
* [UUID PECL extension|http://pecl.php.net/package/uuid]
{zone-data}

{zone-data:requirements}
* This component *will* check if a string is a valid UUID.
* This component *will* use the uuid PECL extension if it is available
* This component *will* validate 36-character UUIDs.
* This component *will* will return true if the string is a valid UUID.
* This component *will* will ignore case.
* This component *will* will return false on wrong length
* This component *will* will return false on invalid chars (valid is 0-9a-z)
* This component *will* will return false on wrong positioned hyphens for 36 character UUIDs

{zone-data}

{zone-data:dependencies}
* Zend_Validate_Abstract
{zone-data}

{zone-data:operation}
The component is instantiated to validate UUID strings.
{zone-data}

{zone-data:milestones}
* Milestone 1: [DONE] write proposal
* Milestone 2: Get community feedback
* Milestone 3: Get the proposal approved
* Milestone 4: Working prototype checked into the incubator supporting use cases #1, #2
* Milestone 5: Unit tests exist, work, and are checked into SVN.
* Milestone 6: Initial documentation exists.
{zone-data}

{zone-data:class-list}
* Zend_Validate_Uuid
{zone-data}

{zone-data:use-cases}
{composition-setup}
{deck:id=Usecases}

{card:label=UC-01 basic usage}
{code}
<?php

// basic usage
require_once 'Zend/Validate/Uuid.php';

$validator = new Zend_Validate_Uuid();

$validator->isValid('4b4bbd09-4b28-40e0-8160-526bc0a8012e'); // true
$validator->isValid('4B4BBD09-4B28-40E0-8160-526BC0A8012E'); // true

$validator->isValid('4B4BBD09-4B28-40E0-8160-526BC0A8012'); // false (not 36 characters)
$validator->isValid('Z4b4bbd0-4b28-40e0-8160-526bc0a8012e'); // false (not 0-9a-z)
$validator->isValid('4b4bbd-094b28-40e0-8160-526bc0a8012e'); // false (wrong position of hyphen)
{code}
{card}

{card:label=UC-02 zend filter input usage}
{code}
<?php

$data = array('id' => '4b4bbd09-4b28-40e0-8160-526bc0a8012e');

$filters = array(
'*' => array('StringTrim','StripTags'),
);

$validators = array(
'id' => array('Uuid'),
);

require_once 'Zend/Filter/Input.php';
$input = new Zend_Filter_Input($filters, $validators, $data);

if ($input->hasInvalid() || $input->hasMissing()) {
// has invalid
echo "The following field(s) are missing or invalid: " . join(', ', array_keys($input->getMessages())) . PHP_EOL;
require_once 'Zend/Debug.php';
Zend_Debug::dump($input->getMessages());
} else {
// valid
echo "Input data is valid." . PHP_EOL;
}
{code}
{card}
{deck}
{zone-data}

{zone-data:skeletons}
{composition-setup}
{deck:id=Skeletons}

{card:label=Zend_Validate_Uuid}
{code}
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Validate
* @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id$
*/

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

/**
* @category Zend
* @package Zend_Validate
* @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Validate_Uuid extends Zend_Validate_Abstract
{
/**
* Validation failure message key for when the value contains non-alphabetic
* or non-digit characters
*/
const NOT_UUID = 'notUuid';

/**
* Validation failure message key for when the value is an empty string
*/
const STRING_EMPTY = 'stringEmpty';

/**
* Validation failure message template definitions
*
* @var array
*/
protected $_messageTemplates = array(
self::NOT_UUID => "'%value%' is not a valid UUID",
self::STRING_EMPTY => "'%value%' is an empty string"
);

/**
* Sets default option values for this instance
*
* @return void
*/
public function __construct()
{
}

/**
* Defined by Zend_Validate_Interface
*
* Returns true if and only if $value contains a valid UUID
*
* @param string $value
*
* @return boolean
*/
public function isValid($value)
{
$value = (string) $value;

$this->_value = $value;

// check if string is empty
if (!strlen($value)) {
$this->_error(self::STRING_EMPTY);
return false;
}

if (function_exists('uuid_is_valid') && !uuid_is_valid($value))
{
$this->_error(self::NOT_UUID);
return false;
}

// check length
if (strlen($value) !== 36) {
$this->_error(self::NOT_UUID);
return false;
}

// are there some invalid characters
$pattern = '/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i';
if (!preg_match($pattern, $value)) {
$this->_error(self::NOT_UUID);
return false;
}

return true;
}
}
{code}
{card}

{card:label=Zend_Validate_UuidTest}
{code}
<?php

/**
* Zend Validate Uuid Test
*/
final class Zend_Validate_UuidTest extends PHPUnit_Framework_TestCase
{
/**
* @var Zend_Validate_Uuid
*/
protected $_validator;

/**
* @var string
*/
protected $_uuid;

/**
* Prepares the environment before running a test.
*/
protected function setUp() {

// call parent
parent::setUp();

// create uuid validator
$this->_validator = new Zend_Validate_Uuid(true);

// valid uuid
$this->_uuid = '4b4bbd09-4b28-40e0-8160-526bc0a8012e';
}

/**
* Cleans up the environment after running a test.
*/
protected function tearDown() {

// cleanup
$this->_validator = null;
$this->_uuid = null;

// call parent
parent::tearDown();
}

public function testConstructorAndIsValid() {
// constructor creates long format validator
$default = new Zend_Validate_Uuid();
$this->assertTrue($default->isValid($this->_uuid));
}

public function testEmptyMessage()
{
// check error message: STRING_EMPTY
$this->assertFalse($this->_validator->isValid(''));

$errors = (array) $this->_uuid->getErrors();
$this->assertSame(Zend_Validate_Uuid::STRING_EMPTY, $errors[0]);
$this->assertSame(1, count($errors));
}

public function testNotUuidMessage()
{
// check error message: NOT_UUID
$invalid = 'adaiosdjasoidjaio';
$this->assertFalse($this->_validator->isValid($invalid));

$errors = (array) $this->_validator->getErrors();
$this->assertSame(Zend_Validate_Uuid::NOT_UUID, $errors[0]);
$this->assertSame(1, count($errors));

$messages = $this->_validator->getMessages();
$this->assertContains($invalid, $messages[Zend_Validate_Uuid::NOT_UUID]);
}

public function testIsValid() {

// simple test
$this->assertTrue($this->_validator->isValid($this->_uuid));

// uppercase
$this->assertTrue($this->_validator->isValid(strtoupper($this->_uuid)));

// empty string
$this->assertFalse($this->_validator->isValid(''));

// too short & too long
$this->assertFalse($this->_validator->isValid('12345678901234567890123456789012345'));
$this->assertFalse($this->_validator->isValid('1234567890123456789012345678901234567'));

// check invalid
$invalid = '12345!78-1234-1234-1234-123456789012';
$this->assertFalse($this->_validator->isValid($invalid));

$invalid = '12345678-12!4-1234-1234-123456789012';
$this->assertFalse($this->_validator->isValid($invalid));

$invalid = '12345678-1234-1!34-1234-123456789012';
$this->assertFalse($this->_validator->isValid($invalid));

$invalid = '12345678-1234-1234-1!34-123456789012';
$this->assertFalse($this->_validator->isValid($invalid));

$invalid = '12345678-1234-1234-1234-123!56789012';
$this->assertFalse($this->_validator->isValid($invalid));

// check part length
$invalid = '1234567-01234-1234-1234-123456789012';
$this->assertFalse($this->_validator->isValid($invalid));

$invalid = '12345678-123-01234-1234-123456789012';
$this->assertFalse($this->_validator->isValid($invalid));

$invalid = '12345678-1234-123-01234-123456789012';
$this->assertFalse($this->_validator->isValid($invalid));

$invalid = '12345678-1234-1234-123-0123456789012';
$this->assertFalse($this->_validator->isValid($invalid));

// check parts count
$invalid = '1234567801234-1234-1234-123456789012';
$this->assertFalse($this->_validator->isValid($invalid));

$invalid = '123-5678-1234-01234-1234-123456789012';
$this->assertFalse($this->_validator->isValid($invalid));
}
}
{code}
{card}
{deck}
{zone-data}

{zone-template-instance}]]></ac:plain-text-body></ac:macro>