? 799856_og_notifications_4x_02.patch
? modules/og_notifications/799856_og_notifications_4x_01.patch
Index: modules/og_notifications/og_notifications.install
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/og/modules/og_notifications/Attic/og_notifications.install,v
retrieving revision 1.9.4.3
diff -u -r1.9.4.3 og_notifications.install
--- modules/og_notifications/og_notifications.install	18 May 2009 05:20:09 -0000	1.9.4.3
+++ modules/og_notifications/og_notifications.install	13 Jul 2010 20:52:07 -0000
@@ -158,6 +158,15 @@
 }
 
 /**
+ * First 4.x update. Update module that may be blank for subscriptions of this module
+ */
+function og_notifications_update_6010() {
+  $ret = array();
+  $ret[] = update_sql("UPDATE {notifications} SET module = 'og_notifications' WHERE type = 'grouptype'");
+  return $ret;
+}
+
+/**
  * Populate the og_notifications_table with any uids added prior to installation
  * or when disabled.
  */
Index: modules/og_notifications/og_notifications.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/og/modules/og_notifications/Attic/og_notifications.module,v
retrieving revision 1.24.4.25
diff -u -r1.24.4.25 og_notifications.module
--- modules/og_notifications/og_notifications.module	16 Apr 2010 16:33:18 -0000	1.24.4.25
+++ modules/og_notifications/og_notifications.module	13 Jul 2010 20:52:08 -0000
@@ -15,8 +15,10 @@
   global $user;
 
   switch ($path) {
-    case 'user/%/notifications/group':
+    case 'user/%/notifications/grouptype':
       return t('Customize notifications for each of your groups and each of their content types along with their frequency and delivery method.');
+    case 'admin/messaging/notifications/events':
+      return t('Notifications OG provides its own templates. These will override the templates here for subscriptions to group content types.');
   }
 }
 
@@ -25,17 +27,26 @@
  */
 function og_notifications_menu() {
   $items = array();
-  $items['user/%user/notifications/add/grouptype'] = array(
-    'title' => 'Group notifications',
-    'page callback' => 'og_notifications_user_page',
-    'page arguments' => array(1),
-    'access callback' => 'notifications_content_access',
-    'access arguments' => array(1, 'subscribe to content in groups'),
+  $items['user/%user/notifications/grouptype'] = array(
+    'title' => 'Groups content',
+    'description' => 'Content types in groups',
+    'page callback' => 'notifications_user_subscription_list_page',
+    'page arguments' => array('grouptype', 1),
+    // This can be enabled by the UI module
+    'access callback' => FALSE,
+    'type' => MENU_LOCAL_TASK,
+    'weight' => 10,
+  );
+  $items['user/%user/notifications/group'] = array(
+    'title' => 'Groups',
+    'description' => 'All content in groups',
+    'page callback' => 'notifications_user_subscription_list_page',
+    'page arguments' => array('group', 1),
+    // This can be enabled by the UI module
+    'access callback' => FALSE,
     'type' => MENU_LOCAL_TASK,
     'weight' => 10,
-    'file' => 'og_notifications.pages.inc'
   );
-
   return $items;
 }
 
@@ -96,13 +107,7 @@
         '#multiple' => TRUE
       );
       break;
-    case 'notifications_add_subscription_form':
-      // Remove unauthorised node types.
-      if ($form['type']['#value'] == 'grouptype') {
-        $content_types = array_filter(variable_get('og_notifications_content_types', array()));
-        $form['info']['fields'][1]['value']['#options'] = array_intersect_key($form['info']['fields'][1]['value']['#options'], $content_types);
-      }
-      break;
+
     case 'user_profile_form':
       // Insert autosubscribe option into the messaging section of the user edit
       // form.
@@ -119,6 +124,7 @@
         );
       }
       break;
