$type) { if (variable_get('spaces_announce_'. $k, false)) { $items[$k .'_announce'] = array( 'label' => t('!type Announcements', array('!type' => $type->name)), 'description' => t("Accept incoming !type annoucements", array('!type' => $type->name)), 'options' => array('0' => 'Off', 1 => 'On'), ); } } return $items; } /** * Implementation of hook_nodeapi * * Log viewing on view, and save primary gid relation on update and insert. */ function spaces_announce_nodeapi(&$node, $op, $teaser = NULL, $page = NULL) { if (variable_get('spaces_announce_'. $node->type, false)) { switch ($op) { case 'view': if ($gid = spaces_announce_primary_gid($node->nid)) { if (spaces_gid() != $gid) { if ($page) { // If this is not the primary group than then node is being // recieved, so we do two things; log the view, and set context. db_query("UPDATE {spaces_announce_log} a SET a.count = a.count + 1, a.viewed = %d WHERE a.nid = %d", time(), $node->nid); context_set('spaces', 'annoucement', $node->type); // If a ' NODETYPE_announcement' feature is defined give it the chance to // become the active feature. $context = new StdClass(); $context->space = 'spaces'; $context->key = 'feature'; $context->value = $node->type .'_announcement'; if ($context = context_ui_context('load', $context)) { context_set($context->space, $context->key, $context->value); } } // Add "from" text to content. $group = node_load($gid); $group_name = spaces_is_member($gid) ? l($group->title, 'node/'. $gid) : $group->title; $node->content['announce_primary_group'] = array( '#value' => theme('announce_group_label', $group_name), '#weight' => -100, ); } } break; case 'update': // If the annoucement settings have been changed for a root book page // push those changes to the rest of the book. if ($node->type == 'book' && $node->parent == 0) { _spaces_announce_apply_book_perms($node); } // Check to see if the post has a primary_gid, if it doesn't cascade // into the 'insert' case so that the primary_gid is silently corrected. if (spaces_announce_primary_gid($node->nid)) { break; } case 'insert': db_query('INSERT INTO {spaces_announce} (nid, gid) VALUES (%d, %d)', $node->nid, spaces_gid()); db_query('INSERT INTO {spaces_announce_log} (nid) VALUES (%d)', $node->nid); break; case 'delete': db_query('DELETE FROM {spaces_announce} WHERE nid = %d', $node->nid); db_query('DELETE FROM {spaces_announce_log} WHERE nid = %d', $node->nid); break; } } } /** * Implementation of hook_form_alter. */ function spaces_announce_form_alter($form_id, &$form) { // Add check box to nodetype forms if ($form_id == 'node_type_form' && isset($form['identity']['type'])) { $form['workflow']['spaces_announce'] = array( '#type' => 'checkbox', '#title' => t('Enable announcements'), '#default_value' => variable_get('spaces_announce_'. $form['#node_type']->type, 0), '#description' => t('Allow this content type to be broadcast from one group to another.'), ); } // Add group checkboxes to node forms. if (isset($form['type']) && ($form['type']['#value'] .'_node_form') && variable_get('spaces_announce_'. $form['type']['#value'], 0)) { global $user; $gid = spaces_gid(); // Retrieve the primary_gid for exiting nodes. if (is_numeric($form['#node']->nid)) { $primary_gid = spaces_announce_primary_gid($form['#node']->nid); // It's possible that a post doesn't have an assigned primary gid, so if it's in the // current group we assume that the current group is the primary one, and set the // primary_gid so that it can be respected and saved on form submission. if (!$primary_gid && in_array($gid, $form['#node']->og_groups)) { $primary_gid = $gid; } } if (!isset($primary_gid) || $primary_gid == $gid) { // Retrieve groups which the current user is a member and where the announce setting is enabled. $gids = array(); // If the user has admin nodes they can edit annoucements they didn't author and will need be // able to post posts in any groups which can recieve posts. if (user_access('administer nodes')) { $result = db_query("SELECT DISTINCT(gid), title FROM {spaces_features} i INNER JOIN {og_uid} og ON i.gid = og.nid INNER JOIN {node} n ON og.nid = n.nid WHERE i.id ='%s' AND i.type = 1 AND i.value <> 0", $form['type']['#value'] .'_announce'); } else { $result = db_query("SELECT DISTINCT(gid), title FROM {spaces_features} i INNER JOIN {og_uid} og ON i.gid = og.nid INNER JOIN {node} n ON og.nid = n.nid WHERE i.id ='%s' AND i.type = 1 AND i.value <> 0 AND og.uid = %d", $form['type']['#value'] .'_announce', $user->uid); } while ($row = db_fetch_object($result)) { $gids[$row->gid] = $row->title; } // Remove the current group from broadcast options. unset($gids[$gid]); // If the node has groups, present those - minus the primary groups, otherwise use the spaces_gid. if (isset($primary_gid)) { $active_gids = array_diff($form['#node']->og_groups, array($primary_gid)); } else { $active_gids = array(); } if (isset($form['parent']) && $form['parent']['#default_value'] !== null) { $parent = node_load($form['parent']['#default_value']); $active_gids = array_merge($active_gids, $parent->og_groups); $parent_set = true; } if (count($gids)) { if ($parent_set) { $form['announce_display'] = array( '#type' => 'checkboxes', '#title' => t('Broadcast to'), '#description' => t('Broadcast settings are controled by at the root of the book.'), // '#value' => $active_gids, '#default_value' => $active_gids, '#options' => $gids, '#disabled' => true, ); $form['announce_hidden'] = array( '#type' => 'hidden', '#value' => serialize($active_gids), ); } else { $form['announce'] = array( '#type' => 'checkboxes', '#title' => t('Broadcast to'), '#description' => t('Selected groups will recieve this post.'), '#default_value' => $active_gids, '#options' => $gids, ); } // Add after_build function to save extra og relations. $form['#after_build'][] = 'spaces_announce_group_save'; } } else { $link = cl(t('Click here'), spaces_group_path($primary_gid) .'/node/'. $form['#node']->nid, array(), null, null, false, false, true); drupal_set_message(t('This !type was not authored in this group and should not be edited here. !click_here to edit where it was created.', array('!type' => $form['type']['#value'], '!click_here' => $link))); } } elseif ($form_id == 'intranet_features_form') { $form['settings']['intranet_home']['#options']['announcements'] = t('Announcements'); } } /** * After build handler for announcement node forms. */ function spaces_announce_group_save($form, $form_values) { if (count($form['#post'])) { $gid = spaces_gid(); $gids[$gid] = $gid; if (count($form['#post']['announce'])) { $announce_gids = $form['#post']['announce']; } elseif (isset($form['#post']['announce_hidden'])) { $announce_gids = unserialize($form['#post']['announce_hidden']); } if (is_array($announce_gids)) { foreach ($announce_gids as $value) { $gids[$value] = $value; } form_set_value($form['og_nodeapi']['visible']['og_groups'], $gids); } } return $form; } /** * Recursive function to walk a book and propagate OG changes. * * @param $node * A skeletal node object, needs the following properties; nid, og_groups, og_public */ function _spaces_announce_apply_book_perms($node) { $result = db_query('SELECT b.nid, n.type FROM {book} b INNER JOIN {node} n ON b.vid = n.vid WHERE parent = %d', $node->nid); while ($child = db_fetch_object($result)) { // Add groups and privacy setting from parent. $child->og_groups = $node->og_groups; $child->og_public = $node->og_public; // Save new group relations. og_save_ancestry($child); // Process access changes. node_access_acquire_grants($child); // Recurse. _spaces_announce_apply_book_perms($child); } } /** * Retrieve the primary gid for a node. * * @param $nid * The node id of the item * * @return * Gid ie node id of the primary group. */ function spaces_announce_primary_gid($nid) { return db_result(db_query('SELECT gid FROM {spaces_announce} WHERE nid = %d', $nid)); } /** * Retrieve the view log for a announcement */ function spaces_announce_log($nid) { return db_fetch_object(db_query('SELECT count, viewed FROM {spaces_announce_log} WHERE nid = %d', $nid)); } /** * Implementation of hook_views_tables. */ function spaces_announce_views_tables() { $tables['spaces_announce'] = array( 'name' => 'spaces_announce', // 'provider' => 'internal', 'join' => array( 'left' => array( 'table' => 'node', 'field' => 'nid' ), 'right' => array( 'field' => 'nid' ) ), 'filters' => array( 'announce_cg' => array( 'name' => t('Announce: Posted in current group'), 'help' => t('Announcement was posted in current group. If page is not in any group context, no nodes are listed and thus a block would not appear.'), 'operator' => 'views_handler_operator_eqneq', 'list' => 'views_handler_filter_groupcurrent', 'list-type' => 'select', 'handler' => 'spaces_announce_handler_filter_cg', ), ), ); $tables['spaces_announce_log'] = array( 'name' => 'spaces_announce_log', // 'provider' => 'internal', 'join' => array( 'left' => array( 'table' => 'node', 'field' => 'nid' ), 'right' => array( 'field' => 'nid' ) ), 'fields' => array( 'count' => array( 'name' => t('Announce: Views Count'), 'sortable' => true, 'help' => t('This will display the number of times a node has been read.'), ), 'viewed' => array( 'name' => t('Announce: Last Viewed Time'), 'sortable' => true, 'handler' => views_handler_field_dates(), 'option' => 'string', 'help' => t('Display the time the node was last read.'), ), ), ); return $tables; } /** * Implementation of hook_views_arguments() */ function spaces_announce_views_arguments() { $args = array( 'announce_gid' => array( 'name' => t("Announce: Primary group nid(s)"), 'handler' => 'spaces_announce_handler_argument_gid', 'help' => t('Filter for posts by primary group.'), ), ); return $args; } /** * Argument handler for primary group arg */ function spaces_announce_handler_argument_gid($op, &$query, $argtype, $arg = '') { switch ($op) { case 'summary': // TODO implement a summary view return; case 'link': // TODO implement link op for summary view break; case 'sort': // TODO implement sort op for summary view break; case 'filter': $query->ensure_table('spaces_announce'); $query->add_where('spaces_announce.gid = %d', $arg); break; case 'title': return db_result(db_query_range('SELECT title FROM {node} WHERE nid = %d', $query, 0, 1));; } } /** * From picg in OG; "Lovely filter handler which restricts posts to the current group. Useful for group related blocks." * * @return void **/ function spaces_announce_handler_filter_cg($op, $filter, $filterinfo, &$query) { $query->ensure_table('spaces_announce'); $query->add_where("spaces_announce.gid ". $filter['operator'] ." ***CURRENT_GID***"); } function theme_announce_group_label($link) { return "
". t('Announcement from ') . $link ."
"; }