'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%' // width ), 'header' => _bean_usage_table_headers($bean_delta), 'rows' => array(), // table rows ); 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']) ? '' . t('No title set') . '' : $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 ), ); } // if (!empty($bean_label_cell)) 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'); } // if (!empty($usage)) else { if ($delta_specific) { $output = '

' . t('This bean is not used anywhere on the site.') . '

'; } 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); }