Index: resource_conflict.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/resource_conflict/resource_conflict.module,v
retrieving revision 1.1.2.5
diff -u -r1.1.2.5 resource_conflict.module
--- resource_conflict.module	28 Jun 2008 17:39:43 -0000	1.1.2.5
+++ resource_conflict.module	28 Jul 2008 04:24:57 -0000
@@ -1,53 +1,84 @@
 <?php
-
-// $Id: resource_conflict.module,v 1.1.2.5 2008/06/28 17:39:43 deviantintegral Exp $
+// $Id$
+//VIM setup ex: et sw=2 ts=2 syntax=php
 
 /**
  * Implementation of hook_nodeapi
  *
- * Determine if a CCK nodereferenced resource is currently booked.
+ * Determine if a required resource is currently booked.
  */
 function resource_conflict_nodeapi(&$node, $op, $teaser = NULL, $page = NULL) {
-  $type = $node->type;
-  
-  switch($op) {
+  switch ($op) {
     case 'validate':
-      if (variable_get('resource_conflict_' . $type, FALSE)) {
-        // Find the relevant fields to check against
-        $fields = variable_get('resource_conflict_fields_' . $type, FALSE);
-        if(empty($fields)) break;
-        
+      $type = $node->type;
+      if (! variable_get('resource_conflict_type_' . $type, FALSE)) {
+        //conflict handling is not enabled for this node
+        break;
+      }
+
+      require_once(drupal_get_path('module', 'date_api') .'/date.inc');
+
+      // Find the date field to use for time overlapping_node_ids detection
+      $date_field = variable_get('resource_conflict_date_field_' . $type, FALSE);
+
+      $overlapping_node_ids = array();
+      if (!empty($date_field)) {
+        // Get the start and end Date of the current node
+        $start = $node-> {$date_field}[0]['value'];
+        $end   = $node-> {$date_field}[0]['value2'];
+        $end = $end ? $end : $start;
+        // Get all conflicting Date nodes
+        $overlapping_node_ids = _resource_conflict_overlaps_from_date($start, $end);
+      }
+      if (!empty($node->event_start)) {
         // Get all overlapping events
-        $overlap = _resource_conflict_event_overlap($node->event_start, $node->event_end);
-        if(empty($overlap)) break;
-        
-        foreach($overlap as $nid) {
-          // Don't have the node conflict with itself
-          if ($nid != $node->nid)
-            $overlap_nodes[] = node_load($nid);
-        }
-        if(empty($overlap_nodes)) break;
-        
-        foreach($fields as $field) {
-          foreach($node->{$field} as $instance) {
-            foreach ($overlap_nodes as $conflict) {
-              
-              // If there is empty variable $conflict->{$field} when you use more then one resource conflict contents
-              if (empty($conflict->{$field})) continue;
-              
-              foreach($conflict->{$field} as $conflict_instance) {
-                if ($instance['nid'] == $conflict_instance['nid']) {
-                  $booked_resource = node_load($instance['nid']);
-                  form_set_error('Resource Conflict', 
-                    t('There is a resource conflict. "%resource" is currently booked. Please choose a different time or a different resource.',
-                      array('%resource' => $booked_resource->title)));
-                }
-              }
-            }
-          }
+        $tmp = _resource_conflict_overlaps_from_event($node->event_start, $node->event_end);
+        $overlapping_node_ids = array_merge($overlapping_node_ids, $tmp);
+      }
+
+      // Load conflicting nodes
+      $conflicting_nodes = array();
+      foreach ($overlapping_node_ids as $nid) {
+        // Don't have the node conflict with itself
+        if ($nid != $node->nid) {
+          $conflicting_nodes[] = node_load($nid);
         }
       }
-      break;
+
+      // Display conflict errors
+      _resource_conflict_display_conflict_errors($node, $conflicting_nodes);
+    break;
+  }
+}
+
+
+/**
+ * Compare our demand to the demand of overlapping nodes
+ * and display errors for the intersections
+ *
+ * @param $node the currently validating node
+ * @param $conflicting_nodes array of nodes that overlap with this node
+ */
+function _resource_conflict_display_conflict_errors($node, $conflicting_nodes) {
+  $our_demands = _resource_conflict_get_node_resource_demand($node);
+  foreach ($conflicting_nodes as $conflicting_node) {
+    $other_demands = _resource_conflict_get_node_resource_demand($conflicting_node);
+
+    // select the resources that both this node and the other node demands
+    $conflicting_resources = array();
+    foreach ($our_demands as $our_demand => $dummy) {
+      if ($other_demands[$our_demand]) {
+        $conflicting_resources[] = node_load($our_demand);
+      }
+    }
+
+    // display the error for each conflict
+    foreach ($conflicting_resources as $conflicting_resource) {
+      form_set_error('Resource Conflict', 
+      t('There is a resource conflict: "%resource" is currently booked for "%booker". Please choose a different time or a different resource.',
+      array('%booker' => $conflicting_node->title,
+          '%resource' => $conflicting_resource->title)));
+    }
   }
 }
 
@@ -65,20 +96,24 @@
       '#collapsible' => 1,
     );
     
-    $form['resource_conflict_set']['resource_conflict'] = array(
+    $form['resource_conflict_set']['resource_conflict_type'] = array(
       '#type' => 'checkbox',
       '#title' => t('Enable resource conflict checking for this content type.'),
-      '#default_value' => variable_get('resource_conflict_' . $type, 0),
+      '#default_value' => variable_get('resource_conflict_type_' . $type, 0),
       '#description' => t('If this is enabled, this content type must also be event enabled.'),
     );
     
     if ($type != NULL) {
-      $fields = content_fields();
+	  $type_info = content_types($type);
+      $fields = $type_info['fields'];
       
-      foreach($fields as $field) {
+      foreach ($fields as $field) {
         if ($field['type'] == 'nodereference') {
           $nodereference_fields[$field['field_name']] = $field['widget']['label'];
         }
+        elseif ($field['type'] == 'date') {
+          $date_fields[$field['field_name']] = $field['widget']['label'];
+        }
       }
     }
     
@@ -88,19 +123,143 @@
       );
     }
     else {
-      $form['resource_conflict_set']['resource_conflict_fields'] = array(
+      $form['resource_conflict_set']['resource_conflict_reference_fields'] = array(
         '#type' => 'select',
         '#title' => t('Fields to check for conflicts'),
         '#options' => $nodereference_fields,
         '#multiple' => TRUE,
-        '#default_value' => variable_get('resource_conflict_fields_' . $type, FALSE),
+        '#default_value' => variable_get('resource_conflict_reference_fields_'.$type, FALSE),
         '#description' => t("Select the node reference resources which can't be booked at the same time.")
       );
     }
+    if (empty($date_fields)) {
+      $form['resource_conflict_set']['no_date_fields'] = array(
+        '#value' => t('Please create some CCK Date fields for this content type OR enable the event module on it.')
+      );
+    }
+    else {
+      $form['resource_conflict_set']['resource_conflict_date_field'] = array(
+        '#type' => 'select',
+        '#title' => t('Fields to use as date for conflict checks'),
+        '#options' => $date_fields,
+        '#multiple' => FALSE,
+        '#default_value' => variable_get('resource_conflict_date_field_'.$type, FALSE),
+        '#description' => t("Select the date field when other resources can't be booked.")
+      );
+    }
+    //set custom validation and submit callbacks
+    $form['#validate']['resource_conflict_form_validate'] = array();
+    $form['#submit']['resource_conflict_form_submit'] = array();
+  }
+}
+
+/**
+ * Validate the node_type_form
+ */
+function resource_conflict_form_validate($form_id, $form_values) {
+  if ($form_id == 'node_type_form') {
+    if ($form_values['resource_conflict_type']) {
+      if (empty($form_values['resource_conflict_reference_fields'])) {
+         form_set_error('resource_conflict_reference_fields', t("Reference field must be set if conflict handling is enabled."));
+      }
+      if (empty($form_values['resource_conflict_date_field']) &&
+            (empty($form_values['event_nodeapi']) || $form_values['event_nodeapi'] == 'never')
+         ) {
+         form_set_error('resource_conflict_reference_fields', t("CCK Date field must be set (or event module must be enabled on this content type) if conflict handling is enabled."));
+      }
+    }
+  }
+}
+
+/**
+ * Submit the node_type_form
+ */
+function resource_conflict_form_submit($form_id, $form_values) {
+  $type = $form_values['type'];
+  $old_type = $form_values['old_type'];
+  $conflict_types = variable_get("resource_conflict_types", array());
+
+  //unset old entry
+  if (!empty($old_type)) {
+    $key = array_search($old_type, $conflict_types);
+    unset($conflict_types[$key]);
+  }
+  
+  //make new entry if this type is conflict handled
+  if ($form_values['resource_conflict_type']) {
+    $conflict_types[] = $type;
   }
+
+  variable_set("resource_conflict_types", $conflict_types);
+}
+
+/**
+ * Get the conflict enabled types
+ *
+ * @return
+ *   An array of type names
+ */
+function _resource_conflict_get_conflict_enabled_types() {
+  $conflict_types = variable_get("resource_conflict_types", array());
+	return $conflict_types;
+}
+
+/**
+ * Get a conflict enabled node's resource demand
+ *
+ * @param $node
+ *   The node which resurce demand will be returned
+ * @return
+ *   An array with keys of the node ID's, values of true
+ */
+function _resource_conflict_get_node_resource_demand($node) {
+	$type = $node->type;
+	$reference_fields = variable_get('resource_conflict_reference_fields_' . $type, array());
+
+	$demand = array();
+	foreach ($reference_fields as $reference_field) {
+		$references = $node-> {$reference_field};
+		foreach ($references as $reference) {
+			$demand[$reference['nid']] = true;
+		}
+	}
+	return $demand;
+}
+
+/**
+ * Determine if any nodes conflict between the specified dates using Date API.
+ *
+ * @param $date_start
+ *   The start date of the date to check
+ * @param $date_end
+ *   The end date of the date to check.
+ * @return
+ *   An array of node ID's
+ */
+function _resource_conflict_overlaps_from_date($date_start, $date_end) {
+  $start = date_make_date($date_start, 'GMT', 'db', DATE_ISO);
+  $end = date_make_date($date_start, 'GMT', 'db', DATE_ISO);
+  return _resource_conflict_get_overlaps($start, $end);
 }
+
 /**
- * Determine if any events overlap the specified times
+ * Determine if any nodes conflict between the specified dates using Event.
+ *
+ * @param $event_start
+ *   The start date of the event to check
+ * @param $event_end
+ *   The end date of the event to check.
+ * @return
+ *   An array of node ID's
+ */
+function _resource_conflict_overlaps_from_event($event_start, $event_end) {
+  $start = date_make_date($event_start, 'GMT', 'db', DATE_UNIX);
+  $end = date_make_date($event_start, 'GMT', 'db', DATE_UNIX);
+  return _resource_conflict_get_overlaps($start, $end);
+}
+
+/**
+ * Determine if any conflict enabled nodes overlap the specified times
  *
  * 1. $start is within the event time
  * 2. $end end is within the event time
@@ -108,21 +267,48 @@
  * 4. Allow the end of one event to occur at the start of the next
  * 
  * @param $start
- *   The start time of events to search
+ *   The start time of events to search as dateAPI object
  * @param $end
- *   The end time of events to search
+ *   The end time of events to search as dateAPI object
  * @return
  *   An array of node ID's
  */
-function _resource_conflict_event_overlap($start, $end) {
-  $query = "SELECT nid FROM {event} WHERE (%d >= event_start AND %d < event_end)
-    OR (%d > event_start AND %d <= event_end)
-    OR (%d <= event_start AND %d >= event_end)";
-  $result = db_query($query, $start, $start, $end, $end, $start, $end);
-  
-  // Create an array of all of the results
-  while($row = db_fetch_array($result)) {
-    $rows[] = $row['nid'];
-  }
-  return $rows;
-}
\ No newline at end of file
+function _resource_conflict_get_overlaps($start, $end) {
+  $date_start = date_show_value($start, 'db', DATE_ISO);
+  $event_start = date_show_value($start, 'db', DATE_UNIX);
+  $event_end = date_show_value($end, 'db', DATE_UNIX);
+  $date_end = date_show_value($end, 'db', DATE_ISO);
+
+  $rows = array();
+  $conflict_types = _resource_conflict_get_conflict_enabled_types();
+	foreach ($conflict_types as $type) {
+    $date_field = variable_get('resource_conflict_date_field_' . $type, FALSE);
+
+    if($date_field) {
+      $start_field_name = $date_field . "_value";
+      $end_field_name   = $date_field . "_value2";
+
+      $query = "SELECT nid FROM {content_type_$type} WHERE('%s' >= $start_field_name AND '%s' < $end_field_name)
+      OR('%s' > $start_field_name AND '%s' <= $end_field_name)
+      OR('%s' <= $start_field_name AND '%s' >= $end_field_name)";
+      $result = db_query($query, $date_start, $date_start, $date_end, $date_end, $date_start, $date_end);
+
+      // Create an array of all of the results
+      while ($row = db_fetch_array($result)) {
+        $rows[] = $row['nid'];
+      }
+    }
+    else { //event enabled
+      $query = "SELECT nid FROM {event} WHERE (%d >= event_start AND %d < event_end)
+        OR (%d > event_start AND %d <= event_end)
+        OR (%d <= event_start AND %d >= event_end)";
+      $result = db_query($query, $event_start, $event_start, $event_end, $event_end, $event_start, $event_end);
+      
+      // Create an array of all of the results
+      while($row = db_fetch_array($result)) {
+        $rows[] = $row['nid'];
+      }
+    }
+	}
+	return $rows;
+}
Index: resource_conflict.info
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/resource_conflict/resource_conflict.info,v
retrieving revision 1.1.2.1
diff -u -r1.1.2.1 resource_conflict.info
--- resource_conflict.info	19 Sep 2007 21:54:26 -0000	1.1.2.1
+++ resource_conflict.info	28 Jul 2008 04:24:56 -0000
@@ -1,3 +1,4 @@
 name = Resource Conflict
-description = Provides a mechanism for notifying of event conflict based on nodereferenced resources.
-dependencies = event nodereference
\ No newline at end of file
+description = Provides a mechanism for notifying of conflict based on nodereferenced resources.
+dependencies = nodereference date_api
+project = "resource_conflict"
