diff --git a/css/ctools.css b/css/ctools.css index 4a2d875d53620c10c95ac663f41590b8b903af91..aac0f2b0c3f25c30070428d52b18ebbac5659e8e 100644 --- a/css/ctools.css +++ b/css/ctools.css @@ -11,12 +11,14 @@ padding: 1em; } -a.ctools-ajaxing { +a.ctools-ajaxing, +input.ctools-ajaxing { padding-right: 18px !important; background: url(../images/status-active.gif) right center no-repeat; } -input.ctools-ajaxing { - padding-right: 18px; - background: url(../images/status-active.gif) right center no-repeat; +div.ctools-ajaxing { + float: left; + width: 18px; + background: url(../images/status-active.gif) center center no-repeat; } diff --git a/includes/context.inc b/includes/context.inc index ac0a3de1f250607fadee85c185ce696f828105ff..10edd6c27a4bc62aa30d8e43faea53b0b6d15c64 100644 --- a/includes/context.inc +++ b/includes/context.inc @@ -509,7 +509,12 @@ function ctools_context_create($type, $data = NULL, $conf = FALSE) { */ function ctools_context_create_empty($type) { if ($function = ctools_plugin_load_function('ctools', 'contexts', $type, 'context')) { - return $function(TRUE); + $context = $function(TRUE); + if (is_object($context)) { + $context->empty = TRUE; + } + + return $context; } } @@ -657,6 +662,13 @@ function ctools_context_get_context_from_argument($argument, $arg, $empty = FALS $context->keyword = $argument['keyword']; $context->id = ctools_context_id($argument, 'argument'); $context->original_argument = $arg; + + if (!empty($context->empty)) { + $context->placeholder = array( + 'type' => 'argument', + 'conf' => $argument, + ); + } } return $context; } @@ -768,6 +780,12 @@ function ctools_context_get_context_from_relationship($relationship, $source_con $context->identifier = $relationship['identifier']; $context->page_title = isset($relationship['title']) ? $relationship['title'] : ''; $context->keyword = $relationship['keyword']; + if (!empty($context->empty)) { + $context->placeholder = array( + 'type' => 'relationship', + 'conf' => $relationship, + ); + } return $context; } } @@ -827,14 +845,6 @@ function ctools_context_get_context_from_relationships($relationships, &$context if (empty($contexts[$rdata['context']])) { continue; } - /* - $relationship = ctools_context_get_context_from_relationship($rdata['name']); - // If the relationship can't be found or its context can't be found, - // ignore. - if (!$relationship) { - continue; - } - */ $cid = ctools_context_id($rdata, 'relationship'); if ($context = ctools_context_get_context_from_relationship($rdata, $contexts[$rdata['context']])) { @@ -889,18 +899,31 @@ function ctools_get_contexts() { * @return * A context object if one can be loaded. */ -function ctools_context_get_context_from_context($context, $type = 'context') { +function ctools_context_get_context_from_context($context, $type = 'context', $argument = NULL) { ctools_include('plugins'); - if ($function = ctools_plugin_load_function('ctools', 'contexts', $context['name'], 'context')) { + $plugin = ctools_get_context($context['name']); + if ($function = ctools_plugin_get_function($plugin, 'context')) { if (!isset($context['context_settings'])) { $context['context_settings'] = array(); } + if (isset($argument) && isset($plugin['placeholder name'])) { + $context['context_settings'][$plugin['placeholder name']] = $argument; + } + $return = $function($type == 'requiredcontext', $context['context_settings'], TRUE); if ($return) { $return->identifier = $context['identifier']; $return->page_title = isset($context['title']) ? $context['title'] : ''; $return->keyword = $context['keyword']; + + if (!empty($context->empty)) { + $context->placeholder = array( + 'type' => 'context', + 'conf' => $context, + ); + } + return $return; } } @@ -1031,6 +1054,105 @@ function ctools_context_get_form($contexts) { } } +/** + * Replace placeholders with real contexts using data extracted from a form + * for the purposes of previews. + * + * @param $contexts + * All of the contexts, including the placeholders. + * @param $arguments + * The arguments. These will be acquired from $form_state['values'] and the + * keys must match the context IDs. + * + * @return + * A new $contexts array containing the replaced contexts. Not all contexts + * may be replaced if, for example, an argument was unable to be converted + * into a context. + */ +function ctools_context_replace_placeholders($contexts, $arguments) { + foreach ($contexts as $cid => $context) { + if (empty($context->empty)) { + continue; + } + + $new_context = NULL; + switch ($context->placeholder['type']) { + case 'relationship': + $relationship = $context->placeholder['conf']; + if (isset($contexts[$relationship['context']])) { + $new_context = ctools_context_get_context_from_relationship($relationship, $contexts[$relationship['context']]); + } + break; + case 'argument': + if (!empty($arguments[$cid])) { + $argument = $context->placeholder['conf']; + $new_context = ctools_context_get_context_from_argument($argument, $arguments[$cid]); + } + break; + case 'context': + if (!empty($arguments[$cid])) { + $context_info = $context->placeholder['conf']; + $new_context = ctools_context_get_context_from_context($context_info, 'requiredcontext', $arguments[$cid]); + } + break; + } + + if ($new_context && empty($new_context->empty)) { + $contexts[$cid] = $new_context; + } + } + + return $contexts; +} + +/** + * Provide a form array for getting data to replace placeholder contexts + * with real data. + */ +function ctools_context_replace_form(&$form, $contexts) { + foreach ($contexts as $cid => $context) { + if (empty($context->empty)) { + continue; + } + + // Get plugin info from the context which should have been set when the + // empty context was created. + $info = NULL; + $plugin = NULL; + $settings = NULL; + switch ($context->placeholder['type']) { + case 'argument': + $info = $context->placeholder['conf']; + $plugin = ctools_get_argument($info['name']); + $settings = $info['settings']; + + break; + case 'context': + $info = $context->placeholder['conf']; + $plugin = ctools_get_context($info['name']); + $settings = $info['context_settings']; + break; + } + + // Ask the plugin where the form is. + if ($plugin && isset($plugin['placeholder form'])) { + if (is_array($plugin['placeholder form'])) { + $form[$cid] = $plugin['placeholder form']; + } + else if (function_exists($plugin['placeholder form'])) { + $widget = $plugin['placeholder form']($argument['settings']); + if ($widget) { + $form[$cid] = $widget; + } + } + + if (!empty($form[$cid])) { + $form[$cid]['#title'] = t('@identifier (@keyword)', array('@keyword' => '%' . $context->keyword, '@identifier' => $context->identifier)); + } + } + } +} + // --------------------------------------------------------------------------- // Functions related to loading access control plugins diff --git a/js/ajax-responder.js b/js/ajax-responder.js index 4b0d0d0e1cff241f71c172da906dd38b90348d7c..5dfa9b2fab585a40190654145b597dfbd832aaa9 100644 --- a/js/ajax-responder.js +++ b/js/ajax-responder.js @@ -71,6 +71,9 @@ Drupal.CTools.AJAX.clickAJAXButton = function() { return false; } + // Put our button in. + this.form.clk = this; + var url = Drupal.CTools.AJAX.findURL(this); $(this).addClass('ctools-ajaxing'); var object = $(this); diff --git a/js/modal.js b/js/modal.js index 195156e493b3099b0521b4038a096b917c2d29c1..194bbb63833bec932067bbcca76396a3c9d2f741 100644 --- a/js/modal.js +++ b/js/modal.js @@ -147,6 +147,7 @@ Drupal.CTools.Modal.submitAjaxForm = function() { }, complete: function() { object.removeClass('ctools-ajaxing'); + $('.ctools-ajaxing', object).removeClass('ctools-ajaxing'); }, dataType: 'json' }); @@ -154,6 +155,7 @@ Drupal.CTools.Modal.submitAjaxForm = function() { catch (err) { alert("An error occurred while attempting to process " + url); $(this).removeClass('ctools-ajaxing'); + $('.ctools-ajaxing', this).removeClass('ctools-ajaxing'); return false; } return false; @@ -181,12 +183,15 @@ Drupal.behaviors.CToolsModal = function(context) { .append('<input type="hidden" name="op" value="">'); // add click handlers so that we can tell which button was clicked, // because the AJAX submit does not set the values properly. + $('input[type="submit"]:not(.ctools-use-modal-processed)', context) .addClass('ctools-use-modal-processed') .click(function() { - var name = $(this).attr('name'); - $('input[name="' + name + '"]', context).val($(this).val()); + // Make sure it knows our button. + this.form.clk = this; + $(this).after('<div class="ctools-ajaxing"> </div>'); }); + } }; diff --git a/plugins/arguments/nid.inc b/plugins/arguments/nid.inc index de19cea640adae1d9af27bba00123c09bf2331f0..c983906a9242d3c18bdb04ec4dc7bfc66b7e3a0b 100644 --- a/plugins/arguments/nid.inc +++ b/plugins/arguments/nid.inc @@ -16,6 +16,10 @@ function ctools_nid_ctools_arguments() { 'keyword' => 'node', 'description' => t('Creates a node context from a node ID argument.'), 'context' => 'ctools_argument_nid_context', + 'placeholder form' => array( + '#type' => 'textfield', + '#description' => t('Enter the node ID of a node for this argument'), + ), ); return $args; } diff --git a/plugins/arguments/node_edit.inc b/plugins/arguments/node_edit.inc index 7838665e2f7d2aabcaf229ca9abd54e44f1afe3e..e462e3dcb6c75f0d5751a0f17a6b6c3324b5d264 100644 --- a/plugins/arguments/node_edit.inc +++ b/plugins/arguments/node_edit.inc @@ -17,6 +17,10 @@ function ctools_node_edit_ctools_arguments() { 'keyword' => 'node', 'description' => t('Creates a node edit form context from a node ID argument.'), 'context' => 'ctools_node_edit_context', + 'placeholder form' => array( + '#type' => 'textfield', + '#description' => t('Enter the node ID of a node for this argument'), + ), ); return $args; } diff --git a/plugins/arguments/string.inc b/plugins/arguments/string.inc index 0bb646531655de8dd918d1583cb6e44c738bc2a2..1bb225909631c84fda8c7872e77e90d362edd896 100644 --- a/plugins/arguments/string.inc +++ b/plugins/arguments/string.inc @@ -17,6 +17,10 @@ function ctools_string_ctools_arguments() { 'keyword' => 'string', 'description' => t('A string is a minimal context that simply holds a string that can be used for some other purpose.'), 'context' => 'ctools_string_context', + 'placeholder form' => array( + '#type' => 'textfield', + '#description' => t('Enter a value for this argument'), + ), ); return $args; } diff --git a/plugins/arguments/term.inc b/plugins/arguments/term.inc index e481c00c848e486e49918b4f4d79a8e1531b6988..de24fc15f172c7a9b02da656c58434b89b1e8568 100644 --- a/plugins/arguments/term.inc +++ b/plugins/arguments/term.inc @@ -19,6 +19,7 @@ function ctools_term_ctools_arguments() { 'context' => 'ctools_term_context', 'default' => array('input_form' => 'tid'), 'settings form' => 'ctools_term_settings_form', + 'placeholder form' => 'ctools_term_ctools_argument_placeholder', ); return $args; } @@ -86,3 +87,21 @@ function ctools_term_settings_form(&$form, &$form_state, $conf) { ); } +/** + * Form fragment to get an argument to convert a placeholder for preview. + */ +function ctools_term_ctools_argument_placeholder($conf) { + switch ($conf['input_form']) { + case 'tid': + default: + return array( + '#type' => 'textfield', + '#description' => t('Enter a taxonomy term ID.'), + ); + case 'term': + return array( + '#type' => 'textfield', + '#description' => t('Enter a taxonomy term name.'), + ); + } +} diff --git a/plugins/arguments/uid.inc b/plugins/arguments/uid.inc index cc2290e87208cd8e799ae7148ddf6572c54a6647..f194b893074e29738629ddbf9c8764015fd54f08 100644 --- a/plugins/arguments/uid.inc +++ b/plugins/arguments/uid.inc @@ -17,6 +17,10 @@ function ctools_uid_ctools_arguments() { 'keyword' => 'user', 'description' => t('Creates a user context from a user ID argument.'), 'context' => 'ctools_argument_uid_context', + 'placeholder form' => array( + '#type' => 'textfield', + '#description' => t('Enter the user ID of a user for this argument'), + ), ); return $args; } diff --git a/plugins/arguments/vid.inc b/plugins/arguments/vid.inc index 59929705b16e200f34359783eff583e8e007d3d2..9be9f586653d53e291ca1505eed303822d45e50c 100644 --- a/plugins/arguments/vid.inc +++ b/plugins/arguments/vid.inc @@ -17,6 +17,10 @@ function ctools_vid_ctools_arguments() { 'keyword' => 'vocabulary', 'description' => t('Creates a vocabulary context from a vocabulary ID argument.'), 'context' => 'ctools_vid_context', + 'placeholder form' => array( + '#type' => 'textfield', + '#description' => t('Enter the vocabulary ID for this argument'), + ), ); return $args; } diff --git a/plugins/content_types/block/block.inc b/plugins/content_types/block/block.inc index ef26057b5042da01bfe60d20268c1bcabcef071b..ebd4a3b7774d8207899a8151fe7e5cb74fde9062 100644 --- a/plugins/content_types/block/block.inc +++ b/plugins/content_types/block/block.inc @@ -70,7 +70,12 @@ function ctools_block_content_type_render($subtype, $conf) { return; } - $block->title = $block->subject; + if (isset($block->subject)) { + $block->title = $block->subject; + } + else { + $block->title = NULL; + } if (user_access('administer blocks')) { $block->admin_links = array( @@ -131,13 +136,6 @@ function ctools_block_content_type_edit_form(&$form, &$form_state) { // Does nothing! } -/** - * The submit form stores the data in $conf. - */ -function ctools_block_content_type_edit_form_submit(&$form, &$form_state) { - $form_state['conf'] = $form_state['values']; -} - /** * Returns an edit form for a block. */ diff --git a/plugins/content_types/custom/custom.inc b/plugins/content_types/custom/custom.inc index 6401f5ffcdcde296b4bc2c91ae4029841b92b9f3..39c35654c1699919a809c73e54240b070adb6611 100644 --- a/plugins/content_types/custom/custom.inc +++ b/plugins/content_types/custom/custom.inc @@ -104,5 +104,7 @@ function ctools_custom_content_type_edit_form(&$form, &$form_state) { * The submit form stores the data in $conf. */ function ctools_custom_content_type_edit_form_submit(&$form, &$form_state) { - $form_state['conf'] = $form_state['values']; + foreach (array_keys($form_state['plugin']['defaults']) as $key) { + $form_state['conf'][$key] = $form_state['values'][$key]; + } } diff --git a/plugins/contexts/node.inc b/plugins/contexts/node.inc index 033e2031017bb4e82fbb4d7bb49351fd1f235ba1..12217a65b24ad9185ee07c40b6368b82c036d361 100644 --- a/plugins/contexts/node.inc +++ b/plugins/contexts/node.inc @@ -23,6 +23,10 @@ function ctools_node_ctools_contexts() { 'context name' => 'node', 'convert list' => 'ctools_context_node_convert_list', 'convert' => 'ctools_context_node_convert', + 'placeholder form' => array( + '#type' => 'textfield', + '#description' => t('Enter the node ID of a node for this context.'), + ), ); return $args; } diff --git a/plugins/contexts/node_add_form.inc b/plugins/contexts/node_add_form.inc index 54bcb5349e217f95b526ffd4a6ca6f02bdb38e1b..bd1dc96400f77ed7a671d2cab7fc11a1e95ca910 100644 --- a/plugins/contexts/node_add_form.inc +++ b/plugins/contexts/node_add_form.inc @@ -20,6 +20,10 @@ function ctools_node_add_form_ctools_contexts() { 'context name' => 'node_add_form', 'convert list' => array('type' => t('Node type')), 'convert' => 'ctools_context_node_add_form_convert', + 'placeholder form' => array( + '#type' => 'textfield', + '#description' => t('Enter the node type this context.'), + ), ); return $args; } diff --git a/plugins/contexts/node_edit_form.inc b/plugins/contexts/node_edit_form.inc index cb3267a5a5b42691e34b70814587b12b69e2aaa1..92c840d4c19e895357168a377bb4c3d750de2ef6 100644 --- a/plugins/contexts/node_edit_form.inc +++ b/plugins/contexts/node_edit_form.inc @@ -19,6 +19,10 @@ function ctools_node_edit_form_ctools_contexts() { 'settings form validate' => 'ctools_context_node_edit_form_settings_form_validate', 'keyword' => 'node_edit', 'context name' => 'node_edit_form', + 'placeholder form' => array( + '#type' => 'textfield', + '#description' => t('Enter the node ID of a node for this argument:'), + ), ); return $args; } diff --git a/plugins/contexts/string.inc b/plugins/contexts/string.inc index e33f73911e1164623c0754f7c5136a982df3c560..99f0efec2c14c419f98c93e8e8b0da18adca11d6 100644 --- a/plugins/contexts/string.inc +++ b/plugins/contexts/string.inc @@ -20,6 +20,10 @@ function ctools_string_ctools_contexts() { 'context name' => 'string', 'convert list' => array('raw' => t('Raw string')), 'convert' => 'ctools_context_string_convert', + 'placeholder form' => array( + '#type' => 'textfield', + '#description' => t('Enter the string for this context.'), + ), ); return $args; } diff --git a/plugins/relationships/user_from_node.inc b/plugins/relationships/user_from_node.inc index bccfed4304d75405e556c85911c9925ba06b864c..e5138d3c9d823624549d866a0320302212d602d3 100644 --- a/plugins/relationships/user_from_node.inc +++ b/plugins/relationships/user_from_node.inc @@ -12,7 +12,7 @@ */ function ctools_user_from_node_ctools_relationships() { $args['user_from_node'] = array( - 'title' => t("User from node"), + 'title' => t("Node author"), 'keyword' => 'user', 'description' => t('Creates the author of a node as a user context.'), 'required context' => new ctools_context_required(t('Node'), 'node'), @@ -26,9 +26,10 @@ function ctools_user_from_node_ctools_relationships() { */ function ctools_user_from_node_context($context = NULL, $conf) { // If unset it wants a generic, unfilled context, which is just NULL - if (empty($context->data)) { + if (empty($context->data) || !isset($context->data->uid)) { return ctools_context_create_empty('user', NULL); } + if (isset($context->data->uid)) { // Load the user that is the author of the node $uid = $context->data->uid; @@ -37,8 +38,5 @@ function ctools_user_from_node_context($context = NULL, $conf) { // Send it to ctools return ctools_context_create('user', $account); } - else { - return ctools_context_create_empty('user', NULL); - } }