"; $tab_content = ""; foreach ( $settings as $conf ){ list( $name , $delta ) = explode( "-" , $conf ); //use this function to get the block content, //instead of hard code //example: array( 'module' => 'comment' , 'delta' => '0' , 'override_title' => 0 , 'override_title_text' => '' ), $temp = tabbed_block_output_content_block( array( 'module'=>$name , 'delta'=>$delta , 'override_title' => 0 , 'override_title_text' => '' ) ); //tab headers $tab_subject .= "
  • ".$temp->subject."
  • "; //tabe content $tab_content .= "
    ".$temp->content."
    "; $i++; } $tab_subject .= ""; }else{ //if no settings exists $block['subject'] = "Tabbed Block Block"; $tab_subject = ''; $tab_content = 'Configure this block'; } //tab wrapper needed for tab $block['content'] = "
    "; $block['content'] .= $tab_subject.$tab_content; $block['content'] .= "
    "; return $block; } } /** * hook_uninstall * */ function tabbed_block_uninstall(){ variable_del( 'tabbed_block_settings' ); } /** * Menu callback. Output a block content only * for ajax use only */ function tabbed_block_js() { $block = tabbed_block_block( "view" ); print drupal_to_js(array('status' => TRUE, 'content' => $block['content'] )); exit(); } /** * hook_menu() * register both ajax request path and settings menu path * */ function tabbed_block_menu($may_cache){ $items = array(); //register PHP handler for ajax request $items[] = array( 'path' => 'tabbed_block/menu', 'title' => t('Tabbed Block'), 'access' => user_access('access content'), 'type' => MENU_CALLBACK, 'callback' => 'tabbed_block_js' ); //settings path $items[] = array( 'path' => 'admin/settings/tabbed_block', 'title' => t('Tabbed Block settings'), 'access' => $access, 'callback' => 'drupal_get_form', 'callback arguments' => 'tabbed_block_admin_settings', 'description' => 'Config the tabbed block', 'type' => MENU_NORMAL_ITEM, ); $items = array_merge($items, module_invoke_all('tabbed_block_menu', $may_cache)); return $items; } /** * hook_help() * */ function tabbed_block_help($section) { switch ($section) { case 'admin/modules#tabbed_block': case 'admin/help#tabbed_block': return '

    A module with tabs blocks

    '; break; } } /** * in response to find the block html * * @param[module]:module name * @param[delta] * @param[override_title] * @param['override_title_text'] * * @return $block array */ function tabbed_block_output_content_block($conf) { $block = (object) module_invoke($conf['module'], 'block', 'view', $conf['delta']); $block->module = $conf['module']; $block->delta = $conf['delta']; if ($conf['override_title']) { $block->subject = check_plain($conf['override_title_text']); } $result = db_query("SELECT pages, visibility FROM {blocks} WHERE module = '%s' AND delta = %d",$block->module, $block->delta); $block = (object)array_merge((array)$block,(array)db_fetch_object($result)); if ($block->pages) { if ($block->visibility < 2) { $path = drupal_get_path_alias($_GET['q']); $regexp = '/^('. preg_replace(array('/(\r\n?|\n)/', '/\\\\\*/', '/(^|\|)\\\\($|\|)/'), array('|', '.*', '\1'. preg_quote(variable_get('site_frontpage', 'node'), '/') .'\2'), preg_quote($block->pages, '/')) .')$/'; $page_match = !($block->visibility xor preg_match($regexp, $path)); } else { $page_match = drupal_eval($block->pages); } } else { $page_match = TRUE; } if($page_match) { $output = $block; } return $output; } /** * core function to config wht is inside the tabbed block. * the function will not do anything to DB until save is pressed * so there is hidden fields to save the current settings until 'save' * * callback from tabbed_block_menu * * use non-drupal process flow. * * @return $form */ function tabbed_block_admin_settings( ){ $block_list = array(); //process submit if ( $_POST['form_id'] == 'tabbed_block_admin_settings' ){ //init exists blocks from POST instead of database settings if ( $_POST['exists'] ){ for( $i=0 ; $i < count($_POST['exists']) ; $i++ ){ $block_list[] = $_POST['exists'][$i]['hidden']; } } //process add block buttom if ( $_POST['op'] == t('Add block') ){ //insert the selected block into settings $block_list[] = t($_POST['block']); drupal_set_message("Added successfully.
    Note that this configuration will not be saved until you press the save buttom"); }elseif ($_POST['op'] == t('Delete all block') ){ $block_list = array(); drupal_set_message("Deleted successfully.
    Note that this configuration will not be saved until you press the save buttom"); }elseif ($_POST['op'] == t('Save') ){ variable_set( 'tabbed_block_settings' , $block_list ); drupal_set_message( "Blocks saved sucessfully." ); }elseif ( strpos( $_POST['op'] , "#" ) ){ list( $op , $key ) = explode( "#" , $_POST['op'] ); if ( $op == t("Delete") ){ array_splice( $block_list , $key , 1 ); drupal_set_message("Deleted successfully.
    Note that this configuration will not be saved until you press the save buttom"); }elseif ( $op == t("up") ){ //find the block need to move $move_block = array_slice( $block_list , $key , 1 ); //delete the moved block from array array_splice( $block_list , $key , 1 ); //a self defined function to perform re-index and insertion of $move_block $block_list = array_move( $block_list , $move_block[0] , $key-1 ); drupal_set_message("Move up successfully.
    Note that this configuration will not be saved until you press the save buttom"); }elseif ( $op == t("down") ){ //find the block need to move $move_block = array_slice( $block_list , $key , 1 ); //delete the moved block from array array_splice( $block_list , $key , 1 ); //a self defined function to perform re-index and insertion of $move_block $block_list = array_move( $block_list , $move_block[0] , $key+1 ); drupal_set_message("Move down successfully.
    Note that this configuration will not be saved until you press the save buttom"); }else{ print_r($_POST); exit(); } }else{ print_r($_POST); exit(); } }else{ //if not POST data, get current setting from DB $block_list = variable_get('tabbed_block_settings', array()); } $form['help'] = array( '#type' => 'fieldset', '#title' => t('Help'), '#collapsible' => false, '#weight' => -7, ); $form['help']['text'] = array( '#value' => t( "Use the add buttom below to add block, in order
    Or use the trash bin buttom to delete blocks.
    Note that nothing will be saved until you press the save buttom. "), ); //generate an exists block list, with their names, position, and operation buttoms $form['exists'] = array( '#type' => 'fieldset', '#title' => t('Existing block'), '#collapsible' => true, '#weight' => -6, '#tree' => TRUE, ); if ( $block_list ){ //init count of blocks $max_i = count( $block_list )-1; //generate form for each $block_list for ( $i = 0 ; $i < count($block_list) ; $i++ ){ $block = $block_list[$i]; list( $name , $delta ) = explode( "-" , $block ); $blocks_name = module_invoke( $name, 'block', 'list'); $module_path = base_path() . drupal_get_path('module', 'tabbed_block'); //delete buttom $form['exists'][$i]['delete'] = array( '#type' => 'tabbed_block_imagebutton', '#image' => $module_path . '/user-trash.png', '#title' => 'Delete this module', '#default_value' => 'Delete#'.$i, '#prefix' => "
    ", ); //move up buttom if ( $i != 0 ){ $form['exists'][$i]['up'] = array( '#type' => 'tabbed_block_imagebutton', '#image' => $module_path . '/go-up.png', '#title' => 'Go Up', '#default_value' => 'up#'.$i, ); }else{ $form['exists'][$i]['up'] = array( '#value' => '     ', ); } //move down buttom if ( $i != $max_i ){ $form['exists'][$i]['down'] = array( '#type' => 'tabbed_block_imagebutton', '#image' => $module_path . '/go-down.png', '#title' => 'Go Down', '#default_value' => 'down#'.$i, ); }else{ $form['exists'][$i]['down'] = array( '#value' => '     ', ); } //hidden field for records position on operations other than save $form['exists'][$i]['hidden'] = array( '#type' => 'hidden', '#value' => $block, ); //name of blocks for display $form['exists'][$i]['name'] = array( '#type' =>'markup', '#value' => $blocks_name[$delta]['info'], '#subfix' => "
    ", ); } $form['exists']['reset'] = array( '#type' => 'button', '#value' => t('Delete all block'), '#prefix' => "
    ", '#subfix' => "
    ", ); }else{ //message for no block configured $form['exists']['message'] = array( '#type' =>'markup', '#value' => "There is no block added currently", ); } $form['add'] = array( '#type' => 'fieldset', '#title' => t('Add block to list'), '#collapsible' => true, '#weight' => -5, ); //generate the select list of all blocks from all modules foreach (module_list() as $module) { $module_blocks = module_invoke($module, 'block', 'list'); if ($module_blocks) { $array = array(); foreach ($module_blocks as $delta => $block) { // strip_tags used because it goes through check_plain and that // just looks bad. $array["$module-$delta"] = strip_tags($block['info']); } $options[$module] = $array; } } $form['add']['block'] = array( '#type' => 'select', '#options' => $options, '#title' => t('Please select a block that you want to add'), '#width' => 20, ); $form['add']['submit'] = array( '#type' => 'button', '#value' => t('Add block'), ); $form['save']['submit'] = array( '#type' => 'button', '#value' => t('Save'), ); return $form; } /** * implement image buttom * */ function tabbed_block_imagebutton_value() { // null function guarantees default_value doesn't get moved to #value. } /** * implement image buttom theme * * @return themed image input button html */ function theme_tabbed_block_imagebutton($element) { return '\n"; } /** * hook_element() * implement image buttom, define a new element * * @return type */ function tabbed_block_elements() { $type['tabbed_block_imagebutton'] = array( '#input' => TRUE, '#button_type' => 'submit', '#executes_submit_callback' => TRUE, '#name' => 'op', '#process'=> array('tabbed_block_imagebutton_process' => array()), ); return $type; } /** * implement image buttom * * @return $form */ function tabbed_block_imagebutton_process($form) { $form['op_x'] = array( '#name' => $form['#name'] . '_x', '#input' => TRUE, '#button_type' => 'submit', '#form_submitted' => TRUE, ); return $form; } /** * define a function that move values to a specific index inside array * * @param $in_array: the array that need to be inserted * @param $insert: the insert element * @param $new_key: the position of the insert element * * @return $array: the sortted array */ function array_move( $in_array , $insert , $new_key ){ $new_array = array(); reset( $in_array ); //as there is one more element have to insert, so $i<= count for ( $i = 0 ; $i <= count( $in_array ) ; $i++ ){ if ( $i == $new_key ){ $new_array[] = $insert; }else{ $new_array[] = current( $in_array ); next( $in_array ); } } return $new_array; }