bean_usage.module in Bean (for Drupal 7) 7
Bean Admin Functions and Display
File
bean_usage/bean_usage.moduleView source
<?php
/* @file
* Show where Beans are used.
* Currently limited to beans displayed with blockreference.
*
*/
/**
* Implements hook_menu()
*
* @return array
*/
function bean_usage_menu() {
$items = array();
// Todo: beans can be placed via context and block admin - we should account for those as well.
// usage tab on bean view
$items['block/%bean_delta/usage'] = array(
'title' => 'Usage',
'description' => 'Displays a list of entities where this bean is used.',
'type' => MENU_LOCAL_TASK,
'context' => MENU_CONTEXT_PAGE | MENU_CONTEXT_INLINE,
'page callback' => 'bean_usage_output',
'page arguments' => array(
1,
),
'access arguments' => array(
'view bean usage',
),
);
// bean usage report
$items['admin/reports/bean/usage'] = array(
'title' => t('Bean usage'),
'description' => 'Displays a list of Beans (blockreferences) and where they are used.',
'page callback' => 'bean_usage_output',
'page arguments' => array(
4,
),
'access arguments' => array(
'view bean usage',
),
);
$items['admin/reports/bean/usage/list'] = array(
'title' => t('Usage'),
'description' => 'Displays a list of Beans (blockreferences) and where they are used.',
'weight' => 0,
'page callback' => 'bean_usage_output',
'page arguments' => array(
5,
),
'access arguments' => array(
'view bean usage',
),
'type' => MENU_DEFAULT_LOCAL_TASK,
);
$items['admin/reports/bean/usage/settings'] = array(
'title' => t('Settings'),
'description' => t('Displays a list of Beans (blockreferences) and where they are used.'),
'weight' => 1,
'page callback' => 'drupal_get_form',
'page arguments' => array(
'bean_usage_settings',
),
'access arguments' => array(
'administer bean usage',
),
'file' => 'includes/bean_usage.forms.inc',
'type' => MENU_LOCAL_TASK | MENU_NORMAL_ITEM,
);
return $items;
}
/**
* Implements hook_permission()
*
* @return array
*/
function bean_usage_permission() {
$perms = array(
'view bean usage' => array(
'title' => t('View bean usage'),
'description' => t('View a list of Beans (blockreferences) and where they are used.'),
),
'administer bean usage' => array(
'title' => t('Administer bean usage'),
'description' => t('Administer settings for the bean usage page.'),
),
);
return $perms;
}
/**
* @file
* Bean Admin Functions and Display
*/
/**
* Displays a table of Beans and their usage
*
* @return string - the HTML for the table
*/
function bean_usage_output($bean = NULL) {
module_load_include('inc', 'bean_usage', 'includes/bean_usage.forms');
$output = '';
$bean_delta = NULL;
$delta_specific = $delta_found = FALSE;
$bean_usage_form = drupal_get_form('bean_usage_filters');
if (!empty($bean) && is_object($bean)) {
$delta_specific = TRUE;
}
else {
if (is_numeric($bean)) {
$delta_specific = TRUE;
$bean = bean_load($bean);
}
}
if (is_object($bean)) {
drupal_set_title($bean->label . ' Usage');
$bean_delta = $bean->delta;
}
// Get all fields that are of type blockreference and not deleted
$fields = bean_usage_blockreference_fields();
// If we have something to work with
if (!empty($fields)) {
$filters = drupal_get_query_parameters();
if ($delta_specific) {
$delta_found = FALSE;
}
$entity_types = bean_usage_blockrefence_entity_types();
$bundles = bean_usage_blockreference_bundles();
$query = '';
foreach ($fields as $i => $field) {
if (!$delta_found) {
$field_name = $field->name;
$data_table = 'field_data_' . $field_name;
if ($i == 0) {
$query = _bean_usage_field_data($data_table, $i, $field_name, $entity_types, $bundles, $filters, $delta_specific, $bean);
}
else {
$query
->union(_bean_usage_field_data($data_table, $i, $field_name, $entity_types, $bundles, $filters, $delta_specific, $bean));
}
}
}
// Get the data
$data = $query
->execute()
->fetchAll(0);
if (!empty($data)) {
// Sort the data - default sort is by label
usort($data, 'bean_usage_sort_by_label');
if (!empty($_GET['order'])) {
$sort_by = empty($_GET['order']) ? '' : str_replace('bean ', '', strtolower($_GET['order']));
switch ($sort_by) {
case 'label':
usort($data, 'bean_usage_sort_by_label');
break;
case 'title':
usort($data, 'bean_usage_sort_by_title');
break;
case 'type':
usort($data, 'bean_usage_sort_by_type');
break;
}
}
if (!empty($_GET['sort']) && $_GET['sort'] == 'desc') {
$data = array_reverse($data);
}
$content = array();
foreach ($data as $bean_data) {
// We want to link to display the entity type title/name
$entity_title = '';
switch ($bean_data->entity_type) {
// If its a node, get the node title
case 'node':
$entity_title = _bean_usage_entity_display('node', $bean_data->entity_id, 'nid', 'title');
break;
// If its a user, get the user name
case 'user':
$entity_title = _bean_usage_entity_display('user', $bean_data->entity_id, 'uid', 'name');
break;
}
$content[$bean_data->label][$bean_data->entity_type][$bean_data->entity_id]['bean_title'] = $bean_data->title;
$content[$bean_data->label][$bean_data->entity_type][$bean_data->entity_id]['bean_type'] = $bean_data->type;
$content[$bean_data->label][$bean_data->entity_type][$bean_data->entity_id]['entity_id'] = $bean_data->entity_id;
$content[$bean_data->label][$bean_data->entity_type][$bean_data->entity_id]['entity_title'] = $entity_title;
if ($delta_specific) {
$delta_found = TRUE;
}
}
}
// If we have any usage data create and display the table of data
if (!empty($content)) {
$rows = count($content);
$results_per_page = variable_get('bean_usage_results_per_page', 30);
// set up pager variables
pager_default_initialize($rows, $results_per_page, $element = 0);
// Set up output table
$bean_table_data = array(
'attributes' => array(
// set table attributes
'width' => '100%',
),
'header' => _bean_usage_table_headers($bean_delta),
'rows' => array(),
);
if ($filters) {
$bean_table_data['caption'] = t('Filters: ') . $filters;
}
// Get the result subset for the current page
$page = empty($_GET['page']) ? 0 : $_GET['page'];
$range_start = $page * $results_per_page;
$usage = array_slice($content, $range_start, $results_per_page);
// If the user is on a higher page and then filters, the page
if (!empty($filters) && $page != 0 && count($usage) == 0) {
while (count($usage) == 0) {
$page--;
$range_start = $page * $results_per_page;
$usage = array_slice($content, $range_start, $results_per_page);
}
}
foreach ($usage as $bean_label => $entity_type) {
foreach ($entity_type as $type => $delta) {
$rowspan = count($delta);
$bean_label_cell = '';
if (empty($bean_delta)) {
$bean_label_cell = array(
'data' => $bean_label,
'rowspan' => $rowspan,
'width' => '30%',
);
}
// we create the row with the bean name first and set the rowspan to however many deltas there are
foreach ($delta as $entity) {
$bean_title_cell = array(
'data' => empty($entity['bean_title']) ? '<em>' . t('No title set') . '</em>' : $entity['bean_title'],
'rowspan' => $rowspan,
'width' => '30%',
);
$bean_type_cell = array(
'data' => $entity['bean_type'],
'rowspan' => $rowspan,
'width' => '10%',
);
// We want to prefix the entity title with the entity id
// We also want the entity title to link back the to the entity page
$link_prefix = '';
$text_prefix = '';
switch ($type) {
case 'node':
$text_prefix = '[nid:' . $entity['entity_id'] . '] ';
$link_prefix = 'node/';
break;
case 'user':
$text_prefix = '[uid:' . $entity['entity_id'] . '] ';
$link_prefix = 'user/';
break;
}
// switch ($entity_type)
// add the usage data to the table
// We only need to add the Bean label once per delta, Since we set it above we check for its emptiness
if (!empty($bean_label_cell)) {
$bean_table_data['rows'][] = array(
0 => $bean_label_cell,
1 => $bean_title_cell,
2 => $bean_type_cell,
3 => array(
'data' => $text_prefix . l($entity['entity_title'], $link_prefix . $entity['entity_id']),
'width' => '30%',
'no_striping' => TRUE,
),
);
}
else {
$bean_table_data['rows'][] = array(
$text_prefix . l(t($entity['entity_title']), $link_prefix . $entity['entity_id'], array(
'attributes' => array(
'title' => $entity['entity_title'],
'target' => '_blank',
),
)),
);
}
// else
// empty out the $bean_row so that it doesn't display more than one if there are multiple deltas for the block
$bean_label_cell = '';
}
// foreach ($delta)
}
//foreach ($entity_type)
}
// foreach ($usage)
// Set the output using theme_table with the header and rows created above
if (!$delta_specific) {
$output .= drupal_render($bean_usage_form);
}
$output .= theme('table', $bean_table_data);
$output .= theme('pager');
}
else {
if ($delta_specific) {
$output = '<p>' . t('This bean is not used anywhere on the site.') . '</p>';
}
else {
$output .= $bean_usage_form;
$output .= 'There is no bean usage to report for ' . $filters;
}
}
// else
}
// if (!empty($fields))
// return the output for page rendering
return $output;
}
/**
* Get all fields that are of type blockreference and not deleted
*
* @return mixed
*/
function bean_usage_blockreference_fields() {
$fields =& drupal_static(__FUNCTION__);
if (!isset($fields)) {
$query = db_select('field_config', 'fc');
$query
->addField('fc', 'field_name', 'name');
$query
->leftJoin('field_config_instance', 'fci', 'fc.field_name = fci.field_name');
$fields = $query
->condition('fc.type', 'blockreference')
->condition('fc.deleted', 0)
->orderBy('fc.field_name', 'asc')
->execute()
->fetchAll(0);
}
return $fields;
}
/**
* Get all of the entity types used with beans via blockreference
*
* @return array
*/
function bean_usage_blockrefence_entity_types() {
$entity_types = array();
$et_query = db_select('field_config_instance', 'fci')
->distinct();
$et_query
->addField('fci', 'entity_type', 'type');
$et_query
->join('field_config', 'fc', 'fc.field_name = fci.field_name');
$et_res = $et_query
->condition('fc.type', 'blockreference')
->execute()
->fetchAll(0);
foreach ($et_res as $entity) {
$entity_types[] = $entity->type;
}
return $entity_types;
}
/**
* Get all of the bundles used with beans via blockreference
*
* @return array
*/
function bean_usage_blockreference_bundles() {
$bundles = array();
$b_query = db_select('field_config_instance', 'fci')
->distinct();
$b_query
->join('field_config', 'fc', 'fc.field_name = fci.field_name');
$b_res = $b_query
->fields('fci', array(
'bundle',
))
->condition('fc.type', 'blockreference')
->execute()
->fetchAll(0);
foreach ($b_res as $bundle) {
$bundles[] = $bundle->bundle;
}
return $bundles;
}
/**
* Helper function to display an entity on the report
*
* @param $table
* @param $value
* @param $key
* @param $column
* @return mixed
*/
function _bean_usage_entity_display($table, $value, $key, $column) {
$query = db_select($table, 't')
->fields('t', array(
$column,
))
->condition($key, $value)
->execute()
->fetchAssoc();
return $query[$column];
}
/**
* Get the data from the field_data tables for bean usage based on bean.bid and bean.delta
*
* @param string $data_table
* @param int $i
* @param string $field_name
* @param array $entity_types
* @param array $bundles
* @param string $filter
* @param boolean $delta_specific
* @param object bean
*
* @return SelectQuery
*/
function _bean_usage_field_data($data_table, $i, $field_name, $entity_types, $bundles, $filters = NULL, $delta_specific = FALSE, $bean = NULL) {
$query = db_select($data_table, 'fd' . $i);
$query
->leftJoin('block', 'bl', 'fd' . $i . '.' . $field_name . '_bid = bl.bid');
$query
->join('bean', 'b', 'b.delta = bl.delta');
$query
->fields('b', array(
'bid',
'label',
'title',
'type',
));
$query
->fields('fd' . $i, array(
'entity_id',
'delta',
'entity_type',
));
$query
->addField('fd' . $i, $field_name . '_bid', 'bid');
$query_and = db_and();
$query_and
->condition('bl.module', 'bean');
$query_and
->condition('bl.theme', variable_get('theme_default', NULL));
$query_and
->condition('fd' . $i . '.entity_type', $entity_types, 'IN');
$query_and
->condition('fd' . $i . '.bundle', $bundles, 'IN');
if (!empty($filters['type'])) {
$query_and
->condition('b.type', array(
$filters['type'],
), 'IN');
}
if (!empty($filters['title'])) {
$query_and
->condition('b.title', '%' . $filters['title'] . '%', 'LIKE');
}
if (!empty($filters['label'])) {
$query_and
->condition('b.label', '%' . $filters['label'] . '%', 'LIKE');
}
if ($delta_specific && !empty($bean)) {
$query_and
->condition('b.bid', intval($bean->bid));
}
$query
->condition($query_and);
return $query;
}
/**
* Set the table headers for the table output based on the page that calls for the data.
*
* @param null $bean_delta
*
* @return array
*/
function _bean_usage_table_headers($bean_delta = NULL) {
if (empty($bean_delta)) {
$table_data_headers = array(
0 => array(
'data' => t('Bean label'),
'field' => 'label',
'sort' => 'asc',
),
1 => array(
'data' => t('Bean title'),
'field' => 'title',
),
2 => array(
'data' => t('Bean type'),
'field' => 'type',
),
3 => array(
'data' => t('Used in'),
),
);
}
else {
$table_data_headers = array(
0 => array(
'data' => t('Used in'),
),
);
}
return $table_data_headers;
}
/**
* Sort bean usage by bean.label
*
* @param $a
* @param $b
*
* @return int
*/
function bean_usage_sort_by_label($a, $b) {
return strcmp($a->label, $b->label);
}
/**
* Sort bean usage by bean.title
*
* @param $a
* @param $b
*
* @return int
*/
function bean_usage_sort_by_title($a, $b) {
return strcmp($a->title, $b->title);
}
/**
* Sort bean usage by bean.type
*
* @param $a
* @param $b
*
* @return int
*/
function bean_usage_sort_by_type($a, $b) {
return strcmp($a->type, $b->type);
}
Functions
Name | Description |
---|---|
bean_usage_blockrefence_entity_types | Get all of the entity types used with beans via blockreference |
bean_usage_blockreference_bundles | Get all of the bundles used with beans via blockreference |
bean_usage_blockreference_fields | Get all fields that are of type blockreference and not deleted |
bean_usage_menu | Implements hook_menu() |
bean_usage_output | Displays a table of Beans and their usage |
bean_usage_permission | Implements hook_permission() |
bean_usage_sort_by_label | Sort bean usage by bean.label |
bean_usage_sort_by_title | Sort bean usage by bean.title |
bean_usage_sort_by_type | Sort bean usage by bean.type |
_bean_usage_entity_display | Helper function to display an entity on the report |
_bean_usage_field_data | Get the data from the field_data tables for bean usage based on bean.bid and bean.delta |
_bean_usage_table_headers | Set the table headers for the table output based on the page that calls for the data. |