diff --git a/og_menu.module b/og_menu.module index b2658b4..93348fd 100644 --- a/og_menu.module +++ b/og_menu.module @@ -35,7 +35,6 @@ function og_menu_og_permission() { /** * Implements hook_og_ui_get_group_admin(). - * */ function og_menu_og_ui_get_group_admin($group_type, $gid) { $items = array(); @@ -216,6 +215,17 @@ function og_menu_menu() { } /** + * Implements hook_ctools_plugin_dierctory(). + * + * To let the system know where our content_type plugins are. + */ +function og_menu_ctools_plugin_directory($module, $plugin) { + if ($module == 'ctools' && !empty($plugin)) { + return "plugins/$plugin"; + } +} + +/** * Implements hook_theme_registry_alter(). */ function og_menu_theme_registry_alter(&$theme_registry) { @@ -681,8 +691,8 @@ function og_menu_node_prepare($node) { foreach ($og_fields as $field_name => $label) { $field = field_info_field($field_name); $target_type = $field['settings']['target_type']; - // The handler delivers all available targets for each content type, skip - // the ids if we already have that type's results. + // The handler delivers all available targets for each content type, + // skip the ids if we already have that type's results. if (empty($groups[$target_type])) { $instance = field_info_instance('node', $field_name, $type); // Using the handler allows us to get user options from OG without @@ -693,9 +703,9 @@ function og_menu_node_prepare($node) { foreach ($ids as $key => $values) { $field_gids += $values; } - // Not ready yet, if a user has access to menus in one group, it does - // not mean we can give him access to the menus of all groups he has - // access to. + // Not ready yet, if a user has access to menus in one group, + // it does not mean we can give him access to the menus of + // all groups he has access to. if (!empty($field_gids) && !(user_access('administer menu') || user_access('administer og menu'))) { foreach ($field_gids as $gid => $name) { if (!og_user_access($target_type, $gid, 'administer og menu')) { @@ -922,6 +932,7 @@ function og_menu_get_group_menus($groups = NULL, $user = NULL) { $query ->fields('om', array('gid', 'group_type', 'menu_name')) ->fields('m', array('title')); + $query->orderBy('title', 'ASC'); $gids_condition = db_or(); foreach ($groups as $group_type => $group_gids) { diff --git a/og_menu.pages.inc b/og_menu.pages.inc index 6c6c4f5..3b8e533 100644 --- a/og_menu.pages.inc +++ b/og_menu.pages.inc @@ -18,6 +18,13 @@ function og_menu_overview_page($group_type, $gid) { // Set the breadcrumb. og_set_breadcrumb($group_type, $gid, array(l(t('Group'), "$group_type/$gid/group"))); + // @todo Replace by D7 database independent functions. + $result = db_query(" + SELECT om.gid, om.menu_name as name, m.title as title, m.description as description FROM {og_menu} om + LEFT JOIN {menu_custom} m + ON om.menu_name = m.menu_name + WHERE om.gid = :gid + ORDER BY title", array(':gid' => $gid)); $header = array(t('Title'), array('data' => t('Operations'), 'colspan' => '3')); $rows = array(); foreach (og_menu_get_menus($group_type, $gid) as $menu) { @@ -196,7 +203,6 @@ function og_menu_edit_item_form($form, &$form_state, $type, $group_type, $gid, $ // Set the title of the page. drupal_set_title(t('Add item into menu !mtitle', array('!mtitle' => $menu['title'])), PASS_THROUGH); - // Build the form. $form['parent']['#options'] = menu_parent_options($list, array('mlid' => 0)); $form['og_menu_group_type'] = array( @@ -263,6 +269,124 @@ function og_menu_delete_item_form($form, &$form_state, $item, $group_type, $gid, } /** + * Form callback for OG Menu configuration. + */ +function og_menu_config_form($form, &$form_state) { + + $form['og_menu_block_links'] = array( + '#type' => 'checkbox', + '#title' => t('Convert OG Menu block titles into links'), + '#default_value' => variable_get('og_menu_block_links', FALSE), + '#description' => t('If enabled, OG Menu block titles will link to the groupnode.'), + ); + + $form['og_menu_create_by_default'] = array( + '#type' => 'checkbox', + '#title' => t('Automatically create a OG Menu for new Organic Group'), + '#default_value' => variable_get('og_menu_create_by_default', FALSE), + '#description' => t('If enabled, an OG Menu will be created by default when + a new Organic Group node is created.'), + ); + + $form['og_menu_context_limit'] = array( + '#type' => 'checkbox', + '#title' => t('Limit available menus to provided context'), + '#default_value' => variable_get('og_menu_context_limit', FALSE), + '#description' => t('If enabled, instead of loading all available menus on + node creation or editing, og menu will only load menus associated with the + current context. On sites with a lot of menus this can greatly improve + page performance.'), + ); + + $form['og_menu_max_menus_per_group'] = array( + '#type' => 'textfield', + '#title' => t('Maximum number of menus per group'), + '#default_value' => variable_get('og_menu_max_menus_per_group', 1), + '#size' => 20, + '#maxlength' => 5, + '#required' => TRUE, + '#description' => t("Enter 0 for no limit. Users with the 'administer menu' + permission will be able to bypass this."), + ); + + $form['og_menu_assignment'] = array( + '#type' => 'radios', + '#options' => array( + 'select' => t('Select list'), + 'autocomplete' => t('Textbox with autocomplete'), + ), + '#title' => t('Use autocomplete field on menu admin page'), + '#default_value' => variable_get('og_menu_assignment', 'autocomplete'), + '#required' => 'TRUE', + '#description' => t('Autocomplete is recommended when you have a lot of organic groups.'), + ); + + // Visibility setting to hide OG Menus on selected pages. + $form['og_menu_visibility'] = array( + '#type' => 'fieldset', + '#title' => t('Admin page visibility'), + '#description' => t("On sites with multiple OG Menus it might be prefereable + to hide them in places where you don't need them."), + ); + + $form['og_menu_visibility']['og_menu_show_blocks'] = array( + '#type' => 'checkbox', + '#title' => t("Show blocks for individual OG Menus"), + '#default_value' => variable_get('og_menu_show_blocks', FALSE), + '#description' => t("If disabled, blocks for OG Menus will be hidden from the block administration page."), + ); + $form['og_menu_visibility']['og_menu_show_nodetype'] = array( + '#type' => 'checkbox', + '#title' => t("Include OG Menus in node type menu settings"), + '#default_value' => variable_get('og_menu_show_nodetype', FALSE), + '#description' => t("If disabled, OG Menus will be hidden from the node type config page."), + ); + if (module_exists('menu_position')) { + $form['og_menu_visibility']['og_menu_show_menuposition'] = array( + '#type' => 'checkbox', + '#title' => t("Show as available parent in menu position rules."), + '#default_value' => variable_get('og_menu_show_menuposition', FALSE), + '#description' => t("If disabled, OG Menus will be hidden from the menu position parent selection dropdown."), + ); + } + if (module_exists('homebox')) { + $form['og_menu_visibility']['og_menu_show_homebox'] = array( + '#type' => 'checkbox', + '#title' => t("Show blocks in Homebox admin page"), + '#default_value' => variable_get('og_menu_show_homebox', FALSE), + '#description' => t("If disabled, blocks for OG Menus will be hidden from the homebox administration page."), + ); + } + return system_settings_form($form); +} + +/** + * Validation for OG Menu config form. + */ +function og_menu_config_form_validate($form, &$form_state) { + $max_num = $form_state['values']['og_menu_max_menus_per_group']; + if (!is_numeric($max_num)) { + form_set_error('og_menu_max_menus_per_group', t('You must enter an integer for the maximum number of menus per group.')); + } + elseif ($max_num < 0) { + form_set_error('og_menu_max_menus_per_group', t('Maximum number of menus per group must be positive.')); + } + + foreach ($form_state['values'] as $form_index => $form_val) { + if (preg_match('/^og_menu_default_links_(\w+)$/', $form_index)) { + $links = explode("\n", $form_val); + foreach ($links as $link) { + $link_parts = explode('|', $link); + if (substr($link_parts[0], 0, 1) == '/') { + form_set_error('$form_index', + t("%link is not a valid link. Make sure link does not start with a '/'.", array('%link' => $link))); + } + } + } + } +} + +/** * Callback for admin/structure/og_menu. * * Just duplicates the standard menu list, but only displays those created diff --git a/plugins/content_types/og_menu_pane_content_type.inc b/plugins/content_types/og_menu_pane_content_type.inc new file mode 100644 index 0000000..3f16897 --- /dev/null +++ b/plugins/content_types/og_menu_pane_content_type.inc @@ -0,0 +1,180 @@ + t('OG Menu pane'), + 'description' => t('This pane renders a OG Menu'), + // 'single' => TRUE means has no subtypes. + 'single' => TRUE, + // Constructor. + 'content_types' => array('og_menu_pane_content_type'), + // Name of a function which will render the pane. + 'render callback' => 'og_menu_pane_content_type_render', + 'edit form' => 'og_menu_pane_content_type_edit_form', + // Add our content type to Organic Groups category. + 'category' => t('Organic groups'), + // Optionally pass in the node context. If no context is selected, + // we will try to determine the group from the args passed. + 'required context' => new ctools_context_optional(t('Node'), 'node'), +); + +/** + * Output function for the og_menu pane content type. + */ +function og_menu_pane_content_type_render($subtype, $conf, $args, $context) { + + // Grabs the gid from the node's group ref field (for group content nodes). + if (isset($context->data->{OG_AUDIENCE_FIELD}[LANGUAGE_NONE][0])) { + $gid = $context->data->{OG_AUDIENCE_FIELD}[LANGUAGE_NONE][0]['target_id']; + } + + // This should be true for group nodes. + elseif (isset($context->data->{OG_GROUP_FIELD})) { + $gid = $context->data->nid; + } + + // If we are using something like a view, and passing in the gid + // through the URL, then the argument should hold the gid. This also + // should be true for the group node if no context was selected. + elseif (!empty($args)) { + if (og_is_group('node', $args[0])) { + $gid = intval($args[0]); + } + else { + return FALSE; + } + } + else { + return FALSE; + } + + // Get the OG menu for the group. + $groups = array('node' => array($gid)); + $menus = og_menu_get_group_menus($groups); + $conf['og_menu_index'] = !empty($conf['og_menu_index']) ? $conf['og_menu_index'] : 1; + $menu = $menus[$conf['og_menu_index'] - 1]; + + if ($menu) { + $pane = new stdClass(); + $pane->title = check_plain($menu['title']); + // Link the pane title to the group if this has been set in configuration. + if (isset($conf['og_menu_pane_block_links']) && $conf['og_menu_pane_block_links']) { + $pane->title_link = 'node/' . $gid; + } + if (module_exists('menu_block')) { + // Build up an array for menu in levels. + $conf['menu_name'] = $menu['menu_name']; + $conf['parent_mlid'] = $menu['menu_name'] . ':0'; + $conf['delta'] = 1; + $conf['sort'] = FALSE; + $conf['title_link'] = FALSE; + $conf['follow'] = FALSE; + $conf['expanded'] = isset($conf['expanded']) ? $conf['expanded'] : FALSE; + $conf['level'] = isset($conf['level']) ? $conf['level'] : 1; + $conf['depth'] = isset($conf['depth']) ? $conf['depth'] : 1; + $rendered_menu = menu_tree_build($conf); + $pane->content = $rendered_menu['content']; + } + else { + $pane->content = menu_tree($menu['menu_name']); + } + return $pane; + } + // If no menu was found return. + else { + return FALSE; + } +} + +/** + * Edit_form callback for the content type. + */ +function og_menu_pane_content_type_edit_form($form, &$form_state) { + $conf = $form_state['conf']; + + $form['og_menu_pane_block_links'] = array( + '#type' => 'checkbox', + '#title' => t('Link the title to group node'), + '#default_value' => !empty($conf['og_menu_pane_block_links']) ? $conf['og_menu_pane_block_links'] : '', + '#prefix' => '
', + '#suffix' => '
', + ); + $form['og_menu_index'] = array( + '#type' => 'select', + '#title' => t('Menu index'), + '#default_value' => $conf['og_menu_index'], + '#options' => array( + '1' => t('First Menu'), + '2' => t('Second Menu'), + '3' => t('Third Menu'), + ), + '#description' => t('Select the OG menu to display.'), + ); + $form['level'] = array( + '#type' => 'select', + '#title' => t('Starting level'), + '#default_value' => $conf['level'], + '#options' => array( + '1' => t('1st level (primary)'), + '2' => t('2nd level (secondary)'), + '3' => t('3rd level (tertiary)'), + '4' => t('4th level'), + '5' => t('5th level'), + '6' => t('6th level'), + '7' => t('7th level'), + '8' => t('8th level'), + '9' => t('9th level'), + ), + '#description' => t('Blocks that start with the 1st level will always be visible. Blocks that start with the 2nd level or deeper will only be visible when the trail to the active menu item is in the block’s tree.'), + ); + $form['depth'] = array( + '#type' => 'select', + '#title' => t('Maximum depth'), + '#default_value' => $conf['depth'], + '#options' => array( + '1' => '1', + '2' => '2', + '3' => '3', + '4' => '4', + '5' => '5', + '6' => '6', + '7' => '7', + '8' => '8', + '9' => '9', + '0' => t('Unlimited'), + ), + '#description' => t('From the starting level, specify the maximum depth of the menu tree.'), + ); + $form['expanded'] = array( + '#type' => 'checkbox', + '#title' => t('Expand all children of this tree.'), + '#default_value' => isset($conf['expanded']) ? $conf['expanded'] : 0, + ); + if (!module_exists('menu_block')) { + $form['level']['#disabled'] = TRUE; + $form['level']['#description'] = t('Requires module Menu Block
') . $form['level']['#description']; + $form['depth']['#disabled'] = TRUE; + $form['depth']['#description'] = t('Requires module Menu Block
') . $form['depth']['#description']; + $form['expanded']['#disabled'] = TRUE; + $form['expanded']['#description'] = t('Requires module Menu Block
') . $form['expanded']['#description']; + } + return $form; +} + +/** + * Submit callback for content type editing form. + */ +function og_menu_pane_content_type_edit_form_submit(&$form, &$form_state) { + foreach (element_children($form) as $key) { + if (!empty($form_state['values'][$key])) { + $form_state['conf'][$key] = $form_state['values'][$key]; + } + } +}