block_inject.module in Block Inject 7
The Block Inject module functions.
File
block_inject.moduleView source
<?php
/**
* @file
* The Block Inject module functions.
*/
/**
* Implements hook_boot().
*
* In order to make sure Block Inject gets loaded very early on in the
* bootstrapping phase.
*/
function block_inject_boot() {
// Empty on purpose.
}
/**
* Implements hook_permission().
*/
function block_inject_permission() {
return array(
'administer block inject' => array(
'title' => t('Administer the Block Inject module'),
),
'override default block injection' => array(
'title' => t('Override default behaviour per node'),
),
);
}
/**
* Implements hook_menu().
*/
function block_inject_menu() {
$items['admin/structure/block-inject'] = array(
'title' => 'Block Inject',
'description' => 'Create block regions to inject into content',
'page callback' => 'block_inject_list',
'access arguments' => array(
'administer block inject',
),
'type' => MENU_NORMAL_ITEM,
'file' => 'block_inject.admin.inc',
);
$items['admin/structure/block-inject/exceptions'] = array(
'title' => 'Exceptions',
'description' => 'Nodes excepted from being injected',
'page callback' => 'block_inject_exceptions_list',
'access arguments' => array(
'administer block inject',
),
'type' => MENU_NORMAL_ITEM,
'file' => 'block_inject.admin.inc',
);
$items['admin/structure/block-inject/add'] = array(
'title' => 'Add inject region',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'block_inject_add_inject_form',
),
'access arguments' => array(
'administer block inject',
),
'type' => MENU_LOCAL_ACTION,
'file' => 'block_inject.admin.inc',
);
$items['admin/structure/block-inject/%/delete'] = array(
'title' => 'Delete block inject region',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'block_inject_delete_confirm',
3,
),
'access arguments' => array(
'administer block inject',
),
'type' => MENU_CALLBACK,
'file' => 'block_inject.admin.inc',
);
$items['admin/structure/block-inject/%/edit'] = array(
'title' => 'Edit block inject region',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'block_inject_edit_form',
3,
),
'access arguments' => array(
'administer block inject',
),
'type' => MENU_CALLBACK,
'file' => 'block_inject.admin.inc',
);
return $items;
}
/**
* Returns all the content types available on the site.
*/
function block_inject_get_all_node_types() {
$query = db_select('node_type', 'nt')
->fields('nt', array(
'type',
'name',
));
$result = $query
->execute();
$records = array();
foreach ($result as $record) {
$records[$record->type] = check_plain($record->name);
}
return $records;
}
/**
* Checks if the node type exists already in the "block_inject" table and
* returns an array of the available node types (not used in any region).
*/
function block_inject_get_node_types() {
// Get all node types on the site.
$site_node_types = block_inject_get_all_node_types();
// Get all the regions in the "block_inject" table.
$regions = block_inject_get_regions();
$existing_node_types = array();
// Create array containing the node types used in regions.
foreach ($regions as $region) {
// Foreach region, check if it has multiple node types assigned.
if (strpbrk($region->node_type, ', ') != FALSE) {
// If multiple node types on a region, create array with the node types
// for each of the regions with multiple node types.
$existing_node_types_array = explode(', ', $region->node_type);
// Add each of those node types into the final array.
foreach ($existing_node_types_array as $type) {
$existing_node_types[] = $type;
}
}
else {
// If only one node type in a region, add it to the final node type array.
$existing_node_types[] = $region->node_type;
}
}
// Update array and remove the node types that are used regions.
foreach ($existing_node_types as $type) {
unset($site_node_types[$type]);
}
return $site_node_types;
}
/**
* Implements hook_system_info_alter().
*/
function block_inject_system_info_alter(&$info, $file, $type) {
if ($type == 'theme') {
// Using the deprecated function to retrieve the regions in order to avoid
// problems during the update.php process.
$regions = _block_inject_get_regions_old();
// Add regions to the site.
foreach ($regions as $region) {
$info['regions']['block_inject-' . $region->id] = t('Block Inject: @title', array(
'@title' => $region->region,
));
}
}
}
/**
* Implements hook_node_view().
*/
function block_inject_node_view($node, $view_mode, $langcode) {
// Only apply if we are looking at the full view mode.
if ($view_mode !== 'full') {
return;
}
// Check if there is an injectable region for this node type.
$injectable = block_inject_get_region_by_node_type($node->type);
if (!$injectable) {
return;
}
// Inject the region.
$render = block_inject_do_injection($node, $injectable);
if ($render) {
$node->content['body'][0]['#markup'] = $render;
}
}
/**
* Implements hook_panels_pane_content_alter().
*/
function block_inject_panels_pane_content_alter($content, $pane, $args, $contexts) {
$pane_types = array(
'entity_field',
'node_content',
);
$pane_subtypes = array(
'node:body',
'node_content',
);
if (!in_array($pane->type, $pane_types)) {
return;
}
if (!in_array($pane->subtype, $pane_subtypes)) {
return;
}
if (!isset($contexts['argument_entity_id:node_1'])) {
return;
}
$node = $contexts['argument_entity_id:node_1']->data;
// Check if there is an injectable region for this node type.
$injectable = block_inject_get_region_by_node_type($node->type);
if (!$injectable) {
return;
}
$render = block_inject_do_injection($node, $injectable);
if (!$render) {
return;
}
// For the body field panel pane.
if ($pane->subtype === 'node:body') {
$content->content[0]['#markup'] = $render;
}
// For the node content panel pane.
if ($pane->subtype === 'node_content') {
$content->content['body'][0]['#markup'] = $render;
}
}
/**
* Helper function that prepares and calls the injection on a node.
*
* @param $node
* The node object that gets injected
*
* @param $injectable
* The injectable that goes into the node's body field
*
* @return string
* The markup of the injected body field.
*/
function block_inject_do_injection($node, $injectable) {
// Check for exceptions.
$exception = block_inject_green_light($node->nid);
$go_ahead = FALSE;
if (empty($exception)) {
$go_ahead = TRUE;
}
elseif ($exception['bi_id'] != $injectable->id) {
$go_ahead = TRUE;
}
if (!$go_ahead) {
return FALSE;
}
// Return the blocks for each region to be injected into a variable.
$region = block_get_blocks_by_region('block_inject-' . $injectable->id);
// Prepare the attributes for the region div.
$classes = array(
'block-inject',
'block-inject-' . $injectable->id,
);
$attributes = array(
'id' => 'block-inject-' . $injectable->id,
'class' => $classes,
);
// Create hook_block_inject_attributes_alter($attributes).
$clearfix = true;
$vars = array(
'node' => clone $node,
'attributes' => &$attributes,
'clearfix' => &$clearfix,
);
drupal_alter('block_inject_attributes', $vars);
// Get the body field.
$body = block_inject_get_body_from_node($node);
// Check for default conditions for offset.
$offset = 0;
$condition = block_inject_process_condition($node->type, $body);
if ($condition) {
$offset = $condition;
}
// Check if there is an individual offset on the node.
$get_offset = block_inject_get_offset($node->nid);
if (isset($get_offset)) {
$offset = $offset + $get_offset['offset'];
}
// Try the injection and return the injected body.
if ($render = block_inject_node($region, $body, $offset, $attributes, $clearfix)) {
return $render;
}
}
/**
* Injects the region in the middle of the node.
*
* @param array $region
* An array of the regions to be injected.
*
* @param string $body
* The body field to be injected in.
*
* @return bool|string
* The injected body string or false if not enough paragraphs.
*/
function block_inject_node($region, $body, $offset = 0, $attributes = array(), $clearfix = true) {
// Break up the body field string into an array of paragraphs.
$array_explode = explode("<p>", $body);
if ($array_explode[0] === "") {
unset($array_explode[0]);
}
// Return false if the number of paragraphs is not at least 4.
if (count($array_explode) < 4) {
return FALSE;
}
// Get the half number of the total number of paragraphs (round up).
$array_explode_half = round(count($array_explode) / 2);
// Add the attributes to the region renderable array
$region['#prefix'] = '<div ' . drupal_attributes($attributes) . '>';
$region['#suffix'] = '</div>';
// Add a clearfix div if requested
if ($clearfix === true) {
$region['#suffix'] .= '<div class="clearfix"></div>';
}
// Insert the renderable region array into the middle of the body field.
array_splice($array_explode, $array_explode_half + $offset, 0, render($region));
// Re-create the body field string with the region injected.
return block_inject_implode_paragraphs($array_explode);
}
/**
* Takes an array of exploded paragraphs which contain the injected region wrapped
* in a div and 'implodes' them back into a string.
*
* @param $exploded
* Array of exploded paragraphs
*
* @return string
*/
function block_inject_implode_paragraphs($exploded) {
$output = '';
foreach ($exploded as $paragraph) {
if (strpos($paragraph, '<div') === 0) {
$output .= $paragraph;
continue;
}
$output .= '<p>' . $paragraph;
}
return $output;
}
/**
* Retrieves from the database the existing declared regions for injection.
*
* Deprecated function introduced for the smooth update to 7.x-1.2-alpha4
*/
function _block_inject_get_regions_old() {
$result = db_select('block_inject', 'bi')
->fields('bi', array(
'region',
'node_type',
'id',
'node_name',
))
->orderBy('region', 'ASC')
->execute();
return $result;
}
/**
* Retrieves from the database the existing declared regions for injection.
*/
function block_inject_get_regions() {
$result = db_select('block_inject', 'bi')
->fields('bi', array(
'region',
'node_type',
'id',
'node_name',
'bi_condition',
))
->orderBy('region', 'ASC')
->execute();
return $result;
}
/**
* Retrieves from the database the a region for a specific node type.
*
* @param $type
* The node type
*
* @return mixed
* The region or false if none exists
*/
function block_inject_get_region_by_node_type($type) {
$regions = block_inject_get_regions();
foreach ($regions as $region) {
// If the region has only one node type assigned,
// proceed with the injection.
if ($type == $region->node_type) {
return $region;
}
// If there are more node types this region needs to be injected in, check
// if the current one is among them.
$node_types = explode(', ', $region->node_type);
if (in_array($type, $node_types)) {
return $region;
}
}
return FALSE;
}
/**
* Retrieves one existing declared region for injection.
*/
function block_inject_get_region_by_id($id) {
$result = db_select('block_inject', 'bi')
->fields('bi', array(
'region',
'node_type',
'id',
'node_name',
'bi_condition',
))
->condition('id', $id)
->orderBy('region', 'ASC')
->execute()
->fetchObject();
return $result;
}
/**
* Rebuilds data, clears caches.
*/
function block_inject_rebuild_data() {
cache_clear_all();
system_rebuild_theme_data();
drupal_theme_rebuild();
}
/**
* Adds a new region to the database
*
* @param string $region
* The region name.
*
* @param string $node_type
* The machine readable node type name it applies for.
*
* @param string $node_type_name
* The human readable node type name it applies for.
*
* @param string $condition
* Serialized array for the condition.
*/
function block_inject_add_region($region, $node_type, $node_type_name, $condition = NULL) {
$insert = db_insert('block_inject')
->fields(array(
'region' => $region,
'node_type' => $node_type,
'node_name' => $node_type_name,
'bi_condition' => $condition,
))
->execute();
}
/**
* Deletes a region from the database.
*
* @param int $id
* Id of the region to be deleted.
*/
function block_inject_remove_region($id) {
$db_remove = db_delete('block_inject')
->condition('id', $id)
->execute();
block_inject_rebuild_data();
}
/**
* Updates a region in the database.
*
* @param int $id
* Id of the region to be updated.
*
* @param string $new_region
* The new region name.
*
* @param string $new_node_type
* The new machine readable node type name it applies for.
*
* @param string $new_node_type_name
* The new human readable node type name it applies for.
*/
function block_inject_update_region($id, $new_region, $new_node_type, $new_node_type_name, $condition = NULL) {
$db_edit = db_update('block_inject')
->fields(array(
'region' => $new_region,
'node_type' => $new_node_type,
'node_name' => $new_node_type_name,
'bi_condition' => $condition,
))
->condition('id', $id)
->execute();
}
/**
* Checks for duplicate region names.
*
* @param string $region_name
* Name of the region to be checked.
*
* Returns FALSE if the region name is already used, TRUE if it is not.
*/
function block_inject_check_region_name($region_name) {
$result = db_select('block_inject', 'bi')
->fields('bi', array(
'region',
))
->condition('region', $region_name)
->orderBy('region', 'ASC')
->execute()
->fetchAssoc();
if (strtolower($result['region']) == strtolower($region_name)) {
return FALSE;
}
else {
return TRUE;
}
}
/**
* Implements hook_form_FORM-ID_alter().
*
* Adds to the node edit form the Block Inject elements (offset & exception)
*
*/
function block_inject_form_node_form_alter(&$form, &$form_state, $form_id) {
// Gets the node info in dedicated vars.
$node_type = $form['type']['#value'];
$node = $form['#node'];
// Stores the block inject ID for the node type of this form, if exists.
$bi = block_inject_find_bi_id($node_type);
// Checks if $bi contains anything.
// If contains, can go ahead and add the exception checkbox onto the form.
if ($bi) {
// Checks if there is an exception in the table for this nid
$bi_exception_default_value = 0;
if (isset($form['nid']['#value'])) {
$check_exception = block_inject_green_light($node->nid);
if ($check_exception) {
// If there is, sets the default value to 1, else it stays 0.
$bi_exception_default_value = 1;
}
// Set the default value for the offset select box.
$offset = block_inject_get_offset($form['#node']->nid);
if (isset($offset['offset'])) {
$bi_offset_default_value = $offset['offset'];
}
else {
$bi_offset_default_value = 0;
}
}
else {
$bi_offset_default_value = 0;
}
// Get the body field.
$body = block_inject_get_body_from_node($node);
// Check if the node form is on an already existing node.
if (isset($form['nid']['#value'])) {
// Get the number of paragraphs in the body.
$body_explode = explode("<p>", $body);
$paragraphs = count($body_explode);
// Get the middle place in the body.
$middle = round($paragraphs / 2) - 1;
// Create the select field options.
$i = 0;
$half = array();
while ($i < $middle) {
$i++;
$half[] = $i;
}
if (count($half) >= 1) {
foreach (array_reverse($half) as $i) {
$offset_options[] = -$i;
}
}
$offset_options[] = 0;
if (count($half) >= 1) {
foreach ($half as $i) {
$offset_options[] = $i;
}
}
}
else {
$offset_options = array(
0,
);
}
// Creates a new fieldset for the Block Inject settings.
$form['block_inject'] = array(
'#type' => 'fieldset',
'#title' => t('Block Inject settings'),
'#collapsible' => TRUE,
'#collapsed' => TRUE,
'#group' => 'additional_settings',
'#weight' => $form['author']['#weight'] - 5,
'#attributes' => array(
'class' => array(
'block-inject-node-form',
),
),
'#attached' => array(
'js' => array(
drupal_get_path('module', 'block_inject') . '/block_inject.js',
),
),
'#access' => user_access('override default block injection'),
);
// Check for existing condition on this node.
$region_id = block_inject_find_bi_id($node->type);
$region = block_inject_get_region_by_id($region_id->id);
$condition_offset = FALSE;
if ($region->bi_condition) {
$condition = unserialize($region->bi_condition);
$condition_offset = block_inject_process_condition($node->type, $body);
}
// Add the markup field if there is a condition on the node.
if ($condition_offset) {
// Check if singular.
if ($condition_offset == '1' || $condition_offset == '-1') {
$condition_offset = $condition_offset . ' paragraph';
}
else {
$condition_offset = $condition_offset . ' paragraphs';
}
// Renders the markup field with the warning if there is a condition.
$form['block_inject']['block_inject_conditions_info'] = array(
'#type' => 'markup',
'#markup' => t('Attention, the injection in this node already is offset
by @number. Please take this into account if you want to offset more.', array(
'@number' => check_plain($condition_offset),
)),
'#prefix' => '<div class="messages warning">',
'#suffix' => '</div>',
);
}
// Renders the block inject exception checkbox.
$form['block_inject']['block_inject_exception'] = array(
'#type' => 'checkbox',
'#title' => t('Remove the Block Inject effect on this node'),
'#description' => t('This will prevent the region to be injected into this
node.'),
'#default_value' => $bi_exception_default_value,
);
// Renders the block inject offset select box
$form['block_inject']['block_inject_offset'] = array(
'#type' => 'select',
'#title' => t('Block Inject paragraph offset'),
'#description' => t('If the default injection place is not ideal within
the context of your node, you can move it up or down by providing an
offset of the number of paragraphs you would like it moved by.'),
'#options' => array_combine($offset_options, $offset_options),
'#default_value' => $bi_offset_default_value,
);
}
}
/**
* Implements hook_node_submit().
*
* Saves to the block_inject_exceptions table the exception.
*/
function block_inject_node_submit($node, $form, &$form_state) {
$nid = $form_state['values']['nid'];
$node_type = $form_state['values']['type'];
$bi = block_inject_find_bi_id($node_type);
if (isset($form_state['values']['block_inject_offset'])) {
$offset = $form_state['values']['block_inject_offset'];
}
else {
$offset = 0;
}
if (isset($form_state['values']['block_inject_exception'])) {
if ($form_state['values']['block_inject_exception'] == 1) {
if ($offset != 0) {
block_inject_insert_exception($nid, $bi->id, 1, $offset);
}
else {
block_inject_insert_exception($nid, $bi->id, 1);
}
}
if ($form_state['values']['block_inject_exception'] == 0) {
if ($offset == 0) {
block_inject_remove_exception('nid', $nid);
}
else {
block_inject_insert_exception($nid, $bi->id, 0, $offset);
}
}
}
elseif ($offset != 0) {
block_inject_insert_exception($nid, $bi->id, 0, $offset);
}
}
/**
* Retrieves the ID of the block_inject rule based on node type provided.
*
* Returns an object containing property id.
*/
function block_inject_find_bi_id($node_type) {
$result = db_select('block_inject', 'bi')
->fields('bi', array(
'id',
))
->condition('node_type', '%' . $node_type . '%', 'LIKE')
->execute()
->fetch();
return $result;
}
/**
* Inserts the exception into the database
*/
function block_inject_insert_exception($nid, $bi_id, $exception, $offset = NULL) {
$existing = db_select('block_inject_exceptions', 'bie')
->fields('bie', array(
'id',
))
->condition('nid', $nid)
->execute()
->fetch();
if ($existing !== FALSE) {
$query = db_update('block_inject_exceptions')
->fields(array(
'except_injection' => $exception,
'offset' => $offset,
))
->condition('nid', $nid)
->execute();
}
else {
$insert = db_insert('block_inject_exceptions')
->fields(array(
'bi_id' => $bi_id,
'nid' => $nid,
'except_injection' => $exception,
'offset' => $offset,
))
->execute();
}
}
/**
* Removes the exception from the database
*/
function block_inject_remove_exception($type, $selector) {
$db_remove = db_delete('block_inject_exceptions');
if ($type == 'nid') {
$db_remove
->condition('nid', $selector);
}
if ($type == 'bi_id') {
$db_remove
->condition('bi_id', $selector);
}
$db_remove
->execute();
}
/**
* Checks to see if there is an exception in the block_inject_exceptions table
*
* @param int $nid
* The node ID of the node to check for
*
* Returns an array with the ID of the block_inject rule
*/
function block_inject_green_light($nid) {
$result = db_select('block_inject_exceptions', 'bie')
->fields('bie', array(
'bi_id',
'except_injection',
))
->condition('nid', $nid)
->condition('except_injection', 1)
->execute()
->fetchAssoc();
return $result;
}
/**
* Checks to see if there is an offset for a particular node
*
* @param int $nid
* The node ID of the node to check for
*
* Returns the offset
*/
function block_inject_get_offset($nid) {
$result = db_select('block_inject_exceptions', 'bie')
->fields('bie', array(
'offset',
))
->condition('nid', $nid)
->isNotNull('offset')
->execute()
->fetchAssoc();
return $result;
}
/**
* Retrieves from the database the existing exceptions from injection.
*
* Returns an array of node objects ordered by node ID
*/
function block_inject_get_exceptions() {
$select = db_select('block_inject_exceptions', 'bie')
->fields('bie', array(
'nid',
'bi_id',
))
->orderBy('nid', 'ASC')
->execute();
$nids_object = $select
->fetchAll();
return $nids_object;
}
/**
* Helper function to process the condition for an injection.
*
* @param $node_type
* The node type
*
* @param $body
* The node body
*
* @return bool|int
* False if no condition, or the number of paragraphs to offset.*
*/
function block_inject_process_condition($node_type, $body) {
// Get injectable region ID.
$id = block_inject_find_bi_id($node_type);
// Get the injectable region.
$region = block_inject_get_region_by_id($id->id);
if ($region->bi_condition) {
// Get condition information.
$condition = unserialize($region->bi_condition);
$operator = $condition['condition']['operator'];
$compare_to = $condition['condition']['paragraph_no'];
$action_offset = $condition['action']['offset'];
// Break up the body field string into an array of paragraphs.
$array_explode = explode("<p>", render($body));
if ($array_explode[0] === "") {
unset($array_explode[0]);
}
// Count the body paragraphs.
$body_paragraphs = count($array_explode);
// Process condition.
switch ($operator) {
case '=':
if ($body_paragraphs = $compare_to) {
return $action_offset;
}
break;
case '>':
if ($body_paragraphs > $compare_to) {
return $action_offset;
}
break;
case '<':
if ($body_paragraphs < $compare_to) {
return $action_offset;
}
break;
}
}
return FALSE;
}
/**
* Helper function to retrieve proper body value from the node.
*
* @param object $node
* The node object of the body.
*
* @return string
* Sanitized body value or false if problems.
*/
function block_inject_get_body_from_node($node) {
$body = field_get_items('node', $node, 'body');
if (isset($body[0]['safe_value'])) {
return $body[0]['safe_value'];
}
if ($body[0]['format'] === 'plain_text') {
return check_plain($body[0]['value']);
}
else {
return check_markup($body[0]['value'], $body[0]['format']);
}
}
Functions
Name![]() |
Description |
---|---|
block_inject_add_region | Adds a new region to the database |
block_inject_boot | Implements hook_boot(). |
block_inject_check_region_name | Checks for duplicate region names. |
block_inject_do_injection | Helper function that prepares and calls the injection on a node. |
block_inject_find_bi_id | Retrieves the ID of the block_inject rule based on node type provided. |
block_inject_form_node_form_alter | Implements hook_form_FORM-ID_alter(). |
block_inject_get_all_node_types | Returns all the content types available on the site. |
block_inject_get_body_from_node | Helper function to retrieve proper body value from the node. |
block_inject_get_exceptions | Retrieves from the database the existing exceptions from injection. |
block_inject_get_node_types | Checks if the node type exists already in the "block_inject" table and returns an array of the available node types (not used in any region). |
block_inject_get_offset | Checks to see if there is an offset for a particular node |
block_inject_get_regions | Retrieves from the database the existing declared regions for injection. |
block_inject_get_region_by_id | Retrieves one existing declared region for injection. |
block_inject_get_region_by_node_type | Retrieves from the database the a region for a specific node type. |
block_inject_green_light | Checks to see if there is an exception in the block_inject_exceptions table |
block_inject_implode_paragraphs | Takes an array of exploded paragraphs which contain the injected region wrapped in a div and 'implodes' them back into a string. |
block_inject_insert_exception | Inserts the exception into the database |
block_inject_menu | Implements hook_menu(). |
block_inject_node | Injects the region in the middle of the node. |
block_inject_node_submit | Implements hook_node_submit(). |
block_inject_node_view | Implements hook_node_view(). |
block_inject_panels_pane_content_alter | Implements hook_panels_pane_content_alter(). |
block_inject_permission | Implements hook_permission(). |
block_inject_process_condition | Helper function to process the condition for an injection. |
block_inject_rebuild_data | Rebuilds data, clears caches. |
block_inject_remove_exception | Removes the exception from the database |
block_inject_remove_region | Deletes a region from the database. |
block_inject_system_info_alter | Implements hook_system_info_alter(). |
block_inject_update_region | Updates a region in the database. |
_block_inject_get_regions_old | Retrieves from the database the existing declared regions for injection. |