From eeeee7b49b5ee4330481d0edf8feb2775bde29e4 Mon Sep 17 00:00:00 2001 From: phpnut Date: Mon, 20 Aug 2007 01:58:44 +0000 Subject: [PATCH] Implementing automatic UUID for primary keys if the field is CHAR(36). Stripped out old code from NeatString. Added String:uuid(); Renamed neat_string.test.php. Added test for UUID generation. git-svn-id: https://svn.cakephp.org/repo/branches/1.2.x.x@5552 3807eeeb-6ff5-0310-8944-8be069107fe0 --- cake/bootstrap.php | 1 + cake/libs/model/model.php | 10 ++ cake/libs/string.php | 104 +++++++++--------- .../{neat_string.test.php => string.test.php} | 22 +++- 4 files changed, 80 insertions(+), 57 deletions(-) rename cake/tests/cases/libs/{neat_string.test.php => string.test.php} (62%) diff --git a/cake/bootstrap.php b/cake/bootstrap.php index 03d14624f..1a9a5bdb5 100644 --- a/cake/bootstrap.php +++ b/cake/bootstrap.php @@ -44,6 +44,7 @@ if (!defined('PHP5')) { require LIBS . 'cache.php'; require LIBS . 'session.php'; require LIBS . 'security.php'; + require LIBS . 'string.php'; if (isset($cakeCache)) { $cache = 'File'; diff --git a/cake/libs/model/model.php b/cake/libs/model/model.php index 215129cdc..f431a9137 100644 --- a/cake/libs/model/model.php +++ b/cake/libs/model/model.php @@ -1048,6 +1048,16 @@ class Model extends Overloadable { $success = false; } } else { + foreach ($this->_tableInfo->value as $key => $value) { + if(in_array($this->primaryKey, $value)) { + if($this->_tableInfo->value[$key]['type'] === 'string' && $this->_tableInfo->value[$key]['length'] === 36) { + $fields[] = $this->primaryKey; + $values[] = String::uuid(); + } + break; + } + } + if (!$db->create($this, $fields, $values)) { $success = $created = false; } else { diff --git a/cake/libs/string.php b/cake/libs/string.php index 59b71ee10..73571e618 100644 --- a/cake/libs/string.php +++ b/cake/libs/string.php @@ -3,7 +3,6 @@ /** * String handling methods. * - * Random passwords, splitting strings into arrays, removing Cyrillic characters, stripping whitespace. * * PHP versions 4 and 5 * @@ -29,68 +28,67 @@ /** * String handling methods. * - * Random passwords, splitting strings into arrays, removing Cyrillic characters, stripping whitespace. * * @package cake * @subpackage cake.cake.libs */ -class NeatString{ +class String extends Object { /** - * Returns an array with each of the non-empty characters in $string as an element. + * Gets a reference to the String object instance * - * @param string $string String to split - * @return array An array where each element is a non empty character + * @return object String instance * @access public * @static */ - function toArray($string) { - $split = preg_split('//', $string, -1, PREG_SPLIT_NO_EMPTY); - return $split; - } -/** - * Returns string with Cyrillic characters translated to Roman ones. - * - * @param string $string String to translate - * @return string String with cyrillic chracters translated - * @access public - * @static - */ - function toRoman($string) { - $pl = array('ą','ć','ę','ł','ń','ó','ś','ź','ż','Ą','Ć','Ę','�?','Ń','Ó','Ś','Ź','Ż'); - $ro = array('a','c','e','l','n','o','s','z','z','A','C','E','L','N','O','S','Z','Z'); - $replace = str_replace($pl, $ro, $string); - return $replace; - } -/** - * Returns string as lowercase with whitespace removed. - * - * @param string $string String to convert - * @return string Converted string - * @access public - * @static - */ - function toCompressed($string) { - $whitespace = array("\n", " ", "\r", "\0", "\x0B", " "); - $replace = strtolower(str_replace($whitespace, '', $string)); - return $replace; - } -/** - * Returns a random password. - * - * @param integer $length Length of generated password - * @param string $available_chars List of characters to use in password - * @return string Generated password - * @access public - * @static - */ - function randomPassword($length, $available_chars = 'ABDEFHKMNPRTWXYABDEFHKMNPRTWXY23456789') { - $chars = preg_split('//', $available_chars, -1, PREG_SPLIT_NO_EMPTY); - $char_count = count($chars); - $out = ''; - for ($ii = 0; $ii < $length; $ii++) { - $out .= $chars[rand(1, $char_count)-1]; + function &getInstance() { + static $instance = array(); + + if (!isset($instance[0]) || !$instance[0]) { + $instance[0] =& new String(); } - return $out; + return $instance[0]; + } +/** + * Generate a random UUID + * + * @see http://www.ietf.org/rfc/rfc4122.txt + * @return RFC 4122 UUID + * @static + */ + function uuid() { + $node = env('SERVER_ADDR'); + + if(empty($node)) { + $host = env('HOSTNAME'); + + if (empty($host)) { + $host = env('HOST'); + } + + if (empty($host)) { + $node = ip2long('127.0.0.1'); + } else { + $ip = gethostbyname($host); + if ($ip === $host) { + $node = crc32($host); + } else { + $node = ip2long($ip); + } + } + } else { + $node = ip2long($node); + } + + if (function_exists('zend_thread_id')) { + $pid = zend_thread_id(); + } else { + $pid = getmypid(); + } + + list($timeMid, $timeLow) = explode(' ', microtime()); + $uuid = sprintf("%08x-%04x-%04x-%02x%02x-%04x%08x", (int)$timeLow, (int)substr($timeMid, 2) & 0xffff, + mt_rand(0, 0xfff) | 0x4000, mt_rand(0, 0x3f) | 0x80, mt_rand(0, 0xff), $pid, $node); + return $uuid; } } ?> \ No newline at end of file diff --git a/cake/tests/cases/libs/neat_string.test.php b/cake/tests/cases/libs/string.test.php similarity index 62% rename from cake/tests/cases/libs/neat_string.test.php rename to cake/tests/cases/libs/string.test.php index 0897d9df4..cd14ee767 100644 --- a/cake/tests/cases/libs/neat_string.test.php +++ b/cake/tests/cases/libs/string.test.php @@ -26,17 +26,31 @@ * @lastmodified $Date$ * @license http://www.opensource.org/licenses/opengroup.php The Open Group Test Suite License */ -uses('neat_string'); +uses('string'); /** * Short description for class. * * @package cake.tests * @subpackage cake.tests.cases.libs */ -class NeatStringTest extends UnitTestCase { +class StringTest extends UnitTestCase { - function skip() { - $this->skipif (true, 'NeatString not implemented'); + function testUuidGeneration() { + $result = String::uuid(); + $match = preg_match("/^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/", $result); + $this->assertTrue($match); + } + + function testMultipleUuidGeneration() { + $check = array(); + $count = rand(10, 1000); + for($i = 0; $i < $count; $i++) { + $result = String::uuid(); + $match = preg_match("/^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/", $result); + $this->assertTrue($match); + $this->assertFalse(in_array($result, $check)); + $check[] = $result; + } } } ?> \ No newline at end of file