Index: uuid.install
===================================================================
RCS file: /cvs/drupal/contributions/modules/uuid/uuid.install,v
retrieving revision 1.1
diff -u -r1.1 uuid.install
--- uuid.install	21 Oct 2008 16:37:06 -0000	1.1
+++ uuid.install	14 Aug 2009 18:29:43 -0000
@@ -5,59 +5,56 @@
  * Implementation of hook_install().
  */
 function uuid_install() {
-  // Create tables.
   drupal_install_schema('uuid');
-
-  // Build UUIDs.
-  $tables = array('node' => 'nid', 'users' => 'uid');
-  foreach ($tables as $table => $key) {
-    db_query('INSERT INTO {uuid_' . $table . '} SELECT ' . $key . ', UUID() FROM {' . $table . '}');
-  }
 }
 
 /**
  * Implementation of hook_schema().
  */
 function uuid_schema() {
-  return array(
-    'uuid_node' => uuid_table_schema('nid'),
-    'uuid_users' => uuid_table_schema('uid'),
-  );
-} 
-
-/**
- * Return schema for a uuid table.
- *
- * @param $key
- *   Name of key field, e.g. nid for nodes.
- * @return
- *   Array with table structure definition (schema).
- */
-function uuid_table_schema($key = 'key') {
-  return array(
+  $schema = array();
+  
+  $schema['uuid'] = array(
+    'description' => 'Stores UUID data.',
     'fields' => array(
-      $key => array(
+      'oid' => array(
         'type' => 'int',
         'unsigned' => TRUE,
         'not null' => TRUE,
-        'default' => 0,
-        'description' => t('The primary key of the record which this UUID was generated for.'),
+        'description' => 'The primary key of the object which this UUID was generated for.',
       ),
       'uuid' => array(
         'type' => 'varchar',
+        'length' => 36,
+        'not null' => TRUE,
+        'description' => 'The Universally Unique Identifier.',
+      ),
+      'object' => array(
+        'type' => 'varchar',
         'length' => 64,
         'not null' => TRUE,
-        'default' => '',
-        'description' => t('The Universally Unique Identifier.'),
+        'description' => "The Drupal object targeted (node, user, taxonomy...).",
+      ),
+      'module' => array(
+        'type' => 'varchar',
+        'length' => 255,
+        'not null' => TRUE,
+        'default' => 'uuid',
+        'description' => "The module from which the block originates; for example, 'user' for the Who's Online block, and 'block' for any custom blocks.",
       ),
     ),
-    'primary key' => array($key, 'uuid'),
+    'primary key' => array('oid', 'uuid', 'object'),
+    'unique keys' => array(
+      'uuid' => 'uuid',
+    ),
   );
+  
+  return $schema;
 }
 
 /**
  * Implementation of hook_uninstall().
  */
-function content_uninstall() {
+function uuid_uninstall() {
   drupal_uninstall_schema('uuid');
 }
Index: uuid.module
===================================================================
RCS file: /cvs/drupal/contributions/modules/uuid/uuid.module,v
retrieving revision 1.1
diff -u -r1.1 uuid.module
--- uuid.module	21 Oct 2008 16:37:06 -0000	1.1
+++ uuid.module	17 Aug 2009 07:49:23 -0000
@@ -1,14 +1,228 @@
 <?php
 // $Id: uuid.module,v 1.1 2008/10/21 16:37:06 recidive Exp $
 
+
+/** ----------------------------------------------------------------------------------
+*                                   Drupal hooks
+----------------------------------------------------------------------------------- */
 /**
- * Implementation of hook_init().
+ * Implementation of hook_menu()
  */
-function uuid_init() {
-  $modules = array('node', 'user');
-  foreach ($modules as $module) {
-    if (module_exists($module)) {
-      module_load_include('inc', 'uuid', 'uuid_' . $module);
+function uuid_menu() {
+  $items = array();
+
+  $items['admin/settings/uuid'] = array(
+    'title' => 'Universally Unique IDentifier',
+    'description' => 'UUID generation settings',
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('uuid_admin'),
+    'access arguments' => array('administer uuid'),
+    'file' => 'uuid.admin.inc',
+  );
+
+  return $items;
+}
+
+/**
+ * Implementation of hook_perm()
+ */
+function uuid_perm() {
+  return array('administer uuid');
+}
+
+/**
+ * Implementation of hook_nodeapi().
+ */
+function uuid_nodeapi(&$node, $op, $teaser, $page) {
+  if (in_array($node->type, variable_get('uuid_automatic_for_nodes', array()))) {
+    switch ($op) {
+      case 'load':
+        return db_fetch_array(db_query("SELECT uuid FROM {uuid} WHERE oid = %d AND object = '%s' AND module = '%s'", $node->nid, 'node', 'uuid'));
+      case 'insert':
+        uuid_create_uuid($node->nid, 'node');
+        break;
+      case 'delete':
+        db_query("DELETE FROM {uuid} WHERE nid = %d AND object = '%s' AND module = '%s'", $node->nid, 'node', 'uuid');
+        break;
     }
   }
 }
+
+/**
+ * Implementation of hook_user().
+ */
+function uuid_user($op, &$edit, &$account, $category = NULL) {
+  switch ($op) {
+    case 'load':
+      $account->uuid = db_result(db_query("SELECT uuid FROM {uuid} WHERE oid = %d AND object = '%s' AND module = '%s'", $account->uid, 'user', 'uuid'));
+      break;
+    case 'insert':
+      uuid_create_uuid($account->uid, 'user');
+      break;
+    case 'delete':
+      db_query("DELETE FROM {uuid} WHERE uid = %d AND object = '%s' AND module = '%s'", $account->uid, 'user', 'uuid');
+      break;
+  }
+}
+
+/**
+ * Implementation of hook_taxonomy().
+ */
+function uuid_taxonomy($op, $type, $array = NULL) {
+  $colname = $type == 'term' ? 'tid' : 'vid';
+  
+  if (in_array($array['vid'], variable_get('uuid_automatic_for_taxonomy', array()))) {
+    switch ($op) {
+      case 'insert':
+        uuid_create_uuid($array[$colname], $type);
+        break;
+      case 'delete':
+        db_query("DELETE FROM {uuid} WHERE oid = %d AND object = '%s' AND module = '%s'", $array[$colname], $type, 'uuid');
+        break;
+    }
+  }
+}
+
+/** ----------------------------------------------------------------------------------
+*                            Token module hooks
+----------------------------------------------------------------------------------- */
+/**
+ * Implementation of hook_token_values().
+ */
+function uuid_token_values($type, $object = NULL, $options = array()) {
+  $values = array();
+  
+  switch ($type) {
+    case 'node':
+      $values['uuid-raw'] = uuid_get_uuid($object->nid, 'node');
+      break;
+    case 'user':
+      $values['uuid-raw'] = uuid_get_uuid($object->uid, 'user');
+      break;
+    case 'taxonomy':
+      $values['uuid-raw'] = uuid_get_uuid($object->uid, 'taxonomy');
+      break;
+  }
+
+  return $values;
+}
+
+/**
+ * Implementation of hook_token_list().
+ */
+function uuid_token_list($type = 'all') {
+  $tokens = array();
+  
+  if ($type == 'node' || $type == 'all') {
+    // A filtered entry is not necessary, uuid can only contain alphanumeric and space chars
+    $tokens['node']['uuid-raw'] = t("The Universally Unique IDentifier (UUID). Be sure that required node content type(s) has(ve) been configured to support UUID (!url), even the returned value will be empty.", array('!url' => l(t('Administer UUID'), 'admin/settings/uuid')));
+  }
+  
+  if ($type == 'user' || $type == 'all') {
+    // A filtered entry is not necessary, uuid can only contain alphanumeric and space chars
+    $tokens['user']['uuid-raw'] = t("The Universally Unique IDentifier (UUID). Be sure that users have been configured to support UUID (!url), even the returned value will be empty.", array('!url' => l(t('Administer UUID'), 'admin/settings/uuid')));
+  }
+  
+  if ($type == 'taxonomy' || $type == 'all') {
+    // A filtered entry is not necessary, uuid can only contain alphanumeric and space chars
+    $tokens['taxonomy']['uuid-raw'] = t("The Universally Unique IDentifier (UUID). Be sure that required vocabulary(ies) )has(ve) been configured to support UUID (!url), even the returned value will be empty.", array('!url' => l(t('Administer UUID'), 'admin/settings/uuid')));
+  }
+
+  return $tokens;
+}
+/** ----------------------------------------------------------------------------------
+*                                Various functions
+----------------------------------------------------------------------------------- */ 
+/**
+ * @desc  Generates a Universally Unique IDentifier, version 4.
+ * 
+ * RFC 4122 (http://www.ietf.org/rfc/rfc4122.txt) defines a special type of Globally
+ * Unique IDentifiers (GUID), as well as several methods for producing them. One
+ * such method, described in section 4.4, is based on truly random or pseudo-random
+ * number generators, and is therefore implementable in a language like PHP.
+ *
+ * We choose to produce pseudo-random numbers with the Mersenne Twister, and to always
+ * limit single generated numbers to 16 bits (ie. the decimal value 65535). That is
+ * because, even on 32-bit systems, PHP's RAND_MAX will often be the maximum *signed*
+ * value, with only the equivalent of 31 significant bits. Producing two 16-bit random
+ * numbers to make up a 32-bit one is less efficient, but guarantees that all 32 bits
+ * are random.
+ *
+ * The algorithm for version 4 UUIDs (ie. those based on random number generators)
+ * states that all 128 bits separated into the various fields (32 bits, 16 bits, 16 bits,
+ * 8 bits and 8 bits, 48 bits) should be random, except : (a) the version number should
+ * be the last 4 bits in the 3rd field, and (b) bits 6 and 7 of the 4th field should
+ * be 01. We try to conform to that definition as efficiently as possible, generating
+ * smaller values where possible, and minimizing the number of base conversions.
+ *
+ * @copyright   Copyright (c) CFD Labs, 2006. This function may be used freely for
+ *              any purpose ; it is distributed without any form of warranty whatsoever.
+ * @author      David Holmes <dholmes@cfdsoftware.net>
+ *
+ * @return  string  A UUID, made up of 32 hex digits and 4 hyphens.
+ * 
+ * @see  http://php.net/manual/en/function.uniqid.php#65879
+ */
+function uuid_uuid() {
+  // If the function provided by the uuid pecl extension is available, use that.
+  if( function_exists("uuid_create")) {
+    return uuid_create(UUID_TYPE_DEFAULT);
+  }
+
+  // The field names refer to RFC 4122 section 4.1.2
+  return sprintf('%04x%04x %04x %03x4 %04x %04x%04x%04x',
+    mt_rand(0, 65535), mt_rand(0, 65535), // 32 bits for "time_low"
+    mt_rand(0, 65535), // 16 bits for "time_mid"
+    mt_rand(0, 4095),  // 12 bits before the 0100 of (version) 4 for "time_hi_and_version"
+    bindec(substr_replace(sprintf('%016b', mt_rand(0, 65535)), '01', 6, 2)),
+      // 8 bits, the last two of which (positions 6 and 7) are 01, for "clk_seq_hi_res"
+      // (hence, the 2nd hex digit after the 3rd hyphen can only be 1, 5, 9 or d)
+      // 8 bits for "clk_seq_low"
+    mt_rand(0, 65535), mt_rand(0, 65535), mt_rand(0, 65535) // 48 bits for "node" 
+  );
+}
+ 
+/**
+ * @desc  Determines if a UUID is valid.
+ * 
+ * @author  anarchivist (http://matienzo.org/)
+ * 
+ * @return  boolean
+ */
+function uuid_uuid_is_valid($uuid) {
+  if (function_exists("uuid_is_valid")) {
+    $valid = uuid_is_valid($uuid);
+  } else {
+    $valid = preg_match('/^[A Fa f0 9]{8} [A Fa f0 9]{4} [A Fa f0 9]{4} [A Fa f0 9]{4} [A Fa f0 9]{12}$/', $uuid);
+  }
+  return (boolean) $valid;
+}
+
+/**
+* @desc Store a new UUID in the database
+* @param int Object ID
+* @param string Object type (node, user, term, vocabulary...)
+* @param string The name of the module that add the UUID
+* @return The UUID on suucess, else FALSE
+*/
+function uuid_create_uuid($oid, $object, $module = 'uuid') {
+  if (is_numeric($oid)) {
+    $uuid = uuid_uuid();
+    db_query("INSERT INTO {uuid} (oid, uuid, object, module) VALUES (%d, '%s', '%s', '%s')", $oid, $uuid, $object, $module);
+    return $uuid;
+  }
+  
+  return FALSE;
+}
+
+/**
+* @desc Retrieve an existing UUID from the database
+* @param int Object ID
+* @param string Object type (node, user, term, vocabulary...)
+* @param string The name of the module that add the UUID
+* @return The UUID on suucess, else FALSE
+*/
+function uuid_get_uuid($oid, $object, $module = 'uuid') {
+  return db_result(db_query("SELECT u.uuid FROM {uuid} u WHERE u.oid = %d AND u.object = '%s' AND u.module = '%s'", $oid, $object, $module));
+}
+

