array( 'label' => t('Block'), 'entity class' => 'Bean', 'controller class' => 'BeanEntityAPIController', // This class provides integration with the Inline entity form module. 'inline entity form' => array( 'controller' => 'BeanInlineEntityFormController', ), 'base table' => 'bean', 'revision table' => 'bean_revision', 'fieldable' => TRUE, 'entity keys' => array( 'id' => 'bid', 'bundle' => 'type', 'label' => 'label', 'name' => 'delta', 'revision' => 'vid', 'default revision' => 'default_revision', ), 'bundles' => array(), 'bundle keys' => array( 'bundle' => 'type', ), 'label callback' => 'entity_class_label', 'uri callback' => 'entity_class_uri', 'access callback' => 'bean_access', 'view callback' => 'bean_view_callback', 'module' => 'bean', 'metadata controller class' => 'BeanMetadataController', 'view modes' => array( 'default' => array( 'label' => t('Default'), 'custom settings' => FALSE, ), ), 'field replacement' => array( 'title' => array( 'field' => array( 'type' => 'text', 'cardinality' => 1, 'translatable' => TRUE, ), 'instance' => array( 'label' => t('Title'), 'description' => t('The Title of the block.'), 'required' => FALSE, 'settings' => array( 'text_processing' => 0, ), 'widget' => array( 'weight' => -5, ), ), ), ), 'translation' => array( 'entity_translation' => array( 'class' => 'EntityTranslationBeanHandler', 'base path' => 'block/%bean_delta', 'path wildcard' => '%bean_delta', 'path schemes' => array( 'default' => array(), ), ), ), ), ); foreach (bean_get_types() as $type) { if (!empty($type)) { $return['bean']['bundles'][$type->type] = array( 'label' => $type->getLabel(), 'description' => $type->getDescription(), 'admin' => array( 'path' => 'admin/structure/block-types/manage/%bean_type', 'real path' => 'admin/structure/block-types/manage/' . $type->buildURL(), 'bundle argument' => 4, 'access arguments' => array('administer bean types'), ), ); } } return $return; } /** * Implements hook_menu(). */ function bean_menu() { $items = array(); $items['block/add'] = array( 'title' => 'Add Block', 'page callback' => 'bean_add_page', 'access arguments' => array('add'), 'access callback' => 'bean_add_page_access', 'file' => 'includes/bean.pages.inc', ); foreach (bean_get_types() as $type) { if (!empty($type)) { $items['block/add/' . $type->buildURL()] = array( 'title' => $type->getLabel(), 'title callback' => 'check_plain', 'page callback' => 'bean_add', 'page arguments' => array($type->type), 'access callback' => 'bean_access', 'access arguments' => array('create', $type->type), 'file' => 'includes/bean.pages.inc', ); } } $items['block/%bean_delta'] = array( 'title' => 'Block', 'page callback' => 'bean_view_page', 'page arguments' => array(1), 'access arguments' => array('view bean page'), 'file' => 'includes/bean.pages.inc', ); $items['block/%bean_delta/view'] = array( 'title' => 'View', 'type' => MENU_DEFAULT_LOCAL_TASK, 'context' => MENU_CONTEXT_NONE, 'weight' => -20, ); $items['block/%bean_delta/edit'] = array( 'title' => 'Edit Block', 'type' => MENU_LOCAL_TASK, 'context' => MENU_CONTEXT_PAGE | MENU_CONTEXT_INLINE, 'page callback' => 'bean_edit', 'page arguments' => array(1), 'access arguments' => array('update', 'bean', 1), 'access callback' => 'entity_access', 'file' => 'includes/bean.pages.inc', ); $items['block/%bean_delta/delete'] = array( 'title' => 'Delete Block', 'page callback' => 'drupal_get_form', 'page arguments' => array('bean_delete_confirm', 1), 'access callback' => 'entity_access', 'access arguments' => array('delete', 'bean', 1), 'weight' => 1, 'type' => MENU_LOCAL_TASK, 'context' => MENU_CONTEXT_NONE, 'file' => 'includes/bean.pages.inc', ); $items['block/%bean_delta/revisions'] = array( 'title' => 'Revisions', 'page callback' => 'bean_revisions_page', 'page arguments' => array(1), 'access arguments' => array('view bean revisions'), 'file' => 'includes/bean.pages.inc', 'type' => MENU_LOCAL_TASK, ); $items['block/%bean_delta/revisions/%'] = array( 'title callback' => 'bean_revision_title', 'title arguments' => array(1), 'page callback' => 'bean_view', 'page arguments' => array(1), 'access callback' => 'entity_access', 'access arguments' => array('view', 'bean', 1), 'file' => 'includes/bean.pages.inc', 'load arguments' => array(3), ); $items['block/%bean_delta/revisions/%/view'] = array( 'title' => 'View', 'page callback' => 'bean_view', 'page arguments' => array(1), 'access callback' => 'entity_access', 'access arguments' => array('view', 'bean', 1), 'file' => 'includes/bean.pages.inc', 'load arguments' => array(3), 'weight' => -10, 'type' => MENU_DEFAULT_LOCAL_TASK, 'context' => MENU_CONTEXT_NONE, ); $items['block/%bean_delta/revisions/%/edit'] = array( 'title' => 'Edit', 'page callback' => 'bean_edit', 'page arguments' => array(1), 'access callback' => 'entity_access', 'access arguments' => array('update', 'bean', 1), 'file' => 'includes/bean.pages.inc', 'load arguments' => array(3), 'type' => MENU_LOCAL_TASK, 'context' => MENU_CONTEXT_PAGE | MENU_CONTEXT_INLINE, ); $items['block/%bean_delta/revisions/%/set-active'] = array( 'title' => 'Set active', 'page callback' => 'drupal_get_form', 'page arguments' => array('bean_set_default_confirm', 1), 'access callback' => 'entity_access', 'access arguments' => array('update', 'bean', 1), 'file' => 'includes/bean.pages.inc', 'load arguments' => array(3), 'type' => MENU_LOCAL_TASK, 'context' => MENU_CONTEXT_PAGE | MENU_CONTEXT_INLINE, ); $items['block/%bean_delta/revisions/%/delete'] = array( 'title' => 'Delete', 'page callback' => 'drupal_get_form', 'page arguments' => array('bean_delete_revision_confirm', 1), 'access callback' => 'entity_access', 'access arguments' => array('delete', 'bean', 1), 'file' => 'includes/bean.pages.inc', 'load arguments' => array(3), 'weight' => 1, 'type' => MENU_LOCAL_TASK, 'context' => MENU_CONTEXT_NONE, ); $items['admin/content/blocks'] = array( 'title' => 'Blocks', 'description' => 'Manage blocks used on your site.', 'page callback' => 'bean_list', 'access arguments' => array('access bean overview'), 'file' => 'includes/bean.pages.inc', 'type' => MENU_LOCAL_TASK | MENU_NORMAL_ITEM, ); if (module_exists('devel')) { $devel_path = drupal_get_path('module', 'devel'); $items['block/%bean_delta/devel'] = array( 'title' => 'Devel', 'page callback' => 'devel_load_object', 'page arguments' => array('bean', 1), 'access arguments' => array('administer beans'), 'type' => MENU_LOCAL_TASK, 'file' => 'devel.pages.inc', 'file path' => $devel_path, 'weight' => 100, ); $items['block/%bean_delta/devel/load'] = array( 'title' => 'Load', 'type' => MENU_DEFAULT_LOCAL_TASK, ); $items['block/%bean_delta/devel/render'] = array( 'title' => 'Render', 'page callback' => 'devel_render_object', 'page arguments' => array('bean', 1), 'access arguments' => array('administer beans'), 'file' => 'devel.pages.inc', 'file path' => $devel_path, 'type' => MENU_LOCAL_TASK, 'weight' => 100, ); } return $items; } /** * Title callback */ function bean_revision_title($bean) { return $bean->label(); } /** * Implements hook_admin_paths(). */ function bean_admin_paths() { if (variable_get('node_admin_theme')) { $paths = array( 'block/*/edit' => TRUE, 'block/*/delete' => TRUE, 'block/*/revisions' => TRUE, 'block/*/revisions/*/edit' => TRUE, 'block/*/revisions/*/set-active' => TRUE, 'block/*/revisions/*/delete' => TRUE, 'block/add' => TRUE, 'block/add/*' => TRUE, ); return $paths; } } /** * Title of the bean */ function bean_page_title($bean) { return $bean->label; } /** * Menu Argument Loader */ function bean_type_load($type) { return bean_load_plugin_class(strtr($type, array('-' => '_'))); } /** * Menu Argument Loader for panelizer tab. */ function bean_type_panelizer_load($type) { $type = bean_load_plugin_class(strtr($type, array('-' => '_'))); return $type->type; } /** * Gets an array of all bean types, keyed by the type name. * * @return BeanType * Depending whether $type isset, an array of bean types or a single one. */ function bean_get_types() { $bean_types = &drupal_static(__FUNCTION__); if (empty($bean_types)) { $bean_types = bean_load_plugin_class_all(); } return $bean_types; } /** * Fetch the widget plugin info */ function bean_fetch_plugin_info($plugin = NULL) { $plugins = &drupal_static(__FUNCTION__); ctools_include('plugins'); if (empty($plugins)) { if (($cache = cache_get('bean_plugins')) && !empty($cache->data)) { $plugins = $cache->data; } else { $plugins = ctools_get_plugins('bean', 'types'); // Only use modules with the same version. $allowed_modules = array_keys(ctools_plugin_api_info('bean', 'types', bean_min_version(), bean_current_version())); foreach ($plugins as $key => $plugin_value) { if (!in_array($plugin_value['module'], $allowed_modules) || ($plugin_value['abstract'])) { unset($plugins[$key]); } } cache_set('bean_plugins', $plugins); } } if (empty($plugin)) { return $plugins; } else { // Make sure the plugin is in the cache. if (!isset($plugins[$plugin])) { $plugin_info = ctools_get_plugins('bean', 'types', $plugin); if (empty($allowed_modules)) { $allowed_modules = array_keys(ctools_plugin_api_info('bean', 'types', bean_current_version(), bean_min_version())); } if (in_array($plugin_info['module'], $allowed_modules)) { $plugins[$plugin] = $plugin_info; cache_set('bean_plugins', $plugins); } } // If we still don't have the plugin then return NULL. if (empty($plugins[$plugin])) { return NULL; } return $plugins[$plugin]; } } /** * Reset the static variables and caches. */ function bean_reset($skip_menu_rebuild = FALSE, $rehash_blocks= FALSE) { // Clear ctools cache. ctools_include('plugins'); ctools_get_plugins_reset(); cache_clear_all('plugins:bean:types', 'cache'); cache_clear_all('ctools_plugin_files', 'cache', TRUE); // Invoke modules to clear their caches. foreach (module_implements('bean_cache_clear') as $module) { module_invoke($module, 'bean_cache_clear'); } // Rebuild ctools plugin types and the menu. ctools_plugin_get_plugin_type_info(TRUE); if (!$skip_menu_rebuild) { menu_rebuild(); } // Rehashes blocks for active themes. This will populate the blocks table and allow // modules like blockreference to work properly. if ($rehash_blocks && module_exists('block')) { block_flush_caches(); } } /** * Implements hook_bean_cache_clear(). */ function bean_bean_cache_clear() { // Clear static variables. drupal_static_reset('bean_access'); drupal_static_reset('bean_get_types'); drupal_static_reset('bean_get_all_beans'); drupal_static_reset('bean_fetch_plugin_info'); drupal_static_reset('bean_load_plugin_class'); drupal_static_reset('bean_block_info'); // Flush caches. cache_clear_all('bean_plugins', 'cache'); if (module_exists('block')) { cache_clear_all(NULL, 'cache_block'); } cache_clear_all(NULL, 'cache_page'); } /** * Clear out cache_block table * @param object $bean the bean object */ function bean_cache_clear_block($bean = null) { if (isset($bean->delta)) { cache_clear_all('bean:' . $bean->delta . ':', 'cache_block', TRUE); } else { cache_clear_all('bean:', 'cache_block', TRUE); } } /** * Load a widget class * * @param $plugin_key string * the key fo the plugin * @return BeanTypePluginInterface | Boolean * An instance of the bean class or FALSE if not loaded */ function bean_load_plugin_class($plugin_key = NULL) { $cache = &drupal_static(__FUNCTION__); if (!isset($cache[$plugin_key])) { ctools_include('plugins'); $class = ctools_plugin_load_class('bean', 'types', $plugin_key, 'handler'); if ($class && bean_check_plugin_class($class)) { $cache[$plugin_key] = new $class(bean_fetch_plugin_info($plugin_key)); } } return isset($cache[$plugin_key]) ? $cache[$plugin_key] : FALSE; } /** * Check the plugin type class * * @param $class string * The name of the bean type class * @return Boolean */ function bean_check_plugin_class($class) { $ref_class = new ReflectionClass($class); if ($ref_class->isInstantiable() && in_array('BeanTypePluginInterface', $ref_class->getInterfaceNames())) { return TRUE; } return FALSE; } /** * Load all widget classes */ function bean_load_plugin_class_all() { $return = array(); foreach (bean_fetch_plugin_info() as $plugin) { if (!empty($plugin['name']) && $plugin['name'] !== 'bean' && $plugin_class = bean_load_plugin_class($plugin['name'])) { $return[$plugin['name']] = $plugin_class; } } return $return; } /** * Load all beans */ function bean_get_all_beans() { $beans = &drupal_static(__FUNCTION__); if (!isset($beans)) { $query = new EntityFieldQuery(); $result = $query ->entityCondition('entity_type', 'bean') ->execute(); if (isset($result['bean'])) { $beans = bean_load_multiple(array_keys($result['bean'])); } else { $beans = array(); } } return $beans; } /** * Fetch a bean object. * * @param $bid * Integer specifying the bean id. * @param $reset * A boolean indicating that the internal cache should be reset. * @return * A fully-loaded $bean object or FALSE if it cannot be loaded. * * @see bean_load_multiple() */ function bean_load($bid, $reset = FALSE) { $beans = bean_load_multiple(array($bid), array(), $reset); return reset($beans); } /** * Fetch a bean revision * * A new function to not break the bean_load API */ function bean_load_revision($bid, $vid, $reset = FALSE) { $conditions = array('vid' => $vid); $beans = bean_load_multiple(array($bid), $conditions, $reset); return reset($beans); } /** * Fetch a bean object by its delta. * * @param $delta * String specifying the bean delta. * @param $reset * A boolean indicating that the internal cache should be reset. * @return Bean * A fully-loaded $bean object or FALSE if it cannot be loaded. */ function bean_load_delta($delta, $reset = FALSE, $revision = NULL) { static $deltas = array(); if (!$reset && !$revision && isset($deltas[$delta])) { return $deltas[$delta]; } $result = db_select('bean', 'b') ->fields('b', array('bid')) ->condition('delta', $delta) ->execute(); if ($bid = $result->fetchField()) { if ($revision) { return bean_load_revision($bid, $revision, $reset); } else { $deltas[$delta] = bean_load($bid, $reset); return $deltas[$delta]; } } return FALSE; } /** * Menu callback to load a bean by the delta */ function bean_delta_load($delta, $revision = NULL) { return bean_load_delta($delta, FALSE, $revision); } /** * Load multiple beans based on certain conditions. * * @param $bids * An array of bean IDs. * @param $conditions * An array of conditions to match against the {bean} table. * @param $reset * A boolean indicating that the internal cache should be reset. * @return * An array of bean objects, indexed by pid. * * @see entity_load() * @see bean_load() */ function bean_load_multiple($bids = array(), $conditions = array(), $reset = FALSE) { return entity_load('bean', $bids, $conditions, $reset); } /** * Delete a bean revision */ function bean_delete_revision($vid) { return entity_get_controller('bean')->deleteRevision($vid); } /** * Implements hook_permissions(). */ function bean_permission() { $perms = array( 'administer bean types' => array( 'title' => t('Administer block types'), 'description' => t('Create and delete fields on beans, and set their permissions.'), ), 'administer beans' => array( 'title' => t('Administer beans'), 'description' => t('Delete, add, edit and view all beans.'), ), 'access bean overview' => array( 'title' => t('Access the Bean overview page'), 'description' => t('Visit !url', array('!url' => "admin/content/blocks")), ), 'edit bean view mode' => array( 'title' => t('Change the View Mode of the Bean'), 'description' => t('Ability to change the view mode on the bean form'), ), 'view bean page' => array( 'title' => t('View Bean page'), 'description' => t('Visit !url', array('!url' => 'block/< delta >')), ), 'administer bean settings' => array( 'title' => t('Administer Bean Settings'), ), 'view bean revisions' => array( 'title' => t('View Bean revisions'), ), ); // Add a Permission for each entity type. bean_reset(TRUE); foreach (bean_get_types() as $bean_type) { $bean_type_name = check_plain($bean_type->type); $perms += array( "create any $bean_type_name bean" => array( 'title' => t('%type_name: Add Bean', array('%type_name' => $bean_type->getLabel())), ), "edit any $bean_type_name bean" => array( 'title' => t('%type_name: Edit Bean', array('%type_name' => $bean_type->getLabel())), ), "view any $bean_type_name bean" => array( 'title' => t('%type_name: View Bean', array('%type_name' => $bean_type->getLabel())), ), "delete any $bean_type_name bean" => array( 'title' => t('%type_name: Delete Bean', array('%type_name' => $bean_type->getLabel())), ), ); } return $perms; } /** * Access callback for the entity API. */ function bean_type_access($op, $type = NULL, $account = NULL) { return user_access('administer bean types', $account); } /** * Determines whether the given user has access to a bean. * * @param $op * The operation being performed. One of 'view', 'update', 'create', 'delete' * or just 'edit' (being the same as 'create' or 'update'). * @param $bean * Optionally a bean or a bean type to check access for. If nothing is * given, access for all beans is determined. * @param $account * The user to check for. Leave it to NULL to check for the current user. * @return boolean * Whether access is allowed or not. */ function bean_access($op, $bean = NULL, $account = NULL) { $rights = &drupal_static(__FUNCTION__, array()); // Only real permissions are view, delete, create and edit switch ($op) { case 'view': case 'delete': case 'create': $op = $op; break; case 'add': $op = 'create'; break; default: $op = 'edit'; } // If no user object is supplied, the access check is for the current user. if (empty($account)) { $account = $GLOBALS['user']; } $cid = is_object($bean) ? $bean->bid : $bean; // If we've already checked access for this node, user and op, return from cache. if (isset($rights[$account->uid][$cid][$op])) { return $rights[$account->uid][$cid][$op]; } if (user_access('administer beans', $account)) { return TRUE; } // We grant access to the bean if both of the following conditions are met: // - No modules say to deny access. // - At least one module says to grant access. // If no module specified either allow or deny, we fall back to the default. $access = module_invoke_all('bean_access', $bean, $op, $account); if (in_array(FALSE, $access, TRUE)) { $rights[$account->uid][$cid][$op] = FALSE; return FALSE; } elseif (in_array(TRUE, $access, TRUE)) { $rights[$account->uid][$cid][$op] = TRUE; return TRUE; } if (isset($bean) && isset($bean->type)) { if (user_access("$op any {$bean->type} bean", $account)) { $rights[$account->uid][$cid][$op] = TRUE; return TRUE; } } elseif (isset($bean) && is_string($bean)) { if (user_access("$op any {$bean} bean", $account)) { $rights[$account->uid][$cid][$op] = TRUE; return TRUE; } } else { // Here we are looking for access to any of the types. foreach (bean_get_types() as $bean_type) { $perm = $op . ' any ' . $bean_type->type . ' bean'; if (user_access($perm, $account)) { $rights[$account->uid][$cid][$op] = TRUE; return TRUE; } } } return FALSE; } /** * Access callback for the general Bean add page (block/add). */ function bean_add_page_access() { if (user_access('administer bean types') || user_access('administer beans')) { return TRUE; } foreach (bean_get_types() as $bean_type) { if (entity_access('create', 'bean', $bean_type->type)) { return TRUE; } } return FALSE; } /** * Inserts or updates a bean object into the database. * * @param $bean * The bean object to be inserted. * * @return * Failure to write a record will return FALSE. Otherwise SAVED_NEW or * SAVED_UPDATED is returned depending on the operation performed. */ function bean_save(Bean $bean) { return $bean->save(); } /** * Deletes an existing bean. * * @param $bean * The message object to be bean. */ function bean_delete(Bean $bean) { return $bean->delete(); } /** * Helper to easily create a bean. * * @param $values array * Array with the following keys: * - "arguments" - Array with arguments that should be replaced on run time in * the message type. * * @return Bean */ function bean_create($values) { return entity_create('bean', $values); } /** * View the Bean */ function bean_view(Bean $bean, $view_mode = 'default', $langcode = NULL) { if (!isset($langcode)) { $langcode = $GLOBALS['language_content']->language; } return $bean->view($view_mode, $langcode); } /** * View callback */ function bean_view_callback($entities, $view_mode, $langcode, $entity_type) { $render = array(); foreach($entities as $key => $entity) { $id = entity_id($entity_type, $entity); $render[$entity_type][$id] = bean_view($entity, $view_mode, $langcode); } return $render; } /** * Implements hook_block_info(). */ function bean_block_info() { $blocks = &drupal_static(__FUNCTION__, array()); if (!empty($blocks)) { return $blocks; } $blocks = array(); $beans = bean_get_all_beans(); foreach ($beans as $bean) { $blocks[$bean->delta] = array( 'info' => $bean->adminTitle(), 'cache' => $bean->getInfo('cache_level'), ); } return $blocks; } /** * Implements hook_block_view(). */ function bean_block_view($delta = '') { $return = array(); $bean = bean_load_delta($delta); if (entity_access('view', 'bean', $bean) && $bean) { $content = $bean->view($bean->view_mode); if (!is_array($content)) { $content = array( '#markup' => $content, ); } $return = array( 'content' => $content, 'subject' => isset($bean->title) ? filter_xss($bean->title, $allowed_tags = array('em', 'strong', 'i', 'b')) : '', ); } if (!empty($return['content']) && module_exists('contextual')) { $return['content']['#contextual_links']['bean'] = array( 'block', array($bean->Identifier(), 'edit') ); } return $return; } /** * Define the name of the api hook */ function bean_types_hook_name() { return 'bean_types_api_info'; } /** * The current version of the API */ function bean_current_version() { return 5; } /** * The minimal version */ function bean_min_version() { return 4; } /** * Implements hook_bean_types_api_info(). */ function bean_bean_types_api_info() { return array( 'api' => bean_current_version(), ); } /** * Implements hook_ctools_plugin_type(). */ function bean_ctools_plugin_type() { return array( 'types' => array( 'cache' => TRUE, 'use hooks' => TRUE, 'classes' => array('handler'), 'info file' => TRUE, 'alterable' => TRUE, 'defaults' => array( 'abstract' => FALSE, 'label' => t('Block'), 'description' => '', 'cache_level' => DRUPAL_CACHE_PER_ROLE, // Editable in the block type UI // THESE should have 'bean_custom' as the class 'editable' => FALSE, 'view_mode' => 'default', 'handler' => array( 'class' => 'BeanDefault', 'parent' => 'bean', 'file' => 'BeanDefault.class.php', 'path' => drupal_get_path('module', 'bean') . '/plugins', ), ), ), ); } /** * Implements hook_bean_types(). */ function bean_bean_types() { $plugins = array(); $plugins['bean'] = array( 'handler' => array( 'class' => 'BeanPlugin', 'file' => 'BeanPlugin.class.php', 'path' => drupal_get_path('module', 'bean') . '/plugins', ), ); $plugins['bean_default'] = array( 'abstract' => TRUE, 'handler' => array( 'class' => 'BeanDefault', 'parent' => 'bean', 'file' => 'BeanDefault.class.php', 'path' => drupal_get_path('module', 'bean') . '/plugins', ), ); return $plugins; } /** * Implements hook_theme(). */ function bean_theme() { return array( 'bean' => array( 'render element' => 'entity', 'template' => 'bean', ), 'bean_add_list' => array( 'variables' => array('content' => NULL), ), ); } /** * Implements hook_menu_local_tasks_alter(). */ function bean_menu_local_tasks_alter(&$data, $router_item, $root_path) { // Add action link to 'block/add' on 'admin/content/blocks' page. if ($root_path == 'admin/content/blocks' && bean_get_types()) { $item = menu_get_item('block/add'); if ($item['access']) { $data['actions']['output'][] = array( '#theme' => 'menu_local_action', '#link' => $item, ); } } } /** * Implements hook_workbench_create_alter(). */ function bean_workbench_create_alter(&$output) { $items = array(); $i = 0; foreach (bean_get_types() as $bean_type) { if (entity_access('create', 'bean', $bean_type->type)) { $items[str_replace(' ', '', $bean_type->getLabel()) . '_' . $i] = array( 'title' => $bean_type->getLabel(), 'href' => 'block/add/' . $bean_type->buildURL(), 'description' => $bean_type->getDescription(), 'localized_options' => array(), 'page_arguments' => serialize(array('bean')), ); $i++; } } if (!empty($items)) { ksort($items); $output['bean_types'] = array( '#title' => t('Create Blocks'), '#markup' => theme('node_add_list', array('content' => $items)), '#theme' => 'workbench_element', ); } } /** * Implements hook_modules_enabled() */ function bean_modules_enabled($modules) { bean_reset(TRUE); } /** * Implements hook_field_extra_fields(). */ function bean_field_extra_fields() { $extra = array(); foreach (bean_get_types() as $type) { $extra['bean'][$type->type]['display']['title'] = array( 'label' => t('Title'), 'description' => t('Bean module element'), 'weight' => -9, ); $extra['bean'][$type->type]['form']['label'] = array( 'label' => t('Label'), 'description' => t('Bean module element'), 'weight' => -10, ); $extra['bean'][$type->type]['form']['title'] = array( 'label' => t('Title'), 'description' => t('Bean module element'), 'weight' => -9, ); $extra['bean'][$type->type]['form']['revision'] = array( 'label' => t('Revision settings'), 'description' => t('Bean module element'), 'weight' => 10, ); $extra['bean'][$type->type]['form']['view_mode'] = array( 'label' => t('View mode'), 'description' => t('Bean module element'), 'weight' => 10, ); } return $extra; } /** * Implements hook_views_api() */ function bean_views_api() { return array( 'api' => 3, 'path' => drupal_get_path('module', 'bean') . '/views', ); } /** * Implements hook_flush_caches(). */ function bean_flush_caches() { bean_reset(TRUE); return array(); } /** * Implements hook_admin_menu_output_build(). * * Places the "Add block" tree into the toolbar from Admin Menu module * * @see admin_menu_admin_menu_output_build() */ function bean_admin_menu_output_build(&$content) { if (!isset($content['menu'])) { return; } // Retrieve the "Add block" link tree. $link = db_query("SELECT * FROM {menu_links} WHERE router_path = 'block/add' AND module = 'system'")->fetchAssoc(); $conditions = array(); for ($i = 1; $i < MENU_MAX_DEPTH; $i++) { if (!empty($link["p$i"])) { $conditions["p$i"] = $link["p$i"]; } } $tree = menu_build_tree($link['menu_name'], array( 'conditions' => $conditions, 'min_depth' => $link['depth'], )); $links = admin_menu_links_menu($tree); if (!empty($links)) { // If the user has access to the top-level "Content" category, insert the // "Add content" link tree there. if (isset($content['menu']['admin/content'])) { $content['menu']['admin/content'] += $links; } // Otherwise insert "Add blocks" as top-level category. else { $key = key($links); $links[$key]['#weight'] = -100; $content['menu'] += $links; } } } /** * CTools callback for Bean blocks. * * @see _ctools_block_content_type_content_type() in block.inc. */ function bean_ctools_block_info($module, $delta, &$info) { // Use the core block icon. $info['icon'] = 'icon_contrib_block.png'; // Load the full bean. $bean = bean_load_delta($delta); // Identify the bean type. $bean_types = bean_get_types(); // By default store all beans in the Blocks category. $info['category'] = t('Blocks'); // If the bean type loaded correctly (should always happen), if (isset($bean_types[$bean->type])) { // Optionally group the blocks by their bean type.. if (variable_get('bean_ctools_separate', TRUE)) { $info['category'] = t('Blocks') . ': ' . $bean_types[$bean->type]->getLabel(); } // Optionally prefix the block with the bean type's label. if (variable_get('bean_ctools_prefix', FALSE)) { $info['title'] = $bean_types[$bean->type]->getLabel() . ': ' . $info['title']; } } } /** * Implements hook_ctools_plugin_directory(). * * Inform ctools about our panelizer plugin. */ function bean_ctools_plugin_directory($module, $plugin) { if (in_array($module, array('panelizer'))) { return 'plugins/' . $plugin; } }