Index: og.install =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/og/og.install,v retrieving revision 1.16 diff -u -F^f -r1.16 og.install --- og.install 1 Aug 2006 23:40:03 -0000 1.16 +++ og.install 22 Aug 2006 15:26:32 -0000 @@ -26,19 +26,23 @@ function og_install() { is_admin int(1) NOT NULL DEFAULT 0, uid int(11) NOT NULL, mail_type int(11) NULL, - created int(11) NULL DEFAULT 0, - changed int(11) NULL DEFAULT 0, + created int(11) NULL DEFAULT 0, + changed int(11) NULL DEFAULT 0, PRIMARY KEY (nid, uid) ) /*!40100 DEFAULT CHARACTER SET utf8 */;"); - - $sql = "ALTER TABLE {node_access} DROP PRIMARY KEY, ADD INDEX `nid_gid_realm` ( `nid` , `gid` , `realm`)"; - db_query($sql); - $sql = "ALTER TABLE {node_access} CHANGE grant_view grant_view int(11) unsigned NOT NULL default '0'"; - db_query($sql); + db_query("CREATE TABLE {og_ancestry} ( + nid int(11) NOT NULL, + group_nid int(11) NOT NULL, + is_public int(1) NOT NULL, + PRIMARY KEY (nid), + KEY (group_nid) + ) /*!40100 DEFAULT CHARACTER SET utf8 */;"); - $sql = "UPDATE {system} SET status = 1 WHERE name = 'og_basic'"; - db_query($sql); + // TODO: use enable_module() when that hits core + // $sql = "UPDATE {system} SET status = 1 WHERE name = 'og_basic'"; + // db_query($sql); + break; case 'pgsql': db_query("CREATE TABLE {og} ( @@ -66,22 +70,19 @@ function og_install() { changed numeric(11) NULL DEFAULT 0, PRIMARY KEY (nid, uid) );"); - - $sql = "ALTER TABLE {node_access} ". - "DROP CONSTRAINT {node_access}_pkey;"; - db_query($sql); - - $sql = "CREATE INDEX nid_gid_realm ON {node_access} (nid, gid, realm);"; - db_query($sql); - - $sql = "ALTER TABLE {node_access} ". - "ALTER COLUMN grant_view TYPE numeric(11), ". - "ALTER COLUMN grant_view SET NOT NULL, ". - "ALTER COLUMN grant_view SET DEFAULT '0';"; - db_query($sql); - - $sql = "UPDATE {system} SET status = 1 WHERE name = 'og_basic'"; - db_query($sql); + + db_query("CREATE TABLE {og_ancestry} ( + nid numeric(11) NOT NULL, + group_nid numeric(11) NOT NULL, + is_public numeric(1) NOT NULL, + PRIMARY KEY (nid), + ); + CREATE INDEX group_nid_idx ON group_nid (numeric); + "); + + // TODO. use enable_module() once that hits core + // $sql = "UPDATE {system} SET status = 1 WHERE name = 'og_basic'"; + // db_query($sql); break; } @@ -291,3 +292,48 @@ function og_update_11() { } return $ret ? $ret : array(); } + +// use the new na_arbitrator way of writing to node_access table +function og_update_12() { + switch ($GLOBALS['db_type']) { + case 'mysql': + case 'mysqli': + $ret[] = update_sql("CREATE TABLE {og_ancestry} ( + nid int(11) NOT NULL, + group_nid int(11) NOT NULL, + is_public int(1) NULL, + PRIMARY KEY (nid), + KEY (group_nid) + ) /*!40100 DEFAULT CHARACTER SET utf8 */;"); + og_migrate_12(); + break; + case 'pgsql': + db_query("CREATE TABLE {og_ancestry} ( + nid numeric(11) NOT NULL, + group_nid numeric(11) NOT NULL, + is_public numeric(1) NOT NULL, + PRIMARY KEY (nid) + ); + CREATE INDEX group_nid_idx ON group_nid (numeric); + "); + break; + } + return $ret ? $ret : array(); +} + +// TODO: more testing +function og_migrate_12() { + $ret = array(); + $result = db_query_range("SELECT * FROM node_access WHERE realm IN ('og_all', 'og_subscriber') AND nid < %d", 0, 20); + while ($row = db_fetch_object($result)) { + if ($row->realm == 'og_all') { + $grants[] = array('realm' => 'og_public', 'gid' => 0, 'view' => 1, 'update' => 0, 'delete' => 0); + } + else { + $grants[] = array('realm' => 'og_subscriber', 'gid' => $row->gid, 'view' => 1, 'update' => 1, 'delete' => 0); + } + + node_access_write_grants($row, $grants); + unset($grants); + } +} \ No newline at end of file Index: og.module =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/og/og.module,v retrieving revision 1.227 diff -u -F^f -r1.227 og.module --- og.module 7 Aug 2006 19:24:02 -0000 1.227 +++ og.module 22 Aug 2006 15:26:34 -0000 @@ -35,18 +35,17 @@ function og_help($section) { switch ($section) { case 'admin/help#og': break; - case 'admin/modules#description': + case 'admin/settings/modules#description': return t("Organic groups"); - case strstr($section, 'admin/block/configure/og'): + case strstr($section, 'admin/build/block/configure/og'): return t('Group specific blocks are only visible on group pages and not on systemwide pages like the home page or admin pages.'); case 'admin/settings/og': - return t('In order to let group admins determine their own group theme, you must enable multiple themes using %page.', array('%page' => l(t('theme configuration page'), 'admin/themes'))); + return t('In order to let group admins determine their own group theme, you must enable multiple themes using !page.', array('!page' => l(t('theme configuration page'), 'admin/themes'))); } } function og_menu($may_cache) { global $user; - $items = array(); if ($may_cache) { @@ -61,8 +60,10 @@ function og_menu($may_cache) { $items[] = array('path' => 'og/deny', 'type' => MENU_CALLBACK, 'callback' => 'og_deny', 'access' => $access, 'title' => t('deny subscription request')); $items[] = array('path' => 'og/create_admin', 'type' => MENU_CALLBACK, 'callback' => 'og_create_admin', 'access' => $access, 'title' => t('create group administrator')); $items[] = array('path' => 'og/delete_admin', 'type' => MENU_CALLBACK, 'callback' => 'og_delete_admin', 'access' => $access, 'title' => t('delete group administrator')); - $items[] = array('path' => 'og/remove_node', 'type' => MENU_CALLBACK, 'callback' => 'og_remove_node', 'access' => $access, 'title' => t('remove post from group')); + $items[] = array('path' => 'og/remove_node', 'type' => MENU_CALLBACK, 'callback' => 'drupal_get_form', 'callback arguments' => array('og_remove_node'), 'access' => $access, 'title' => t('remove post from group')); $items[] = array('path' => 'og/feed', 'callback' => 'og_feed', 'title' => t('group feed'), 'type' => MENU_CALLBACK, 'access' => user_access('access content')); + + $items[] = array('path' => 'admin/settings/og', 'callback' => 'drupal_get_form', 'callback arguments' => array('og_admin_settings'), 'title' => t('organic groups configuration')); } else { // we get a NOTICE if doing this from within og_theme() so I do it here for now. @@ -75,7 +76,7 @@ function og_menu($may_cache) { $items[] = array('path' => "og/manage/$key", 'callback' => 'og_manage', 'title' => t('manage subscription'), 'callback arguments' => array($key), 'type' => MENU_CALLBACK, 'access' => user_access('access content')); $items[] = array('path' => "og/invite/$key", 'callback' => 'og_invite', 'title' => t('send invitation'), 'callback arguments' => array($key), 'type' => MENU_CALLBACK, 'access' => user_access('access content')); // group admin only - $items[] = array('path' => "og/users/$key/add", 'callback' => 'og_add_users_page', 'title' => t('add subscribers'), 'callback arguments' => array($key), 'type' => MENU_LOCAL_TASK, 'access' => node_access('update', array('nid' => $key, 'status' => 1)), 'weight' => 5); + $items[] = array('path' => "og/users/$key/add", 'callback' => 'drupal_get_form', 'title' => t('add subscribers'), 'callback arguments' => array(og_add_users, $key), 'type' => MENU_LOCAL_TASK, 'access' => node_access('update', array('nid' => $key, 'status' => 1)), 'weight' => 5); // silly page that just redirects to the group page $items[] = array('path' => "og/view/$key", 'callback' => 'og_nodeview', 'title' => $sub['title'], 'callback arguments' => array($key), 'access' => TRUE, 'type' => MENU_CALLBACK); @@ -85,7 +86,7 @@ function og_menu($may_cache) { if (arg(0) == 'node' && is_numeric(arg(1))) { $node = node_load(arg(1)); if (og_is_group_type($node->type)) { - $items[] = array('path' => 'node/'. arg(1). '/email', 'title' => t('email'), 'callback' => 'og_email', 'callback arguments' => array(arg(1)), 'access' => node_access('update', $node), 'type' => MENU_LOCAL_TASK, 'weight' => 7); + $items[] = array('path' => 'node/'. arg(1). '/email', 'title' => t('email'), 'callback' => 'drupal_get_form', 'callback arguments' => array('og_email_form', arg(1)), 'access' => node_access('update', $node), 'type' => MENU_LOCAL_TASK, 'weight' => 7); } } } @@ -105,7 +106,7 @@ function og_init() { og_theme(); og_set_locale(); - if (module_exist('views')) { + if (module_exists('views')) { include drupal_get_path('module', 'og'). '/og_views.inc'; } } @@ -185,7 +186,7 @@ function og_theme() { elseif (arg(0) == 'comment' && is_numeric(arg(2))) { $group_node = og_set_theme(arg(2)); } - + og_set_group_context($group_node); } @@ -253,23 +254,22 @@ function og_nodeview($gid) { drupal_goto("node/$gid"); } + /** * Admins may broadcast email to all their subscribers * * @param $gid * the nid of a group. */ -function og_email($gid) { + function og_email_form($gid) { $node = node_load($gid); drupal_set_title(t('Send email to %group', array('%group' => $node->title))); - $form = og_email_form($gid); - return drupal_get_form('og_email_form', $form); -} - -function og_email_form($gid) { + $result = db_query(og_list_users_sql(1), $gid); - $txt = format_plural(db_num_rows($result), '1 subscriber', 'all %count subscribers'); - drupal_set_message(t('Your email will be sent to %count in this group. Please use this feature sparingly.', array('%count' => l($txt, "og/users/$gid")))); + $txt = format_plural(db_num_rows($result), '1 subscriber', 'all @count subscribers'); + if (!$_POST) { + drupal_set_message(t('Your email will be sent to !count in this group. Please use this feature sparingly.', array('!count' => l($txt, "og/users/$gid")))); + } $form['subject'] = array('#type' => 'textfield', '#title' => t('Subject'), '#size' => 70, '#maxlength' => 250, '#description' => t("Enter a subject for your email."), '#required' => true); $form['body'] = array('#type' => 'textarea', '#title' => t('Body'), '#rows' => 5, '#cols' => 90, '#description' => t('Enter a body for your email.'), '#required' => true); @@ -283,16 +283,15 @@ function og_email_form_submit($form_id, $msg = $form_values['body']. t("\n\n--------------------------------\nThis message was sent by an administrator in the '%group' group at %site. To visit this group, browse to %url1. To unsubscribe from this group, visit %url2", array('%group' => $node->title, '%site' => variable_get('site_name', drupal), '%url1' => url("node/$node->nid", NULL, NULL, TRUE), '%url2' => url("og/unsubscribe/$node->nid", NULL, NULL, TRUE))); global $user; $from = $user->mail; - $headers = "From: $from\nReply-to: $from\nX-Mailer: Drupal\nReturn-path: $from"; $sql = og_list_users_sql(1); $result = db_query($sql, $form_values['gid']); while ($row = db_fetch_object($result)) { $emails[] = $row->mail; } foreach ($emails as $mail) { - user_mail(trim($mail), $form_values['subject'], $msg, $headers); + drupal_mail('og_mail', trim($mail), $form_values['subject'], $msg, $from); } - drupal_set_message(t('%count emails sent.', array('%count' => count($emails)))); + drupal_set_message(format_plural(count($emails), '1 email sent.', '@count emails sent')); drupal_goto("node/{$form_values[gid]}"); } @@ -306,7 +305,15 @@ function og_manage($gid) { } $group = node_load($gid); + $bc = array(l(t('home'), ''), l(t('groups'), 'og'), l($group->title, "node/$gid")); + drupal_set_breadcrumb($bc); + + return drupal_get_form('og_manage_form', $group); +} +function og_manage_form($group) { + global $user; + // avoid double messages on POST if (!$_POST) { // group manager can't unsubscribe @@ -317,18 +324,19 @@ function og_manage($gid) { drupal_set_message(t('You may not unsubscribe from this group because you are its owner. A site administrator can assign ownership to another user and then you can unsubscribe.')); } else { - $links[] = l(t('Unsubscribe from this group'), "og/unsubscribe/$gid", NULL, 'destination=og'); - $form['unsubscribe'] = array('#type' => 'markup', '#title' => t('Goodbye'), '#value' => theme('item_list', $links, t('Actions'))); + $links[] = array('unsubscribe' => array( + 'title' => t('Unsubscribe from this group'), + 'href' => "og/unsubscribe/$group->nid", + 'query' => 'destination=og' + )); + $form['unsubscribe'] = array('#type' => 'item', '#title' => t('Goodbye'), '#value' => theme('item_list', $links, t('Actions'))); } } - $form['mail_type'] = array('#type' => 'radios', '#title' => t('Email notification'), '#default_value' => $user->og_groups[$gid]['mail_type'], '#options' => array(1 => t('enabled'), 0 => t('disabled')), '#description' => t('Do you want to receive an email each time a message is posted to this group?')); + $form['mail_type'] = array('#type' => 'radios', '#title' => t('Email notification'), '#default_value' => $user->og_groups[$group->nid]['mail_type'], '#options' => array(1 => t('enabled'), 0 => t('disabled')), '#description' => t('Do you want to receive an email each time a message is posted to this group?')); $form['op'] = array('#type' => 'submit', '#value' => t('Submit')); - $form['gid'] = array('#type' => 'value', '#value' => $gid); - $output = drupal_get_form('og_manage_form', $form); - $bc = array(l(t('home'), ''), l(t('groups'), 'og'), l($group->title, "node/$gid")); - drupal_set_breadcrumb($bc); - return $output; + $form['gid'] = array('#type' => 'value', '#value' => $group->nid); + return $form; } function og_manage_form_submit($form_id, $form_values) { @@ -389,9 +397,8 @@ function og_approve($gid, $uid) { $subj = t("Subscription request approved for '%title'", array('%title' => $node->title)); $body = t('You may now post messages in this group located at %url', array('%url' => url("node/$node->nid", NULL, NULL, TRUE))); $from = variable_get('site_mail', ini_get('sendmail_from')); - $headers = "From: $from\nReply-to: $from\nX-Mailer: Drupal\nReturn-path: $from\nErrors-to: $from"; $account = user_load(array('uid' => $uid)); - user_mail($account->mail, $subj, $body, $headers); + drupal_mail('og_approve', $account->mail, $subj, $body, $from); drupal_goto("node/$gid"); } else { @@ -409,7 +416,7 @@ function og_deny($gid, $uid) { $from = variable_get('site_mail', ini_get('sendmail_from')); $headers = "From: $from\nReply-to: $from\nX-Mailer: Drupal\nReturn-path: $from\nErrors-to: $from"; $account = user_load(array('uid' => $uid)); - user_mail($account->mail, $subj, $body, $headers); + drupal_mail('og_deny', $account->mail, $subj, $body, $from); drupal_goto("node/$gid"); } else { @@ -421,7 +428,7 @@ function og_create_admin($gid, $uid) { $node = node_load($gid); if (node_access('update',$node)) { og_save_subscription($gid, $uid, array('is_admin' => 1)); - drupal_set_message(t('User was promoted to %ga', array('%ga' => theme('placeholder', t('group administrator'))))); + drupal_set_message(t('User was promoted to %ga', array('%ga' => t('group administrator')))); drupal_goto("node/$gid"); } else { @@ -433,7 +440,7 @@ function og_delete_admin($gid, $uid) { $node = node_load($gid); if (node_access('update', $node)) { og_save_subscription($gid, $uid, array('is_admin' => 0)); - drupal_set_message(t('User is no longer a %ga', array('%ga' => theme('placeholder', t('group administrator'))))); + drupal_set_message(t('User is no longer a %ga', array('%ga' => t('group administrator')))); drupal_goto("node/$gid"); } else { @@ -444,12 +451,12 @@ function og_delete_admin($gid, $uid) { function og_remove_node($gid, $nid) { if (node_access('update', node_load($gid))) { $node = node_load($nid); - $form['confirm'] = array('#type' => 'markup', '#title' => t('Confirmation'), '#value' => t('Remove %title from this group.', array('%title' => theme('placeholder', $node->title)))); + $form['confirm'] = array('#type' => 'markup', '#title' => t('Confirmation'), '#value' => t('Remove %title from this group.', array('%title' => $node->title))); $form['og_confirm'] = array('#type' => 'value', '#value' => 1); $form['op'] = array('#type' => 'submit', '#value' => t('Remove')); $form['nid'] = array('#type' => 'value', '#value' => $nid); $form['gid'] = array('#type' => 'value', '#value' => $gid); - return drupal_get_form('og_remove_node', $form); + return $form; } else { drupal_access_denied(); @@ -461,7 +468,7 @@ function og_remove_node_submit($form_id, if ($form_values['og_confirm']) { $sql = "DELETE FROM {node_access} WHERE nid=%d AND gid=%d AND realm IN ('og_subscriber', 'og_public')"; db_query($sql, $form_values['nid'], $form_values['gid']); - drupal_set_message(t('%title removed from group.', array('%title' => theme('placeholder', $node->title)))); + drupal_set_message(t('%title removed from group.', array('%title' => $node->title))); drupal_goto("node/{$form_values['gid']}"); } } @@ -469,9 +476,7 @@ function og_remove_node_submit($form_id, function og_invite($gid) { $node = node_load($gid); if ($node->og_selective < OG_INVITE_ONLY || node_access('update', $node)) { - $max = variable_get('og_email_max', 10); - $form = og_invite_form($gid); - return drupal_get_form('og_invite_form', $form); + return drupal_get_form('og_invite_form', $gid); } else { drupal_access_denied(); @@ -542,11 +547,10 @@ function og_invite_form_submit($form_id, $body .= $form_values['pmessage'] ? "\n\n ----------------------------\n". $form_values['pmessage']. "\n--------------------------------" : ''; global $user; $from = $user->mail; - $headers = "From: $from\nReply-to: $from\nX-Mailer: Drupal\nReturn-path: $from"; foreach ($emails as $mail) { - user_mail($mail, $subj, $body, $headers); + drupal_mail('og_invite_form', $mail, $subj, $body, $from); } - drupal_set_message(format_plural(count($emails), '%count invitations sent.', '%count invitations sent.')); + drupal_set_message(format_plural(count($emails), '1 invitation sent.', '@count invitations sent.')); } function og_subscribe($gid, $uid = NULL) { @@ -601,22 +605,21 @@ function og_subscribe_user($gid, $accoun $body = t('To instantly approve this request, visit %url. ', array('%url' => url("og/approve/$node->nid/$account->uid", NULL, NULL, TRUE))); $body .= t('You may deny this request or manage subscribers at %url', array('%url' => url("og/users/$node->nid", NULL, NULL, TRUE))); $from = variable_get('site_mail', ini_get('sendmail_from')); - $headers = "From: $from\nX-Mailer: Drupal\nReturn-path: $from\nErrors-to: $from"; - user_mail(implode(', ', $admins), $subj, $body, $headers); + drupal_mail(implode(', ', $admins), $subj, $body, $from); } $return_value = array('type' => 'approval', - 'message' => t('Subscription request to the %group group awaits approval by an administrator.', array('%group' => theme('placeholder', $node->title)))); + 'message' => t('Subscription request to the @group group awaits approval by an administrator.', array('@group' => $node->title))); break; case OG_OPEN: og_save_subscription($gid, $account->uid, array('is_active' => 1)); $return_value = array('type' => 'subscribed', - 'message' => t('Subscribed to the %group group', array('%group' => theme('placeholder', $node->title)))); + 'message' => t('Subscribed to the %group @group', array('@group' => $node->title))); break; case OG_CLOSED: case OG_INVITE_ONLY: $return_value = array('type' => 'rejected', - 'message' => t('Subscription request to the %group group was rejected, only group administrators can add users to this group.', array('%group' => theme('placeholder', $node->title)))); + 'message' => t('Subscription request to the @group group was rejected, only group administrators can add users to this group.', array('@group' => $node->title))); } return $return_value; } @@ -665,7 +668,7 @@ function og_list_users_sql($min_is_activ return "SELECT u.uid, u.name, u.mail, u.picture, ou.* FROM {og_uid} ou INNER JOIN {users} u ON ou.uid = u.uid WHERE ou.nid = %d AND u.status > 0 AND is_active >= $min_is_active AND is_admin >= $min_is_admin ORDER BY u.name ASC"; } -function og_add_users_page($gid) { +function og_add_users($gid) { $form['og_names'] = array('#type' => 'textarea', '#title' => t('List of users'), '#rows' => 5, @@ -674,8 +677,7 @@ function og_add_users_page($gid) { ); $form['op'] = array('#type' => 'submit', '#value' => t('Submit')); $form['gid'] = array('#type' => 'value', '#value' => $gid); - $output = drupal_get_form('og_add_users', $form); - return $output; + return $form; } function og_add_users_validate($form_id, $form_values) { @@ -708,7 +710,7 @@ function og_add_users_submit($form_id, $ foreach ($accounts as $account) { og_save_subscription($form_values['gid'], $account->uid, array('is_active' => 1)); } - drupal_set_message(t('%count added to the group', array('%count' => format_plural(count($accounts), '1 user', '%count users')))); + drupal_set_message(format_plural(count($accounts), '1 user added to the group', '@count users added to the group')); } function og_list_users_page($gid) { @@ -797,7 +799,7 @@ function og_list_groups_page_html($resul $rows[] = array(array('data' => t('No groups'), 'colspan' => 4)); } elseif (!empty($user->og_groups)) { - drupal_set_message(t('You may also view an OPML file listing RSS feeds from your subscribed groups.', array('%opml' => url('og/user/opml'))), 'help'); + drupal_set_message(t('You may also view an !opml listing RSS feeds from your subscribed groups.', array('!opml' => l(t('OPML file'), 'og/user/opml'))), 'help'); } return theme('table', $header, $rows). theme('pager', NULL, 50); } @@ -863,13 +865,8 @@ function og_get_home_nodes_sql($str_type */ function og_db_rewrite_sql($sql, $primary_table, $primary_field, $args) { if (isset($args['og_nid']) && is_numeric($args['og_nid'])) { - // we add this JOIN for node admins and when node access is disabled because node_rewrite_sql() adds it for everyone else - if (user_access('administer nodes') || node_access_view_all_nodes()) { - $query['join'] = 'INNER JOIN {node_access} na ON n.nid = na.nid'; - } - $where[] = '(na.gid = '. $args['og_nid']. " AND na.realm = 'og_subscriber')"; // private nodes - $where[] = '(na.grant_view = '. $args['og_nid']. " AND na.realm = 'og_public')"; // public nodes - $query['where'] = implode(' OR ', $where); + $query['join'] = 'INNER JOIN {og_ancestry} oga ON n.nid = oga.nid'; + $query['where'] = 'oga.group_nid = '. $args['og_nid']; return $query; } } @@ -883,7 +880,11 @@ function og_view_group(&$node, $teaser = // if you just want to change the presentation of a group home page section, redefine theme_og_list_generic() function theme_og_view($node, $teaser = FALSE, $page = FALSE) { if ($teaser || !$page) { - $node->teaser = $node->og_description; + $node->content['og_description'] = array( + '#type' => 'item', + '#title' => t('Description'), + '#value' => $node->og_description + ); } else { $bc[] = array('path' => "og", 'title' => t('groups')); @@ -894,7 +895,12 @@ function theme_og_view($node, $teaser = 'type' => 'application/rss+xml', 'title' => $node->title. t(' RSS feed'), 'href' => url("og/feed/$node->nid"))); - $output = ''; + // save the mission in an array element for use by themes if desired + // $node->content['og_mission'] = array( +// '#type' => 'item', +// '#title' => t('Mission'), +// '#value' => theme('og_mission', $node) +// ); // 2 views. 'segregate each content type' or 'a river of news' if (variable_get('og_home_page_presentation', 'gbct') == 'ron') { @@ -902,9 +908,10 @@ function theme_og_view($node, $teaser = $num = variable_get('og_max_posts', 10); $result = pager_query(db_rewrite_sql($sql, 'n', 'nid', array('og_nid' => $node->nid)), $num); while ($onenode = db_fetch_object($result)) { - $output .= node_view(node_load($onenode->nid), TRUE, FALSE); + $nodes .= node_view(node_load($onenode->nid), TRUE, FALSE); } - $output .= theme('pager', NULL, $num); + $node->content['nodes'] = array('#value' => $nodes); + $node->content['pager'] = array('#value' => theme('pager', NULL, $num)); } else { $mode = 'all'; @@ -917,18 +924,18 @@ function theme_og_view($node, $teaser = $types[$ntype] = $ntype; } $exempt = array_merge(variable_get('og_node_types', array('og')), variable_get('og_omitted', array())); - foreach ($types as $type => $val) { - if (!in_array($type, $exempt)) { - if ($table = og_list_og($node->nid, $type, $mode)) { + foreach ($types as $type) { + if (!in_array($type->type, $exempt)) { + if ($table = og_list_og($node->nid, $type->type, $mode)) { $output .= $table; } } } } $url = url("og/feed/$node->nid"); - $node->og_xml_icon = theme('xml_icon', $url); + $node->content['og_xml_icon'] = array('#value' => theme('xml_icon', $url)); - if (!$output) { + if (!$nodes) { global $user; if (in_array($node->nid, array_keys($user->og_groups))) { drupal_set_message(t('No posts in this group.')); @@ -938,14 +945,7 @@ function theme_og_view($node, $teaser = } } } - // save the homepage nodes in an array element for use by themes if desired - $node->homepage_nodes = $output; - if ($node->body) { - // save the mission in an array element for use by themes if desired - $node->og_mission = theme('og_mission', $node); - } - $node->body = $node->og_mission. $output. $node->og_xml_icon; return $node; } @@ -954,15 +954,19 @@ function theme_og_mission($node) { } /** - * Adds standard fields for any node named as a group node + * Adds standard fields for any node configured to be a group node * * @param object $node */ -function og_node_form($node) { +function og_group_form($node) { global $user; $edit = $_POST['edit']; + // all group home pages are publically accessible as far as og is concerned. their posts may or may not be. + // change this via hook_form_alter() if you want subscriber only group home pages. this may become part of og.module one day + $form['og_public'] = array('#type' => 'value', '#value' => TRUE); + $form['og_description'] = array('#type' => 'textfield', '#title' => t('Description'), '#default_value' => $node->og_description, '#size' => 70, '#maxlength' => 150, '#required' => true, '#description' => t('A brief description for the group details block and the group directory.'), '#weight' => -4); $form['og_website'] = array('#type' => 'textfield', '#title' => t('Group website'), '#default_value' => $node->og_website, '#description' => t('If your group has its own website, enter the address here.')); @@ -1017,7 +1021,7 @@ function og_node_form($node) { $default = TRUE; // fall through case OG_DIRECTORY_CHOOSE_FALSE: - $form['og_directory'] = array('#type' => 'checkbox', '#title' => t('list in groups directory'), '#default_value' => $node->nid ? $node->og_directory : $default, '#description' => t('Should this group appear on the %page?', array('%page' => l(t('list of groups page'),'og')))); + $form['og_directory'] = array('#type' => 'checkbox', '#title' => t('list in groups directory'), '#default_value' => $node->nid ? $node->og_directory : $default, '#description' => t('Should this group appear on the !page?', array('!page' => l(t('list of groups page'),'og')))); break; } @@ -1049,7 +1053,7 @@ function og_node_form($node) { } // language - if (module_exist('locale') && $languages = locale_supported_languages()) { + if (module_exists('locale') && $languages = locale_supported_languages()) { if (count($languages['name']) > 1) { $languages['name'] = array_map('check_plain', $languages['name']); $form['locale']['og_language'] = array('#type' => 'radios', @@ -1065,21 +1069,13 @@ function og_node_form($node) { return $form; } -// get og_public property for given node -function og_node_load_public($node) { - $sql = "SELECT grant_view FROM {node_access} WHERE nid = %d AND gid=0 AND realm='og_all'"; - $gv = db_result(db_query($sql, $node->nid)); - $node->og_public = $gv ? 1 : 0; - return $node; -} - // returns all the group affiliations for a given node. function og_get_node_groups($node) { if (!og_is_group_type($node->type)) { - $sql = "SELECT na.gid, n.title FROM {node_access} na INNER JOIN {node} n ON na.gid = n.nid WHERE na.nid = %d AND na.realm='og_subscriber' AND na.gid != 0"; + $sql = "SELECT oga.group_nid, n.title FROM {og_ancestry} oga INNER JOIN {node} n ON oga.nid = n.nid WHERE oga.nid = %d"; $result = db_query($sql, $node->nid); while ($row = db_fetch_object($result)) { - $groups[$row->gid] = $row->title; + $groups[$row->group_nid] = $row->title; } return $groups ? $groups : array(); } @@ -1095,14 +1091,6 @@ function og_validate_group(&$node) { } function og_submit_group(&$node) { - // if a post isn't in any groups. it must be public. this assumption is the heart of the problem with - // running multiple node permission modules at same time. ideally, all node permission modules could - // communicate and only make the node public if no permission module objected (i.e. 'deny') - // this problem needs solving in core drupal - if (empty($node->og_groups)) { - $node->og_public = 1; - } - // comments are not allowed on group nodes, since we don't have any nice way to present them if (og_is_group_type($node->type)) { $node->comment = COMMENT_NODE_DISABLED; @@ -1124,7 +1112,7 @@ function og_load_group(&$node) { $sql = 'SELECT selective AS og_selective, description AS og_description, theme AS og_theme, website AS og_website, register AS og_register, directory AS og_directory, notification AS og_notification, language AS og_language FROM {og} WHERE nid = %d'; $result = db_query($sql, $node->nid); $node = (object) array_merge((array)$node, (array)db_fetch_array($result)); - $node->comment = COMMENT_NODE_DISABLED; // we don't use comments on og nodes + $node->comment = COMMENT_NODE_DISABLED; // we don't use comments on og nodes. technically not needed since we set this on node submit } function og_insert_group($node) { @@ -1157,7 +1145,7 @@ function og_nodeapi(&$node, $op, $teaser break; case 'load': if (!og_is_group_type($node->type)) { - $node = og_node_load_public($node); + $node->og_public = db_result(db_query_range("SELECT is_public FROM {og_ancestry} WHERE nid = %d", $node->nid, 0, 1)); } else { og_load_group($node); @@ -1182,8 +1170,7 @@ function og_nodeapi(&$node, $op, $teaser } break; case 'delete': - og_delete_grants($node); - $sql = "DELETE FROM {og} WHERE nid = %d"; + $sql = "DELETE FROM {og_ancestry} WHERE nid = %d"; db_query($sql, $node->nid); $sql = "DELETE FROM {og_uid} WHERE nid = %d"; db_query($sql, $node->nid); @@ -1191,23 +1178,29 @@ function og_nodeapi(&$node, $op, $teaser case 'insert': if (og_is_group_type($node->type)) { og_insert_group($node); + // make sure the node owner is a full powered subscriber + og_save_subscription($node->nid, $node->uid, array('is_active' => 1, 'is_admin' => 1)); } - if (variable_get('og_enabled', 0)) { - og_save_permissions($node); + elseif (!og_is_omitted_type($node->type)) { + og_save_ancestry($node); } - if (!module_exist('og2list')) { + + // TODO: move this to cron to help give tiome to fix typos, and help scaling + if (!module_exists('og2list')) { if ($node->status) { $node->msgid = "$node->nid-0". og_msgid_server(); - og_mail(node_get_name($node), $node); + og_mail(node_get_types('name', $node), $node); } } break; case 'update': if (og_is_group_type($node->type)) { og_update_group($node); + // make sure the node owner is a full powered subscriber + og_save_subscription($node->nid, $node->uid, array('is_active' => 1, 'is_admin' => 1)); } - if (variable_get('og_enabled', 0)) { - og_save_permissions($node); + elseif (!og_is_omitted_type($node->type)) { + og_save_ancestry($node); } break; case 'search result': @@ -1228,16 +1221,19 @@ function og_msgid_server() { } function og_form_alter($form_id, &$form) { - $node = $form['#node']; - - if (!strpos($form_id, 'node_form') || in_array($node->type, variable_get('og_omitted', array()))) { - return; + if (strpos($form_id, 'node_form')) { + $node = $form['#node']; + if (og_is_group_type($node->type)) { + $form = array_merge($form, og_group_form($node)); + } + elseif (!in_array($node->type, variable_get('og_omitted', array()))) { + og_form_add_og_audience($form_id, $form); + } } - og_form_add_og_audience($form_id, $form); } /** - * Helper method to add OG audience fields to a given form. This is + * Helper method to add OG audience fields to a given node form. This is * lives in a separate method from og_form_alter() so it can be shared * by other OG contrib modules. */ @@ -1246,72 +1242,65 @@ function og_form_add_og_audience($form_i $edit = $_REQUEST['edit']; $node = $form['#node']; - if (og_is_group_type($node->type)) { - $form = array_merge($form, og_node_form($node)); + $required = variable_get('og_audience_required', 0); + $subs = og_get_subscriptions($node->uid); + foreach ($subs as $key => $val) { + $options[$key] = $val['title']; + } + + // TODO: this behavior is not ideal in some curcumstances. We might disable those checkboxes where admin is not a subscriber + if ($node->nid && $node->uid != $user->uid && !og_is_group_type($node->type)) { } - else { - $required = variable_get('og_audience_required', 0); - $subs = og_get_subscriptions($node->uid); - foreach ($subs as $key => $val) { - $options[$key] = $val['title']; - } - - // TODO: this behavior is not ideal in some curcumstances. We might disable those checkboxes where admin is not a subscriber - if ($node->nid && $node->uid != $user->uid && !og_is_group_type($node->type)) { - // i think this is displaying during unwanted times - // drupal_set_message(t('Admins: If you want to assign this post to a group whose checkbox does not appear below, you must first change the %author. The author\'s subscriptions are shown in the audience field.', array('%author' => theme('placeholder', t('Author'))))); - } - // get the visibility for normal users - $vis = variable_get('og_visibility', 0); - - // override visibility for og admins and when author only has 1 group - if (user_access('administer organic groups') && $vis < 2) { - $vis = $vis == OG_VISIBLE_GROUPONLY ? OG_VISIBLE_CHOOSE_PRIVATE : OG_VISIBLE_CHOOSE_PUBLIC; - } - elseif (!count($subs)) { - // don't show checkbox if no subscriptions. must be public. - $vis = OG_VISIBLE_BOTH; - } - - switch ($vis) { - case OG_VISIBLE_BOTH: - $form['og_nodeapi']['og_public'] = array('#type' => 'value', '#value' => 1); - break; - case OG_VISIBLE_GROUPONLY: - $form['og_nodeapi']['og_public'] = array('#type' => 'value', '#value' => 0); - break; + // get the visibility for normal users + $vis = variable_get('og_visibility', 0); + + // override visibility for og admins and when author only has 1 group + if (user_access('administer organic groups') && $vis < 2) { + $vis = $vis == OG_VISIBLE_GROUPONLY ? OG_VISIBLE_CHOOSE_PRIVATE : OG_VISIBLE_CHOOSE_PUBLIC; + } + elseif (!count($subs)) { + // don't show checkbox if no subscriptions. must be public. + $vis = OG_VISIBLE_BOTH; + } + + switch ($vis) { + case OG_VISIBLE_BOTH: + $form['og_nodeapi']['og_public'] = array('#type' => 'value', '#value' => 1); + break; + case OG_VISIBLE_GROUPONLY: + $form['og_nodeapi']['og_public'] = array('#type' => 'value', '#value' => 0); + break; - //user decides how public the post is. - case OG_VISIBLE_CHOOSE_PUBLIC: - $form['og_nodeapi']['visible']['og_public'] = array('#type' => 'checkbox', '#title' => t('Public'), '#default_value' => $node->nid ? $node->og_public : 1, '#description' => t('Show this post to everyone, or only to subscribers of the groups checked below. Only uncheck this box if truly needed.')); - break; - case OG_VISIBLE_CHOOSE_PRIVATE: - $form['og_nodeapi']['visible']['og_public'] = array('#type' => 'checkbox', '#title' => t('Public'), '#default_value' => $node->nid ? $node->og_public : 0, '#description' => t('Show this post to everyone, or only to subscribers of the groups checked below. Only check this box if truly needed.')); - break; - } + //user decides how public the post is. + case OG_VISIBLE_CHOOSE_PUBLIC: + $form['og_nodeapi']['visible']['og_public'] = array('#type' => 'checkbox', '#title' => t('Public'), '#default_value' => $node->nid ? $node->og_public : 1, '#description' => t('Show this post to everyone, or only to subscribers of the groups checked below. Only uncheck this box if truly needed.')); + break; + case OG_VISIBLE_CHOOSE_PRIVATE: + $form['og_nodeapi']['visible']['og_public'] = array('#type' => 'checkbox', '#title' => t('Public'), '#default_value' => $node->nid ? $node->og_public : 0, '#description' => t('Show this post to everyone, or only to subscribers of the groups checked below. Only check this box if truly needed.')); + break; + } - if (isset($edit['og_groups'])) { - // populate field from the querystring if sent - $groups = $edit['og_groups']; - } - elseif ($node->nid) { - $groups = $node->og_groups; - } - else { - $groups = array(); - } + if (isset($edit['og_groups'])) { + // populate field from the querystring if sent + $groups = $edit['og_groups']; + } + elseif ($node->nid) { + $groups = $node->og_groups; + } + else { + $groups = array(); + } - if (count($subs)) { - $form['og_nodeapi']['visible']['og_groups'] = array('#type' => 'checkboxes', '#title' => t('Audience'), '#options' => $options, '#required' => $required, '#description' => t('Show this post in these groups.'), '#default_value' => $groups); - } + if (count($subs)) { + $form['og_nodeapi']['visible']['og_groups'] = array('#type' => 'checkboxes', '#title' => t('Audience'), '#options' => $options, '#required' => $required, '#description' => t('Show this post in these groups.'), '#default_value' => $groups); + } - if (count($form['og_nodeapi']['visible']) > 1) { - $form['og_nodeapi']['#type'] = 'fieldset'; - $form['og_nodeapi']['#title'] = t('Groups'); - $form['og_nodeapi']['#collapsible'] = TRUE; - $form['og_nodeapi']['#collapsed'] = isset($edit['og_groups']) ? TRUE : FALSE; - } + if (count($form['og_nodeapi']['visible']) > 1) { + $form['og_nodeapi']['#type'] = 'fieldset'; + $form['og_nodeapi']['#title'] = t('Groups'); + $form['og_nodeapi']['#collapsible'] = TRUE; + $form['og_nodeapi']['#collapsed'] = isset($edit['og_groups']) ? TRUE : FALSE; } } @@ -1332,7 +1321,7 @@ function og_get_visibility_default() { function og_comment($comment, $op) { switch ($op) { case 'insert': - if ($comment['status'] == COMMENT_PUBLISHED && !module_exist('og2list')) { + if ($comment['status'] == COMMENT_PUBLISHED && !module_exists('og2list')) { $node = node_load($comment['nid']); $comment['og_groups'] = $node->og_groups; $comment['msgid'] = $comment['nid']. '-'. $comment['cid']. og_msgid_server(); @@ -1405,7 +1394,7 @@ function og_mail($type, $obj) { $group_home = url("node/$row->gid", NULL, NULL, TRUE); $group_name = mime_header_encode($row->group_name); $groupheaders = $headers. "\nList-Id: $group_name <$group_home>\nList-Unsubscribe: <$unsubscribe>\nList-Owner: $owner <$ownerurl>\nList-Archive: <$group_home>"; - user_mail($row->mail, $subj, $txt, $groupheaders); + drupal_mail('og_mail', $row->mail, $subj, $txt, NULL, $groupheaders); } } } @@ -1462,10 +1451,10 @@ function og_user($op, $edit, &$account, $values = array(); $result = db_query(db_rewrite_sql('SELECT n.nid, n.title, o.* FROM {node} n INNER JOIN {og} o ON n.nid = o.nid WHERE n.type IN ('. str_pad('', count(variable_get('og_node_types', array('og'))) * 5 - 1, "'%s',") .') AND o.register = 1 ORDER BY n.title'), variable_get('og_node_types', array('og'))); while ($group = db_fetch_object($result)) { - $options[$group->nid] = t('Subscribe to %name.', array('%name' => theme('placeholder', $group->title))); + $options[$group->nid] = t('Subscribe to @name.', array('@name' => $group->title)); $values[$group->nid] = in_array($group->nid, (array) $edit['og_register']) ? $group->nid : 0; if ($group->selective) { - $options[$group->nid] .= ' '. theme('placeholder', t('(approval needed)')); + $options[$group->nid] .= ' '. t('(approval needed)'); } } if (count($options)) { @@ -1501,17 +1490,9 @@ function og_user($op, $edit, &$account, } } -/** - * In the 'og_subscriber' realm, the gid is usually the nid of a group. This is used - * to store which nodes should show up in which groups. When applied to an og node, grant_view is - * always 1 but you can set it to 0 in order to have a completely private group homepage. - * In the og_public realm, the gid is always 0 but the grant_view column holds the parent group. This is needed so - * that public nodes appear on the group home page for non subscribers. The og_all realm is used to denote a public node. -**/ function og_node_grants($account, $op) { if ($op == 'view') { $grants['og_public'][] = 0; // everyone can see a public node - $grants['og_all'][] = 0; } // get subscriptions @@ -1528,114 +1509,48 @@ function og_node_grants($account, $op) { return $grants ? $grants : array(); } -function og_save_permissions(&$node) { - $sql = "DELETE FROM {node_access} WHERE realm LIKE '%s' AND nid = %d"; - db_query($sql, 'og_%', $node->nid); - - if (!og_is_group_type($node->type)) { - // put the post into each selected group. we need a separate row for public and private nodes. - // for public nodes, the grant_view column indicaOGtes which group the node belongs to. The gid=0 always. Needed to get - // public nodes to display on the home page for non subscribers - // we INSERT a broad grant here but og_node_grants() only issues it selectively for a given operation +function og_save_ancestry($node) { + if (!og_is_omitted_type($node->type)) { + $sql = "DELETE FROM {og_ancestry} WHERE nid = %d"; + db_query($sql, $node->nid); if (is_array($node->og_groups)) { foreach ($node->og_groups as $gid) { - $sql = "INSERT INTO {node_access} (nid, gid, realm, grant_view, grant_update, grant_delete) VALUES (%d, %d, 'og_subscriber', 1, 1, 1)"; - db_query($sql, $node->nid, $gid); - - if ($node->og_public) { - $sql = "INSERT INTO {node_access} (nid, gid, realm, grant_view) VALUES (%d, 0, 'og_public', %d)"; - db_query($sql, $node->nid, $gid); - } + $sql = "INSERT INTO {og_ancestry} (nid, group_nid, is_public) VALUES (%d, %d, %d)"; + db_query($sql, $node->nid, $gid, $node->og_public); } } + } +} - // if the public checkbox was selected, give a universal grant for this node - if ($node->og_public) { - $sql = "INSERT INTO {node_access} (nid, gid, realm, grant_view) VALUES (%d, 0, 'og_all', 1)"; - db_query($sql, $node->nid); +function og_node_access_records($node) { + if (og_is_omitted_type($node->type)) { + return; + } + + if (is_array($node->og_groups)) { + foreach ($node->og_groups as $gid) { + // we write a broad grant here but og_node_grants() only issues it selectively. + $grants[] = array('realm' => 'og_subscriber', 'gid' => $gid, 'grant_view' => 1, 'grant_update' => 1, 'grant_delete' => 1); } } - else { - // all groups are publically accessible, although their posts may not be - // if you really want an inaccessible group homepage, you should go to node_access table and delete the record which is inserted here. - $sql = "INSERT INTO {node_access} (nid, gid, realm, grant_view) VALUES (%d, 0, 'og_all', 1)"; - db_query($sql, $node->nid); - - // we INSERT a broad grant here but only og_node_grants() only issues it selectively. Enabes all group admins to edit the og node - $sql = "INSERT INTO {node_access} (nid, gid, realm, grant_view, grant_update, grant_delete) VALUES (%d, %d, 'og_subscriber', 1, 1, 0)"; - db_query($sql, $node->nid, $node->nid); - - // make sure the node owner is a full powered subscriber - og_save_subscription($node->nid, $node->uid, array('is_active' => 1, 'is_admin' => 1)); + + if ($node->og_public) { + $grants[] = array('realm' => 'og_public', 'gid' => 0, 'grant_view' => 1, 'grant_update' => 0, 'grant_delete' => 0); + } + + // propose a deny for non public nodes whose type matters to og and aren't in a group + if (!count($grants)) { + $grants[] = array('priority' => 10, 'realm' => 'og_public', 'gid' => 0, 'grant_view' => 0, 'grant_update' => 0, 'grant_delete' => 0); } -} - -// delete all existing grants for this module -function og_delete_grants(&$node) { - $sql = "DELETE FROM {node_access} WHERE realm LIKE '%s' AND nid = %d"; - db_query($sql, 'og_%', $node->nid); + return $grants; } -/** - * Update the node_access table when a user enables/disables the module in the - * settings page. Because Drupal does not, at this - * time, provide hooks that run automatically upon the enabling/disabling of a - * module in the admin/modules page, we must force the site-admin to explicitly - * enable/disable a module on the settings page, in - * addition to enabling/disabling the module in the admin/modules page. - * - * Here, if the user is enabling the module, we make sure the default entry in - * the node_access table is deleted and walk through all the nodes in the node table - * and grant all view access as is the default case when this module is not - * enabled. We only do this for nodes whose permissions haven't been set before by - * this module. It is possible that a site-admin may have previously enabled the - * module before disabling it. Upon re-enabling, we want to account for the old - * permissions set by the module by not re-inserting entries for them. - * - * Disabling the module simply requires re-inserting the default entry back into - * the node access table to give 'view' perms to everyone for everything: - * (0, 0, 'all', 1, 0, 0) - */ -function _og_update_db($enable) { - if (!$enable) { - // We use the delete statement to avoid inserting a duplicate entry - // into the database. Without the DELETE query, this can happen - // when a site admin has already enabled the modules from the - // settings page and goes back to it and resaves the enabled setting. - switch ($GLOBALS['db_type']) { - case 'mysql': - case 'mysqli': - db_query('REPLACE INTO {node_access} VALUES (0, 0, \'all\', 1, 0, 0)'); - break; - case 'pgsql': - $result = db_query("UPDATE {node_access} SET nid=0, gid=0, realm='all', grant_view=1, grant_update=0, grant_delete=0 WHERE nid=0 AND gid=0 and realm='all'"); - if (!db_num_rows($result)) { - db_query('INSERT INTO {node_access} VALUES (0, 0, \'all\', 1, 0, 0)'); - } - break; - } - drupal_set_message(t('Organic groups access control has been disabled. You may now disable the module on the %modules page', array('%modules' => l(t('admin/modules'), 'admin/modules')))); - } - else { - // The module was just enabled or re-enabled; provide default view - // access to everyone for nodes that were created between the previous - // disabling of the module and the current enabling of the module; - // nodes that were created during a previous enabled period are - // left-alone. Permissions for those nodes will be the same as when - // the module was previously enabled. - db_query('DELETE from {node_access} WHERE nid=0 AND gid=0 AND realm=\'all\' AND grant_view=1 AND grant_update=0 AND grant_delete=0'); - - // Assign universal grant to all non-group nodes which don't already have any grants from this module - $result = db_query("SELECT n.nid, na.gid FROM {node} n LEFT JOIN {node_access} na ON n.nid = na.nid AND realm LIKE '%og%' WHERE n.type NOT IN (". str_pad('', count(variable_get('og_node_types', array('og'))) * 5 - 1, "'%s',") .') AND na.gid IS NULL', variable_get('og_node_types', array('og'))); - while ($row = db_fetch_object($result)) { - $sql = "INSERT INTO {node_access} (nid, gid, realm, grant_view) VALUES (%d, 0, 'og_all', 1)"; - db_query($sql, $row->nid); - } - drupal_set_message(t('Organic groups access control enabled.')); - } +function og_is_omitted_type($type) { + return in_array($type, variable_get('og_omitted', array())); } + /** * Menu callback */ @@ -1712,10 +1627,11 @@ function og_block($op = 'list', $delta = function og_block_notifications() { if ($groupnode = og_get_group_context()) { - $content = t('This group offers a %groupfeed and an %email.', array('%groupfeed' => l(t('RSS feed'), 'og/feed/'. $groupnode->nid), '%email' => l(t('email subscription'), 'og/manage/'. $groupnode->nid))); - if (module_exist('views')) { + $content = t('This group offers a !groupfeed and an !email.', array('!groupfeed' => l(t('RSS feed'), 'og/feed/'. $groupnode->nid), '!email' => l(t('email subscription'), 'og/manage/'. $groupnode->nid))); + if (module_exists('views')) { $content .= t(' Or subscribe to these personalized, sitewide feeds:'); - $links[] = t('my unread: '). theme('links', array(l('feed', 'group/myunread/feed'), l('page', 'group/og_unread'))); + $links[] = t('my unread: '). theme('links', array(array('feed' => array('title' => 'feed', 'href' => 'group/myunread/feed'), 'page' => array('title' => 'page', 'href' => 'group/og_unread')))); + // TODO: new link format $links[] = t('my groups: '). theme('links', array(l('feed', 'group/mytracker/feed'), l('page', 'group/og_tracker'))); $links[] = t('all posts: '). theme('links', array(l('feed', 'group/tracker/feed'), l('page', 'groups/tracker'))); $content .= theme('item_list', $links); @@ -1833,13 +1749,12 @@ function og_block_details() { } } } - // $output = "
". check_plain($node->og_description). "
"; if ($subscription == 'active') { $links = module_invoke_all('og_create_links', $node); if ($node->og_selective < OG_INVITE_ONLY) { $links[] = l(t('invite friend'), "og/invite/$node->nid"); } - $txt = format_plural($cntall-$cntpending, '1 subscriber', '%count subscribers'); + $txt = format_plural($cntall-$cntpending, '1 subscriber', '@count subscribers'); $txt = l($txt, "og/users/$node->nid"); $txt .= $cntpending ? " ($cntpending)" : ''; $links[] = $txt; @@ -1868,7 +1783,7 @@ function og_block_details() { $links[] = l($txt, "og/subscribe/$node->nid", array(), "destination=node/$node->nid"); } else { - $links[] = t('This is a %closed group. The group administrators add/remove subscribers as needed.', array('%closed' => theme('placeholder', t('closed')))); + $links[] = t('This is a @closed group. The group administrators add/remove subscribers as needed.', array('@closed' => t('closed'))); } $output .= theme('item_list', $links); @@ -1880,27 +1795,26 @@ function og_block_details() { // $group is an object containing the group node function og_og_create_links($group) { - foreach (node_get_types() as $type => $name) { + foreach (node_get_types() as $type) { $exempt = array_merge(variable_get('og_node_types', array('og')), variable_get('og_omitted', array())); - if (!in_array($type, $exempt) && node_access('create', $type)) { - $links[] = l(t('create %type', array('%type' => $name)), "node/add/$type", array('title' => t('Add a new %s in this group.', array('%s' => $name))), "edit[og_groups][]=$group->nid"); + if (!in_array($type->type, $exempt) && node_access('create', $type->type)) { + $links[] = l(t('create !type', array('!type' => $type->name)), "node/add/$type->type", array('title' => t('Add a new %s in this group.', array('%s' => $type->name))), "edit[og_groups][]=$group->nid"); } } return $links ? $links : array(); } function og_settings_submit($form_id, $form_values) { + node_access_rebuild(); if ($_POST['op'] == t('Enable')) { - _og_update_db(TRUE); variable_set('og_enabled', 1); } elseif ($_POST['op'] == t('Disable')) { - _og_update_db(FALSE); variable_set('og_enabled', 0); } } -function og_settings() { +function og_admin_settings() { $form['#submit']['og_settings_submit'] = array(); // custom submit handler $form['#submit']['system_settings_form_submit'] = array(); // form.inc never calls the $callback if a submit handler is defined drupal_set_title(t('Organic groups configuration')); @@ -1915,44 +1829,45 @@ function og_settings() { $description = t('You usually want to enable access control with this module. The button below will delete one record in your node_access table and thus enable node permissions on your site. You may revert by clicking the same button again.'); } $form['og_settings']['og_module_status'] = array('#type' => 'fieldset', '#title' => t('Module status'), '#description' => $description); - $form['og_settings']['og_module_status']['module_action'] = array('#type' => 'submit', '#value' => $btn_text, '#prefix' => t('Organic groups access control is currently') . ' ' . theme('placeholder', $status). '.
'); + $form['og_settings']['og_module_status']['module_action'] = array('#type' => 'submit', '#value' => $btn_text, '#prefix' => t('Organic groups access control is currently %status.', array('%status' => $status)). '
'); $form['og_settings']['group_details'] = array('#type' => 'fieldset', '#title' => t('Group details')); // groups directory visibility $options = array(t('New groups don\'t appear in the groups directory. Administrators control the directory exclusively.'), t('New groups always appear in the groups directory.'), - t('Group creator chooses whether her group appears in the directory. Defaults to %in.', array('%in' => theme('placeholder', t('in directory')))), - t('Group creator chooses whether her group appears in the directory. Defaults to %out.', array('%out' => theme('placeholder', t('not in directory')))), + t('Group creator chooses whether her group appears in the directory. Defaults to %in.', array('%in' => t('in directory'))), + t('Group creator chooses whether her group appears in the directory. Defaults to %out.', array('%out' => t('not in directory'))), ); - $form['og_settings']['group_details']['og_visibility_directory'] = array('#type' => 'radios', '#title' => t('Groups directory control'), '#default_value' => variable_get('og_visibility_directory', OG_DIRECTORY_CHOOSE_TRUE), '#description' =>t('OG admins always see the checkbox for adding a group to the %dir. Note that changing this setting has no effect on existing posts. Re-save those posts to acquire this new setting.', array('%dir' => theme('placeholder', t('groups directory')))), '#options' => $options); + $form['og_settings']['group_details']['og_visibility_directory'] = array('#type' => 'radios', '#title' => t('Groups directory control'), '#default_value' => variable_get('og_visibility_directory', OG_DIRECTORY_CHOOSE_TRUE), '#description' =>t('OG admins always see the checkbox for adding a group to the %dir. Note that changing this setting has no effect on existing posts. Re-save those posts to acquire this new setting.', array('%dir' => t('groups directory'))), '#options' => $options); // groups registration visibility $options = array(t('New groups don\'t appear in on the registration form. Administrators control the form exclusively.'), t('New groups always appear on the registration form.'), - t('Group creator chooses whether her group appears on the registration form. Defaults to %in.', array('%in' => theme('placeholder', t('on form')))), - t('Group creator chooses whether her group appears on the registration form. Defaults to %out.', array('%out' => theme('placeholder', t('not on form')))), + t('Group creator chooses whether her group appears on the registration form. Defaults to %in.', array('%in' => t('on form'))), + t('Group creator chooses whether her group appears on the registration form. Defaults to %out.', array('%out' => t('not on form'))), ); - $form['og_settings']['group_details']['og_visibility_registration'] = array('#type' => 'radios', '#title' => t('Registration form control'), '#default_value' => variable_get('og_visibility_registration', OG_REGISTRATION_CHOOSE_FALSE), '#description' =>t('OG admins always see the checkbox for adding a group to the %dir. Note that changing this setting has no effect on existing posts. Re-save those posts to acquire this new setting.', array('%dir' => theme('placeholder', t('registration form')))), '#options' => $options); + $form['og_settings']['group_details']['og_visibility_registration'] = array('#type' => 'radios', '#title' => t('Registration form control'), '#default_value' => variable_get('og_visibility_registration', OG_REGISTRATION_CHOOSE_FALSE), '#description' =>t('OG admins always see the checkbox for adding a group to the %dir. Note that changing this setting has no effect on existing posts. Re-save those posts to acquire this new setting.', array('%dir' => t('registration form'))), '#options' => $options); // email subscriptions visibility $options = array(t('New group members are never subscribed to email notifications by default. Users may choose to enable this for themselves on their my subscription page.'), t('New group members are always subscribed to email notifications by default.'), - t('Group creator chooses whether her members are automatically subscribed to email notifications. Defaults to %in.', array('%in' => theme('placeholder', t('yes notification')))), - t('Group creator chooses whether her members are automatically subscribed to email notifications. Defaults to %out.', array('%out' => theme('placeholder', t('no notification')))), + t('Group creator chooses whether her members are automatically subscribed to email notifications. Defaults to %in.', array('%in' => t('yes notification'))), + t('Group creator chooses whether her members are automatically subscribed to email notifications. Defaults to %out.', array('%out' => t('no notification'))), ); - $form['og_settings']['group_details']['og_visibility_notification'] = array('#type' => 'radios', '#title' => t('Group email notifications'), '#default_value' => variable_get('og_visibility_notification', OG_NOTIFICATION_NEVER), '#description' =>t('Should new subscribers to a group automatically be notified via email when new content is posted to the group? Note that changing this setting has no effect on existing subscriptions.', array('%dir' => theme('placeholder', t('groups directory')))), '#options' => $options); + $form['og_settings']['group_details']['og_visibility_notification'] = array('#type' => 'radios', '#title' => t('Group email notifications'), '#default_value' => variable_get('og_visibility_notification', OG_NOTIFICATION_NEVER), '#description' =>t('Should new subscribers to a group automatically be notified via email when new content is posted to the group? Note that changing this setting has no effect on existing subscriptions.', array('%dir' => t('groups directory'))), '#options' => $options); $form['og_settings']['node_form'] = array('#type' => 'fieldset', '#title' => t('Node authoring form')); $form['og_settings']['node_form']['og_help'] = array('#type' => 'textarea', '#default_value' => variable_get('og_help', ''), '#cols' => 70, '#rows' =>5, '#title' => t('Explanation or submission guidelines'), '#description' => t('This text will be displayed at the top of the group submission form. It is useful for helping or instructing your users.')); - $options = array(t('Visible only within the targeted groups'), t('Visible within the targeted groups and on other pages'), t('Visibility chosen by author/editor using a checkbox on the posting form. '). t('Checkbox defaults to %pub.', array('%pub' => theme('placeholder', t('Public')))), t('Visibility chosen by author/editor using a checkbox on the posting form. '). t('Checkbox defaults to %pri.', array('%pri' => theme('placeholder', t('Private'))))); - $form['og_settings']['node_form']['og_visibility'] = array('#type' => 'radios', '#title' => t('Visibility of posts'), '#default_value' => variable_get('og_visibility', 0), '#description' =>t('Determine how broadly available a given post should be when it is affiliated with a group. OG admins always see the checkbox for making a post %pub. Note that changing this setting has no effect on existing posts. Re-save those posts to acquire this new setting.', array('%pub' => theme('placeholder', t('Public')))), '#options' => $options); + $options = array(t('Visible only within the targeted groups'), t('Visible within the targeted groups and on other pages'), t('Visibility chosen by author/editor using a checkbox on the posting form. '). t('Checkbox defaults to @pub.', array('@pub' => t('Public'))), t('Visibility chosen by author/editor using a checkbox on the posting form. '). t('Checkbox defaults to @pri.', array('@pri' => t('Private')))); + $form['og_settings']['node_form']['og_visibility'] = array('#type' => 'radios', '#title' => t('Visibility of posts'), '#default_value' => variable_get('og_visibility', 0), '#description' =>t('Determine how broadly available a given post should be when it is affiliated with a group. OG admins always see the checkbox for making a post @pub. Note that changing this setting has no effect on existing posts. Re-save those posts to acquire this new setting.', array('@pub' => t('Public'))), '#options' => $options); $options = array(t('optional'), t('required')); $form['og_settings']['node_form']['og_audience_required'] = array('#type' => 'radios', '#title' => t('Audience required'), '#default_value' => variable_get('og_audience_required', FALSE), '#options' => $options, '#description' => t('Do you require that all posts be affiliated with a group? If so, new users will be unable to complete a post until they join a group. Note that changing this setting will affect existing posts when they are edited.')); unset($options); - foreach (node_get_types() as $type => $name) { - $options[$type] = t($name); + $types = node_get_types(); + foreach ($types as $type) { + $options[$type->type] = t($type->name); } $og_node_type_options = $options; // save this for og_node_types // hide node types which are already serving as a group node @@ -1965,16 +1880,16 @@ function og_settings() { $options = array('ron' => t('River of News'), 'gbct' => t('Group by content type')); $form['og_settings']['home']['og_home_page_presentation'] = array('#type' => 'radios', '#title' => t('Presentation style'), '#options' => $options, '#default_value' => variable_get('og_home_page_presentation', 'gbct'), '#description' => t('If neither of these presentations suits you, you may override in the theme layer.')); $form['og_settings']['home']['og_max_posts'] = array('#type' => 'textfield', '#title' => t('Maximum posts on group home page'), '#size' => 3, '#maxlength' => 2, '#default_value' => variable_get('og_max_posts', 10), '#description' => t("If using River of News display, indicate the number of posts on home page. If grouping posts by content type, indicate number of posts per type."), ); - $form['og_settings']['home']['og_node_types'] = array('#type' => 'select', '#title' => t('Group home page node types'), '#default_value' => variable_get('og_node_types', array('og')), '#options' => $og_node_type_options, '#description' => t("Select the node types which act as group home pages. Usually %group is the best choice.", array('%group' => theme('placeholder', 'group'))), '#multiple' => TRUE); + $form['og_settings']['home']['og_node_types'] = array('#type' => 'select', '#title' => t('Group home page node types'), '#default_value' => variable_get('og_node_types', array('og')), '#options' => $og_node_type_options, '#description' => t("Select the node types which act as group home pages. Usually %group is the best choice.", array('%group' => 'group')), '#multiple' => TRUE); // TODO: move this to block config? Will be used elsewhere? - $form['og_settings']['og_member_pics'] = array('#type' => 'checkbox', '#title' => t('Member pictures'), '#value' => 1, '#default_value' => variable_get('og_member_pics', TRUE), '#description' => t('Should member pictures be shown in the group subscribers and group details blocks? You must also enable pictures in %user.', array('%user' => l(t('User configuration'), 'admin/settings/user')))); - return $form; + $form['og_settings']['og_member_pics'] = array('#type' => 'checkbox', '#title' => t('Member pictures'), '#value' => 1, '#default_value' => variable_get('og_member_pics', TRUE), '#description' => t('Should member pictures be shown in the group subscribers and group details blocks? You must also enable pictures in !user.', array('!user' => l(t('User configuration'), 'admin/settings/user')))); + return system_settings_form($form); } // try to get the theme's preferred way to show each type's node listing. if not specified, show the generic node listing (which is also themeable) // $mode can be 'brief' or 'all' function og_list_og($gid, $type, $mode = 'all') { - $output = theme(node_get_base($type). '_list_og', $gid, $mode); + $output = theme(node_get_types('type', $type). '_list_og', $gid, $mode); if (!$output) { $output = theme('og_list_generic', $gid, $type, $mode); } @@ -1996,7 +1911,7 @@ function theme_og_list_generic($gid, $ty if ($pager = theme('pager', NULL, $num, $i, array('ntype' => $type))) { $rows[] = array(array('data' => $pager, 'colspan' => '4')); } - return $rows ? '
' . node_get_name($type) . '' . theme('table', $header, $rows) . '
' : NULL; + return $rows ? '
' . node_get_types('name', $type) . '' . theme('table', $header, $rows) . '
' : NULL; } // TODO: maybe use a custom theme('mark') here? Index: og_basic.module =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/og/og_basic.module,v retrieving revision 1.3 diff -u -F^f -r1.3 og_basic.module --- og_basic.module 12 Jun 2006 01:05:57 -0000 1.3 +++ og_basic.module 22 Aug 2006 15:26:34 -0000 @@ -31,7 +31,7 @@ function og_basic_menu($may_cache) { * node types. This will help contributed modules catch up without much pain. */ function og_basic_node_info() { - return array('og' => array('name' => t('group'), 'base' => 'og_basic')); + return array('og' => array('name' => t('group'), 'module' => 'og_basic')); } /** Index: og_views.inc =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/og/og_views.inc,v retrieving revision 1.2 diff -u -F^f -r1.2 og_views.inc --- og_views.inc 30 Jun 2006 16:54:18 -0000 1.2 +++ og_views.inc 22 Aug 2006 15:26:35 -0000 @@ -52,8 +52,8 @@ function og_views_tables() { ) ) ), - 'og_node' => array( - 'name' => 'node_access', + 'og_ancestry' => array( + 'name' => 'og_ancestry', 'join' => array( 'left' => array( 'table' => 'node', @@ -62,18 +62,14 @@ function og_views_tables() { 'right' => array( 'field' => 'nid', ), - 'extra' => array( - 'realm' => 'og_subscriber', - 'gid != node.nid' => NULL, - ), ), ), 'og_node_data' => array( 'name' => 'node', 'join' => array( 'left' => array( - 'table' => 'og_node', - 'field' => 'gid', + 'table' => 'og_ancestry', + 'field' => 'group_nid', ), 'right' => array( 'field' => 'nid', @@ -158,19 +154,6 @@ function og_views_tables() { ), ), ), - 'node_access' => array( - 'name' => 'node_access', - 'join' => array( - 'left' => array( - 'table' => 'node', - 'field' => 'nid', - ), - 'right' => array( - 'table' => 'node_access', - 'field' => 'nid', - ) - ) - ) ); }