comment-0
[1] => blog-0
[order] => module_name-delta
)
* list of all tabbed blocks(tabbed_block_list)
Array
(
[0] => 0
[1] => 1
[index] => name
)
*
*/
/**
* hook_block()
* @param $op: list or view or Add block
* @param $delta: delta
*
* @return $block
* $block['subject']: subject of the block
* $block['content']: content of the block
*/
function tabbed_block_block( $op="list" , $delta=0 ){
static $core_sent;
if ( !$core_sent ){
$path = drupal_get_path('module', 'tabbed_block');
//include js files
//tabs
//ajax for this block
drupal_add_js( $path."/tabbed_block.js" );
}
if ( $op == "list" ){
$list = variable_get( 'tabbed_block_list', NULL );
foreach ( $list as $block_key => $block_name ){
//TODO: change the display name
$blocks[$block_key]['info'] = t("Tabbed Block").$block_key;
}
return $blocks;
}else if( $op == "view" ){
//css for this block module
drupal_add_css($path .'/tabbed_block.css');
drupal_add_js("var base_path = ".drupal_to_js(base_path()) , "inline" );
//get current settings
$settings = variable_get( 'tabbed_block_settings'.$delta , NULL);
//if there is settings:
if ( $settings ){
//currently do not use subject for this block, may override in config of block inside drupal
//TODO: enable name suuply in tabbed_block_list(v1.0+)
$block['subject'] = "";
//counter
$i = 0;
$tab_subject = "
";
$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
//catch potential empty block, redirect user to overide title
if ( $temp->subject ){
$tab_subject .= "- ".$temp->subject."
";
}else{
$tab_subject .= "- Error! click here!
";
$tab_content .= "Config title here.";
}
//tabe content
if ( $temp->content ){
$tab_content .= "".$temp->content."
";
}else{
$tab_content .= "Nothing here.
";
}
$i++;
}
$tab_subject .= "
";
}elseif( !variable_get( 'tabbed_block_list' , NULL) ){
$block['subject'] = "Tabbed Block Block";
$tab_subject = '';
$tab_content = 'No tabbed Block exists. Add';
}else{
//if 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;
}
}
/**
* Menu callback. Output a block content only
* for ajax use only
* $_POST['id'] = block-tabbed_block-0
*/
function tabbed_block_js() {
//require the block html
$block = tabbed_block_block( "view" , substr( $_POST['id'] , -1 , 1 ) );
print drupal_to_js(array('status' => TRUE, 'content' => $block['content'] ));
exit();
}
/**
* display a list of tabbed block
* from menu: admin/settings/tabbed_block/list
*
*/
function tabbed_block_list(){
$output = '';
$header = array( 'Name' , 'Operation' );
$list = variable_get( 'tabbed_block_list' , NULL );
if ( $list ){
foreach ( $list as $block_key => $block_name ){
$rows[] = array(
'tabbed_block'.$block_key ,
'edit delete' );
}
$output .= theme('table', $header, $rows);
}else{
$output = 'No Tabbed block configured';
}
return $output;
}
/**
* hook_menu()
* register both ajax request path and settings menu path
*
*/
function tabbed_block_menu($may_cache){
$items = array();
$access = user_access('administer blocks');
//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 list
$items[] = array(
'path' => 'admin/settings/tabbed_block',
'title' => t('Tabbed Block settings'),
'access' => $access,
'callback' => 'tabbed_block_list',
'description' => 'Config the tabbed block',
//'#type' => MENU_SUGGESTED_ITEM,
//'weight' => -7,
);
$items[] = array(
'path' => 'admin/settings/tabbed_block/list',
'title' => t('List'),
'access' => $access,
'callback' => 'tabbed_block_list',
'type' => MENU_DEFAULT_LOCAL_TASK,
'weight' => -7,
);
$items[] = array(
'path' => 'admin/settings/tabbed_block/add',
'title' => t('Add'),
'access' => $access,
'callback' => 'tabbed_block_add',
'type' => MENU_LOCAL_TASK,
'weight' => 0,
);
//admin/settings/tabbed_block/edit/0
if ( arg(0)=='admin' && arg(1)=='settings' && arg(2)=='tabbed_block' ){
$delta = arg(4);
//edit
if ( arg(3)=='edit' ){
$items[] = array(
'path' => 'admin/settings/tabbed_block/edit/'.$delta,
'title' => t('Edit'),
'access' => $access,
'callback' => 'drupal_get_form',
'callback arguments' => 'tabbed_block_admin_settings',
);
}elseif( arg(3)=='delete' ){
$items[] = array(
'path' => 'admin/settings/tabbed_block/delete/'.$delta,
'title' => t('Are you sure you want to delete Tabbed block ').$delta."?",
'access' => $access,
'callback' => 'drupal_get_form',
'callback arguments' => 'tabbed_block_delete',
);
}
}
$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']);
}
if ( !$block->subject ){
$temp = block_box_get( $conf['delta'] );
$block->subject = $temp['title'];
}
if ( !$block->subject ){
$temp = db_fetch_array(db_query("SELECT title FROM {blocks} WHERE module = '".$conf['module']."' AND delta ='".$conf['delta']."'" ) );
$block->subject = $temp['title'];
}
$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;
}
/**
* function for add tabbed block
*
*/
function tabbed_block_add( ){
$list = variable_get( 'tabbed_block_list' , NULL );
if ( $list ){
ksort( $list );
$max_key = $list[count($list)];
$list[] = $max_key+1 ;
}else{
$list[] = 0;
}
variable_set( 'tabbed_block_list' , $list );
drupal_set_message( 'Tabbed Block added.' );
drupal_goto( 'admin/settings/tabbed_block' );
}
/**
* Menu callback: confirm delete block
*/
function tabbed_block_delete( $form_values = NULL ) {
$form['id'] = array('#type' => 'hidden', '#value' => arg(4));
$form['warning'] = array(
'#value' => t('Please remove this block from sidebars before delete it')."
",
'#prefix' => '',
'#subfix' => '
',
);
$form['help'] = array(
'#value' => t('This action cannot be undone.')."
",
'#prefix' => '',
'#subfix' => '
',
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Delete'),
);
$form['cancel'] = array(
'#value' => "".t('Cancel')."",
);
return $form;
}
function tabbed_block_delete_submit( $form_id , $form_values ) {
$list = variable_get( 'tabbed_block_list' , NULL );
unset($list[arg(4)]);
variable_set( 'tabbed_block_list' , $list );
variable_del( 'tabbed_block_settings'.$form_values['id'] );
return 'admin/settings/tabbed_block';
}
/**
* 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( $form_values = NULL ){
global $tabbed_block_validation;
//get args passed in, to find the delta of this editing block
$module_delta = arg(4);
if ( $form_values['exists'] ){
for( $i=0 ; $i < count($form_values['exists']) ; $i++ ){
$block_list[] = $form_values['exists'][$i]['hidden'];
}
}
//process ops, before validation only
if ( $tabbed_block_validation ){
//process add block buttom
if ( $form_values['op'] == t('Add block') ){
//insert the selected block into settings
$block_list[] = $form_values['block'];
drupal_set_message("Added successfully.
Note that this configuration will not be saved until you press the save buttom");
}elseif ($form_values['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 ( strpos( $form_values['op'] , "#" ) ){
list( $op , $key ) = explode( "#" , $form_values['op'] );
if ( $op == "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 == "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 == "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{
drupal_set_message( "Error!
Debug information:
Error during op, form generating phase, with #, unknown op: ".$op , "error" );
}
}elseif ( $op == t("Save") ){
//dummy, never reach here
tabbed_block_admin_settings_submit( 'tabbed_block_admin_settings' , $form_values );
}elseif ( empty($op) ){
//save if and only if after this function is the second time arrive
tabbed_block_admin_settings_submit( 'tabbed_block_admin_settings' , $form_values );
}else{
drupal_set_message( "Error!
Debug information:
Error during op, form generating phase, unknown op: ".$op , "error" );
}
$tabbed_block_validation = FALSE;
}else{
//if not POST data, get current setting from DB
$block_list = variable_get('tabbed_block_settings'.$module_delta, 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 , 2 );
$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' => 'button',
'#image' => $module_path . '/user-trash.png',
'#title' => 'Delete this module',
'#value' => 'Delete#'.$i,
'#prefix' => "",
'#attributes' => array('style' => 'background-image:url(../../../../modules/tabbed_block/user-trash.png);'),
);
//move up buttom
if ( $i != 0 ){
$form['exists'][$i]['up'] = array(
'#type' => 'button',
'#image' => $module_path . '/go-up.png',
'#title' => 'Go Up',
'#value' => 'up#'.$i,
'#attributes' => array('style' => 'background-image:url(../../../../modules/tabbed_block/go-up.png);'),
);
}else{
$form['exists'][$i]['up'] = array(
'#value' => ' ',
);
}
//move down buttom
if ( $i != $max_i ){
$form['exists'][$i]['down'] = array(
'#type' => 'button',
'#image' => $module_path . '/go-down.png',
'#title' => 'Go Down',
'#value' => 'down#'.$i,
'#attributes' => array('style' => 'background-image:url(../../../../modules/tabbed_block/go-down.png);'),
);
}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['reset'] = array(
'#type' => 'button',
'#value' => t('Delete all block'),
);
}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');
// do not display blocks that is from tabbed_block, which means, do not support recursive blocks
if ($module_blocks && $module != 'tabbed_block') {
$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' => 30,
);
$form['add']['submit'] = array(
'#type' => 'button',
'#value' => t('Add block'),
);
$form['delta'] = array(
'#type' => 'hidden',
'#value' => $module_delta,
);
$form['save']['submit'] = array(
'#type' => 'button',
'#value' => t('Save'),
);
$form['#multistep'] = TRUE;
$form['#redirect'] = FALSE;
return $form;
}
/**
* validate
* it is used to prevent double process of thr form, if op is not save
*
*/
function tabbed_block_admin_settings_validate( $form_id , $form_values ){
global $tabbed_block_validation;
$tabbed_block_validation = TRUE;
}
/**
* submit
* this function will not do anything unless $form_values['exists'] is set to
* which means, hook_submit do not process anything, as ['exists'] is build by tabbed_block_admin_settings(), if validation is true
*
* it is only called by tabbed_block_admin_setting(), as a normal function call.
*/
function tabbed_block_admin_settings_submit( $form_id , $form_values ){
//process submit
$variable = 'tabbed_block_settings'.arg(4);
//init exists blocks from POST instead of database settings
if ( $form_values['exists'] ){
for( $i=0 ; $i < count($form_values['exists']) ; $i++ ){
$block_list[] = $form_values['exists'][$i]['hidden'];
}
if ($form_values['op'] == t('Save') ){
variable_set( $variable , $block_list );
drupal_set_message( "Blocks saved sucessfully." );
}
}else{
//nothing here. delete all blocks will arrive true here.
variable_del( $variable );
drupal_set_message( "All Blocks deleted sucessfully." );
}
return 'admin/settings/tabbed_block';
}
/**
* 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;
}