+
     case 'og_admin_settings':
       unset($form['og_new_node_subject'], $form['og_new_node_body']);
       $form['og_settings']['notifications']['#description'] = t('Node event notifications can be configured via the <a href="!url">messaging templates</a> interface.', array('!url' => url('admin/messaging/template')));
@@ -175,39 +181,56 @@
 }
 
 /**
- * Implementation of hook_messaging().
+ * Implementation of hook_notifications_templates()
  */
-function og_notifications_messaging($op, $arg1 = NULL, $arg2 = NULL, $arg3 = NULL, $arg4 = NULL) {
+function og_notifications_notifications_templates($op, $type = 'all', $language = NULL) {
   switch ($op) {
-    case 'message groups':
-      // Generic notifications event
-      $info['og-notifications'] = array(
-        'module' => 'og_notifications',
-        'name' => t('OG notifications (default)'),
-        'help' => t('Most fields will be provided during the event.'),
-        'description' => t('Notifications for organic groups node events. Other group notification strings can be customized via the <a href="!url">OG config</a> page.', array('!url' => url('admin/og/og')))
-      );
-      $info['og-notifications-insert'] = array(
-        'module' => 'og_notifications',
-        'name' => t('OG notifications for new content'),
-        'help' => t('Most fields will be provided during the event.'),
-        'description' => t('Notifications for organic groups node creation events.')
-      );
-      $info['og-notifications-update'] = array(
-        'module' => 'og_notifications',
-        'name' => t('OG notifications for updated content'),
-        'help' => t('Most fields will be provided during the event.'),
-        'description' => t('Notifications for organic groups node update events.')
-      );
-      $info['og-notifications-comment'] = array(
-        'module' => 'og_notifications',
-        'name' => t('OG notifications for comments'),
-        'help' => t('Most fields will be provided during the event.'),
-        'description' => t('Notifications for organic groups comment events.')
-      );
+    case 'help':
+      if (strpos($type, 'og-notifications') === 0) {
+        $help[] = t('Most fields will be provided during the event.');
+        return $help;
+      }
+      break;
+  
+    case 'info':
+      $info = array();
+      if ($type == 'all' || $type == 'og-notifications') {
+        // Generic notifications event
+        $info['og-notifications'] = array(
+          'module' => 'og_notifications',
+          'name' => t('OG notifications (default)'),
+          'description' => t('Notifications for organic groups node events. Other group notification strings can be customized via the <a href="!url">OG config</a> page.', array('!url' => url('admin/og/og'))),
+        );
+      }
+      if ($type == 'all' || $type == 'og-notifications-insert') {
+        $info['og-notifications-insert'] = array(
+          'module' => 'og_notifications',
+          'name' => t('OG notifications for new content'),
+          'description' => t('Notifications for organic groups node creation events.'),
+          'fallback' => 'og-notifications',
+        );
+      }
+      if ($type == 'all' || $type == 'og-notifications-update') {
+        $info['og-notifications-update'] = array(
+          'module' => 'og_notifications',
+          'name' => t('OG notifications for updated content'),
+          'description' => t('Notifications for organic groups node update events.'),
+          'fallback' => 'og-notifications',
+        );
+      }
+      if ($type == 'all' || $type == 'og-notifications-comment') {
+        $info['og-notifications-comment'] = array(
+          'module' => 'og_notifications',
+          'name' => t('OG notifications for comments'),
+          'help' => t('Most fields will be provided during the event.'),
+          'description' => t('Notifications for organic groups comment events.'),
+          'fallback' => 'og-notifications',
+        );
+      }
       return $info;
-    case 'message keys':
-      switch ($arg1) {
+
+    case 'parts':
+      switch ($type) {
         case 'og-notifications':
         case 'og-notifications-insert':
         case 'og-notifications-update':
@@ -221,169 +244,128 @@
         break;
       }
       break;
-    case 'messages':
-      $template = array(
-        'subject' => t('[site-name] [ogname]: [title]'),
-        'header' => t("Greetings, [user],"),
-        'main' => array(
-          t('A [type-name] has been updated in group [ogname]: [title]'),
-          t('[node-teaser]'),
-          t('Read more at [node-url].')
-        ),
-        'footer' => array(
-          t('This is an automatic message from [site-name]'),
-          t('To manage your subscriptions, browse to [subscriptions-manage]')
-        )
-      );
-      switch ($arg1) {
-        case 'og-notifications':
-        case 'og-notifications-update':
-          return $template;
-        case 'og-notifications-insert':
-          $template['main'] = array(
-            t('A [type-name] has been created in group [ogname]: [title]'),
-            t('[node-teaser]'),
-            t('Read more at [node-url].')
-          );
-          return $template;
-        case 'og-notifications-comment':
-          $template['main'] = array(
-              t('A new comment has been added by [comment-author-name] to this thread in group [ogname]: [comment-title]'),
-              t('[comment-body]'),
-              t('Read more at [comment-url] or reply via [comment-reply-url].')
-          );
+ 
+    case 'defaults':
+      if (strpos($type, 'og-notifications') === 0) {
+        $template = array(
+          'subject' => t('[site-name] [ogname]: [title]', array(), $language->language),
+          'header' => t("Greetings, [user],", array(), $language->language),
+          'main' => array(
+            t('A [type-name] has been updated in group [ogname]: [title]', array(), $language->language),
+            '[node-teaser]',
+            t('Read more at [node-url].', array(), $language->language)
+          ),
+          'footer' => array(
+            t('This is an automatic message from [site-name]', array(), $language->language),
+            t('To manage your subscriptions, browse to [subscriptions-manage]', array(), $language->language)
+          )
+        );
+        switch ($type) {
+          case 'og-notifications-insert':
+            $template['main'] = array(
+              t('A [type-name] has been created in group [ogname]: [title]', array(), $language->language),
+              '[node-teaser]',
+              t('Read more at [node-url].', array(), $language->language)
+            );
+            break;
+          case 'og-notifications-comment':
+            $template['main'] = array(
+                t('A new comment has been added by [comment-author-name] to this thread in group [ogname]: [comment-title]', array(), $language->language),
+                '[comment-body]',
+                t('Read more at [comment-url] or reply via [comment-reply-url].', array(), $language->language)
+            );
+            break;
+          }
           return $template;
-      }
+        }
       break;
     case 'tokens':
       $tokens = array();
-      if (strpos($arg1, 'og-notifications') === 0) {
+      if (strpos($type, 'og-notifications') === 0) {
         $tokens = array('global', 'subscription', 'user', 'node', 'comment');
       }
-
       return $tokens;
   }
 }
 
 /**
- * A workaround to ensure that OG can provide custom message templates for
- * notifications.
- *
- * @param Object $message
- *   The message object.
- * @param Object $info
- *   Sending method information.
- */
-function og_notifications_message_alter(&$message, $info) {
-  if ($sid = _og_notification_check_message($message)) {
-    $event = $message->notifications['events'][0];
-    // Cater for different message groups (actions).
-    $group = 'og-notifications-'. $event->action;
-    $send_method = $message->method;
-    $subscription = notifications_load_subscription($sid);
-
-    $text = array(
-      'subject' => messaging_message_part($group, 'subject', $send_method, $event),
-      'header' => messaging_message_part($group, 'header', $send_method, $event),
-      'footer' => messaging_message_part($group, 'footer', $send_method, $event)
-    );
-
-    if (isset($message->body['main']) ) {
-      $text['main'] = messaging_message_part($group, 'main', $send_method, $event);
-    }
-    else {
-      $text['event'] = messaging_message_part($group, 'main', $send_method, $event);
-    }
-
-
-    $objects = array('user' => $message->account, 'node' => $event->objects['node'], 'subscription' => $subscription);
-    if ($event->action == 'comment') {
-      $objects['comment'] = $event->objects['comment'];
-    }
-
-    $objects = array_merge($objects, $event->objects);
-    $text = messaging_text_replace($text, $objects);
-
-    $message->subject = $text['subject'];
-    unset($text['subject']);
-    $message->body = array_merge($message->body,$text);
-  }
-}
-
-/**
  * Implementation of hook_notifications().
  */
-function og_notifications_notifications($op, &$arg0, $arg1 = NULL, $arg2 = NULL) {
+function og_notifications_notifications($op) {
   switch ($op) {
-    case 'names':
-      $subs = &$arg0;
-      if ($subs->event_type == 'node') {
-        if (!empty($subs->fields['group']) && ($group = node_load($subs->fields['group']))) {
-          $subs->names['group'] = t('Group: %name', array('%name' => $group->title));
-        }
-      }
-      break;
     case 'subscription types':
       $types['grouptype'] = array(
         'event_type' => 'node',
         'title' => t('Content type in group'),
         'access' => 'subscribe to content in groups',
         'page callback' => 'og_notifications_user_page',
-        'user page' => 'user/%user/notifications/group',
+        'user page' => 'user/%user/notifications/grouptype',
         'fields' => array('group', 'type'),
-        'description' => t('Subscribe to specific content within a group.')
+        'description' => t('Subscribe to specific content within a group.'),
+        'module' => 'og_notifications', // Will be the prefix for these templates
+      );
+      $types['group'] = array(
+        'event_type' => 'node',
+        'title' => t('All content in group'),
+        'access' => 'subscribe to content in groups',
+        'page callback' => 'og_notifications_user_page',
+        'user page' => 'user/%user/notifications/group',
+        'fields' => array('group'),
+        'description' => t('Subscribe to specific content within a group.'),
+        'module' => 'og_notifications', // Will be the prefix for these templates
       );
       return $types;
+ 
     case 'subscription fields':
       $fields['group'] = array(
         'name' => t('Group'),
-        'field' => 'nid',
+        'field' => 'group',
         'type' => 'int',
-        'options callback' => 'og_notifications_groups',
-        'format callback' => 'notifications_node_nid2title'
-      );
-      // Notifications does not allow custom callbacks for overlapping fields.
-      // This is resolved via a form_alter refines the field to only displsy
-      // authorised node types.
-      $fields['type'] = array(
-        'name' => t('Content type'),
-        'field' => 'type',
-        'type' => 'string',
-        'options callback' => 'notifications_content_types'
+        'options callback' => 'og_notifications_user_groups',
+        'object_type' => 'node',
       );
       return $fields;
-    case 'query':
-      $query = array();
+  }
+}
 
-      if ($arg0 == 'event' && $arg1 == 'node' && $node = $arg2->node) {
-        if (!empty($node->og_groups)) {
-          $query[]['fields']['group'] = $node->og_groups;
-        }
-      }
-      else if ($arg0 == 'user' && $arg1 == 'node') {
-        // Called by notifications_autosubscribe; $arg2 holds the nid.
-        $query[]['fields']['group'] = $arg2;
-      }
+/**
+ * Implementation of hook_notifications_subscription_fields_alter()
+ * 
+ * Add a different 'options callback' for content types of group subscriptions
+ */
+function og_notifications_notifications_subscription_fields_alter(&$fields) {
+  // Add "[subscription type] options callback" for these types of subscritions
+  $fields['type']['grouptype options callback'] = 'og_notifications_content_types';
+  $fields['type']['group options callback'] = 'og_notifications_content_types';
+}
 
-      return $query;
-    case 'node options':
-      return _og_notifications_node_options($arg0, $arg1);
-    case 'event load':
-      // Piggy-backing on notifications_content.
-      break;
-    case 'event types':
-      // Piggy-backing on notifications_content.
-      break;
+/**
+ * Return available content types for group subscriptions (translated names)
+ */
+function og_notifications_content_types($subscription = NULL) {
+  static $types;
+  
+  if (!isset($types)) {
+    $content_types = array_filter(variable_get('og_notifications_content_types', array()));
+    $types = array_intersect_key(notifications_content_type_name(), $content_types);
+  }
+  
+  return $types;
+}
+
+/**
+ * Implementation of hook notifications_subscription()
+ */
+function og_notifications_notifications_subscription($op, $subscription = NULL, $account = NULL) {
+  switch ($op) {
     case 'access':
-      $type = $arg0;
-      $account = $arg1;
-      $object = $arg2;
-      if ($type == 'subscription' && !empty($object->fields['group'])) {
-        if (($group = node_load($object->fields['group'])) && og_is_group_type($group->type) && notifications_content_node_allow($account, $group)) {
-          return array(TRUE);
+      // Check access control for subscription
+      if (($conditions = $subscription->get_conditions()) && !empty($conditions['group']) && is_numeric($conditions['group'])) {
+        if (($group = node_load($conditions['group'])) && og_is_group_type($group->type) && notifications_content_node_allow($account, $group)) {
+          return TRUE;
         }
         else {
-          return array(FALSE);
+          return FALSE;
         }
       }
       break;
@@ -391,6 +373,57 @@
 }
 
 /**
+ * Implementation of hook_notifications_object_node()
+ */
+function og_notifications_notifications_object_node($op, $node, $account = NULL) {
+  switch ($op) {
+    case 'conditions':
+      if (!empty($node->og_groups)) {
+        return array('group' => $node->og_groups);
+      }
+      break;
+
+    case 'subscriptions':
+      // Return available subscription options for this node and this user account
+      $options = array();
+      // If node is a group type and the user is subscribed to this group.
+      if (og_is_group_type($node->type) && isset($account->og_groups[$node->nid])) {
+        foreach (og_notifications_content_types() as $type => $name) {
+          $options[] = array(
+            'name' => t('@type posts in @group', array('@group' => $node->title, '@type' =>  $name)),
+            'type' => 'grouptype',
+            'fields' => array('group' => $node->nid, 'type' => $type)
+          );
+        }
+      }
+      // If node is part of a group user may be subscribed to the node through one
+      // of the groups.
+      if (!empty($node->og_groups)) {
+        foreach ($node->og_groups as $index => $gid) {
+          // Only members get to see subscription options.
+          $content_types = og_notifications_content_types();
+          if (isset($account->og_groups[$gid]) && isset($content_types[$node->type]) ) {
+            // Content type
+            $options[] = array(
+              'name' => t('@type posts in @group', array('@group' => $node->og_groups_both[$gid], '@type' => notifications_content_type_name($node->type))),
+              'type' => 'grouptype',
+              'fields' => array('group' => $gid, 'type' => $node->type)
+            );
+          }
+        }
+      }
+      return $options;
+  }
+}
+
+/**
+ * Callback for finding a template name for og subscriptions
+ */
+function og_notifications_notifications_event_get_template($event) {
+  return 'og-notifications-' . $event->action; 
+}
+
+/**
  * Options callback for subscription fields in hook_notifications. Returns a
  * list of groups for the current user (presuming that this callback is only
  * relevant in the "add subscriptions" page).
@@ -398,10 +431,8 @@
  * @return Array $options
  *   An array of the users organic groups.
  */
-function og_notifications_groups() {
-  $options = array();
-  $uid = arg(0) == 'user' && is_numeric(arg(1)) ? arg(1) : 0;
-
+function og_notifications_user_groups($subscription) {
+  $uid = $subscription->uid;
   $result = db_query("SELECT n.nid, n.title FROM {og_uid} ogu INNER JOIN {node} n USING (nid) WHERE ogu.uid = %d", $uid);
   while ($group = db_fetch_object($result)) {
     $options[$group->nid] = $group->title;
@@ -464,11 +495,9 @@
   // Remove all existing user->group subscriptions.
   og_notifications_user_unsubscribe($account, $gid);
 
-  $subscription_default = _notifications_subscription_defaults($account);
-
-  $subscription_default['uid'] = $account->uid;
-  $subscription_default['type'] = 'grouptype';
-  $subscription_default['event_type'] = 'node';
+  $subscription_default = notifications_build_subscription('grouptype');
+  $subscription_default->set_account($account);
+  $subscription_default->add_condition('group', $gid);
 
   // Only subscribe the user to enabled types.
   $content_types = array_filter(variable_get('og_notifications_content_types', array()));
@@ -478,15 +507,12 @@
     $content_types = og_get_types('group_post');
   }
   foreach ($content_types as $type) {
-    // Reset $subscription as notifications_save_subscription casts the input
-    // array into an object.
-    $subscription = $subscription_default;
+    // Clone the template to create a real subscription instance
+    $subscription = clone $subscription_default;
     // String cast due to notifications requiring it (as the value field is
     // a varchar).
-    $subscription['fields'] = array(
-      'group' => (string) $gid,
-      'type' => $type
-    );
+    $subscription->add_condition('type', $type);
+
     notifications_save_subscription($subscription);
   }
 }
@@ -504,71 +530,6 @@
   notifications_delete_subscriptions(array('uid' => $account->uid, 'type' => 'grouptype'), array('group' => $gid));
 }
 
-/**
- * Options to display for node subscriptions.
- */
-function _og_notifications_node_options($account, $node) {
-  $options = array();
-
-  // If node is a group type and the user is subscribed to this group.
-  if (og_is_group_type($node->type) && isset($account->og_groups[$node->nid])) {
-    foreach (array_filter(variable_get('og_notifications_content_types', array())) as $type) {
-      $options[] = array(
-        'name' => t('%type posts in %group', array('%group' => $node->title, '%type' => node_get_types('name', $type))),
-        'type' => 'grouptype',
-        'fields' => array('group' => $node->nid, 'type' => $type)
-      );
-    }
-  }
-  // If node is part of a group user may be subscribed to the node through one
-  // of the groups.
-  if (isset($node->og_groups)) {
-    foreach ($node->og_groups as $index => $gid) {
-      // Only members get to see subscription options.
-      if (isset($account->og_groups[$gid]) && in_array($node->type, array_filter(variable_get('og_notifications_content_types', array())))) {
-        // Content type
-        $options[] = array(
-          'name' => t('%type posts in %group', array('%group' => $node->og_groups_both[$gid], '%type' => node_get_types('name', $node->type))),
-          'type' => 'grouptype',
-          'fields' => array('group' => $gid, 'type' => $node->type)
-        );
-      }
-    }
-  }
-
-  return $options;
-}
-
-/**
- * Helper function for og_notifications_message_alter. This function checks to
- * see if the message object being passed is an OG notification.
- *
- * @param Object $message
- *   The message object.
- * @return Integer
- *   The subscription ID if this is an OG notification message. 0,
- * otherwise ...
- */
-function _og_notification_check_message($message) {
-  $sid = 0;
-
-  if (isset($message->notifications) && isset($message->notifications['subscriptions'])) {
-    $params = current($message->notifications['subscriptions']);
-    // Check if "group" is one of the fields. This is a general presumption
-    // that any subscription with at least two fields, one of them being a
-    // group, is an OG subscription.
-    foreach ($params as $current_sid) {
-      $sid = db_result(db_query("SELECT sid FROM {notifications} WHERE type = 'grouptype' AND sid = %d", $current_sid));
-      if ($sid) {
-        break;
-      }
-    }
-
-  }
-
-  return $sid > 0 ? $sid : 0;
-}
-
 // Used by Views field/filter.
 // TODO: Use constants instead of integers.
 function og_notifications_autosubscribe_map() {
