cck_blocks.module in CCK Blocks 7
Same filename and directory in other branches
File
cck_blocks.moduleView source
<?php
define('CCK_BLOCKS_FIELD_BLOCK_DISABLED', 1);
define('CCK_BLOCKS_FIELD_BLOCK_ENABLED', 2);
/**
* Implements hook_entity_info_alter().
*/
function cck_blocks_entity_info_alter(&$entity_info) {
// Add the 'CCK Blocks' view mode for nodes, users, and taxonomy terms
$entity_info['node']['view modes'] += array(
'cck_blocks' => array(
'label' => t('CCK Blocks'),
'custom settings' => TRUE,
),
);
$entity_info['taxonomy_term']['view modes'] += array(
'cck_blocks' => array(
'label' => t('CCK Blocks'),
'custom settings' => TRUE,
),
);
$entity_info['user']['view modes'] += array(
'cck_blocks' => array(
'label' => t('CCK Blocks'),
'custom settings' => TRUE,
),
);
}
/**
* Implements hook_block_info().
*/
function cck_blocks_block_info() {
$blocks = array();
$fields = field_info_fields();
foreach ($fields as $field_name => $field_info) {
if (variable_get('cck_blocks_' . $field_name . '_block_availability', CCK_BLOCKS_FIELD_BLOCK_DISABLED) == CCK_BLOCKS_FIELD_BLOCK_ENABLED) {
$blocks[$field_name] = array(
'info' => t('Field: @field ', array(
'@field' => $field_name,
)),
'cache' => DRUPAL_NO_CACHE,
);
}
}
return $blocks;
}
/**
* Implements hook_form_FORM_ID_alter().
*/
function cck_blocks_form_block_admin_configure_alter(&$form, $form_state) {
// Add 'node' as a supported token type for block titles
if (!isset($form['settings']['title']['#token_types'])) {
$form['settings']['title']['#token_types'] = array();
}
$form['settings']['title']['#token_types'] = array_merge($form['settings']['title']['#token_types'], array(
'node',
));
}
/**
* Implements hook_block_configure().
*
* @todo test and implement user tokens
* (see http://drupal.org/node/1067708 for why they are left out)
*/
function cck_blocks_block_configure() {
$form = array();
// Provide information about available tokens, if the token ui module is installed.
if (module_exists('token')) {
$token_tree = array(
'#theme' => 'token_tree',
'#token_types' => array(
'node',
'taxonomy',
),
// Specific token types to include.
'#global_types' => TRUE,
// Whether or not to include global token types like current-user, date, etc.
'#click_insert' => TRUE,
// Make tokens clickable & insert into last focused textfield
'#recursion_limit' => 2,
);
$form['view']['token_help'] = array(
'#type' => 'fieldset',
'#title' => t('Replacement patterns'),
'#collapsible' => TRUE,
'#collapsed' => TRUE,
'#description' => t('You may use the following replacement patterns in the block title. Note that node tokens will only work for fields attached to nodes, and taxonomy tokens for fields attached to terms.') . theme('token_tree', $token_tree),
);
}
return $form;
}
/**
* Implements hook_block_view().
*
* @todo Properly test and implement fieldgroup support. See http://drupal.org/node/1720502 and commented out code from http://drupal.org/node/1067708, below).
* @todo investigate conflicting 'user' token types in token replacement (from patch at http://drupal.org/node/1067708)
* @todo save entity data in $block for use by contextual links for entity types other than node.
*/
function cck_blocks_block_view($delta = '') {
$field = field_info_field($delta);
$block = array();
$field_data = FALSE;
$built_nodes =& drupal_static(__FUNCTION__);
$nid = 0;
// First, try to extract a node object form current menu router item
// using menu_get_object().
// If that doesnt work, we'll try to extract a term object and
// then finally a user object.
$entity_object = menu_get_object('node', 1);
$entity_type = 'node';
if (!$entity_object) {
$entity_object = menu_get_object('taxonomy_term', 2);
$entity_type = 'term';
if (!$entity_object) {
$entity_object = menu_get_object('user', 1);
$entity_type = 'user';
}
}
if ($entity_object) {
$block['entity_type'] = $entity_type;
switch ($entity_type) {
case 'node':
/* Determine whether the node's content is being displayed to the user.
* It is, when any revision is displayed, inlcuding the latest one.
* For example, the node's content is not visible to the user when he is
* selecting revisions for comparison or when he is editing the node.
*/
$display_nodecontent = !arg(2) || arg(2) == 'revisions' && is_numeric(arg(3));
/* Only create a block, when a node is loaded, the node's content is displayed
* to the user and the requested field is available in the fields array
*/
if (isset($entity_object->nid) && $display_nodecontent && $field) {
$nid = $entity_object->nid;
// build the node using the cck_blocks view mode if that hasn't been done yet
if (!isset($built_nodes[$nid])) {
// This alternate method from the patch at #1067708 may be needed for fieldgroup support:
// node_build_content($entity_object, 'cck_blocks');
// $built_nodes[$nid] = $entity_object;
field_attach_prepare_view('node', array(
$entity_object->nid => $entity_object,
), 'cck_blocks');
entity_prepare_view('node', array(
$entity_object->nid => $entity_object,
));
$built_nodes[$nid] = field_attach_view('node', $entity_object, 'cck_blocks');
}
// look directly for the cck_field in the content array
if (isset($built_nodes[$nid][$delta])) {
$field_data = $built_nodes[$nid][$delta];
}
// @todo patch from #1067708 used following Entity based approach, with fieldgroup support:
// This needs to be tested thorougly before use, see http://drupal.org/node/1720502
// for work on this in the 6.x branch. The two methods must be tested / combined.
//
//if (isset($entity_object->content[$delta])) {
// $field_data = $entity_object->content[$delta];
//}
//else {
// // cycle through all content data arrays looking for cck groups
// // the cck_field may be within a group
// foreach ($entity_object as $key => $data) {
// if (is_array($data) && (strpos($key, 'group_') == 0) && isset($data['group'][$delta])) {
// $field_data = $data['group'][$delta];
// }
//}
}
break;
case 'term':
if (isset($entity_object->tid) && $field) {
$built_terms =& drupal_static(__FUNCTION__);
$tid = $entity_object->tid;
// build the node in cck_blocks mode if that hasn't been done yet
if (!isset($built_terms[$tid])) {
$built_terms[$tid] = taxonomy_term_view($entity_object, 'cck_blocks');
}
// look directly for the cck_field in the term array
// TODO: deal with fieldgroups for Terms
if (isset($built_terms[$tid][$delta])) {
$field_data = $built_terms[$tid][$delta];
}
}
break;
case 'user':
if (isset($entity_object->uid) && $field) {
$uid = $entity_object->uid;
$built_users =& drupal_static(__FUNCTION__);
if (!isset($built_users[$uid])) {
user_build_content($entity_object, 'cck_blocks');
$built_users[$uid] = $entity_object->content;
}
// look directly for the cck_field in the term array
// TODO: deal with fieldgroups for Users
if (isset($built_users[$uid][$delta])) {
$field_data = $built_users[$uid][$delta];
}
}
break;
}
if ($field_data) {
$block_content = drupal_render($field_data);
if (trim($block_content) != '') {
// Evaluate tokens in a user-defined title, if token module is installed
// We load tokens according to the entity context: nodes for node pages and terms for term pages
// TODO: leaving user field tokens out for now, in case they conflict with current user tokens
// These should be tested and added back in.
global $user;
$data = array(
'user' => $user,
);
if ($entity_type != 'user') {
$data[$entity_type] = $entity_object;
}
$title = db_query("SELECT title FROM {block} WHERE delta = :delta", array(
':delta' => $delta,
))
->fetchField();
if ($title) {
$block['title'] = token_replace($title, $data);
}
/* Use the label of the field as the block's title. Only visible,
* if the user did not enter a custom title for the block as $block->subject
* is replaced by $block->title (if set) in block_list().
*/
$block['subject'] = t($field_data['#title']);
// Set the field's data as the content of the block
$block['content'] = $block_content;
// Pass entity & field info to anyone who wants to modify stuff.
switch ($entity_type) {
case 'node':
$block['node'] = $built_nodes[$nid];
$block['nid'] = $nid;
$block['field'] = $field_data;
break;
}
}
}
}
return $block;
}
/**
* Implements hook_preprocess_block().
*
* @todo add contextual links for other entity types here (user, taxonomy term, etc).
*/
function cck_blocks_preprocess_block(&$vars) {
// Set up contextual links for this CCK Block if the entity type is supported.
if ($vars['block']->module == 'cck_blocks' && !empty($vars['block']->entity_type)) {
switch ($vars['block']->entity_type) {
case 'node':
// Borrow node.modules contextual local tasks for the parent node
$vars['elements']['#contextual_links']['cck_blocks'] = array(
'node',
array(
$vars['block']->nid,
),
);
break;
}
}
}
/**
* Implements hook_contextual_links_view_alter().
*
* @todo Support other entity_types than node with this logic.
*/
function cck_blocks_contextual_links_view_alter(&$element, &$items) {
// Modify the contextual links to make them more intuitive.
if (isset($element['#links']['cck-blocks-edit'])) {
$element['#links']['cck-blocks-edit']['title'] = t('Edit Field');
// We need a better way of calculating the fragment to skip the
// user straight down to the field they want.
$element['#links']['cck-blocks-edit']['fragment'] = drupal_html_id('edit-' . str_replace('_', '-', $element['#element']['#block']->field['#field_name']));
}
if (isset($element['#links']['cck-blocks-delete'])) {
unset($element['#links']['cck-blocks-delete']);
}
}
/**
* Implements hook_form_FORM_ID_alter().
*
* Adds options to the field configuration page for making the field available as a
* block for this specific content type or for every content type that uses it.
*/
function cck_blocks_form_field_ui_field_edit_form_alter(&$form, $form_state) {
// Global settings form
$form['field']['global_block_settings'] = array(
'#type' => 'radios',
'#title' => t('Provide a block for this field using CCK Blocks'),
'#default_value' => variable_get('cck_blocks_' . $form['#field']['field_name'] . '_block_availability', CCK_BLOCKS_FIELD_BLOCK_DISABLED),
'#description' => t('When enabled, this field becomes available as a block in the block admin page. Overridden by content-type-specific settings'),
'#options' => array(
CCK_BLOCKS_FIELD_BLOCK_DISABLED => t('Disabled'),
CCK_BLOCKS_FIELD_BLOCK_ENABLED => t('Enabled'),
),
);
// Add custom form handler to the submit function
$form['#submit'][] = 'cck_blocks_field_settings_submit';
}
function cck_blocks_field_settings_submit($form, &$form_state) {
if ($form_state['values']['field']['global_block_settings'] == CCK_BLOCKS_FIELD_BLOCK_ENABLED) {
variable_set('cck_blocks_' . $form['#field']['field_name'] . '_block_availability', CCK_BLOCKS_FIELD_BLOCK_ENABLED);
}
else {
variable_del('cck_blocks_' . $form['#field']['field_name'] . '_block_availability');
}
}
Functions
Name![]() |
Description |
---|---|
cck_blocks_block_configure | Implements hook_block_configure(). |
cck_blocks_block_info | Implements hook_block_info(). |
cck_blocks_block_view | Implements hook_block_view(). |
cck_blocks_contextual_links_view_alter | Implements hook_contextual_links_view_alter(). |
cck_blocks_entity_info_alter | Implements hook_entity_info_alter(). |
cck_blocks_field_settings_submit | |
cck_blocks_form_block_admin_configure_alter | Implements hook_form_FORM_ID_alter(). |
cck_blocks_form_field_ui_field_edit_form_alter | Implements hook_form_FORM_ID_alter(). |
cck_blocks_preprocess_block | Implements hook_preprocess_block(). |