From 2728006e136d005cdc3e60ef6b1a7373af04bf24 Mon Sep 17 00:00:00 2001 From: Helior Colorado Date: Fri, 1 Jun 2012 18:56:05 -0700 Subject: [PATCH] Added UI for managing bundles. --- README.txt | 30 +---- fieldable_panels_panes.install | 154 ++++++++++++++++++++ fieldable_panels_panes.module | 134 +++++++---------- includes/admin.inc | 77 ---------- plugins/entity/FieldablePanelsPaneEntity.class.php | 4 +- .../fieldable_panels_panes_type_ui.class.php | 134 +++++++++++++++++ .../export_ui/fieldable_panels_panes_type_ui.inc | 113 ++++++++++++++ 7 files changed, 461 insertions(+), 185 deletions(-) create mode 100644 plugins/export_ui/fieldable_panels_panes_type_ui.class.php create mode 100644 plugins/export_ui/fieldable_panels_panes_type_ui.inc diff --git a/README.txt b/README.txt index 3edfe47..bbc5799 100644 --- a/README.txt +++ b/README.txt @@ -1,28 +1,2 @@ -Fieldable Panel Panes support multiple bundles, but at this time there is no -UI to create bundles. - -Bundles can be created in a module via hook_entity_info_alter(). The code -will look something like this: - -function MYMODULE_entity_info_alter(&$entity_info) { - $entity_info['fieldable_panels_pane']['bundles']['my_bundle_name'] = array( - 'label' => t('My bundle name'), - 'pane category' => t('My category name'), - 'pane top level' => FALSE, // set to true to make this show as a top level icon - 'pane icon' => '/path/to/custom/icon/for/this/pane.png', - 'admin' => array( - 'path' => 'admin/structure/panels/entity/manage/%fieldable_panels_panes_type', - 'bundle argument' => 5, - // Note that this has all _ replaced with - from the bundle name. - 'real path' => 'admin/structure/panels/entity/manage/my-bundle-name', - 'access arguments' => array('administer fieldable panels panes'), - ), - ); -} - -Fields are then added to your bundle as normal through the Manage Fields and -Display Fields tabs in the UI. - -You can use this hook to rename or remove the default bundle but remember that -doing so will break any content currently using that bundle. If you do this -be sure to also fix any content already using it. +Fieldable Panel Panes support multiple bundles, and they can be +created in admin/structure/panels/fieldable-panels-panes/add diff --git a/fieldable_panels_panes.install b/fieldable_panels_panes.install index 9671900..55aedf0 100644 --- a/fieldable_panels_panes.install +++ b/fieldable_panels_panes.install @@ -1,6 +1,96 @@ $bundle_info) { + $dupes[] = array( + 'module' => $module, + 'bundle label' => $bundle_info['label'], + 'exists' => isset($items[$bundle_name]), + 'obsolete path' => strpos($bundle_info['admin']['path'], 'admin/structure/panels/entity/manage') !== FALSE, + 'function' => $function, + ); + } + } + } + + if (!empty($dupes)) { + $items = array(); + foreach ($dupes as $dupe) { + $string = array(); + $replacements = array( + '%module' => $dupe['module'], + '%bundle' => $dupe['bundle label'], + '%function' => $dupe['function'] . '()', + ); + $string[] = t('The module %module provides the bundle %bundle in %function.', $replacements); + + if ($dupe['obsolete path']) { + $string[] = t('It also contains an obsolete admin path which can cause errors.'); + } + + if ($dupe['exists']) { + $string[] = t('It should now be safe to remove from code.'); + } + else { + $string[] = t('A type should be created for it in the !add_page before removing from code.', array('!add_page' => l(t('Add Type page'), 'admin/structure/panels/fieldable-panels-panes/add'))); + } + + $items[] = implode(' ', $string); + } + + $requirements['fieldable_panels_panes'] = array( + 'title' => t('Fieldable Panels Panes obsolete bundles'), + 'severity' => REQUIREMENT_WARNING, + 'value' => theme('item_list', array('items' => $items)), + ); + } + } + + return $requirements; +} + + +/** + * Implements hook_install(). + */ +function fieldable_panels_panes_install() { + ctools_include('export'); + + $item = ctools_export_crud_new('fieldable_panels_panes_type'); + $item->name = 'fieldable_panels_pane'; + $item->title = t('Panels Pane'); + ctools_export_crud_save('fieldable_panels_panes_type', $item); +} + + +/** + * Implements hook_uninstall(). + */ +function fieldable_panels_panes_uninstall() { + $results = db_query('SELECT name FROM {fieldable_panels_panes_type}'); + foreach ($results as $type) { + field_attach_delete_bundle('fieldable_panels_pane', $type->name); + } +} + + +/** * Implements hook_schema(). */ function fieldable_panels_panes_schema() { @@ -141,6 +231,38 @@ function fieldable_panels_panes_schema() { ), ); + $schema['fieldable_panels_panes_type'] = array( + 'description' => 'Entity bundle table for panel pane content.', + 'fields' => array( + 'name' => array( + 'description' => 'The machine-readable name of this type.', + 'type' => 'varchar', + 'length' => 32, + 'not null' => TRUE, + 'default' => '', + ), + 'title' => array( + 'description' => 'The human-readable name of this type.', + 'type' => 'varchar', + 'length' => 255, + 'not null' => TRUE, + 'default' => '', + 'translatable' => TRUE, + ), + 'description' => array( + 'description' => 'A brief description of this type.', + 'type' => 'text', + 'size' => 'big', + 'not null' => TRUE, + ), + ), + 'export' => array( + 'admin_title' => 'title', + 'admin_description' => 'description', + ), + 'primary key' => array('name'), + ); + return $schema; } @@ -171,3 +293,35 @@ function fieldable_panels_panes_update_7102(&$sandbox) { ->condition('fpid', $existing, 'NOT IN') ->execute(); } + +/** + * Add Fieldable Panels Panes Type table. + * Save existing bundles to database. + */ +function fieldable_panels_panes_update_7104(&$sandbox) { + ctools_include('export'); + $messages = array(); + + // Add the new table for storing bundles. + $schema = drupal_get_schema('fieldable_panels_panes_type', TRUE); + db_create_table('fieldable_panels_panes_type', $schema); + $messages[] = t('Table %table_name has been added.', array('%table_name' => 'fieldable_panels_panes_type')); + + // Store possible existing bundles provided by other modules. + $bundles = array(); + $entity_info = entity_get_info('fieldable_panels_pane'); + foreach ($entity_info['bundles'] as $bundle_name => $bundle_info) { + $bundles[] = $bundle_info['label']; + + $item = ctools_export_crud_new('fieldable_panels_panes_type'); + $item->name = $bundle_name; + $item->title = $bundle_info['label']; + ctools_export_crud_save('fieldable_panels_panes_type', $item); + } + + if (!empty($bundles)) { + $messages[] = format_plural(count($bundles), 'Added existing bundle %bundle_names to database.', 'Added existing bundles %bundle_names to database.', array('%bundle_names' => implode(', ', $bundles))); + } + + return implode('
', $messages); +} diff --git a/fieldable_panels_panes.module b/fieldable_panels_panes.module index 67da3af..6baf88d 100644 --- a/fieldable_panels_panes.module +++ b/fieldable_panels_panes.module @@ -13,51 +13,51 @@ * Implements hook_entity_info() */ function fieldable_panels_panes_entity_info() { - return array( - 'fieldable_panels_pane' => array( - 'label' => t('Fieldable panel pane'), - 'controller class' => 'PanelsPaneController', - 'base table' => 'fieldable_panels_panes', - 'revision table' => 'fieldable_panels_panes_revision', - 'fieldable' => TRUE, - 'uuid' => TRUE, - 'entity keys' => array( - 'id' => 'fpid', - 'revision' => 'vid', - 'bundle' => 'bundle', - 'label' => 'admin_title', - 'uuid' => 'uuid', - 'revision uuid' => 'vuuid', - ), - 'bundles' => array( - // @todo We need to store the possible bundles and create a UI. - // to allow for more bundles. For now, hook_panels_panes_entity_info_alter - // will work. - 'fieldable_panels_pane' => array( - 'label' => t('Panels pane'), - 'admin' => array( - 'path' => 'admin/structure/panels/entity/manage/%fieldable_panels_panes_type', - 'bundle argument' => 5, - 'real path' => 'admin/structure/panels/entity/manage/fieldable-panels-pane', - 'access arguments' => array('administer fieldable panels panes'), - ), - ), - ), - 'view modes' => array( - // @todo we should support view modes. - 'full' => array( - 'label' => t('Full'), - 'custom settings' => FALSE, - ), + $entity_info['fieldable_panels_pane'] = array( + 'label' => t('Fieldable panel pane'), + 'controller class' => 'PanelsPaneController', + 'base table' => 'fieldable_panels_panes', + 'revision table' => 'fieldable_panels_panes_revision', + 'fieldable' => TRUE, + 'uuid' => TRUE, + 'entity keys' => array( + 'id' => 'fpid', + 'revision' => 'vid', + 'bundle' => 'bundle', + 'label' => 'admin_title', + 'uuid' => 'uuid', + 'revision uuid' => 'vuuid', + ), + 'bundles' => array(), + 'view modes' => array( + // @todo we should support view modes. + 'full' => array( + 'label' => t('Full'), + 'custom settings' => FALSE, ), - - // entity module callbacks - 'view callback' => 'entity_metadata_view_single', - 'creation callback' => 'fieldable_panels_panes_create', - 'access callback' => 'fieldable_panels_panes_access', - 'save callback' => 'fieldable_panels_panes_save', ), + + // entity module callbacks + 'view callback' => 'entity_metadata_view_single', + 'creation callback' => 'fieldable_panels_panes_create', + 'access callback' => 'fieldable_panels_panes_access', + 'save callback' => 'fieldable_panels_panes_save', ); + + ctools_include('export'); + foreach (ctools_export_crud_load_all('fieldable_panels_panes_type') as $type) { + $entity_info['fieldable_panels_pane']['bundles'][$type->name] = array( + 'label' => $type->title, + 'admin' => array( + 'path' => 'admin/structure/panels/fieldable-panels-panes/%fieldable_panels_panes_type', + 'bundle argument' => 4, + 'real path' => 'admin/structure/panels/fieldable-panels-panes/' . $type->name, + 'access arguments' => array('administer fieldable panels panes'), + ), + ); + } + + return $entity_info; } /** @@ -100,20 +100,6 @@ function fieldable_panels_panes_menu() { 'file' => 'includes/admin.inc', ); - - $items['admin/structure/panels/entity'] = array( - 'title' => 'Entities', - 'description' => 'Manage pane content types.', - 'page callback' => 'fieldable_panels_panes_entities_page', - 'type' => MENU_LOCAL_TASK, - ) + $base; - - $items['admin/structure/panels/entity/list'] = array( - 'title' => 'List', - 'type' => MENU_DEFAULT_LOCAL_TASK, - 'weight' => -10, - ) + $base; - $items['admin/structure/panels/entity/view/%fieldable_panels_panes'] = array( 'title callback' => 'fieldable_panels_panes_entity_title', 'title arguments' => array(5), @@ -237,28 +223,6 @@ function fieldable_panels_panes_menu() { 'load arguments' => array(7), ) + $base; - $items['admin/structure/panels/entity/manage/%fieldable_panels_panes_type'] = array( - 'title callback' => 'fieldable_panels_panes_entities_title', - 'title arguments' => array(5), - 'page callback' => 'fieldable_panels_panes_entities_list_page', - 'page arguments' => array(5), - ) + $base; - - $items['admin/structure/panels/entity/manage/%fieldable_panels_panes_type/list'] = array( - 'title' => 'List', - 'type' => MENU_DEFAULT_LOCAL_TASK, - 'weight' => -10, - ); - - $items['admin/structure/panels/entity/manage/%fieldable_panels_panes_type/add'] = array( - 'title' => 'Add', - 'page callback' => 'fieldable_panels_panes_entities_add_page', - 'page arguments' => array(5), - 'access callback' => 'fieldable_panels_panes_access', - 'access arguments' => array('create'), - 'type' => MENU_LOCAL_TASK, - ) + $base; - return $items; } @@ -372,6 +336,16 @@ function fieldable_panels_panes_entities_title($type) { } /** + * Title callback for fieldable panels panes type. + * + * @param $type + * A %ctools_export_ui object. + */ +function fieldable_panels_panes_type_title($type) { + return $type->title; +} + +/** * Ensure an entity can be accessed via URL. * * This requires only administrative access. @@ -407,6 +381,10 @@ function fieldable_panels_panes_ctools_plugin_directory($owner, $plugin_type) { return 'plugins/' . $plugin_type; } + if ($owner == 'ctools' && $plugin_type == 'export_ui') { + return 'plugins/' . $plugin_type; + } + if ($owner == 'panelizer' && defined('PANELIZER_VERSION') && version_compare(PANELIZER_VERSION, '3.0', '>=')) { return 'plugins/' . $plugin_type; } diff --git a/includes/admin.inc b/includes/admin.inc index 5ca6a13..6ca94ac 100644 --- a/includes/admin.inc +++ b/includes/admin.inc @@ -6,83 +6,6 @@ */ /** - * List all bundles and administrative options for entity panes. - */ -function fieldable_panels_panes_entities_page() { - $entity_info = entity_get_info('fieldable_panels_pane'); - - $header = array(t('Name'), array('data' => t('Operations'), 'colspan' => 2)); - $rows = array(); - - foreach ($entity_info['bundles'] as $bundle => $info) { - $type_url_str = str_replace('_', '-', $bundle); - - $row = array(); - - $label = check_plain($info['label']); - $label .= ' ' . t('(Machine name: @type)', array('@type' => $bundle)) . ''; - - $row[] = $label; - - $operations = array(); - - $operations['list'] = array( - 'title' => t('list'), - 'href' => 'admin/structure/panels/entity/manage/' . $type_url_str, - ); - - $operations['add'] = array( - 'title' => t('add'), - 'href' => 'admin/structure/panels/entity/manage/' . $type_url_str . '/add', - ); - - $operations['fields'] = array( - 'title' => t('manage fields'), - 'href' => 'admin/structure/panels/entity/manage/' . $type_url_str . '/fields', - ); - - $operations['display'] = array( - 'title' => t('manage display'), - 'href' => 'admin/structure/panels/entity/manage/' . $type_url_str . '/display', - ); - - $ops = theme('links', array('links' => $operations, 'attributes' => array('class' => array('links', 'inline')))); - - $row[] = $ops; - $rows[] = $row; - } - - $build['panes_table'] = array( - '#theme' => 'table', - '#header' => $header, - '#rows' => $rows, - ); - - return $build; -} - -/** - * List all entities for the given type. - */ -function fieldable_panels_panes_entities_list_page($type) { - return views_embed_view('fieldable_pane_entities', 'default', $type); -} - -/** - * Page callback to add a new pane entity. - */ -function fieldable_panels_panes_entities_add_page($type) { - $form_state = array( - 'entity' => fieldable_panels_panes_create(array('bundle' => $type)), - 'add submit' => TRUE, - ); - - // Default these to reusable. - $form_state['entity']->reusable = TRUE; - return drupal_build_form('fieldable_panels_panes_entity_edit_form', $form_state); -} - -/** * Page callback to view a entity. * * This represents an administrative view only. It is not available to diff --git a/plugins/entity/FieldablePanelsPaneEntity.class.php b/plugins/entity/FieldablePanelsPaneEntity.class.php index 8184718..23f515e 100644 --- a/plugins/entity/FieldablePanelsPaneEntity.class.php +++ b/plugins/entity/FieldablePanelsPaneEntity.class.php @@ -11,8 +11,8 @@ */ class FieldablePanelsPaneEntity extends PanelizerEntityDefault { // @todo this path is too deep to handle. -// public $entity_admin_root = 'admin/structure/panels/entity/manage/%'; -// public $entity_admin_bundle = 5; +// public $entity_admin_root = 'admin/structure/panels/fieldable-panels-panes/%'; +// public $entity_admin_bundle = 4; public $views_table = 'fieldable_panels_panes'; public function entity_access($op, $entity) { diff --git a/plugins/export_ui/fieldable_panels_panes_type_ui.class.php b/plugins/export_ui/fieldable_panels_panes_type_ui.class.php new file mode 100644 index 0000000..03b12d8 --- /dev/null +++ b/plugins/export_ui/fieldable_panels_panes_type_ui.class.php @@ -0,0 +1,134 @@ +plugin); + $name = $item->{$this->plugin['export']['key']}; + + $operations['list'] = array( + 'title' => t('List'), + 'href' => $base_path . '/' . $name . '/list', + ); + + $operations['add_entity'] = array( + 'title' => t('Add Entity'), + 'href' => $base_path . '/' . $name . '/add', + ); + + $operations += parent::build_operations($item); + + $operations['field'] = array( + 'title' => t('Manage Fields'), + 'href' => $base_path . '/' . $name . '/fields', + ); + + $operations['display'] = array( + 'title' => t('Manage Display'), + 'href' => $base_path . '/' . $name . '/display', + ); + + return $operations; + } + + /** + * Allow users to jump right into adding fields. + */ + function edit_form(&$form, &$form_state) { + parent::edit_form($form, $form_state); + + if (module_exists('field_ui')) { + $form['buttons']['save_continue'] = array( + '#type' => 'submit', + '#value' => t('Save and add fields'), + '#access' => $form_state['op'] == 'add' || $form_state['op'] == 'clone', + ); + } + } + + /** + * Update the form state "op" so we can properly redirect. + */ + function edit_form_submit(&$form, &$form_state) { + parent::edit_form_submit($form, $form_state); + + if ($form_state['triggering_element']['#parents'][0] == 'save_continue') { + $form_state['op'] = 'save_continue'; + } + } + + /** + * Ensure menu gets rebuild after saving a new type. + */ + function edit_save_form($form_state) { + parent::edit_save_form($form_state); + + entity_info_cache_clear(); + menu_rebuild(); + + if ($form_state['op'] === 'save_continue') { + $this->plugin['redirect']['save_continue'] = $this->field_admin_path($form_state['values']['name'], 'fields'); + } + } + + /** + * Remove fields associated to bundles that are being deleted. + */ + function delete_form_submit(&$form_state) { + parent::delete_form_submit($form_state); + + if ($form_state['op'] == 'delete') { + field_attach_delete_bundle('fieldable_panels_pane', $form_state['item']->name); + entity_info_cache_clear(); + } + } + + /** + * List entities page. + */ + function list_entities_page($js, $input, $item, $step = NULL) { + drupal_set_title($this->get_page_title('list_entity', $item)); + + return views_embed_view('fieldable_pane_entities', 'default', $item->name); + } + + /** + * Add entity page. + */ + function add_entity_page($js, $input, $item, $step = NULL) { + drupal_set_title($this->get_page_title('add_entity', $item)); + + $form_state = array( + 'entity' => fieldable_panels_panes_create(array('bundle' => $item->name)), + 'add submit' => TRUE, + 'plugin' => $this->plugin, + 'object' => &$this, + 'ajax' => $js, + 'item' => $item, + 'op' => 'add_entity', + 'no_redirect' => TRUE, + 'rerender' => TRUE, + 'step' => $step, + 'function args' => func_get_args(), + ); + + // Default these to reusable. + $form_state['entity']->reusable = TRUE; + $output = drupal_build_form('fieldable_panels_panes_entity_edit_form', $form_state); + if (!empty($form_state['executed'])) { + $this->redirect($form_state['op'], $form_state['item']); + } + + return $output; + } + + /** + * Helper method to derive paths to field ui operations. + */ + function field_admin_path($name, $op) { + return _field_ui_bundle_admin_path('fieldable_panels_pane', $name) . '/' . $op; + } +} diff --git a/plugins/export_ui/fieldable_panels_panes_type_ui.inc b/plugins/export_ui/fieldable_panels_panes_type_ui.inc new file mode 100644 index 0000000..32c59b9 --- /dev/null +++ b/plugins/export_ui/fieldable_panels_panes_type_ui.inc @@ -0,0 +1,113 @@ + 'fieldable_panels_panes_type_ui', + 'schema' => 'fieldable_panels_panes_type', + 'access' => 'administer fieldable panels panes', + 'handler' => array('class' => 'fieldable_panels_panes_type_ui'), + + 'title singular' => t('fieldable panels panes type'), + 'title singular proper' => t('Fieldable Panels Panes Type'), + 'title plural' => t('fieldable panels panes types'), + 'title plural proper' => t('Fieldable Panels Panes Types'), + ); + + $plugin['menu'] = array( + 'menu prefix' => 'admin/structure/panels', + 'menu item' => 'fieldable-panels-panes', + 'menu title' => 'Fieldable Panels Panes', + 'menu description' => 'Create and manage fieldable panels pane types.', + ); + + $plugin['allowed operations'] = array( + 'clone' => FALSE, + ); + + $base_path = ctools_export_ui_plugin_base_path($plugin); + $prefix_count = count(explode('/', $plugin['menu']['menu prefix'])); + + $plugin['menu']['items'] = array( + 'list callback' => array('type' => MENU_LOCAL_TASK), + 'edit callback' => array( + 'path' => '%ctools_export_ui', + 'title callback' => 'fieldable_panels_panes_type_title', + 'title arguments' => array($prefix_count + 1), + 'page arguments' => array($plugin['name'], 'list_entities', $prefix_count + 1), + 'access arguments' => array($plugin['name'], 'list_entities', $prefix_count + 1), + ), + 'list_entities' => array( + 'path' => '%ctools_export_ui/list', + 'title' => 'List', + 'access callback' => 'ctools_export_ui_task_access', + 'access arguments' => array($plugin['name'], 'list_entities'), + 'type' => MENU_DEFAULT_LOCAL_TASK, + 'weight' => -10, + ), + 'add_entity' => array( + 'path' => '%ctools_export_ui/add', + 'title' => 'Add entity', + 'page callback' => 'ctools_export_ui_switcher_page', + 'page arguments' => array($plugin['name'], 'add_entity', $prefix_count + 1), + 'load arguments' => array($plugin['name']), + 'access callback' => 'ctools_export_ui_task_access', + 'access arguments' => array($plugin['name'], 'add_entity'), + 'type' => MENU_LOCAL_TASK, + 'weight' => -9, + ), + 'edit' => array( + 'path' => '%ctools_export_ui/edit', + 'page arguments' => array($plugin['name'], 'edit', $prefix_count + 1), + 'access arguments' => array($plugin['name'], 'edit', $prefix_count + 1), + 'type' => MENU_LOCAL_TASK, + 'weight' => -8, + ), + 'export' => array( + 'path' => '%ctools_export_ui/export', + 'page arguments' => array($plugin['name'], 'export', $prefix_count + 1), + 'access arguments' => array($plugin['name'], 'export', $prefix_count + 1), + ), + 'revert' => array( + 'path' => '%ctools_export_ui/revert', + 'page arguments' => array($plugin['name'], 'delete', $prefix_count + 1), + 'access arguments' => array($plugin['name'], 'delete', $prefix_count + 1), + ), + 'delete' => array( + 'path' => '%ctools_export_ui/delete', + 'page arguments' => array($plugin['name'], 'delete', $prefix_count + 1), + 'access arguments' => array($plugin['name'], 'delete', $prefix_count + 1), + ), + 'enable' => array( + 'path' => '%ctools_export_ui/enable', + 'page arguments' => array($plugin['name'], 'enable', $prefix_count + 1), + 'access arguments' => array($plugin['name'], 'enable', $prefix_count + 1), + ), + 'disable' => array( + 'path' => '%ctools_export_ui/disable', + 'page arguments' => array($plugin['name'], 'disable', $prefix_count + 1), + 'access arguments' => array($plugin['name'], 'disable', $prefix_count + 1), + ), + ); + + $plugin['redirect'] = array( + 'add_entity' => $base_path . '/%ctools_export_ui', + ); + + $plugin['strings'] = array( + 'title' => array( + 'add_entity' => t('Add fieldable panels pane of type %title'), + 'list_entity' => t('List %title entities'), + ), + 'confirmation' => array( + 'save_continue' => array( + 'success' => t('%title has been created.'), + 'fail' => t('%title could not be created.'), + ), + ), + ); + + return $plugin; +} -- 1.7.7.5 (Apple Git-26)