all contrib module security updates done

This commit is contained in:
2020-09-24 22:47:32 +02:00
parent 7d87153100
commit 0fbb9c4610
1612 changed files with 116663 additions and 32269 deletions
@@ -3,6 +3,9 @@ Current API Version: 2.0.8
Please note that the API version is an internal number and does not match release numbers. It is entirely possible that releases will not increase the API version number, and increasing this number too often would burden contrib module maintainers who need to keep up with API changes.
This file contains a log of changes to the API.
API Version 2.0.9
Changed import permissions to use the new 'use ctools import' permission.
API Version 2.0.8
Introduce ctools_class_add().
Introduce ctools_class_remove().
@@ -1,82 +0,0 @@
Current API VERSION: 2.0. See API.txt for more information.
ctools 7.x-1.x-dev
==================
#1008120: "New custom content" shows empty form if custom content panes module is not enabled.
#999302 by troky: Fix jump menu. Apparently this wasn't actually committed the last time it was committed.
#1065976 by tekante and David_Rothstein: Reset plugin static cache during module enable to prevent stale data from harming export ui.
#1016510 by EclipseGC: Make the taxonomy system page functional.
ctools 7.x-1.x-alpha2 (05-Jan-2011)
===================================
#911396 by alex_b: Prevent notices in export UI.
#919768 by mikey_p: Allow url options to be sent to ctools_ajax_command_url().
#358953 by cedarm: Allow term context to return lowercase, spaces to dashes versions of terms.
#931434 by EclipseGc: Argument plugin for node revision ID.
#910656: CTools AJAX sample wizard demo "domesticated" checkbox value not stored.
#922442 by EugenMayer, neclimdul and voxpelli: Make sure ctools_include can handle '' or NULL directory.
#919956 by traviss359: Correct example in wizard advanced help.
#942968: Fix taxonomy term access rule with tag term vocabs.
#840344: node add argument had crufty code causing notices.
#944462 by longhairedgit: Invalid character in regex causes rare notice.
#938778 by dereine: Fix profile content type for D7 updates.
Add detach event to modal close so that wysiwyg can detach the editor.
Variant titles showing up as blank if more than one variant on a page.
#940016: token support was not yet updated for D7.
#940446: Skip validation on back and cancel buttons in all wizards.
#954492: Redirect not always working in wizard.inc
#955348: Lack of redirect on "Update" button in Page Manager causing data loss sometimes.
#941778: Update and save button should not appear in the "Add variant" path.
#955070 by EclipseGc: Update ctools internal page tokens to work properly on content all content.
#956890 by EclipseGc: Update views_content to not use views dependency since that is gone.
#954728 by EclipseGc: Update node template page function name to not collide with new hook_node_view().
#946534 by EclipseGc: Add support for field content on all entitities.
#952586 by EclipseGc: Fix node_author content type.
#959206: If a context is not set when rendering content, attempt to guess the context (fixes Views panes where "From context" was added but pane was never edited.)
#961654 by benshell: drupal_alter() only supports 4 arguments.
#911362 by alex_b: Facilitate plugin cache resets for tests.
#945360 by naxoc: node_tag_new() not updated to D7.
#953804 by EclipseGc: Fix node comment rendering.
#953542 by EclipseGc: Fix node rendering.
#953776 by EclipseGc: Fix node link rendering.
#954772 by EclipseGc: Fix node build mode selection in node content type.
#954762 by EclipseGc: Fix comment forbidden theme call.
#954894 by EclipseGc: Fix breadcrumb content type.
#955180 by EclipseGc: Fix page primary navigation type.
#957190 by EclipseGc: Fix page secondary navigation type.
#957194 by EclipseGc: Remove mission content type, since D7 no longer has a site mission.
#957348 by EclipseGc: Fix search form URL path.
#952586 by andypost: Use format_username for displaying unlinked usernames.
#963800 by benshell: Fix query to fetch custom block title.
#983496 by Amitaibu: Fix term argument to use proper load function.
#989484 by Amitaibu: Fix notice in views plugin.
#982496: Fix token context.
#995026: Fix export UI during enable/disable which would throw notices and not properly set/unset menu items.
#998870 by Amitaibu: Fix notice when content has no icon by using function already designed for that.
#983576 by Amitaibu: Node view fallback task showed white screen.
#1004644 by pillarsdotnet: Update a missed theme() call to D7.
#1006162 by aspilicious: .info file cleanup.
#998312 by dereine: Support the expanded/hidden options that Views did for dependent.js
#955030: Remove no longer supported footer message content type.
Fix broken query in term context config.
#992022 by pcambra: Fix node autocomplete.
#946302 by BerdArt and arywyr: Fix PHP 5.3 reference error.
#980528 by das-peter: Notice fix with entity settings.
#999302 by troky: ctools_jump_menu() needed updating to new form parameters.
#964174: stylizer plugin theme delegation was in the wrong place, causing errors.
#991658 by burlap: Fully load the "user" context for the logged in user because not all fields are in $user.
#1014866 by das-peter: Smarter title panes, notice fix on access plugin descriptions.
#1015662 by troky: plugin .info files were not using correct filepaths.
#941780 by EclipseGc: Restore the "No blocks" functionality.
#951048 by EclipseGc: Tighter entity integration so that new entities are automatic contexts and relationships.
#941800 by me and aspilicious: Use Drupal 7 #machine_name automation on page manager pages and all export_ui defaults.
Disabled exportables and pages not properly greyed out.
#969208 by me and benshell: Get user_view and user profile working.
#941796: Recategorize blocks
ctools 7.x-1.x-alpha1
=====================
Changelog reset for 7.x
Basic conversion done during sprint.
@@ -60,4 +60,4 @@ Upgrading from ctools-6.x-1.x to ctools-7.x-2.x:
For all of these forms, the separate settings #trees in the form are now
gone, so form ids may be adjusted. Also, these are now all real forms
using CTools form wizard instead of fake subforms as previously.
using CTools form wizard instead of fake subforms as previously.
@@ -4,9 +4,8 @@ core = 7.x
dependencies[] = ctools
package = Chaos tool suite
; Information added by drupal.org packaging script on 2013-04-03
version = "7.x-1.3"
; Information added by Drupal.org packaging script on 2019-02-08
version = "7.x-1.15"
core = "7.x"
project = "ctools"
datestamp = "1365013512"
datestamp = "1549603691"
@@ -137,7 +137,7 @@ function bulk_export_export($cli = FALSE, $options = array()) {
// Add hook_ctools_plugin_api at the top of the module code, if there is any.
if ($api_code) {
foreach ($api_code as $api_hook => $text) {
$api = "\n/**\n";
$api = "\n/**\n";
$api .= " * Implements hook_$api_hook().\n";
$api .= " */\n";
$api .= "function {$module_name}_$api_hook(\$module, \$api) {\n";
@@ -148,7 +148,7 @@ function bulk_export_export($cli = FALSE, $options = array()) {
}
if ($module_code) {
$module = "<?php\n\n";
$module = "<?php\n\n";
$module .= "/**\n";
$module .= " * @file\n";
$module .= " * Bulk export of objects generated by Bulk export module.\n";
@@ -193,7 +193,6 @@ function bulk_export_export($cli = FALSE, $options = array()) {
/**
* FAPI definition for the bulk exporter form.
*
*/
function bulk_export_export_form($form, &$form_state) {
@@ -1,4 +1,3 @@
.ctools-button-processed {
border-style: solid;
border-width: 1px;
@@ -17,8 +16,8 @@
.ctools-no-js .ctools-content ul,
.ctools-button-processed .ctools-content ul {
list-style-image: none;
list-style-type: none;
list-style: none none;
margin-left: 0;
}
.ctools-button-processed li {
@@ -1,12 +1,9 @@
.ctools-collapsible-container .ctools-toggle {
float: left;
width: 21px;
height: 21px;
cursor: pointer;
background-position: 7px 7px;
background-repeat: no-repeat;
background-image: url(../images/collapsible-expanded.png);
background: url(../images/collapsible-expanded.png) no-repeat 7px 7px;
}
.ctools-collapsible-container .ctools-collapsible-handle {
@@ -5,8 +5,8 @@
}
.ctools-owns-lock {
background: #FFFFDD none repeat scroll 0 0;
border: 1px solid #F0C020;
background: #ffffdd none repeat scroll 0 0;
border: 1px solid #f0c020;
padding: 1em;
}
@@ -1,4 +1,3 @@
.ctools-dropbutton-processed {
padding-right: 18px;
position: relative;
@@ -20,7 +19,6 @@
height: auto;
position: absolute;
right: 0;
text-indent: -9999px; /* LTR */
top: 0;
width: 17px;
}
@@ -51,6 +49,7 @@
right: 6px;
position: absolute;
top: 0.75em;
white-space: nowrap;
}
.ctools-dropbutton-processed.open .ctools-twisty {
@@ -49,14 +49,14 @@ html.js div.ctools-dropdown div.ctools-dropdown-container {
html.js div.ctools-dropdown div.ctools-dropdown-container ul li li a {
padding-left: 25px;
width: 150px;
color: #027AC6;
color: #027ac6;
}
html.js div.ctools-dropdown div.ctools-dropdown-container ul li a {
text-decoration: none;
padding-left: 5px;
width: 170px;
color: #027AC6;
color: #027ac6;
}
html.js div.ctools-dropdown div.ctools-dropdown-container ul li span {
@@ -69,5 +69,5 @@ html.js div.ctools-dropdown div.ctools-dropdown-container ul li span.text {
}
html.js .ctools-dropdown-hover {
background-color: #ECECEC;
background-color: #ececec;
}
@@ -0,0 +1,60 @@
div.ctools-modal-content {
text-align: right;
}
div.ctools-modal-content .modal-header {
background-color: #2385c2;
padding: 0 1em 0 .25em;
}
div.ctools-modal-content a.close {
color: white;
float: left;
}
/** modal forms CSS **/
div.ctools-modal-content .form-item label {
float: right;
}
div.ctools-modal-content .form-item .description {
clear: right;
}
div.ctools-modal-content .form-item .description .tips {
margin-left: 0;
margin-right: 2em;
}
div.ctools-modal-content fieldset,
div.ctools-modal-content .form-radios,
div.ctools-modal-content .form-checkboxes {
clear: right;
}
div.ctools-modal-content .resizable-textarea {
margin-left: 5em;
margin-right: 15em;
}
div.ctools-modal-content .container-inline .form-item {
margin-right: 0;
margin-left: 2em;
}
div.ctools-modal-content label.hidden-options {
background-position: left;
padding-right: 0;
padding-left: 12px;
}
div.ctools-modal-content label.expanded-options {
background-position: left;
padding-right: 0;
padding-left: 16px;
}
div.ctools-modal-content .dependent-options {
padding-left: 0;
padding-right: 30px;
}
@@ -79,7 +79,7 @@ div.ctools-modal-content .no-float .form-item * {
float: none;
}
div.ctools-modal-content .modal-form .no-float label {
div.ctools-modal-content .modal-form .no-float label {
width: auto;
}
@@ -89,6 +89,10 @@ div.ctools-modal-content .form-checkboxes {
clear: left;
}
div.ctools-modal-content .vertical-tabs-panes > fieldset {
clear: none;
}
div.ctools-modal-content .resizable-textarea {
width: auto;
margin-left: 15em;
@@ -1,4 +1,3 @@
/* Farbtastic placement */
.color-form {
max-width: 50em;
@@ -32,7 +31,8 @@
clear: left; /* LTR */
width: 14em;
}
.color-form .form-text, .color-form .form-select {
.color-form .form-text,
.color-form .form-select {
float: left; /* LTR */
}
.color-form .form-text {
@@ -84,7 +84,7 @@
cursor: default;
}
.ctools-style-icons .form-item {
.ctools-style-icons .form-item {
width: 100px;
float: left;
margin: 0 3px !important;
@@ -1,4 +1,3 @@
.wizard-trail {
font-size: 120%;
}
@@ -17,9 +17,9 @@
* Inform CTools about plugin types.
*
* @return array
* An array of plugin types, keyed by the type name.
* See the advanced help topic 'plugins-creating' for details of the array
* properties.
* An array of plugin types, keyed by the type name.
* See the advanced help topic 'plugins-creating' for details of the array
* properties.
*/
function hook_ctools_plugin_type() {
$plugins['my_type'] = array(
@@ -65,6 +65,7 @@ function hook_ctools_plugin_type() {
* directory location is being requested.
* @param string $plugin_type
* The name of the plugin type for which a base directory is being requested.
*
* @return string
* The path where CTools' plugin system should search for plugin files,
* relative to your module's root. Omit leading and trailing slashes.
@@ -94,7 +95,7 @@ function hook_ctools_plugin_directory($owner, $plugin_type) {
// Yes, this is exactly like Form 2 - just a different reasoning for it.
return "plugins/$plugin_type";
}
// Finally, if nothing matches, it's safe to return nothing at all (or NULL).
// Finally, if nothing matches, it's safe to return nothing at all (== NULL).
}
/**
@@ -155,7 +156,7 @@ function hook_ctools_api_hook_alter(&$list) {
* allow to use it in the math expression api.
*
* @param $functions
* An array which has the functions as value.
* An array which has the functions as value.
*/
function hook_ctools_math_expression_functions_alter(&$functions) {
// Allow to convert from degrees to radiant.
@@ -199,7 +200,13 @@ function hook_ctools_render_alter(&$info, &$page, &$context) {
* or categories or to rename content on specific sites.
*/
function hook_ctools_content_subtype_alter($subtype, $plugin) {
$subtype['render last'] = TRUE;
// Force a particular subtype of a particular plugin to render last.
if ($plugin['module'] === 'some_plugin_module'
&& $plugin['name'] === 'some_plugin_name'
&& $subtype['subtype_id'] === 'my_subtype_id'
) {
$subtype['render last'] = TRUE;
}
}
/**
@@ -225,6 +232,28 @@ function hook_ctools_entity_context_alter(&$plugin, &$entity, $plugin_id) {
}
}
/**
* Alter the conversion of context items by ctools context plugin convert()s.
*
* @param ctools_context $context
* The current context plugin object. If this implemented a 'convert'
* function, the value passed in has been processed by that function.
* @param string $converter
* A string associated with the plugin type, identifying the operation.
* @param string $value
* The value being converted; this is the only return from the function.
* @param $converter_options
* Array of key-value pairs to pass to a converter function from higher
* levels.
*
* @see ctools_context_convert_context()
*/
function hook_ctools_context_converter_alter($context, $converter, &$value, $converter_options) {
if ($converter === 'mystring') {
$value = 'fixed';
}
}
/**
* Alter the definition of entity context plugins.
*
@@ -263,6 +292,22 @@ function hook_ctools_cleanstring_CLEAN_ID_alter(&$settings) {
$settings['lower case'] = TRUE;
}
/**
* Let other modules modify the context handler before it is rendered.
*
* @param object $handler
* A handler for a current task and subtask.
* @param array $contexts
* An associative array of contexts.
* @param array $args
* An array for current args.
*
* @see ctools_context_handler_pre_render()
*/
function ctools_context_handler_pre_render($handler, $contexts, $args) {
$handler->conf['css_id'] = 'my-id';
}
/**
* @} End of "addtogroup hooks".
*/
@@ -3,12 +3,24 @@ description = A library of helpful tools by Merlin of Chaos.
core = 7.x
package = Chaos tool suite
files[] = includes/context.inc
files[] = includes/css-cache.inc
files[] = includes/math-expr.inc
files[] = includes/stylizer.inc
; Information added by drupal.org packaging script on 2013-04-03
version = "7.x-1.3"
; Tests.
files[] = tests/context.test
files[] = tests/css.test
files[] = tests/css_cache.test
files[] = tests/ctools.plugins.test
files[] = tests/ctools.test
files[] = tests/math_expression.test
files[] = tests/math_expression_stack.test
files[] = tests/object_cache.test
files[] = tests/object_cache_unit.test
files[] = tests/page_tokens.test
; Information added by Drupal.org packaging script on 2019-02-08
version = "7.x-1.15"
core = "7.x"
project = "ctools"
datestamp = "1365013512"
datestamp = "1549603691"
@@ -12,24 +12,25 @@
function ctools_requirements($phase) {
$requirements = array();
if ($phase == 'runtime') {
$t = get_t();
$requirements['ctools_css_cache'] = array(
'title' => t('CTools CSS Cache'),
'title' => $t('CTools CSS Cache'),
'severity' => REQUIREMENT_OK,
'value' => t('Exists'),
'value' => $t('Exists'),
);
$path = 'public://ctools/css';
if (!file_prepare_directory($path, FILE_CREATE_DIRECTORY)) {
$requirements['ctools_css_cache']['description'] = t('The CTools CSS cache directory, %path could not be created due to a misconfigured files directory. Please ensure that the files directory is correctly configured and that the webserver has permission to create directories.', array('%path' => file_uri_target($path)));
$requirements['ctools_css_cache']['description'] = $t('The CTools CSS cache directory, %path could not be created due to a misconfigured files directory. Please ensure that the files directory is correctly configured and that the webserver has permission to create directories.', array('%path' => file_uri_target($path)));
$requirements['ctools_css_cache']['severity'] = REQUIREMENT_ERROR;
$requirements['ctools_css_cache']['value'] = t('Unable to create');
$requirements['ctools_css_cache']['value'] = $t('Unable to create');
}
if (!function_exists('error_get_last')) {
$requirements['ctools_php_52']['title'] = t('CTools PHP requirements');
$requirements['ctools_php_52']['description'] = t('CTools requires certain features only available in PHP 5.2.0 or higher.');
$requirements['ctools_php_52']['title'] = $t('CTools PHP requirements');
$requirements['ctools_php_52']['description'] = $t('CTools requires certain features only available in PHP 5.2.0 or higher.');
$requirements['ctools_php_52']['severity'] = REQUIREMENT_WARNING;
$requirements['ctools_php_52']['value'] = t('PHP !version', array('!version' => phpversion()));
$requirements['ctools_php_52']['value'] = $t('PHP !version', array('!version' => phpversion()));
}
}
@@ -37,10 +38,34 @@ function ctools_requirements($phase) {
}
/**
* Implements hook_schemea
* Implements hook_schema().
*/
function ctools_schema() {
return ctools_schema_2();
return ctools_schema_4();
}
/**
* Version 4 of the CTools schema.
*/
function ctools_schema_4() {
$schema = ctools_schema_3();
// Removed due to alternative database configuration issues.
// @see https://www.drupal.org/project/ctools/issues/2941920
return $schema;
}
/**
* Version 3 of the CTools schema.
*/
function ctools_schema_3() {
$schema = ctools_schema_2();
// Update the 'obj' field to be 128 bytes long:
$schema['ctools_object_cache']['fields']['obj']['length'] = 128;
return $schema;
}
/**
@@ -49,7 +74,7 @@ function ctools_schema() {
function ctools_schema_2() {
$schema = ctools_schema_1();
// update the 'name' field to be 128 bytes long:
// Update the 'name' field to be 128 bytes long:
$schema['ctools_object_cache']['fields']['name']['length'] = 128;
// Update the 'data' field to be type 'blob'.
@@ -83,10 +108,10 @@ function ctools_schema_2() {
'serialize' => TRUE,
),
'filter' => array(
'type' => 'int',
'size' => 'tiny',
'description' => 'Whether or not this CSS needs to be filtered.',
),
'type' => 'int',
'size' => 'tiny',
'description' => 'Whether or not this CSS needs to be filtered.',
),
),
'primary key' => array('cid'),
);
@@ -141,6 +166,21 @@ function ctools_schema_1() {
return $schema;
}
/**
* Implements hook_install().
*/
function ctools_install() {
// Activate our custom cache handler for the CSS cache.
variable_set('cache_class_cache_ctools_css', 'CToolsCssCache');
}
/**
* Implements hook_uninstall().
*/
function ctools_uninstall() {
variable_del('cache_class_cache_ctools_css');
}
/**
* Enlarge the ctools_object_cache.name column to prevent truncation and weird
* errors.
@@ -170,7 +210,7 @@ function ctools_update_6003() {
if ($result) {
db_delete('system')->condition('name', 'panels_views')->execute();
module_enable(array('views_content'), TRUE);
}
}
}
/**
@@ -189,7 +229,7 @@ function ctools_update_6005() {
}
/**
* ctools_custom_content table was originally here, but is now moved to
* The ctools_custom_content table was originally here, but is now moved to
* its own module.
*/
function ctools_update_6007() {
@@ -203,17 +243,57 @@ function ctools_update_6007() {
}
/**
* ctools_object_cache needs to be defined as a blob.
* The ctools_object_cache needs to be defined as a blob.
*/
function ctools_update_6008() {
db_delete('ctools_object_cache')
->execute();
db_change_field('ctools_object_cache', 'data', 'data', array(
'type' => 'blob',
'size' => 'big',
'description' => 'Serialized data being stored.',
'serialize' => TRUE,
)
'type' => 'blob',
'size' => 'big',
'description' => 'Serialized data being stored.',
'serialize' => TRUE,
)
);
}
/**
* Enable the custom CSS cache handler.
*/
function ctools_update_7000() {
variable_set('cache_class_cache_ctools_css', 'CToolsCssCache');
}
/**
* Increase the length of the ctools_object_cache.obj column.
*/
function ctools_update_7001() {
db_change_field('ctools_object_cache', 'obj', 'obj', array(
'type' => 'varchar',
'length' => '128',
'not null' => TRUE,
'description' => 'The type of the object this cache is attached to; this essentially represents the owner so that several sub-systems can use this cache.',
));
}
/**
* Increase the length of the ctools_object_cache.name column to 255.
*/
function ctools_update_7002() {
// Removed due to alternative database configuration issues.
// @see https://www.drupal.org/project/ctools/issues/2941920
}
/**
* Revert the length of the ctools_object_cache.name column back to 128.
*/
function ctools_update_7003() {
db_delete('ctools_object_cache')->execute();
db_change_field('ctools_object_cache', 'name', 'name', array(
'type' => 'varchar',
'length' => '128',
'not null' => TRUE,
'description' => 'The name of the object this cache is attached to.',
));
}
@@ -9,7 +9,24 @@
* must be implemented in the module file.
*/
define('CTOOLS_API_VERSION', '2.0.7');
define('CTOOLS_API_VERSION', '2.0.9');
/**
* The current working ctools version.
*
* In a release, it should be 7.x-1.x, which should match what drush make will
* create. In a dev format, it should be 7.x-1.(x+1)-dev, which will allow
* modules depending on new features in ctools to depend on ctools > 7.x-1.x.
*
* To define a specific version of CTools as a dependency for another module,
* simply include a dependency line in that module's info file, e.g.:
* ; Requires CTools v7.x-1.4 or newer.
* dependencies[] = ctools (>=1.4)
*
* @deprecated in CTools 1.15 and will be removed before CTools 2.0.0.
* Use the version provided by the drupal.org packaging system.
*/
define('CTOOLS_MODULE_VERSION', '7.x-1.13');
/**
* Test the CTools API version.
@@ -61,6 +78,9 @@ define('CTOOLS_API_VERSION', '2.0.7');
* The minimum version of CTools necessary for your software to run with it.
* @param $maximum
* The maximum version of CTools allowed for your software to run with it.
*
* @return bool
* TRUE if the running ctools is usable, FALSE otherwise.
*/
function ctools_api_version($minimum, $maximum = NULL) {
if (version_compare(CTOOLS_API_VERSION, $minimum, '<')) {
@@ -75,8 +95,7 @@ function ctools_api_version($minimum, $maximum = NULL) {
}
// -----------------------------------------------------------------------
// General utility functions
// General utility functions.
/**
* Include .inc files as necessary.
*
@@ -104,6 +123,7 @@ function ctools_api_version($minimum, $maximum = NULL) {
* @param $dir
* Optional subdirectory containing the include file.
*/
function ctools_include($file, $module = 'ctools', $dir = 'includes') {
static $used = array();
@@ -133,8 +153,8 @@ function ctools_form_include(&$form_state, $file, $module = 'ctools', $dir = 'in
/**
* Add an arbitrary path to the $form_state so it can work with form cache.
*
* module_load_include uses an unfortunately annoying syntax to work, making it
* difficult to translate the more simple $path + $file syntax.
* The module_load_include() function uses an unfortunately annoying syntax to
* work, making it difficult to translate the more simple $path + $file syntax.
*/
function ctools_form_include_file(&$form_state, $filename) {
if (!isset($form_state['build_info']['args'])) {
@@ -158,6 +178,9 @@ function ctools_form_include_file(&$form_state, $filename) {
* Optional module containing the include.
* @param $dir
* Optional subdirectory containing the include file.
*
* @return string
* A string containing the appropriate path from drupal root.
*/
function ctools_image_path($image, $module = 'ctools', $dir = 'images') {
return drupal_get_path('module', $module) . "/$dir/" . $image;
@@ -197,6 +220,9 @@ function ctools_add_css($file, $module = 'ctools', $dir = 'css') {
* Optional module containing the include.
* @param $dir
* Optional subdirectory containing the include file.
*
* @return string
* A string containing the appropriate path from drupal root.
*/
function ctools_attach_css($file, $module = 'ctools', $dir = 'css') {
return drupal_get_path('module', $module) . "/$dir/$file.css";
@@ -235,6 +261,9 @@ function ctools_add_js($file, $module = 'ctools', $dir = 'js') {
* Optional module containing the include.
* @param $dir
* Optional subdirectory containing the include file.
*
* @return string
* A string containing the appropriate path from drupal root.
*/
function ctools_attach_js($file, $module = 'ctools', $dir = 'js') {
return drupal_get_path('module', $module) . "/$dir/$file.js";
@@ -253,16 +282,29 @@ function ctools_get_roles() {
return user_roles();
}
/*
* Break x,y,z and x+y+z into an array. Numeric only.
/**
* Parse integer sequences of the form "x,y,z" or "x+y+z" into separate values.
*
* A string with integers separated by comma (,) is reported as an 'and' set;
* separation by a plus sign (+) or a space ( ) is an 'or' set. The meaning
* of this is up to the caller. Negative or fractional numbers are not
* recognised.
*
* Additional space characters within or around the sequence are not allowed.
*
* @param $str
* The string to parse.
*
* @return $object
* An object containing
* - operator: Either 'and' or 'or'
* - value: An array of numeric values.
* @return object
* An object containing the properties:
*
* - operator: Either 'and' or 'or' when there are multiple matched values.
* Absent when invalid_input is TRUE or there is only one value.
* - value: An array of integers (never strings) from $str. An empty array is
* returned if the input is empty. A single integer input is returned
* as a single value, but no 'operator' is defined.
* - invalid_input: TRUE if input could not be parsed and the values array
* will contain just -1. This property is otherwise absent.
*/
function ctools_break_phrase($str) {
$object = new stdClass();
@@ -272,7 +314,7 @@ function ctools_break_phrase($str) {
$object->operator = 'or';
$object->value = preg_split('/[+ ]/', $str);
}
else if (preg_match('/^([0-9]+,)*[0-9]+$/', $str)) {
elseif (preg_match('/^([0-9]+,)*[0-9]+$/', $str)) {
$object->operator = 'and';
$object->value = explode(',', $str);
}
@@ -290,7 +332,7 @@ function ctools_break_phrase($str) {
// Doubly ensure that all values are numeric only.
foreach ($object->value as $id => $value) {
$object->value[$id] = intval($value);
$object->value[$id] = (int) $value;
}
return $object;
@@ -298,25 +340,31 @@ function ctools_break_phrase($str) {
/**
* Set a token/value pair to be replaced later in the request, specifically in
* ctools_preprocess_page().
* ctools_page_token_processing().
*
* @param $token
* @param string $token
* The token to be replaced later, during page rendering. This should
* ideally be a string inside of an HTML comment, so that if there is
* no replacement, the token will not render on the page.
* @param $type
* ideally be a string inside of an HTML comment, so that if there is
* no replacement, the token will not render on the page.
* If $token is NULL, the token set is not changed, but is still
* returned.
* @param string $type
* The type of the token. Can be either 'variable', which will pull data
* directly from the page variables
* @param $argument
* If $type == 'variable' then argument should be the key to fetch from
* the $variables. If $type == 'callback' then it should either be the
* callback, or an array that will be sent to call_user_func_array().
* directly from the page variables, or 'callback', which causes a function
* to be called to calculate the value. No other values are supported.
* @param string|array $argument
* For $type of:
* - 'variable': argument should be the key to fetch from the $variables.
* - 'callback': then it should either be the callback function name as a
* string, or an array that will be sent to call_user_func_array(). Argument
* arrays must not use array keys (i.e. $a[0] is the first and $a[1] the
* second element, etc.)
*
* @return
* @return array
* A array of token/variable names to be replaced.
*/
function ctools_set_page_token($token = NULL, $type = NULL, $argument = NULL) {
static $tokens = array();
$tokens = &drupal_static('ctools_set_page_token', array());
if (isset($token)) {
$tokens[$token] = array($type, $argument);
@@ -325,13 +373,32 @@ function ctools_set_page_token($token = NULL, $type = NULL, $argument = NULL) {
}
/**
* Easily set a token from the page variables.
* Reset the defined page tokens within this request.
*
* Introduced for simpletest purposes. Normally not needed.
*/
function ctools_reset_page_tokens() {
drupal_static_reset('ctools_set_page_token');
}
/**
* Set a replacement token from the containing element's children during #post_render.
*
* This function can be used like this:
* $token = ctools_set_variable_token('tabs');
* $token = ctools_set_variable_token('tabs');
*
* $token will then be a simple replacement for the 'tabs' about of the
* variables available in the page template.
* The token "<!-- ctools-page-tabs -->" would then be replaced by the value of
* this element's (sibling) render array key 'tabs' during post-render (or be
* deleted if there was no such key by that point).
*
* @param string $token
* The token string for the page callback, e.g. 'title'.
*
* @return string
* The constructed token.
*
* @see ctools_set_callback_token()
* @see ctools_page_token_processing()
*/
function ctools_set_variable_token($token) {
$string = '<!-- ctools-page-' . $token . ' -->';
@@ -340,10 +407,45 @@ function ctools_set_variable_token($token) {
}
/**
* Easily set a token from the page variables.
* Set a replacement token from the value of a function during #post_render.
*
* This function can be used like this:
* $token = ctools_set_variable_token('id', 'mymodule_myfunction');
* $token = ctools_set_callback_token('id', 'mymodule_myfunction');
*
* Or this (from its use in ctools_page_title_content_type_render):
* $token = ctools_set_callback_token('title', array(
* 'ctools_page_title_content_type_token', $conf['markup'], $conf['id'], $conf['class']
* )
* );
*
* The token (e.g: "<!-- ctools-page-id-1b7f84d1c8851290cc342631ac663053 -->")
* would then be replaced during post-render by the return value of:
*
* ctools_page_title_content_type_token($value_markup, $value_id, $value_class);
*
* @param string $token
* The token string for the page callback, e.g. 'title'.
*
* @param string|array $callback
* For callback functions that require no args, the name of the function as a
* string; otherwise an array of two or more elements: the function name
* followed by one or more function arguments.
*
* NB: the value of $callback must be a procedural (non-class) function that
* passes the php function_exists() check.
*
* The callback function itself will be called with args dependent
* on $callback. If:
* - $callback is a string, the function is called with a reference to the
* render array;
* - $callback is an array, the function is called with $callback merged
* with an array containing a reference to the render array.
*
* @return string
* The constructed token.
*
* @see ctools_set_variable_token()
* @see ctools_page_token_processing()
*/
function ctools_set_callback_token($token, $callback) {
// If the callback uses arguments they are considered in the token.
@@ -367,6 +469,60 @@ function ctools_set_no_blocks($blocks = FALSE) {
$status = $blocks;
}
/**
* Wrapper function to create UUIDs via ctools, falls back on UUID module
* if it is enabled. This code is a copy of uuid.inc from the uuid module.
*
* @see http://php.net/uniqid#65879
*/
function ctools_uuid_generate() {
if (!module_exists('uuid')) {
ctools_include('uuid');
$callback = drupal_static(__FUNCTION__);
if (empty($callback)) {
if (function_exists('uuid_create') && !function_exists('uuid_make')) {
$callback = '_ctools_uuid_generate_pecl';
}
elseif (function_exists('com_create_guid')) {
$callback = '_ctools_uuid_generate_com';
}
else {
$callback = '_ctools_uuid_generate_php';
}
}
return $callback();
}
else {
return uuid_generate();
}
}
/**
* Check that a string appears to be in the format of a UUID.
*
* @see http://drupal.org/project/uuid
*
* @param $uuid
* The string to test.
*
* @return
* TRUE if the string is well formed.
*/
function ctools_uuid_is_valid($uuid = '') {
if (empty($uuid)) {
return FALSE;
}
if (function_exists('uuid_is_valid') || module_exists('uuid')) {
return uuid_is_valid($uuid);
}
else {
ctools_include('uuid');
return uuid_is_valid($uuid);
}
}
/**
* Add an array of classes to the body.
*
@@ -401,6 +557,8 @@ function ctools_class_add($classes, $hook = 'html') {
*/
function ctools_class_remove($classes, $hook = 'html') {
if (!is_array($classes)) {
// @todo Consider using explode(' ', $classes);
// @todo Consider checking that $classes is a string before adding.
$classes = array($classes);
}
@@ -413,12 +571,35 @@ function ctools_class_remove($classes, $hook = 'html') {
}
}
// -----------------------------------------------------------------------
// Drupal core hooks
/**
* Reset the storage used for ctools_class_add and ctools_class_remove.
*
* @see ctools_class_add()
* @see ctools_class_remove()
*/
function ctools_class_reset() {
drupal_static_reset('ctools_process_classes');
}
/**
* Return the classes for the body (added by ctools_class_add).
*
* @return array
* A copy of the array of classes to add to the body tag. If none have been
* added, this will be an empty array.
*
* @see ctools_class_add()
*/
function ctools_get_classes() {
return drupal_static('ctools_process_classes', array());
}
// -----------------------------------------------------------------------
// Drupal core hooks.
/**
* Implement hook_init to keep our global CSS at the ready.
*/
function ctools_init() {
ctools_add_css('ctools');
// If we are sure that CTools' AJAX is in use, change the error handling.
@@ -437,7 +618,7 @@ function ctools_init() {
* Shutdown handler used during ajax operations to help catch fatal errors.
*/
function ctools_shutdown_handler() {
if (function_exists('error_get_last') AND ($error = error_get_last())) {
if (function_exists('error_get_last') && ($error = error_get_last())) {
switch ($error['type']) {
case E_ERROR:
case E_CORE_ERROR:
@@ -483,6 +664,19 @@ function ctools_menu() {
return $items;
}
/**
* Implements hook_permission().
*/
function ctools_permission() {
return array(
'use ctools import' => array(
'title' => t('Use CTools importer'),
'description' => t('The import functionality allows users to execute arbitrary PHP code, so extreme caution must be taken.'),
'restrict access' => TRUE,
),
);
}
/**
* Implementation of hook_cron. Clean up old caches.
*/
@@ -493,24 +687,16 @@ function ctools_cron() {
}
/**
* Ensure the CTools CSS cache is flushed whenever hook_flush_caches is invoked.
* Implements hook_flush_caches().
*/
function ctools_flush_caches() {
// Do not actually flush caches if running on cron. Drupal uses this hook
// in an inconsistent fashion and it does not necessarily mean to *flush*
// caches when running from cron. Instead it's just getting a list of cache
// tables and may not do any flushing.
if (!empty($GLOBALS['locks']['cron'])) {
return;
}
ctools_include('css');
ctools_css_flush_caches();
// Only return the CSS cache bin if it has been activated, to avoid
// drupal_flush_all_caches() from trying to truncate a non-existing table.
return variable_get('cache_class_cache_ctools_css', FALSE) ? array('cache_ctools_css') : array();
}
/**
* Implements hook_element_info_alter().
*
*/
function ctools_element_info_alter(&$type) {
ctools_include('dependent');
@@ -545,12 +731,33 @@ function ctools_registry_files_alter(&$files, $indexed_modules) {
}
// -----------------------------------------------------------------------
// CTools hook implementations.
// FAPI hooks that must be in the .module file.
/**
* Alter the comment form to get a little more control over it.
*/
function ctools_form_comment_form_alter(&$form, &$form_state) {
if (!empty($form_state['ctools comment alter'])) {
// Force the form to post back to wherever we are.
$form['#action'] = url($_GET['q'], array('fragment' => 'comment-form'));
if (empty($form['#submit'])) {
$form['#submit'] = array('comment_form_submit');
}
$form['#submit'][] = 'ctools_node_comment_form_submit';
}
}
function ctools_node_comment_form_submit(&$form, &$form_state) {
$form_state['redirect'][0] = $_GET['q'];
}
// -----------------------------------------------------------------------
// CTools hook implementations.
/**
* Implementation of hook_ctools_plugin_directory() to let the system know
* where all our own plugins are.
*/
function ctools_ctools_plugin_directory($owner, $plugin_type) {
if ($owner == 'ctools') {
return 'plugins/' . $plugin_type;
@@ -571,11 +778,11 @@ function ctools_ctools_plugin_type() {
// -----------------------------------------------------------------------
// Drupal theme preprocess hooks that must be in the .module file.
/**
* A theme preprocess function to automatically allow panels-based node
* templates based upon input when the panel was configured.
*/
function ctools_preprocess_node(&$vars) {
// The 'ctools_template_identifier' attribute of the node is added when the pane is
// rendered.
@@ -585,7 +792,25 @@ function ctools_preprocess_node(&$vars) {
}
}
/**
* Implements hook_page_alter().
*
* Last ditch attempt to remove sidebar regions if the "no blocks"
* functionality has been activated.
*
* @see ctools_block_list_alter()
*/
function ctools_page_alter(&$page) {
$check = drupal_static('ctools_set_no_blocks', TRUE);
if (!$check) {
foreach ($page as $region_id => $region) {
// @todo -- possibly we can set configuration for this so that users can
// specify which blocks will not get rendered.
if (strpos($region_id, 'sidebar') !== FALSE) {
unset($page[$region_id]);
}
}
}
$page['#post_render'][] = 'ctools_page_token_processing';
}
@@ -601,15 +826,16 @@ function ctools_page_token_processing($children, $elements) {
list($type, $argument) = $key;
switch ($type) {
case 'variable':
$tokens[$token] = isset($variables[$argument]) ? $variables[$argument] : '';
$tokens[$token] = isset($elements[$argument]) ? $elements[$argument] : '';
break;
case 'callback':
if (is_string($argument) && function_exists($argument)) {
$tokens[$token] = $argument($variables);
$tokens[$token] = $argument($elements);
}
if (is_array($argument) && function_exists($argument[0])) {
$function = array_shift($argument);
$argument = array_merge(array(&$variables), $argument);
$argument = array_merge(array(&$elements), $argument);
$tokens[$token] = call_user_func_array($function, $argument);
}
break;
@@ -631,7 +857,7 @@ function ctools_process(&$variables, $hook) {
return;
}
$classes = drupal_static('ctools_process_classes', array());
$classes = ctools_get_classes();
// Process the classses to add.
if (!empty($classes[$hook]['add'])) {
@@ -652,7 +878,6 @@ function ctools_process(&$variables, $hook) {
// -----------------------------------------------------------------------
// Menu callbacks that must be in the .module file.
/**
* Determine if the current user has access via a plugin.
*
@@ -676,6 +901,7 @@ function ctools_process(&$variables, $hook) {
* @return
* TRUE if access is granted, false if otherwise.
*/
function ctools_access_menu($access) {
// Short circuit everything if there are no access tests.
if (empty($access['plugins'])) {
@@ -704,7 +930,7 @@ function ctools_access_menu($access) {
* An indexed array of zero or more permission strings to be checked by
* user_access().
*
* @return
* @return bool
* Iff all checks pass will this function return TRUE. If an invalid argument
* is passed (e.g., not a string), this function errs on the safe said and
* returns FALSE.
@@ -733,6 +959,15 @@ function ctools_js_load($js) {
return 0;
}
/**
* Provides the default value for %ctools_js.
*
* This allows drupal_valid_path() to work with %ctools_js.
*/
function ctools_js_to_arg($arg) {
return empty($arg) || $arg == '%' ? 'nojs' : $arg;
}
/**
* Menu _load hook.
*
@@ -757,7 +992,6 @@ function ctools_export_ui_load($item_name, $plugin_name) {
// -----------------------------------------------------------------------
// Caching callbacks on behalf of export-ui.
/**
* Menu access callback for various tasks of export-ui.
*/
@@ -801,7 +1035,7 @@ function ctools_export_ui_ctools_access_get($argument) {
}
/**
* Callback for access control ajax form on behalf of export ui
* Callback for access control ajax form on behalf of export ui.
*
* Returns the cached access config and contexts used.
* Note that this is assuming that access will be in $item->access -- if it
@@ -834,8 +1068,9 @@ function ctools_menu_local_tasks_alter(&$data, $router_item, $root_path) {
}
/**
* Implement hook_block_list_alter() to potentially remove blocks.
* Implements hook_block_list_alter().
*
* Used to potentially remove blocks.
* This exists in order to replicate Drupal 6's "no blocks" functionality.
*/
function ctools_block_list_alter(&$blocks) {
@@ -852,11 +1087,25 @@ function ctools_block_list_alter(&$blocks) {
}
/**
* Implement hook_modules_enabled to clear static caches for detecting new plugins
* Implements hook_modules_enabled().
*
* Clear caches for detecting new plugins.
*/
function ctools_modules_enabled($modules) {
ctools_include('plugins');
ctools_get_plugins_reset();
cache_clear_all('ctools_plugin_files:', 'cache', TRUE);
}
/**
* Implements hook_modules_disabled().
*
* Clear caches for removing disabled plugins.
*/
function ctools_modules_disabled($modules) {
ctools_include('plugins');
ctools_get_plugins_reset();
cache_clear_all('ctools_plugin_files:', 'cache', TRUE);
}
/**
@@ -884,6 +1133,7 @@ function ctools_ctools_entity_context_alter(&$plugin, &$entity, $plugin_id) {
case 'entity_id:taxonomy_term':
$plugin['no ui'] = TRUE;
break;
case 'entity:user':
$plugin = ctools_get_context('user');
unset($plugin['no ui']);
@@ -903,3 +1153,53 @@ function ctools_ctools_entity_context_alter(&$plugin, &$entity, $plugin_id) {
}
}
}
/**
* Implements hook_field_create_field().
*/
function ctools_field_create_field($field) {
ctools_flush_field_caches();
}
/**
* Implements hook_field_create_instance().
*/
function ctools_field_create_instance($instance) {
ctools_flush_field_caches();
}
/**
* Implements hook_field_delete_field().
*/
function ctools_field_delete_field($field) {
ctools_flush_field_caches();
}
/**
* Implements hook_field_delete_instance().
*/
function ctools_field_delete_instance($instance) {
ctools_flush_field_caches();
}
/**
* Implements hook_field_update_field().
*/
function ctools_field_update_field($field, $prior_field, $has_data) {
ctools_flush_field_caches();
}
/**
* Implements hook_field_update_instance().
*/
function ctools_field_update_instance($instance, $prior_instance) {
ctools_flush_field_caches();
}
/**
* Clear field related caches.
*/
function ctools_flush_field_caches() {
// Clear caches of 'Entity field' content type plugin.
cache_clear_all('ctools_entity_field_content_type_content_types', 'cache');
}
@@ -4,9 +4,8 @@ core = 7.x
package = Chaos tool suite
dependencies[] = ctools
; Information added by drupal.org packaging script on 2013-04-03
version = "7.x-1.3"
; Information added by Drupal.org packaging script on 2019-02-08
version = "7.x-1.15"
core = "7.x"
project = "ctools"
datestamp = "1365013512"
datestamp = "1549603691"
@@ -1,5 +1,9 @@
<?php
/**
* @file
*/
/**
* Schema for customizable access rulesets.
*/
@@ -2,7 +2,7 @@
/**
* @file
* ctools_access_ruleset module
* The ctools_access_ruleset module.
*
* This module allows styles to be created and managed on behalf of modules
* that implement styles.
@@ -30,7 +30,7 @@ function ctools_access_ruleset_permission() {
*/
function ctools_access_ruleset_ctools_plugin_directory($module, $plugin) {
// Most of this module is implemented as an export ui plugin, and the
// rest is in ctools/includes/ctools_access_ruleset.inc
// rest is in ctools/includes/ctools_access_ruleset.inc.
if ($module == 'ctools' && ($plugin == 'export_ui' || $plugin == 'access')) {
return 'plugins/' . $plugin;
}
@@ -47,7 +47,7 @@ function ctools_access_ruleset_panels_dashboard_blocks(&$vars) {
'description' => t('Custom rulesets are combinations of access plugins you can use for access control, selection criteria and pane visibility.'),
);
// Load all mini panels and their displays.
// Load all mini panels and their displays.
ctools_include('export');
$items = ctools_export_crud_load_all('ctools_access_ruleset');
$count = 0;
@@ -35,7 +35,7 @@ function ctools_ruleset_ctools_access_merge_plugin($plugin, $parent, $item) {
$plugin['required context'] = array();
foreach ($item->requiredcontexts as $context) {
$info = ctools_get_context($context['name']);
// TODO: allow an optional setting
// TODO: allow an optional setting.
$plugin['required context'][] = new ctools_context_required($context['identifier'], $info['context name']);
}
}
@@ -72,7 +72,7 @@ function ctools_ruleset_ctools_access_get_children($plugin, $parent) {
}
/**
* Settings form for the 'by ruleset' access plugin
* Settings form for the 'by ruleset' access plugin.
*/
function ctools_ruleset_ctools_access_settings(&$form, &$form_state, $conf) {
if (!empty($form_state['plugin']['ruleset']->admin_description)) {
@@ -106,4 +106,3 @@ function ctools_ruleset_ctools_access_summary($conf, $context, $plugin) {
return check_plain($plugin['ruleset']->admin_title);
}
}
@@ -1,5 +1,9 @@
<?php
/**
* @file
*/
$plugin = array(
'schema' => 'ctools_access_ruleset',
'access' => 'administer ctools access ruleset',
@@ -26,4 +30,3 @@ $plugin = array(
),
),
);
@@ -2,7 +2,7 @@
class ctools_access_ruleset_ui extends ctools_export_ui {
function edit_form_context(&$form, &$form_state) {
public function edit_form_context(&$form, &$form_state) {
ctools_include('context-admin');
ctools_context_admin_includes();
ctools_add_css('ruleset');
@@ -27,7 +27,7 @@ class ctools_access_ruleset_ui extends ctools_export_ui {
ctools_context_add_relationship_form($module, $form, $form_state, $form['right']['relationships_table'], $form_state['item'], $name);
}
function edit_form_rules(&$form, &$form_state) {
public function edit_form_rules(&$form, &$form_state) {
// The 'access' UI passes everything via $form_state, unlike the 'context' UI.
// The main difference is that one is about 3 years newer than the other.
ctools_include('context');
@@ -43,11 +43,12 @@ class ctools_access_ruleset_ui extends ctools_export_ui {
$form = ctools_access_admin_form($form, $form_state);
}
function edit_form_rules_submit(&$form, &$form_state) {
public function edit_form_rules_submit(&$form, &$form_state) {
$form_state['item']->access['logic'] = $form_state['values']['logic'];
}
function edit_form_submit(&$form, &$form_state) {
public function edit_form_submit(&$form, &$form_state) {
parent::edit_form_submit($form, $form_state);
}
}
@@ -1,52 +1,52 @@
div.ctools-sample-modal-content {
background:none;
border:0;
color:#000000;
margin:0;
padding:0;
text-align:left;
background: none;
border: 0;
color: #000;
margin: 0;
padding: 0;
text-align: left;
}
div.ctools-sample-modal-content .modal-scroll{
overflow:hidden;
overflow-y:auto;
div.ctools-sample-modal-content .modal-scroll {
overflow: hidden;
overflow-y: auto;
}
div.ctools-sample-modal-content #popups-overlay {
background-color:transparent;
background-color: transparent;
}
div.ctools-sample-modal-content #popups-loading {
width:248px;
position:absolute;
display:none;
opacity:1;
width: 248px;
position: absolute;
display: none;
opacity: 1;
-moz-border-radius: 8px;
-webkit-border-radius: 8px;
z-index:99;
z-index: 99;
}
div.ctools-sample-modal-content #popups-loading span.popups-loading-message {
background:#FFF url(../images/loading-large.gif) no-repeat 8px center;
display:block;
color:#444444;
font-family:Arial;
font-size:22px;
font-weight:bold;
height:36px;
line-height:36px;
padding:0 40px;
background: #fff url(../images/loading-large.gif) no-repeat 8px center;
display: block;
color: #444;
font-family: Arial, serif;
font-size: 22px;
font-weight: bold;
height: 36px;
line-height: 36px;
padding: 0 40px;
}
div.ctools-sample-modal-content #popups-loading table,
div.ctools-sample-modal-content .popups-box table {
margin:0px;
margin: 0;
}
div.ctools-sample-modal-content #popups-loading tbody,
div.ctools-sample-modal-content .popups-box tbody {
border:none;
border: none;
}
div.ctools-sample-modal-content .popups-box tr {
background-color:transparent;
background-color: transparent;
}
div.ctools-sample-modal-content td.popups-border {
background: url(../images/popups-border.png);
background-color:transparent;
background-color: transparent;
border: none;
}
div.ctools-sample-modal-content td.popups-tl,
@@ -54,79 +54,94 @@ div.ctools-sample-modal-content td.popups-tr,
div.ctools-sample-modal-content td.popups-bl,
div.ctools-sample-modal-content td.popups-br {
background-repeat: no-repeat;
height:10px;
padding:0px;
height: 10px;
padding: 0;
}
div.ctools-sample-modal-content td.popups-tl {
background-position: 0 0;
}
div.ctools-sample-modal-content td.popups-tl { background-position: 0px 0px; }
div.ctools-sample-modal-content td.popups-t,
div.ctools-sample-modal-content td.popups-b {
background-position: 0px -40px;
background-position: 0 -40px;
background-repeat: repeat-x;
}
div.ctools-sample-modal-content td.popups-tr { background-position: 0px -10px; width: 10px; }
div.ctools-sample-modal-content td.popups-tr {
background-position: 0 -10px;
width: 10px;
}
div.ctools-sample-modal-content td.popups-cl,
div.ctools-sample-modal-content td.popups-cr {
background-position: -10px 0;
background-repeat: repeat-y;
width:10px;
width: 10px;
}
div.ctools-sample-modal-content td.popups-cl,
div.ctools-sample-modal-content td.popups-cr,
div.ctools-sample-modal-content td.popups-c { padding:0; border: none; }
div.ctools-sample-modal-content td.popups-c { background:#fff; }
div.ctools-sample-modal-content td.popups-bl { background-position: 0px -20px; }
div.ctools-sample-modal-content td.popups-br { background-position: 0px -30px; width: 10px; }
div.ctools-sample-modal-content td.popups-c {
padding: 0;
border: none;
}
div.ctools-sample-modal-content td.popups-c {
background: #fff;
}
div.ctools-sample-modal-content td.popups-bl {
background-position: 0 -20px;
}
div.ctools-sample-modal-content td.popups-br {
background-position: 0 -30px;
width: 10px;
}
div.ctools-sample-modal-content .popups-box,
div.ctools-sample-modal-content #popups-loading {
border: 0px solid #454545;
opacity:1;
overflow:hidden;
padding:0;
background-color:transparent;
border: 0 solid #454545;
opacity: 1;
overflow: hidden;
padding: 0;
background-color: transparent;
}
div.ctools-sample-modal-content .popups-container {
overflow:hidden;
height:100%;
background-color:#fff;
overflow: hidden;
height: 100%;
background-color: #fff;
}
div.ctools-sample-modal-content div.popups-title {
-moz-border-radius-topleft: 0px;
-webkit-border-radius-topleft: 0px;
margin-bottom:0px;
background-color:#ff7200;
border:1px solid #ce5c00;
padding:4px 10px 5px;
color:white;
font-size:1em;
font-weight:bold;
-moz-border-radius-topleft: 0;
-webkit-border-radius-topleft: 0;
margin-bottom: 0;
background-color: #ff7200;
border: 1px solid #ce5c00;
padding: 4px 10px 5px;
color: white;
font-size: 1em;
font-weight: bold;
}
div.ctools-sample-modal-content .popups-body {
background-color:#fff;
padding:8px;
background-color: #fff;
padding: 8px;
}
div.ctools-sample-modal-content .popups-box .popups-buttons,
div.ctools-sample-modal-content .popups-box .popups-footer {
background-color:#fff;
background-color: #fff;
}
div.ctools-sample-modal-content .popups-title a.close {
color: #fff;
text-decoration:none;
text-decoration: none;
}
div.ctools-sample-modal-content .popups-close {
font-size:120%;
float:right;
text-align:right;
font-size: 120%;
float: right;
text-align: right;
}
div.ctools-sample-modal-content .modal-loading-wrapper {
width:220px;
height:19px;
margin:0 auto;
margin-top:2%;
width: 220px;
height: 19px;
margin: 0 auto;
margin-top: 2%;
}
div.ctools-sample-modal-content tbody{
border:none;
div.ctools-sample-modal-content tbody {
border: none;
}
div.ctools-sample-modal-content .modal-content .modal-throbber-wrapper img {
@@ -4,9 +4,8 @@ package = Chaos tool suite
dependencies[] = ctools
core = 7.x
; Information added by drupal.org packaging script on 2013-04-03
version = "7.x-1.3"
; Information added by Drupal.org packaging script on 2019-02-08
version = "7.x-1.15"
core = "7.x"
project = "ctools"
datestamp = "1365013512"
datestamp = "1549603691"
@@ -1,18 +1,18 @@
<?php
/**
* @file
* @file
*/
/**
* Implementation of hook_install()
* Implementation of hook_install()
*/
function ctools_ajax_sample_install() {
}
/**
* Implementation of hook_uninstall()
* Implementation of hook_uninstall()
*/
function ctools_ajax_sample_uninstall() {
@@ -8,16 +8,16 @@
// ---------------------------------------------------------------------------
// Drupal hooks.
/**
* Implementation of hook_menu()
* Implementation of hook_menu()
*/
function ctools_ajax_sample_menu() {
$items['ctools_ajax_sample'] = array(
'title' => 'Chaos Tools AJAX Demo',
'page callback' => 'ctools_ajax_sample_page',
'access callback' => TRUE,
'type' => MENU_NORMAL_ITEM,
'title' => 'Chaos Tools AJAX Demo',
'page callback' => 'ctools_ajax_sample_page',
'access callback' => TRUE,
'type' => MENU_NORMAL_ITEM,
);
$items['ctools_ajax_sample/simple_form'] = array(
'title' => 'Simple Form',
@@ -26,39 +26,39 @@ function ctools_ajax_sample_menu() {
'type' => MENU_CALLBACK,
);
$items['ctools_ajax_sample/%ctools_js/hello'] = array(
'title' => 'Hello World',
'page callback' => 'ctools_ajax_sample_hello',
'page arguments' => array(1),
'access callback' => TRUE,
'type' => MENU_CALLBACK,
'title' => 'Hello World',
'page callback' => 'ctools_ajax_sample_hello',
'page arguments' => array(1),
'access callback' => TRUE,
'type' => MENU_CALLBACK,
);
$items['ctools_ajax_sample/%ctools_js/tablenix/%'] = array(
'title' => 'Hello World',
'page callback' => 'ctools_ajax_sample_tablenix',
'page arguments' => array(1, 3),
'access callback' => TRUE,
'type' => MENU_CALLBACK,
'title' => 'Hello World',
'page callback' => 'ctools_ajax_sample_tablenix',
'page arguments' => array(1, 3),
'access callback' => TRUE,
'type' => MENU_CALLBACK,
);
$items['ctools_ajax_sample/%ctools_js/login'] = array(
'title' => 'Login',
'page callback' => 'ctools_ajax_sample_login',
'page arguments' => array(1),
'access callback' => TRUE,
'type' => MENU_CALLBACK,
'title' => 'Login',
'page callback' => 'ctools_ajax_sample_login',
'page arguments' => array(1),
'access callback' => TRUE,
'type' => MENU_CALLBACK,
);
$items['ctools_ajax_sample/%ctools_js/animal'] = array(
'title' => 'Animal',
'page callback' => 'ctools_ajax_sample_animal',
'page arguments' => array(1),
'access callback' => TRUE,
'type' => MENU_CALLBACK,
'title' => 'Animal',
'page callback' => 'ctools_ajax_sample_animal',
'page arguments' => array(1),
'access callback' => TRUE,
'type' => MENU_CALLBACK,
);
$items['ctools_ajax_sample/%ctools_js/login/%'] = array(
'title' => 'Post-Login Action',
'page callback' => 'ctools_ajax_sample_login_success',
'page arguments' => array(1, 3),
'access callback' => TRUE,
'type' => MENU_CALLBACK,
'title' => 'Post-Login Action',
'page callback' => 'ctools_ajax_sample_login_success',
'page arguments' => array(1, 3),
'access callback' => TRUE,
'type' => MENU_CALLBACK,
);
$items['ctools_ajax_sample/jumped'] = array(
'title' => 'Successful Jumping',
@@ -104,11 +104,11 @@ function ctools_ajax_sample_theme() {
}
// ---------------------------------------------------------------------------
// Page callbacks
// Page callbacks.
/**
* Page callback to display links and render a container for AJAX stuff.
*/
function ctools_ajax_sample_page() {
global $user;
@@ -156,14 +156,14 @@ function ctools_ajax_sample_page() {
// The extra class points to the info in ctools-sample-style which we added
// to the settings, prefixed with 'ctools-modal'.
$links[] = ctools_modal_text_button(t('Modal Login (custom style)'), 'ctools_ajax_sample/nojs/login', t('Login via modal'), 'ctools-modal-ctools-sample-style');
$links[] = ctools_modal_text_button(t('Modal Login (custom style)'), 'ctools_ajax_sample/nojs/login', t('Login via modal'), 'ctools-modal-ctools-sample-style');
}
// Four ways to do our animal picking wizard.
$button_form = ctools_ajax_sample_ajax_button_form();
$links[] = l(t('Wizard (no modal)'), 'ctools_ajax_sample/nojs/animal');
$links[] = ctools_modal_text_button(t('Wizard (default modal)'), 'ctools_ajax_sample/nojs/animal', t('Pick an animal'));
$links[] = ctools_modal_text_button(t('Wizard (custom modal)'), 'ctools_ajax_sample/nojs/animal', t('Pick an animal'), 'ctools-modal-ctools-sample-style');
$links[] = ctools_modal_text_button(t('Wizard (custom modal)'), 'ctools_ajax_sample/nojs/animal', t('Pick an animal'), 'ctools-modal-ctools-sample-style');
$links[] = drupal_render($button_form);
$links[] = ctools_ajax_text_button(t('Hello world!'), "ctools_ajax_sample/nojs/hello", t('Replace text with "hello world"'));
@@ -176,9 +176,9 @@ function ctools_ajax_sample_page() {
// Create a table that we can have data removed from via AJAX.
$header = array(t('Row'), t('Content'), t('Actions'));
$rows = array();
for($i = 1; $i < 11; $i++) {
for ($i = 1; $i < 11; $i++) {
$rows[] = array(
'class' => array('ajax-sample-row-'. $i),
'class' => array('ajax-sample-row-' . $i),
'data' => array(
$i,
md5($i),
@@ -189,10 +189,10 @@ function ctools_ajax_sample_page() {
$output .= theme('table', array('header' => $header, 'rows' => $rows, array('class' => array('ajax-sample-table'))));
// Show examples of ctools javascript widgets
$output .= '<h2>'. t('CTools Javascript Widgets') .'</h2>';
// Show examples of ctools javascript widgets.
$output .= '<h2>' . t('CTools Javascript Widgets') . '</h2>';
// Create a drop down menu
// Create a drop down menu.
$links = array();
$links[] = array('title' => t('Link 1'), 'href' => $_GET['q']);
$links[] = array('title' => t('Link 2'), 'href' => $_GET['q']);
@@ -201,16 +201,16 @@ function ctools_ajax_sample_page() {
$output .= '<h3>' . t('Drop Down Menu') . '</h3>';
$output .= theme('ctools_dropdown', array('title' => t('Click to Drop Down'), 'links' => $links));
// Create a collapsible div
// Create a collapsible div.
$handle = t('Click to Collapse');
$content = 'Nulla ligula ante, aliquam at adipiscing egestas, varius vel arcu. Etiam laoreet elementum mi vel consequat. Etiam scelerisque lorem vel neque consequat quis bibendum libero congue. Nulla facilisi. Mauris a elit a leo feugiat porta. Phasellus placerat cursus est vitae elementum.';
$output .= '<h3>'. t('Collapsible Div') .'</h3>';
$output .= '<h3>' . t('Collapsible Div') . '</h3>';
$output .= theme('ctools_collapsible', array('handle' => $handle, 'content' => $content, 'collapsed' => FALSE));
// Create a jump menu
// Create a jump menu.
ctools_include('jump-menu');
$form = drupal_get_form('ctools_ajax_sample_jump_menu_form');
$output .= '<h3>'. t('Jump Menu') .'</h3>';
$output .= '<h3>' . t('Jump Menu') . '</h3>';
$output .= drupal_render($form);
return array('markup' => array('#markup' => $output));
@@ -225,7 +225,8 @@ function ctools_ajax_sample_hello($js = NULL) {
ctools_include('ajax');
$commands = array();
$commands[] = ajax_command_html('#ctools-sample', $output);
print ajax_render($commands); // this function exits.
// This function exits.
print ajax_render($commands);
exit;
}
else {
@@ -234,7 +235,7 @@ function ctools_ajax_sample_hello($js = NULL) {
}
/**
* Nix a row from a table and restripe.
* Nix a row from a table and restripe.
*/
function ctools_ajax_sample_tablenix($js, $row) {
if (!$js) {
@@ -272,7 +273,7 @@ function ctools_ajax_sample_login($js = NULL) {
$output = array();
$inplace = ctools_ajax_text_button(t('remain here'), 'ctools_ajax_sample/nojs/login/inplace', t('Go to your account'));
$account = ctools_ajax_text_button(t('your account'), 'ctools_ajax_sample/nojs/login/user', t('Go to your account'));
$output[] = ctools_modal_command_display(t('Login Success'), '<div class="modal-message">Login successful. You can now choose whether to '. $inplace .', or go to '. $account.'.</div>');
$output[] = ctools_modal_command_display(t('Login Success'), '<div class="modal-message">Login successful. You can now choose whether to ' . $inplace . ', or go to ' . $account . '.</div>');
}
print ajax_render($output);
exit;
@@ -283,7 +284,7 @@ function ctools_ajax_sample_login($js = NULL) {
*/
function ctools_ajax_sample_login_success($js, $action) {
if (!$js) {
// we should never be here out of ajax context
// We should never be here out of ajax context.
return MENU_NOT_FOUND;
}
@@ -291,11 +292,11 @@ function ctools_ajax_sample_login_success($js, $action) {
ctools_add_js('ajax-responder');
$commands = array();
if ($action == 'inplace') {
// stay here
// Stay here.
$commands[] = ctools_ajax_command_reload();
}
else {
// bounce bounce
// Bounce bounce.
$commands[] = ctools_ajax_command_redirect('user');
}
print ajax_render($commands);
@@ -318,18 +319,18 @@ function ctools_ajax_sample_animal($js = NULL, $step = NULL) {
'show back' => TRUE,
'show cancel' => TRUE,
'show return' => FALSE,
'next callback' => 'ctools_ajax_sample_wizard_next',
'next callback' => 'ctools_ajax_sample_wizard_next',
'finish callback' => 'ctools_ajax_sample_wizard_finish',
'cancel callback' => 'ctools_ajax_sample_wizard_cancel',
// this controls order, as well as form labels
// This controls order, as well as form labels.
'order' => array(
'start' => t('Choose animal'),
),
// here we map a step to a form id.
// Here we map a step to a form id.
'forms' => array(
// e.g. this for the step at wombat/create
// e.g. this for the step at wombat/create.
'start' => array(
'form id' => 'ctools_ajax_sample_start'
'form id' => 'ctools_ajax_sample_start',
),
),
);
@@ -341,7 +342,6 @@ function ctools_ajax_sample_animal($js = NULL, $step = NULL) {
// in creation.
//
// We skip all this here by just using an id of 1.
$object_id = 1;
if (empty($step)) {
@@ -406,7 +406,7 @@ function ctools_ajax_sample_animal($js = NULL, $step = NULL) {
$commands[] = ajax_command_html('#ctools-sample', $animal);
$commands[] = ctools_modal_command_dismiss();
}
else if (!empty($form_state['cancel'])) {
elseif (!empty($form_state['cancel'])) {
// If cancelling, return to the activity.
$commands[] = ctools_modal_command_dismiss();
}
@@ -420,7 +420,7 @@ function ctools_ajax_sample_animal($js = NULL, $step = NULL) {
if ($output === FALSE || !empty($form_state['complete'])) {
return $animal;
}
else if (!empty($form_state['cancel'])) {
elseif (!empty($form_state['cancel'])) {
drupal_goto('ctools_ajax_sample');
}
else {
@@ -430,11 +430,11 @@ function ctools_ajax_sample_animal($js = NULL, $step = NULL) {
}
// ---------------------------------------------------------------------------
// Themes
// Themes.
/**
* Theme function for main rendered output.
*/
function theme_ctools_ajax_sample_container($vars) {
$output = '<div id="ctools-sample">';
$output .= $vars['content'];
@@ -445,7 +445,6 @@ function theme_ctools_ajax_sample_container($vars) {
// ---------------------------------------------------------------------------
// Stuff needed for our little wizard.
/**
* Get a list of our animals and associated forms.
*
@@ -453,6 +452,7 @@ function theme_ctools_ajax_sample_container($vars) {
* which is often how it will work in the real world. If using CTools, what
* you would probably really have, here, is a set of plugins for each animal.
*/
function ctools_ajax_sample_animals() {
return array(
'sheep' => array(
@@ -478,10 +478,10 @@ function ctools_ajax_sample_animals() {
// ---------------------------------------------------------------------------
// Wizard caching helpers.
/**
* Store our little cache so that we can retain data from form to form.
*/
function ctools_ajax_sample_cache_set($id, $object) {
ctools_include('object-cache');
ctools_object_cache_set('ctools_ajax_sample', $id, $object);
@@ -495,7 +495,7 @@ function ctools_ajax_sample_cache_get($id) {
$object = ctools_object_cache_get('ctools_ajax_sample', $id);
if (!$object) {
// Create a default object.
$object = new stdClass;
$object = new stdClass();
$object->type = 'unknown';
$object->name = '';
}
@@ -513,18 +513,18 @@ function ctools_ajax_sample_cache_clear($id) {
// ---------------------------------------------------------------------------
// Wizard in-between helpers; what to do between or after forms.
/**
* Handle the 'next' click on the add/edit pane form wizard.
*
* All we need to do is store the updated pane in the cache.
*/
function ctools_ajax_sample_wizard_next(&$form_state) {
ctools_ajax_sample_cache_set($form_state['object_id'], $form_state['object']);
}
/**
* Handle the 'finish' click on teh add/edit pane form wizard.
* Handle the 'finish' click on the add/edit pane form wizard.
*
* All we need to do is set a flag so the return can handle adding
* the pane.
@@ -542,10 +542,10 @@ function ctools_ajax_sample_wizard_cancel(&$form_state) {
// ---------------------------------------------------------------------------
// Wizard forms for our simple info collection wizard.
/**
* Wizard start form. Choose an animal.
*/
function ctools_ajax_sample_start($form, &$form_state) {
$form_state['title'] = t('Choose animal');
@@ -713,7 +713,7 @@ function ctools_ajax_sample_show_raptor($object) {
}
/**
* Helper function to provide a sample jump menu form
* Helper function to provide a sample jump menu form.
*/
function ctools_ajax_sample_jump_menu_form() {
$url = url('ctools_ajax_sample/jumped');
@@ -723,7 +723,7 @@ function ctools_ajax_sample_jump_menu_form() {
}
/**
* Provide a message to the user that the jump menu worked
* Provide a message to the user that the jump menu worked.
*/
function ctools_ajax_sample_jump_menu_page() {
$return_link = l(t('Return to the examples page.'), 'ctools_ajax_sample');
@@ -732,7 +732,7 @@ function ctools_ajax_sample_jump_menu_page() {
}
/**
* Provide a form for an example ajax modal button
* Provide a form for an example ajax modal button.
*/
function ctools_ajax_sample_ajax_button_form() {
$form = array();
@@ -4,9 +4,8 @@ core = 7.x
package = Chaos tool suite
dependencies[] = ctools
; Information added by drupal.org packaging script on 2013-04-03
version = "7.x-1.3"
; Information added by Drupal.org packaging script on 2019-02-08
version = "7.x-1.15"
core = "7.x"
project = "ctools"
datestamp = "1365013512"
datestamp = "1549603691"
@@ -1,5 +1,9 @@
<?php
/**
* @file
*/
/**
* Schema for CTools custom content.
*/
@@ -2,7 +2,7 @@
/**
* @file
* ctools_custom_content module
* The ctools_custom_content module.
*
* This module allows styles to be created and managed on behalf of modules
* that implement styles.
@@ -30,12 +30,32 @@ function ctools_custom_content_permission() {
*/
function ctools_custom_content_ctools_plugin_directory($module, $plugin) {
// Most of this module is implemented as an export ui plugin, and the
// rest is in ctools/includes/ctools_custom_content.inc
// rest is in ctools/includes/ctools_custom_content.inc.
if ($module == 'ctools' && $plugin == 'export_ui') {
return 'plugins/' . $plugin;
}
}
/**
* Implements hook_get_pane_links_alter().
*/
function ctools_custom_content_get_pane_links_alter(&$links, $pane, $content_type) {
if ($pane->type == 'custom') {
if (!isset($pane->configuration['name'])) {
$name_of_pane = $pane->subtype;
}
else {
$name_of_pane = $pane->configuration['name'];
}
$links['top']['edit_custom_content'] = array(
'title' => t('Edit custom content pane'),
'href' => url('admin/structure/ctools-content/list/' . $name_of_pane . '/edit', array('absolute' => TRUE)),
'attributes' => array('target' => array('_blank')),
);
}
}
/**
* Create callback for creating a new CTools custom content type.
*
@@ -60,7 +80,7 @@ function ctools_custom_content_panels_dashboard_blocks(&$vars) {
'description' => t('Custom content panes are basic HTML you enter that can be reused in all of your panels.'),
);
// Load all mini panels and their displays.
// Load all mini panels and their displays.
ctools_include('export');
$items = ctools_export_crud_load_all('ctools_custom_content');
$count = 0;
@@ -1,5 +1,9 @@
<?php
/**
* @file
*/
$plugin = array(
'schema' => 'ctools_custom_content',
'access' => 'administer custom content',
@@ -17,4 +21,3 @@ $plugin = array(
'handler' => 'ctools_custom_content_ui',
);
@@ -2,7 +2,7 @@
class ctools_custom_content_ui extends ctools_export_ui {
function edit_form(&$form, &$form_state) {
public function edit_form(&$form, &$form_state) {
// Correct for an error that came in because filter format changed.
if (is_array($form_state['item']->settings['body'])) {
$form_state['item']->settings['format'] = $form_state['item']->settings['body']['format'];
@@ -23,6 +23,22 @@ class ctools_custom_content_ui extends ctools_export_ui {
'#title' => t('Title'),
);
$form['title_heading'] = array(
'#title' => t('Title heading'),
'#type' => 'select',
'#default_value' => isset($form_state['item']->settings['title_heading']) ? $form_state['item']->settings['title_heading'] : 'h2',
'#options' => array(
'h1' => t('h1'),
'h2' => t('h2'),
'h3' => t('h3'),
'h4' => t('h4'),
'h5' => t('h5'),
'h6' => t('h6'),
'div' => t('div'),
'span' => t('span'),
),
);
$form['body'] = array(
'#type' => 'text_format',
'#title' => t('Body'),
@@ -38,17 +54,18 @@ class ctools_custom_content_ui extends ctools_export_ui {
);
}
function edit_form_submit(&$form, &$form_state) {
public function edit_form_submit(&$form, &$form_state) {
parent::edit_form_submit($form, $form_state);
// Since items in our settings are not in the schema, we have to do these manually:
$form_state['item']->settings['title'] = $form_state['values']['title'];
$form_state['item']->settings['title_heading'] = $form_state['values']['title_heading'];
$form_state['item']->settings['body'] = $form_state['values']['body']['value'];
$form_state['item']->settings['format'] = $form_state['values']['body']['format'];
$form_state['item']->settings['substitute'] = $form_state['values']['substitute'];
}
function list_form(&$form, &$form_state) {
public function list_form(&$form, &$form_state) {
parent::list_form($form, $form_state);
$options = array('all' => t('- All -'));
@@ -65,7 +82,7 @@ class ctools_custom_content_ui extends ctools_export_ui {
);
}
function list_filter($form_state, $item) {
public function list_filter($form_state, $item) {
if ($form_state['values']['category'] != 'all' && $form_state['values']['category'] != $item->category) {
return TRUE;
}
@@ -73,7 +90,7 @@ class ctools_custom_content_ui extends ctools_export_ui {
return parent::list_filter($form_state, $item);
}
function list_sort_options() {
public function list_sort_options() {
return array(
'disabled' => t('Enabled, title'),
'title' => t('Title'),
@@ -83,21 +100,25 @@ class ctools_custom_content_ui extends ctools_export_ui {
);
}
function list_build_row($item, &$form_state, $operations) {
// Set up sorting
public function list_build_row($item, &$form_state, $operations) {
// Set up sorting.
switch ($form_state['values']['order']) {
case 'disabled':
$this->sorts[$item->name] = empty($item->disabled) . $item->admin_title;
break;
case 'title':
$this->sorts[$item->name] = $item->admin_title;
break;
case 'name':
$this->sorts[$item->name] = $item->name;
break;
case 'category':
$this->sorts[$item->name] = $item->category;
break;
case 'storage':
$this->sorts[$item->name] = $item->type . $item->admin_title;
break;
@@ -117,7 +138,7 @@ class ctools_custom_content_ui extends ctools_export_ui {
);
}
function list_table_header() {
public function list_table_header() {
return array(
array('data' => t('Name'), 'class' => array('ctools-export-ui-name')),
array('data' => t('Title'), 'class' => array('ctools-export-ui-title')),
@@ -11,4 +11,4 @@ There are a number of ways to profit from this:
2. There is a sample panel. You can access it at /ctools_plugin_example/xxxx
to see how it works.
3. There is Advanced Help at admin/advanced_help/ctools_plugin_example.
3. There is Advanced Help at admin/advanced_help/ctools_plugin_example.
@@ -7,9 +7,8 @@ dependencies[] = page_manager
dependencies[] = advanced_help
core = 7.x
; Information added by drupal.org packaging script on 2013-04-03
version = "7.x-1.3"
; Information added by Drupal.org packaging script on 2019-02-08
version = "7.x-1.15"
core = "7.x"
project = "ctools"
datestamp = "1365013512"
datestamp = "1549603691"
@@ -1,9 +1,8 @@
<?php
/*
/**
* @file
*
* Working sample module to demonstrate CTools 3 plugins
* Working sample module to demonstrate CTools 3 plugins.
*
* This sample module is only intended to demonstrate how external modules can
* provide ctools plugins. There is no useful functionality, and it's only
@@ -25,7 +24,7 @@
*/
/**
* Implements hook_menu
* Implements hook_menu.
*/
function ctools_plugin_example_menu() {
$items = array();
@@ -58,7 +57,7 @@ function ctools_plugin_example_ctools_plugin_directory($module, $plugin) {
* Implement hook_ctools_plugin_api().
*
* If you do this, CTools will pick up default panels pages in
* <modulename>.pages_default.inc
* <modulename>.pages_default.inc.
*/
function ctools_plugin_example_ctools_plugin_api($module, $api) {
// @todo -- this example should explain how to put it in a different file.
@@ -71,7 +70,8 @@ function ctools_plugin_example_ctools_plugin_api($module, $api) {
}
/**
* Just provide an explanation page for the admin section
* Just provide an explanation page for the admin section.
*
* @return unknown_type
*/
function ctools_plugin_example_explanation_page() {
@@ -6,7 +6,7 @@
*/
/**
* Default panels pages for CTools Plugin Example
* Default panels pages for CTools Plugin Example.
*
* To pick up this file, your module needs to implement
* hook_ctools_plugin_api() - See ctools_plugin_example_ctools_plugin_api() in
@@ -23,12 +23,10 @@
* @return
* Array of pages, normally exported from Panels.
*/
function ctools_plugin_example_default_page_manager_pages() {
// begin exported panel.
$page = new stdClass;
// Begin exported panel.
$page = new stdClass();
$page->disabled = FALSE; /* Edit this to true to make a default page disabled initially */
$page->api_version = 1;
$page->name = 'ctools_plugin_example';
@@ -37,31 +35,31 @@ function ctools_plugin_example_default_page_manager_pages() {
$page->admin_description = 'This panel provides no functionality to a working Drupal system. It\'s intended to display the various sample plugins provided by the CTools Plugin Example module. ';
$page->path = 'ctools_plugin_example/%sc';
$page->access = array(
'logic' => 'and',
'logic' => 'and',
);
$page->menu = array(
'type' => 'normal',
'title' => 'CTools plugin example',
'name' => 'navigation',
'weight' => '0',
'parent' => array(
'type' => 'none',
'title' => '',
'type' => 'normal',
'title' => 'CTools plugin example',
'name' => 'navigation',
'weight' => '0',
),
'parent' => array(
'type' => 'none',
'title' => '',
'name' => 'navigation',
'weight' => '0',
),
);
$page->arguments = array(
'sc' => array(
'id' => 2,
'identifier' => 'simplecontext-arg',
'name' => 'simplecontext_arg',
'settings' => array(),
),
'sc' => array(
'id' => 2,
'identifier' => 'simplecontext-arg',
'name' => 'simplecontext_arg',
'settings' => array(),
),
);
$page->conf = array();
$page->default_handlers = array();
$handler = new stdClass;
$handler = new stdClass();
$handler->disabled = FALSE; /* Edit this to true to make a default handler disabled initially */
$handler->api_version = 1;
$handler->name = 'page_ctools_panel_context';
@@ -70,44 +68,45 @@ function ctools_plugin_example_default_page_manager_pages() {
$handler->handler = 'panel_context';
$handler->weight = 0;
$handler->conf = array(
'title' => 'Panel',
'no_blocks' => FALSE,
'css_id' => '',
'css' => '',
'contexts' => array(
'0' => array(
'name' => 'simplecontext',
'id' => 1,
'identifier' => 'Configured simplecontext (not from argument)',
'keyword' => 'configured_simplecontext',
'context_settings' => array(
'sample_simplecontext_setting' => 'default simplecontext setting',
),
),
),
'relationships' => array(
'0' => array(
'context' => 'argument_simplecontext_arg_2',
'name' => 'relcontext_from_simplecontext',
'id' => 1,
'identifier' => 'Relcontext from simplecontext (from relationship)',
'keyword' => 'relcontext',
),
),
'access' => array(
'logic' => 'and',
),
'title' => 'Panel',
'no_blocks' => FALSE,
'css_id' => '',
'css' => '',
'contexts' => array(
'0' => array(
'name' => 'simplecontext',
'id' => 1,
'identifier' => 'Configured simplecontext (not from argument)',
'keyword' => 'configured_simplecontext',
'context_settings' => array(
'sample_simplecontext_setting' => 'default simplecontext setting',
),
),
),
'relationships' => array(
'0' => array(
'context' => 'argument_simplecontext_arg_2',
'name' => 'relcontext_from_simplecontext',
'id' => 1,
'identifier' => 'Relcontext from simplecontext (from relationship)',
'keyword' => 'relcontext',
),
),
'access' => array(
'logic' => 'and',
),
'pipeline' => 'standard',
);
$display = new panels_display;
$display = new panels_display();
$display->layout = 'threecol_33_34_33_stacked';
$display->layout_settings = array();
$display->panel_settings = array(
'style' => 'rounded_corners',
'style_settings' => array(
'default' => array(
'corner_location' => 'pane',
),
),
'style' => 'rounded_corners',
'style_settings' => array(
'default' => array(
'corner_location' => 'pane',
),
),
);
$display->cache = array();
$display->title = 'CTools plugin example panel';
@@ -115,7 +114,7 @@ function ctools_plugin_example_default_page_manager_pages() {
$display->title_pane = 1;
$display->content = array();
$display->panels = array();
$pane = new stdClass;
$pane = new stdClass();
$pane->pid = 'new-1';
$pane->panel = 'left';
$pane->type = 'no_context_content_type';
@@ -135,7 +134,7 @@ function ctools_plugin_example_default_page_manager_pages() {
$pane->position = 0;
$display->content['new-1'] = $pane;
$display->panels['left'][0] = 'new-1';
$pane = new stdClass;
$pane = new stdClass();
$pane->pid = 'new-2';
$pane->panel = 'left';
$pane->type = 'custom';
@@ -148,15 +147,15 @@ function ctools_plugin_example_default_page_manager_pages() {
'settings' => array(
'greater_than' => '1',
'arg_length' => '4',
),
),
'context' => 'argument_simplecontext_arg_2',
),
),
),
),
);
$pane->configuration = array(
'title' => 'Long Arg Visibility Block',
'body' => 'This block will be here when the argument is longer than configured arg length. It uses the \'arg_length\' access plugin to test against the length of the argument used for Simplecontext.',
'format' => '1',
'format' => 'filtered_html',
'substitute' => 1,
);
$pane->cache = array();
@@ -166,7 +165,7 @@ function ctools_plugin_example_default_page_manager_pages() {
$pane->position = 1;
$display->content['new-2'] = $pane;
$display->panels['left'][1] = 'new-2';
$pane = new stdClass;
$pane = new stdClass();
$pane->pid = 'new-3';
$pane->panel = 'left';
$pane->type = 'custom';
@@ -179,15 +178,15 @@ function ctools_plugin_example_default_page_manager_pages() {
'settings' => array(
'greater_than' => '0',
'arg_length' => '4',
),
),
'context' => 'argument_simplecontext_arg_2',
),
),
),
),
);
$pane->configuration = array(
'title' => 'Short Arg Visibility',
'body' => 'This block appears when the simplecontext argument is <i>less than</i> the configured length.',
'format' => '1',
'format' => 'filtered_html',
'substitute' => 1,
);
$pane->cache = array();
@@ -197,7 +196,7 @@ function ctools_plugin_example_default_page_manager_pages() {
$pane->position = 2;
$display->content['new-3'] = $pane;
$display->panels['left'][2] = 'new-3';
$pane = new stdClass;
$pane = new stdClass();
$pane->pid = 'new-4';
$pane->panel = 'middle';
$pane->type = 'simplecontext_content_type';
@@ -241,7 +240,7 @@ function ctools_plugin_example_default_page_manager_pages() {
$pane->position = 0;
$display->content['new-4'] = $pane;
$display->panels['middle'][0] = 'new-4';
$pane = new stdClass;
$pane = new stdClass();
$pane->pid = 'new-5';
$pane->panel = 'middle';
$pane->type = 'simplecontext_content_type';
@@ -285,7 +284,7 @@ function ctools_plugin_example_default_page_manager_pages() {
$pane->position = 1;
$display->content['new-5'] = $pane;
$display->panels['middle'][1] = 'new-5';
$pane = new stdClass;
$pane = new stdClass();
$pane->pid = 'new-6';
$pane->panel = 'middle';
$pane->type = 'custom';
@@ -299,7 +298,7 @@ function ctools_plugin_example_default_page_manager_pages() {
item1 is %sc:item1
item2 is %sc:item2
description is %sc:description',
'format' => '1',
'format' => 'filtered_html',
'substitute' => 1,
);
$pane->cache = array();
@@ -309,7 +308,7 @@ function ctools_plugin_example_default_page_manager_pages() {
$pane->position = 2;
$display->content['new-6'] = $pane;
$display->panels['middle'][2] = 'new-6';
$pane = new stdClass;
$pane = new stdClass();
$pane->pid = 'new-7';
$pane->panel = 'right';
$pane->type = 'relcontext_content_type';
@@ -353,7 +352,7 @@ function ctools_plugin_example_default_page_manager_pages() {
$pane->position = 0;
$display->content['new-7'] = $pane;
$display->panels['right'][0] = 'new-7';
$pane = new stdClass;
$pane = new stdClass();
$pane->pid = 'new-8';
$pane->panel = 'top';
$pane->type = 'custom';
@@ -365,7 +364,7 @@ function ctools_plugin_example_default_page_manager_pages() {
'body' => 'The CTools Plugin Example module (and this panel page) are just here to demonstrate how to build CTools plugins.
',
'format' => '2',
'format' => 'full_html',
'substitute' => 1,
);
$pane->cache = array();
@@ -378,12 +377,11 @@ function ctools_plugin_example_default_page_manager_pages() {
$handler->conf['display'] = $display;
$page->default_handlers[$handler->name] = $handler;
// end of exported panel.
// End of exported panel.
$pages['ctools_plugin_example_demo_page'] = $page;
// begin exported panel
$page = new stdClass;
// Begin exported panel.
$page = new stdClass();
$page->disabled = FALSE; /* Edit this to true to make a default page disabled initially */
$page->api_version = 1;
$page->name = 'ctools_plugin_example_base';
@@ -396,7 +394,7 @@ function ctools_plugin_example_default_page_manager_pages() {
$page->arguments = array();
$page->conf = array();
$page->default_handlers = array();
$handler = new stdClass;
$handler = new stdClass();
$handler->disabled = FALSE; /* Edit this to true to make a default handler disabled initially */
$handler->api_version = 1;
$handler->name = 'page_ctools_plugin_example_base_panel_context';
@@ -405,14 +403,15 @@ function ctools_plugin_example_default_page_manager_pages() {
$handler->handler = 'panel_context';
$handler->weight = 0;
$handler->conf = array(
'title' => 'Panel',
'no_blocks' => FALSE,
'css_id' => '',
'css' => '',
'contexts' => array(),
'relationships' => array(),
'title' => 'Panel',
'no_blocks' => FALSE,
'css_id' => '',
'css' => '',
'contexts' => array(),
'relationships' => array(),
'pipeline' => 'standard',
);
$display = new panels_display;
$display = new panels_display();
$display->layout = 'onecol';
$display->layout_settings = array();
$display->panel_settings = array();
@@ -421,7 +420,7 @@ function ctools_plugin_example_default_page_manager_pages() {
$display->hide_title = FALSE;
$display->content = array();
$display->panels = array();
$pane = new stdClass;
$pane = new stdClass();
$pane->pid = 'new-1';
$pane->panel = 'middle';
$pane->type = 'custom';
@@ -431,7 +430,7 @@ function ctools_plugin_example_default_page_manager_pages() {
$pane->configuration = array(
'title' => 'Use this page with an argument',
'body' => 'This demo page works if you use an argument, like <a href="ctools_plugin_example/xxxxx">ctools_plugin_example/xxxxx</a>.',
'format' => '1',
'format' => 'filtered_html',
'substitute' => NULL,
);
$pane->cache = array();
@@ -443,9 +442,8 @@ function ctools_plugin_example_default_page_manager_pages() {
$display->panels['middle'][0] = 'new-1';
$handler->conf['display'] = $display;
$page->default_handlers[$handler->name] = $handler;
// end exported panel.
// End exported panel.
$pages['base_page'] = $page;
return $pages;
}
}
@@ -59,7 +59,8 @@ function ctools_plugin_example_arg_length_ctools_access_check($conf, $context) {
*/
function ctools_plugin_example_arg_length_ctools_access_summary($conf, $context) {
return t('Simpletext argument must be !comp @length characters',
array('!comp' => $conf['greater_than'] ? 'greater than' : 'less than or equal to',
'@length' => $conf['arg_length']));
array(
'!comp' => $conf['greater_than'] ? 'greater than' : 'less than or equal to',
'@length' => $conf['arg_length'],
));
}
@@ -4,7 +4,7 @@
* @file
* Plugin to provide access control based upon role membership.
* This is directly from the ctools module, but serves as a good
* example of an access plugin
* example of an access plugin.
*/
/**
@@ -73,4 +73,3 @@ function ctools_plugin_example_example_role_ctools_access_summary($conf, $contex
}
return format_plural(count($names), '@identifier must have role "@roles"', '@identifier can be one of "@roles"', array('@roles' => implode(', ', $names), '@identifier' => $context->identifier));
}
@@ -2,7 +2,6 @@
/**
* @file
*
* Sample plugin to provide an argument handler for a simplecontext.
*
* Given any argument to the page, simplecontext will get it
@@ -18,14 +17,12 @@
*/
$plugin = array(
'title' => t("Simplecontext arg"),
// keyword to use for %substitution
// Keyword to use for %substitution.
'keyword' => 'simplecontext',
'description' => t('Creates a "simplecontext" from the arg.'),
'context' => 'simplecontext_arg_context',
// 'settings form' => 'simplecontext_arg_settings_form',
// placeholder_form is used in panels preview, for example, so we can
// preview without getting the arg from a URL
// preview without getting the arg from a URL.
'placeholder form' => array(
'#type' => 'textfield',
'#description' => t('Enter the simplecontext arg'),
@@ -5,7 +5,6 @@
* "No context" sample content type. It operates with no context at all. It would
* be basically the same as a 'custom content' block, but it's not even that
* sophisticated.
*
*/
/**
@@ -33,7 +32,7 @@ $plugin = array(
'icon' => 'icon_example.png',
'category' => array(t('CTools Examples'), -9),
// this example does not provide 'admin info', which would populate the
// This example does not provide 'admin info', which would populate the
// panels builder page preview.
);
@@ -56,7 +55,7 @@ function no_context_content_type_render($subtype, $conf, $args, $context) {
$ctools_help = theme('advanced_help_topic', array('module' => 'ctools', 'topic' => 'plugins', 'type' => 'title'));
$ctools_plugin_example_help = theme('advanced_help_topic', array('module' => 'ctools_plugin_example', 'topic' => 'Chaos-Tools--CTools--Plugin-Examples', 'type' => 'title'));
// The title actually used in rendering
// The title actually used in rendering.
$block->title = check_plain("No-context content type");
$block->content = t("
<div>Welcome to the CTools Plugin Example demonstration content type.
@@ -84,7 +83,6 @@ function no_context_content_type_render($subtype, $conf, $args, $context) {
* Note that if we had not provided an entry for this in hook_content_types,
* this could have had the default name
* ctools_plugin_example_no_context_content_type_edit_form.
*
*/
function no_context_content_type_edit_form($form, &$form_state) {
$conf = $form_state['conf'];
@@ -1,6 +1,5 @@
<?php
/**
* @file
* Content type that displays the relcontext context type.
@@ -27,9 +26,8 @@ $plugin = array(
'category' => array(t('CTools Examples'), -9),
'edit form' => 'relcontext_edit_form',
// this example does not provide 'admin info', which would populate the
// This example does not provide 'admin info', which would populate the
// panels builder page preview.
);
/**
@@ -60,7 +58,7 @@ function relcontext_content_type_render($subtype, $conf, $args, $context) {
In our case, the configuration form (\$conf) has just one field, 'config_item_1;
and it's configured with:
");
if (!empty($conf)) {
if (!empty($conf)) {
$block->content .= '<div style="border: 1px solid red;">' . var_export($conf['config_item_1'], TRUE) . '</div>';
}
if (!empty($context)) {
@@ -77,7 +75,6 @@ function relcontext_content_type_render($subtype, $conf, $args, $context) {
/**
* 'Edit' callback for the content type.
* This example just returns a form.
*
*/
function relcontext_edit_form($form, &$form_state) {
$conf = $form_state['conf'];
@@ -1,6 +1,5 @@
<?php
/**
* @file
* Sample ctools content type that takes advantage of context.
@@ -9,7 +8,6 @@
* ctools content type can access and use context. Note that the simplecontext
* can be either configured manually into a panel or it can be retrieved via
* an argument.
*
*/
/**
@@ -31,7 +29,7 @@ $plugin = array(
'edit form' => 'simplecontext_content_type_edit_form',
'admin title' => 'ctools_plugin_example_simplecontext_content_type_admin_title',
// presents a block which is used in the preview of the data.
// Presents a block which is used in the preview of the data.
// Pn Panels this is the preview pane shown on the panels building page.
'admin info' => 'ctools_plugin_example_simplecontext_content_type_admin_info',
'category' => array(t('CTools Examples'), -9),
@@ -103,7 +101,6 @@ function simplecontext_content_type_render($subtype, $conf, $args, $context) {
/**
* 'Edit' callback for the content type.
* This example just returns a form.
*
*/
function simplecontext_content_type_edit_form($form, &$form_state) {
$conf = $form_state['conf'];
@@ -80,4 +80,3 @@ function relcontext_settings_form($conf, $external = FALSE) {
);
return $form;
}
@@ -1,10 +1,8 @@
<?php
/**
* @file
* Sample ctools context type plugin that shows how to create a context from an arg.
*
*/
/**
@@ -14,7 +12,8 @@
$plugin = array(
'title' => t("Simplecontext"),
'description' => t('A single "simplecontext" context, or data element.'),
'context' => 'ctools_plugin_example_context_create_simplecontext', // func to create context
// Func to create context.
'context' => 'ctools_plugin_example_context_create_simplecontext',
'context name' => 'simplecontext',
'settings form' => 'simplecontext_settings_form',
'keyword' => 'simplecontext',
@@ -69,7 +68,7 @@ function ctools_plugin_example_context_create_simplecontext($empty, $data = NULL
// This is used for keyword.
$context->title = $data;
$context->argument = $data;
// Make up a bogus context
// Make up a bogus context.
$context->data = new stdClass();
$context->data->item1 = t("Item1");
$context->data->item2 = t("Item2");
@@ -102,8 +101,6 @@ function simplecontext_settings_form($conf, $external = FALSE) {
return $form;
}
/**
* Provide a list of sub-keywords.
*
@@ -125,10 +122,11 @@ function simplecontext_convert($context, $type) {
switch ($type) {
case 'item1':
return $context->data->item1;
case 'item2':
return $context->data->item2;
case 'description':
return $context->data->description;
}
}
@@ -19,24 +19,24 @@ function ctools_plugin_example_default_panel_pages() {
$page->load_flags = 1;
$page->css_id = '';
$page->arguments = array(
0 =>
0 =>
array(
'name' => 'simplecontext_arg',
'id' => 1,
'default' => '404',
'title' => '',
'identifier' => 'Simplecontext arg',
'keyword' => 'simplecontext',
'name' => 'simplecontext_arg',
'id' => 1,
'default' => '404',
'title' => '',
'identifier' => 'Simplecontext arg',
'keyword' => 'simplecontext',
),
);
$page->relationships = array(
0 =>
0 =>
array(
'context' => 'argument_simplecontext_arg_1',
'name' => 'relcontext_from_simplecontext',
'id' => 1,
'identifier' => 'Relcontext from Simplecontext',
'keyword' => 'relcontext',
'context' => 'argument_simplecontext_arg_1',
'name' => 'relcontext_from_simplecontext',
'id' => 1,
'identifier' => 'Relcontext from Simplecontext',
'keyword' => 'relcontext',
),
);
$page->no_blocks = '0';
@@ -58,14 +58,14 @@ function ctools_plugin_example_default_panel_pages() {
$pane->subtype = 'custom';
$pane->access = array();
$pane->configuration = array(
'style' => 'default',
'override_title' => 0,
'override_title_text' => '',
'css_id' => '',
'css_class' => '',
'title' => '"No Context Item"',
'body' => 'The "no context item" content type is here to demonstrate that you can create a content_type that does not require a context. This is probably the same as just creating a custom php block on the fly, and might serve the same purpose.',
'format' => '1',
'style' => 'default',
'override_title' => 0,
'override_title_text' => '',
'css_id' => '',
'css_class' => '',
'title' => '"No Context Item"',
'body' => 'The "no context item" content type is here to demonstrate that you can create a content_type that does not require a context. This is probably the same as just creating a custom php block on the fly, and might serve the same purpose.',
'format' => '1',
);
$pane->cache = array();
$display->content['new-1'] = $pane;
@@ -78,14 +78,14 @@ function ctools_plugin_example_default_panel_pages() {
$pane->subtype = 'description';
$pane->access = array();
$pane->configuration = array(
'style' => 'default',
'override_title' => 0,
'override_title_text' => '',
'css_id' => '',
'css_class' => '',
'item1' => 'one',
'item2' => 'two',
'item3' => 'three',
'style' => 'default',
'override_title' => 0,
'override_title_text' => '',
'css_id' => '',
'css_class' => '',
'item1' => 'one',
'item2' => 'two',
'item3' => 'three',
);
$pane->cache = array();
$display->content['new-2'] = $pane;
@@ -98,16 +98,16 @@ function ctools_plugin_example_default_panel_pages() {
$pane->subtype = 'custom';
$pane->access = array();
$pane->configuration = array(
'style' => 'default',
'override_title' => 0,
'override_title_text' => '',
'css_id' => '',
'css_class' => '',
'title' => 'Simplecontext',
'body' => 'The "Simplecontext" content and content type demonstrate a very basic context and how to display it.
'style' => 'default',
'override_title' => 0,
'override_title_text' => '',
'css_id' => '',
'css_class' => '',
'title' => 'Simplecontext',
'body' => 'The "Simplecontext" content and content type demonstrate a very basic context and how to display it.
Simplecontext includes configuration, so it can get info from the config. It can also get its information to run from a simplecontext context, generated either from an arg to the panels page or via explicitly adding a context to the page.',
'format' => '1',
'format' => '1',
);
$pane->cache = array();
$display->content['new-3'] = $pane;
@@ -119,17 +119,17 @@ function ctools_plugin_example_default_panel_pages() {
$pane->shown = '1';
$pane->subtype = 'description';
$pane->access = array(
0 => '2',
1 => '4',
0 => '2',
1 => '4',
);
$pane->configuration = array(
'context' => 'argument_simplecontext_arg_1',
'style' => 'default',
'override_title' => 0,
'override_title_text' => '',
'css_id' => '',
'css_class' => '',
'config_item_1' => 'simplecontext called from arg',
'context' => 'argument_simplecontext_arg_1',
'style' => 'default',
'override_title' => 0,
'override_title_text' => '',
'css_id' => '',
'css_class' => '',
'config_item_1' => 'simplecontext called from arg',
);
$pane->cache = array();
$display->content['new-4'] = $pane;
@@ -142,14 +142,14 @@ function ctools_plugin_example_default_panel_pages() {
$pane->subtype = 'custom';
$pane->access = array();
$pane->configuration = array(
'style' => 'default',
'override_title' => 0,
'override_title_text' => '',
'css_id' => '',
'css_class' => '',
'title' => 'Relcontext',
'body' => 'The relcontext content_type gets its data from a relcontext, which is an example of a relationship. This panel should be run with an argument like "/xxx", which allows the simplecontext to get its context, and then the relcontext is configured in this panel to get (create) its data from the simplecontext.',
'format' => '1',
'style' => 'default',
'override_title' => 0,
'override_title_text' => '',
'css_id' => '',
'css_class' => '',
'title' => 'Relcontext',
'body' => 'The relcontext content_type gets its data from a relcontext, which is an example of a relationship. This panel should be run with an argument like "/xxx", which allows the simplecontext to get its context, and then the relcontext is configured in this panel to get (create) its data from the simplecontext.',
'format' => '1',
);
$pane->cache = array();
$display->content['new-5'] = $pane;
@@ -162,13 +162,13 @@ function ctools_plugin_example_default_panel_pages() {
$pane->subtype = 'description';
$pane->access = array();
$pane->configuration = array(
'context' => 'relationship_relcontext_from_simplecontext_1',
'style' => 'default',
'override_title' => 0,
'override_title_text' => '',
'css_id' => '',
'css_class' => '',
'config_item_1' => 'default1',
'context' => 'relationship_relcontext_from_simplecontext_1',
'style' => 'default',
'override_title' => 0,
'override_title_text' => '',
'css_id' => '',
'css_class' => '',
'config_item_1' => 'default1',
);
$pane->cache = array();
$display->content['new-6'] = $pane;
@@ -181,13 +181,13 @@ function ctools_plugin_example_default_panel_pages() {
$pane->subtype = 'custom_php';
$pane->access = array();
$pane->configuration = array(
'style' => 'default',
'override_title' => 0,
'override_title_text' => '',
'css_id' => '',
'css_class' => '',
'title' => '',
'body' => '$arg = arg(1);
'style' => 'default',
'override_title' => 0,
'override_title_text' => '',
'css_id' => '',
'css_class' => '',
'title' => '',
'body' => '$arg = arg(1);
$arg0 = arg(0);
if (!$arg) {
$block->content = <<<END
@@ -209,6 +209,5 @@ END;
$page->displays = array();
$pages['ctools_plugin_example'] = $page;
return $pages;
}
@@ -1,9 +1,7 @@
<?php
/**
* @file
*
* Sample relationship plugin.
*
* We take a simplecontext, look in it for what we need to make a relcontext, and make it.
@@ -33,7 +31,6 @@ function ctools_relcontext_from_simplecontext_context($context = NULL, $conf) {
}
// You should do error-checking here.
// Create the new context from some element of the parent context.
// In this case, we'll pass in the whole context so it can be used to
// create the relcontext.
@@ -47,4 +44,3 @@ function ctools_relcontext_from_simplecontext_settings_form($conf) {
// We won't configure it in this case.
return array();
}
@@ -64,7 +64,7 @@ function ctools_drush_command() {
'machine names' => 'Space separated list of exportables you want to view.',
),
'options' => array(
'indent' => 'The string to use for indentation when dispalying the exportable export code. Defaults to \'\'.',
'indent' => 'The string to use for indentation when displaying the exportable export code. Defaults to \'\'.',
'no-colour' => 'Remove any colour formatting from export string output. Ideal if you are sending the output of this command to a file.',
'module' => $module_text,
'all' => $all_text,
@@ -140,13 +140,14 @@ function ctools_drush_help($section) {
switch ($section) {
case 'meta:ctools:title':
return dt('CTools commands');
case 'meta:entity:summary':
return dt('CTools drush commands.');
}
}
/**
* Drush callback: export
* Drush callback: export.
*/
function ctools_drush_export($module = 'foo') {
$error = FALSE;
@@ -338,7 +339,7 @@ function _ctools_drush_selection_screen(array $tables = array()) {
$build[$table_choice]['count'] = count($multi_select);
$selections[$table_choice] = array();
foreach ($multi_select as $key) {
$selections[$table_choice][$key] = $key;
$selections[$table_choice][$key] = $key;
}
}
}
@@ -445,11 +446,13 @@ function ctools_drush_export_info() {
}
}
}
/**
* Drush callback: Acts as the hub for all op commands to keep
* all arg handling etc in one place.
*/
function ctools_drush_export_op_command() {
$args = func_get_args();
// Get all info for the current drush command.
$command = drush_get_command();
$op = '';
@@ -457,17 +460,20 @@ function ctools_drush_export_op_command() {
switch ($command['command']) {
case 'ctools-export-view':
$op = 'view';
break;
break;
case 'ctools-export-revert':
// Revert is same as deleting. As any objects in the db are deleted.
$op = 'delete';
break;
break;
case 'ctools-export-enable':
$op = 'enable';
break;
break;
case 'ctools-export-disable':
$op = 'disable';
break;
break;
}
if (!$op) {
@@ -475,7 +481,7 @@ function ctools_drush_export_op_command() {
}
if (drush_get_option('all', FALSE)) {
$info = _ctools_drush_export_info('', TRUE);
$info = _ctools_drush_export_info(array(), TRUE);
$exportable_info = $info['exportables'];
$all = drush_confirm(dt('Are you sure you would like to !op all exportables on the system?',
@@ -490,7 +496,6 @@ function ctools_drush_export_op_command() {
}
}
else {
$args = func_get_args();
// Table name should always be first arg...
$table_name = array_shift($args);
// Any additional args are assumed to be exportable names.
@@ -512,7 +517,6 @@ function ctools_drush_export_op_command() {
* @param $op
* @param $table_name
* @param $exportables
*
*/
function ctools_drush_export_op($op = '', $table_name = '', $exportables = NULL) {
$objects = ctools_export_crud_load_multiple($table_name, array_keys($exportables));
@@ -538,7 +542,7 @@ function ctools_drush_export_op($op = '', $table_name = '', $exportables = NULL)
* @param $object_names
*
* @return
* Array of exportable objects (filtered if necessary, by name etc..) or FALSE if not.
* Array of exportable objects (filtered if necessary, by name etc..) or FALSE if not.
*/
function _ctools_drush_export_op_command_logic($op = '', $table_name = NULL, array $object_names = array()) {
if (!$table_name) {
@@ -644,7 +648,7 @@ function _ctools_drush_export_info(array $table_names = array(), $load = FALSE)
return array('exportables' => $exportables, 'schemas' => $schemas);
}
/*
/**
* View a single object.
*
* @param $table_name
@@ -662,7 +666,7 @@ function _ctools_drush_export_view($table_name, $object) {
}
}
/*
/**
* Revert a single object.
*
* @param $table_name
@@ -681,7 +685,7 @@ function _ctools_drush_export_delete($table_name, $object) {
}
}
/*
/**
* Enable a single object.
*
* @param $table_name
@@ -701,7 +705,7 @@ function _ctools_drush_export_enable($table_name, $object) {
}
}
/*
/**
* Disable a single object.
*
* @param $table_name
@@ -723,9 +727,9 @@ function _ctools_drush_export_disable($table_name, $object) {
/**
* Filter a nested array of exportables by export module.
*
* @param $exportables array
* @param array $exportables
* Passed by reference. A nested array of exportables, keyed by table name.
* @param $export_module string
* @param string $export_module
* The name of the export module providing the exportable.
*/
function _ctools_drush_export_module_filter($exportables, $export_module) {
@@ -778,7 +782,7 @@ function _ctools_drush_object_is_disabled($object) {
/**
* Determine if an object is enabled.
*
* @see _ctools_drush_object_is_disabled.
* @see _ctools_drush_object_is_disabled()
*/
function _ctools_drush_object_is_enabled($object) {
return (empty($object->disabled)) ? TRUE : FALSE;
@@ -835,7 +839,7 @@ function _ctools_drush_object_is_not_code_only($object) {
* Array of exportables to count.
*
* @return
* Array of count data containing the following:
* Array of count data containing the following:
* 'total' - A total count of all exportables.
* 'exportables' - An array of exportable counts per table.
*/
@@ -867,26 +871,32 @@ function _ctools_drush_filter_exportables($exportables, $filter) {
// Show enabled exportables only.
case 'enabled':
$eval = '_ctools_drush_object_is_disabled';
break;
break;
// Show disabled exportables only.
case 'disabled':
$eval = '_ctools_drush_object_is_enabled';
break;
break;
// Show overridden exportables only.
case 'overridden':
$eval = '_ctools_drush_object_is_not_overridden';
break;
break;
// Show database only exportables.
case 'database':
$eval = '_ctools_drush_object_is_not_db_only';
break;
break;
// Show code only exportables.
case 'code':
$eval = '_ctools_drush_object_is_not_code_only';
break;
break;
// Do nothing.
case 'all':
break;
default:
drush_log(dt('Invalid filter option. Available options are: enabled, disabled, overridden, database, and code.'), 'error');
return;
@@ -983,33 +993,42 @@ class shellColours {
'light_gray' => '47',
);
/**
* shellColours constructor.
*/
private function __construct() {}
// Returns coloured string
/**
* Returns coloured string.
*/
public static function getColouredOutput($string, $foreground_colour = NULL, $background_colour = NULL) {
$coloured_string = "";
// Check if given foreground colour found
// Check if given foreground colour found.
if ($foreground_colour) {
$coloured_string .= "\033[" . self::$foreground_colours[$foreground_colour] . "m";
}
// Check if given background colour found
// Check if given background colour found.
if ($background_colour) {
$coloured_string .= "\033[" . self::$background_colours[$background_colour] . "m";
}
// Add string and end colouring
$coloured_string .= $string . "\033[0m";
// Add string and end colouring.
$coloured_string .= $string . "\033[0m";
return $coloured_string;
}
// Returns all foreground colour names
/**
* Returns all foreground colour names.
*/
public static function getForegroundColours() {
return array_keys(self::$foreground_colours);
}
// Returns all background colour names
/**
* Returns all background colour names.
*/
public static function getBackgroundColours() {
return array_keys(self::$background_colours);
}
@@ -116,6 +116,10 @@ The first form will always have required configuration added to it. These forms
<dt>required context [Optional]</dt>
<dd>Either a ctools_context_required or ctools_context_optional or array of contexts for this content. If omitted, no contexts are used.</dd>
<dt>create content access [Optional]</dt>
<dd>An optional callback to determine if a user can access this subtype. The callback will receive two arguments, the type and subtype.</dd>
</dl>
<h2>Rendered content</h2>
@@ -154,8 +154,11 @@ function mymodule_schema() {
<dd>Bulk export callback to provide a list of exportable objects to be chosen for bulk exporting. Defaults to $module . '_' . $table . '_list' if the function exists. If it is not, a default listing function will be provided that will make a best effort to list the titles. See ctools_export_default_list().</dd>
<dt>to hook code callback</dt>
<dd>Function used to generate an export for the bulk export process. This is only necessary if the export is more complicated than simply listing the fields. Defaults to $module . '_' . $table . '_to_hook_code'.</dt>
<dd>Function used to generate an export for the bulk export process. This is only necessary if the export is more complicated than simply listing the fields. Defaults to $module . '_' . $table . '_to_hook_code'.</dd>
<dt>boolean</dt>
<dd>Explicitly indicate if a table field contains a boolean or not. The Schema API does not model the
difference between a tinyint and a boolean type. Boolean values are stored in tinyint fields. This may cause mismatch errors when exporting a non-boolean value from a tinyint field. Add this to a tinyint field if it contains boolean data and can be exported. Defaults to TRUE.
<dt>create callback</dt>
<dd>CRUD callback to use to create a new exportable item in memory. If not provided, the default function will be used. The single argument is a boolean used to determine if defaults should be set on the object. This object will not be written to the database by this callback.</dd>
@@ -82,7 +82,7 @@ function ctools_modal_text_button($text, $dest, $alt, $class = '') {
<li> <strong>modalSize</strong>: an array of data to control the sizing of the modal. It can contain:
<ul>
<li> <strong>type</strong>: Either <em>fixed</em> or <em>scale</em>. If fixed, the modal will always be a fixed size. If <em>scale</em> the modal will scale to a percentage of the browser window. <em>Default: scale</em>.
<li> <strong>width</strong>: If </em>fixed</em> the width in pixels. If <em>scale</em> the percentage of the screen expressed as a number less than zero. (For 80 percent, use .8, for example). <em>Default: .8</em></li>
<li> <strong>width</strong>: If <em>fixed</em> the width in pixels. If <em>scale</em> the percentage of the screen expressed as a number less than zero. (For 80 percent, use .8, for example). <em>Default: .8</em></li>
<li> <strong>height</strong>: If <em>fixed</em> the height in pixels. If <em>scale</em> the percentage of the screen expressed as a number less than zero. (For 80 percent, use .8, for example). <em>Default: .8</em></li>
<li> <strong>addWidth</strong>: Any additional width to add to the modal in pixels. Only useful if the type is scale. <em>Default: 0</em></li>
<li> <strong>addHeight</strong>: Any additional height to add to the modal in pixels. Only useful if the type is scale. <em>Default: 0</em></li>
@@ -168,7 +168,7 @@ function ctools_ajax_sample_login($js) {
<pre>
function ctools_ajax_hello_world($js) {
$title = t('Greetings');
$output = '&lt;p&gt;' . t('Hello world') . ''&lt;/p&gt;';
$output = '&lt;p&gt;' . t('Hello world') . '&lt;/p&gt;';
if ($js) {
ctools_modal_render($title, $output);
}
@@ -24,6 +24,18 @@ The following information can be specified for each plugin type:
<dt>cache table</dt>
<dd><em>Defaults to:</em> <strong>'cache'</strong></dd>
<dd>If 'cache' is TRUE, then this value specifies the cache table where the cached plugin information will be stored.</dd>
<dt>classes</dt>
<dd><em>Defaults to:</em> <strong>array()</strong></dd>
<dd>An array of <em>class identifiers</em>(i.e. plugin array keys) which a plugin of this type uses to provide classes to the CTools autoloader. For example, if <strong>classes</strong> is set to array('class'), then CTools will search each <strong>$plugin['class']</strong> for a class to autoload. Depending of the plugin structure, a <em>class identifier</em> may be either:
<dl>
<dt>- a file name:</dt>
<dd>the file which holds the class with the name structure as: <em>[filename].[class].php</em></dd>
<dd>in this case the class name can be different than the <em>class identifier</em></dd>
<dt>- the class name:</dt>
<dd>if the class is in the same file as the $plugin</dd>
<dd>the plugin <em>.inc</em> file can have a different name than the <em>class identifier</em></dd>
</dl>
<dd>
<dt>defaults</dt>
<dd><em>Defaults to:</em> <strong>array()</strong></dd>
<dd>An array of defaults that should be added to each plugin; this can be used to ensure that every plugin has the basic data necessary. These defaults will not ovewrite data supplied by the plugin. This could also be a function name, in which case the callback will be used to provide defaults. NOTE, however, that the callback-based approach is deprecated as it is redundant with the 'process' callback, and as such will be removed in later versions. Consequently, you should only use the array form for maximum cross-version compatibility.</dd>
@@ -1,4 +1,5 @@
<?php
/**
* @file
* Theme function for wrapping menu local actions.
@@ -30,4 +31,4 @@ function theme_ctools_menu_local_actions_wrapper($variables) {
}
return '<ul class="action-links">' . $links . '</ul>';
}
}
@@ -1,6 +1,10 @@
<?php
// Set this so we can tell that the file has been included at some point.
/**
* @file
* Set this so we can tell that the file has been included at some point.
*/
define('CTOOLS_AJAX_INCLUDED', 1);
/**
@@ -49,6 +53,34 @@ function ctools_ajax_text_button($text, $dest, $alt, $class = '', $type = 'use-a
return l($text, $dest, array('html' => TRUE, 'attributes' => array('class' => array($type, $class), 'title' => $alt)));
}
/**
* Render an icon and related text as a link. This will automatically apply an AJAX class
* to the link and add the appropriate javascript to make this happen.
*
* Note: 'html' => true so be sure any text is vetted! Chances are these kinds of buttons will
* not use user input so this is a very minor concern.
*
* @param $text
* The text that will be displayed as the link.
* @param $image
* The icon image to include in the link.
* @param $dest
* The destination of the link.
* @param $alt
* The title text of the link.
* @param $class
* Any class to apply to the link. @todo this should be a options array.
* @param $type
* A type to use, in case a different behavior should be attached. Defaults
* to ctools-use-ajax.
*/
function ctools_ajax_icon_text_button($text, $image, $dest, $alt, $class = '', $type = 'use-ajax') {
drupal_add_library('system', 'drupal.ajax');
$rendered_image = theme('image', array('path' => $image));
$link_content = $rendered_image . "<span>" . $text . "</span>";
return l($link_content, $dest, array('html' => TRUE, 'attributes' => array('class' => array($type, $class), 'title' => $alt)));
}
/**
* Set a single property to a value, on all matched elements.
*
@@ -57,17 +89,17 @@ function ctools_ajax_text_button($text, $dest, $alt, $class = '', $type = 'use-a
* @param $name
* The name or key: of the data attached to this selector.
* @param $value
* The value of the data.
* The value of the data.
*/
function ctools_ajax_command_attr($selector, $name, $value) {
ctools_add_js('ajax-responder');
return array(
'command' => 'attr',
'selector' => $selector,
'name' => $name,
'value' => $value,
);
}
'command' => 'attr',
'selector' => $selector,
'name' => $name,
'value' => $value,
);
}
/**
* Force a client-side redirect.
@@ -126,4 +158,3 @@ function ctools_ajax_render_error($error = '') {
print ajax_render($commands);
exit;
}
@@ -2,7 +2,6 @@
/**
* @file
*
* Plugins to handle cache-indirection.
*
* Simple plugin management to allow clients to more tightly control where
@@ -52,7 +51,6 @@
* @param string $mechanism
* A string containing the plugin name, and an optional data element to
* send to the plugin separated by two colons.
*
* @param string $key
* The key used to identify the cache.
*
@@ -70,7 +68,6 @@ function ctools_cache_get($mechanism, $key) {
* @param string $mechanism
* A string containing the plugin name, and an optional data element to
* send to the plugin separated by two colons.
*
* @param string $key
* The key used to identify the cache.
*
@@ -88,7 +85,6 @@ function ctools_cache_set($mechanism, $key, $object) {
* @param string $mechanism
* A string containing the plugin name, and an optional data element to
* send to the plugin separated by two colons.
*
* @param string $key
* The key used to identify the cache.
*/
@@ -108,13 +104,10 @@ function ctools_cache_clear($mechanism, $key) {
* @param string $mechanism
* A string containing the plugin name, and an optional data element to
* send to the plugin separated by two colons.
*
* @param string $key
* The key used to identify the cache.
*
* @param string $op
* The operation to call, such as 'break' or 'finalize'.
*
* @param mixed $object
* The cache data being operated on, in case it is necessary. This is
* optional so no references should be used.
@@ -150,7 +143,7 @@ function ctools_cache_operation($mechanism, $key, $op, $object = NULL) {
*/
function ctools_cache_find_plugin($mechanism) {
if (strpos($mechanism, '::') !== FALSE) {
// use explode(2) to ensure that the data can contain double
// Use explode(2) to ensure that the data can contain double
// colons, just in case.
list($name, $data) = explode('::', $mechanism, 2);
}
@@ -1,5 +1,4 @@
<?php
// $Id $
/**
* @file
@@ -21,7 +20,7 @@
/**
* Matches Unicode character classes.
*
* See: http://www.unicode.org/Public/UNIDATA/UCD.html#General_Category_Values
* See: http://www.unicode.org/Public/UNIDATA/UCD.html#General_Category_Values.
*
* The index only contains the following character classes:
* Lu Letter, Uppercase
@@ -129,13 +128,13 @@ function ctools_cleanstring($string, $settings = array()) {
$output = transliteration_get($output);
}
// Reduce to the subset of ASCII96 letters and numbers
// Reduce to the subset of ASCII96 letters and numbers.
if ($settings['reduce ascii']) {
$pattern = '/[^a-zA-Z0-9\/]+/';
$output = preg_replace($pattern, $settings['separator'], $output);
}
// Get rid of words that are on the ignore list
// Get rid of words that are on the ignore list.
if (!empty($settings['ignore words'])) {
$ignore_re = '\b' . preg_replace('/,/', '\b|\b', $settings['ignore words']) . '\b';
@@ -159,14 +158,14 @@ function ctools_cleanstring($string, $settings = array()) {
else {
$seppattern = '\\' . $settings['separator'];
}
// Trim any leading or trailing separators (note the need to
// Trim any leading or trailing separators (note the need to.
$output = preg_replace("/^$seppattern+|$seppattern+$/", '', $output);
// Replace multiple separators with a single one
// Replace multiple separators with a single one.
$output = preg_replace("/$seppattern+/", $settings['separator'], $output);
}
// Enforce the maximum component length
// Enforce the maximum component length.
if (!empty($settings['max length'])) {
$output = ctools_cleanstring_truncate($output, $settings['max length'], $settings['separator']);
}
@@ -188,12 +187,14 @@ function ctools_cleanstring($string, $settings = array()) {
* A string which contains the word boundary such as - or _.
*
* @return
* The string truncated below the maxlength.
* The string truncated below the maxlength.
*/
function ctools_cleanstring_truncate($string, $length, $separator) {
if (drupal_strlen($string) > $length) {
$string = drupal_substr($string, 0, $length + 1); // leave one more character
if ($last_break = strrpos($string, $separator)) { // space exists AND is not on position 0
// Leave one more character.
$string = drupal_substr($string, 0, $length + 1);
// Space exists AND is not on position 0.
if ($last_break = strrpos($string, $separator)) {
$string = substr($string, 0, $last_break);
}
else {
@@ -30,8 +30,8 @@ function ctools_collapsible_theme(&$items) {
* Text to put in the handle/title area of the div.
* @param $content
* Text to put in the content area of the div, this is what will get
* collapsed
* @param $collapsed = FALSE
* collapsed.
* @param $collapsed
* If true, this div will start out collapsed.
*/
function theme_ctools_collapsible($vars) {
@@ -56,8 +56,8 @@ function theme_ctools_collapsible($vars) {
* Text to put in the handle/title area of the div.
* @param $content
* Text to put in the content area of the div, this is what will get
* collapsed
* @param $collapsed = FALSE
* collapsed.
* @param $collapsed
* If true, this div will start out collapsed.
*/
function theme_ctools_collapsible_remembered($vars) {
@@ -76,4 +76,3 @@ function theme_ctools_collapsible_remembered($vars) {
return $output;
}
@@ -86,7 +86,7 @@ function ctools_content_process(&$plugin, $info) {
/**
* Fetch metadata on a specific content_type plugin.
*
* @param $content type
* @param mixed $content
* Name of a panel content type.
*
* @return
@@ -146,7 +146,7 @@ function ctools_content_get_subtypes($type) {
if (is_array($function)) {
$subtypes = $function;
}
else if (function_exists($function)) {
elseif (function_exists($function)) {
// Cast to array to prevent errors from non-array returns.
$subtypes = (array) $function($plugin);
}
@@ -155,6 +155,11 @@ function ctools_content_get_subtypes($type) {
// Walk through the subtypes and ensure minimal settings are
// retained.
foreach ($subtypes as $id => $subtype) {
// Ensure that the 'subtype_id' value exists.
if (!isset($subtype['subtype_id'])) {
$subtypes[$id]['subtype_id'] = $id;
}
// Use exact name since this is a modify by reference.
ctools_content_prepare_subtype($subtypes[$id], $plugin);
}
@@ -202,6 +207,13 @@ function ctools_content_get_subtype($type, $subtype_id) {
}
if ($subtype) {
// Ensure that the 'subtype_id' value exists. This is also done in
// ctools_content_get_subtypes(), but it wouldn't be called if the plugin
// provides the subtype through its own function.
if (!isset($subtype['subtype_id'])) {
$subtype['subtype_id'] = $subtype_id;
}
ctools_content_prepare_subtype($subtype, $plugin);
}
return $subtype;
@@ -217,6 +229,7 @@ function ctools_content_prepare_subtype(&$subtype, $plugin) {
}
}
// Trigger hook_ctools_content_subtype_alter().
drupal_alter('ctools_content_subtype', $subtype, $plugin);
}
@@ -241,9 +254,10 @@ function ctools_content_prepare_subtype(&$subtype, $plugin) {
* Any incoming content, if this display is a wrapper.
*
* @return
* The content as rendered by the plugin. This content should be an array
* with the following possible keys:
* The content as rendered by the plugin, or NULL.
* This content should be an object with the following possible properties:
* - title: The safe to render title of the content.
* - title_heading: The title heading.
* - content: The safe to render HTML content.
* - links: An array of links associated with the content suitable for
* theme('links').
@@ -293,21 +307,22 @@ function ctools_content_render($type, $subtype, $conf, $keywords = array(), $arg
$content->subtype = $subtype;
}
// Override the title if configured to
// Override the title if configured to.
if (!empty($conf['override_title'])) {
// Give previous title as an available substitution here.
$keywords['%title'] = empty($content->title) ? '' : $content->title;
$content->original_title = $keywords['%title'];
$content->title = $conf['override_title_text'];
$content->title_heading = isset($conf['override_title_heading']) ? $conf['override_title_heading'] : 'h2';
}
if (!empty($content->title)) {
// Perform substitutions
// Perform substitutions.
if (!empty($keywords) || !empty($context)) {
$content->title = ctools_context_keyword_substitute($content->title, $keywords, $context);
}
// Sterilize the title
// Sterilize the title.
$content->title = filter_xss_admin($content->title);
// If a link is specified, populate.
@@ -318,7 +333,7 @@ function ctools_content_render($type, $subtype, $conf, $keywords = array(), $arg
else {
$url = $content->title_link;
}
// set defaults so we don't bring up notices
// Set defaults so we don't bring up notices.
$url += array('href' => '', 'attributes' => array(), 'query' => array(), 'fragment' => '', 'absolute' => NULL, 'html' => TRUE);
$content->title = l($content->title, $url['href'], $url);
}
@@ -339,7 +354,16 @@ function ctools_content_editable($type, $subtype, $conf) {
return FALSE;
}
if ($function = ctools_plugin_get_function($subtype, 'check editable')) {
$function = FALSE;
if (!empty($subtype['check editable'])) {
$function = ctools_plugin_get_function($subtype, 'check editable');
}
elseif (!empty($type['check editable'])) {
$function = ctools_plugin_get_function($type, 'check editable');
}
if ($function) {
return $function($type, $subtype, $conf);
}
@@ -362,7 +386,7 @@ function ctools_content_admin_title($type, $subtype, $conf, $context = NULL) {
if (is_array($type)) {
$plugin = $type;
}
else if (is_string($type)) {
elseif (is_string($type)) {
$plugin = ctools_get_content_type($type);
}
else {
@@ -380,10 +404,10 @@ function ctools_content_admin_title($type, $subtype, $conf, $context = NULL) {
return $function($subtype, $conf, $pane_context);
}
else if (isset($plugin['admin title'])) {
elseif (isset($plugin['admin title'])) {
return $plugin['admin title'];
}
else if (isset($plugin['title'])) {
elseif (isset($plugin['title'])) {
return $plugin['title'];
}
}
@@ -418,7 +442,7 @@ function ctools_content_get_defaults($plugin, $subtype) {
if (isset($plugin['defaults'])) {
$defaults = $plugin['defaults'];
}
else if (isset($subtype['defaults'])) {
elseif (isset($subtype['defaults'])) {
$defaults = $subtype['defaults'];
}
if (isset($defaults)) {
@@ -427,7 +451,7 @@ function ctools_content_get_defaults($plugin, $subtype) {
return $return;
}
}
else if (is_array($defaults)) {
elseif (is_array($defaults)) {
return $defaults;
}
}
@@ -461,7 +485,7 @@ function ctools_content_admin_info($type, $subtype, $conf, $context = NULL) {
if (empty($output) || !is_object($output)) {
$output = new stdClass();
// replace the _ with " " for a better output
// Replace the _ with " " for a better output.
$subtype = check_plain(str_replace("_", " ", $subtype));
$output->title = $subtype;
$output->content = t('No info available.');
@@ -470,7 +494,7 @@ function ctools_content_admin_info($type, $subtype, $conf, $context = NULL) {
}
/**
* Add the default FAPI elements to the content type configuration form
* Add the default FAPI elements to the content type configuration form.
*/
function ctools_content_configure_form_defaults($form, &$form_state) {
$plugin = $form_state['plugin'];
@@ -504,8 +528,26 @@ function ctools_content_configure_form_defaults($form, &$form_state) {
'#size' => 35,
'#id' => 'override-title-textfield',
'#dependency' => array('override-title-checkbox' => array(1)),
'#dependency_type' => 'disable',
'#dependency_type' => 'hidden',
);
$form['override_title_heading'] = array(
'#type' => 'select',
'#default_value' => isset($conf['override_title_heading']) ? $conf['override_title_heading'] : 'h2',
'#options' => array(
'h1' => t('h1'),
'h2' => t('h2'),
'h3' => t('h3'),
'h4' => t('h4'),
'h5' => t('h5'),
'h6' => t('h6'),
'div' => t('div'),
'span' => t('span'),
),
'#id' => 'override-title-heading',
'#dependency' => array('override-title-checkbox' => array(1)),
'#dependency_type' => 'hidden',
);
$form['aligner_stop'] = array(
'#markup' => '</div>',
);
@@ -536,6 +578,7 @@ function ctools_content_configure_form_defaults_submit(&$form, &$form_state) {
if (isset($form_state['values']['override_title'])) {
$form_state['conf']['override_title'] = $form_state['values']['override_title'];
$form_state['conf']['override_title_text'] = $form_state['values']['override_title_text'];
$form_state['conf']['override_title_heading'] = $form_state['values']['override_title_heading'];
}
}
@@ -568,7 +611,7 @@ function ctools_content_form($op, $form_info, &$form_state, $plugin, $subtype_na
if (!empty($subtype['add form'])) {
_ctools_content_create_form_info($form_info, $subtype['add form'], $subtype, $subtype, $op);
}
else if (!empty($plugin['add form'])) {
elseif (!empty($plugin['add form'])) {
_ctools_content_create_form_info($form_info, $plugin['add form'], $plugin, $subtype, $op);
}
}
@@ -578,7 +621,7 @@ function ctools_content_form($op, $form_info, &$form_state, $plugin, $subtype_na
if (!empty($subtype['edit form'])) {
_ctools_content_create_form_info($form_info, $subtype['edit form'], $subtype, $subtype, $op);
}
else if (!empty($plugin['edit form'])) {
elseif (!empty($plugin['edit form'])) {
_ctools_content_create_form_info($form_info, $plugin['edit form'], $plugin, $subtype, $op);
}
}
@@ -597,7 +640,7 @@ function _ctools_content_create_form_info(&$form_info, $info, $plugin, $subtype,
if (empty($subtype['title'])) {
$title = t('Configure');
}
else if ($op == 'add') {
elseif ($op == 'add') {
$title = t('Configure new !subtype_title', array('!subtype_title' => $subtype['title']));
}
else {
@@ -612,7 +655,7 @@ function _ctools_content_create_form_info(&$form_info, $info, $plugin, $subtype,
),
);
}
else if (is_array($info)) {
elseif (is_array($info)) {
$form_info['order'] = array();
$form_info['forms'] = array();
$count = 0;
@@ -663,7 +706,7 @@ function ctools_content_get_available_types($contexts = NULL, $has_content = FAL
foreach ($plugins as $id => $plugin) {
foreach (ctools_content_get_subtypes($plugin) as $subtype_id => $subtype) {
// exclude items that require content if we're saying we don't
// Exclude items that require content if we're saying we don't
// provide it.
if (!empty($subtype['requires content']) && !$has_content) {
continue;
@@ -687,6 +730,11 @@ function ctools_content_get_available_types($contexts = NULL, $has_content = FAL
}
}
// Check if the content type provides an access callback.
if (isset($subtype['create content access']) && function_exists($subtype['create content access']) && !$subtype['create content access']($plugin, $subtype)) {
continue;
}
// If we made it through all the tests, then we can use this content.
$available[$id][$subtype_id] = $subtype;
}
@@ -698,7 +746,6 @@ function ctools_content_get_available_types($contexts = NULL, $has_content = FAL
* Get an array of all content types that can be fed into the
* display editor for the add content list, regardless of
* availability.
*
*/
function ctools_content_get_all_types() {
$plugins = ctools_get_content_types();
@@ -23,68 +23,156 @@ function ctools_content_menu(&$items) {
/**
* Helper function for autocompletion of entity titles.
*/
function ctools_content_autocomplete_entity($type, $string = '') {
$entity = entity_get_info($type);
function ctools_content_autocomplete_entity($entity_type, $string = '') {
if ($string != '') {
// @todo verify the query logic here, it's untested.
// Set up the query
$query = db_select($entity['base table'], 'b');
if ($entity['entity keys']['label']) {
$query->fields('b', array($entity['entity keys']['id'], $entity['entity keys']['label']))->range(0, 10);
}
else {
$query->fields('b', array($entity['entity keys']['id']))->range(0, 10);
$entity_info = entity_get_info($entity_type);
if (!module_exists('entity')) {
module_load_include('inc', 'ctools', 'includes/entity-access');
_ctools_entity_access($entity_info, $entity_type);
}
// We must query all ids, because if every one of the 10 don't have access
// the user may never be able to autocomplete a node title.
$preg_matches = array();
$matches = array();
$match = preg_match('/\[id: (\d+)\]/', $string, $preg_matches);
if (!$match) {
$match = preg_match('/^id: (\d+)/', $string, $preg_matches);
}
// If an ID match was found, use that ID rather than the whole string.
if ($match) {
$query->condition('b.' . $entity['entity keys']['id'], $preg_matches[1]);
}
elseif ($entity['entity keys']['label']) {
$query->condition('b.' . $entity['entity keys']['label'], '%' . db_like($string) . '%', 'LIKE');
}
$matches = array();
if ($type == 'node') {
if (!user_access('bypass node access')) {
// If the user is able to view their own unpublished nodes, allow them
// to see these in addition to published nodes.
if (user_access('view own unpublished content')) {
$query->condition(db_or()
->condition('b.status', NODE_PUBLISHED)
->condition('b.uid', $GLOBALS['user']->uid)
);
}
else {
// If not, restrict the query to published nodes.
$query->condition('b.status', NODE_PUBLISHED);
}
}
$query->addTag('node_access');
$query->join('users', 'u', 'b.uid = u.uid');
$query->addField('u', 'name', 'name');
foreach ($query->execute() as $nodeish) {
$name = empty($nodeish->name) ? variable_get('anonymous', t('Anonymous')) : check_plain($nodeish->name);
$matches[$nodeish->title . " [id: $nodeish->nid]"] = '<span class="autocomplete_title">' . check_plain($nodeish->title) . '</span> <span class="autocomplete_user">(' . t('by @user', array('@user' => $name)) . ')</span>';
}
$entity_id = $preg_matches[1];
$results = _ctools_getReferencableEntities($entity_type, $entity_info, $entity_id, '=', 1);
}
else {
foreach ($query->execute() as $item) {
$id = $item->{$entity['entity keys']['id']};
if ($entity['entity keys']['label']) {
$matches[$item->{$entity['entity keys']['label']} . " [id: $id]"] = '<span class="autocomplete_title">' . check_plain($item->{$entity['entity keys']['label']}) . '</span>';
}
else {
$matches["[id: $id]"] = '<span class="autocomplete_title">' . check_plain($item->{$entity['entity keys']['id']}) . '</span>';
}
// We cannot find results if the entity doesn't have a label to search.
if (!isset($entity_info['entity keys']['label'])) {
drupal_json_output(array("[id: NULL]" => '<span class="autocomplete_title">' . t('Entity Type !entity_type does not support autocomplete search.', array('!entity_type' => $entity_type)) . '</span>'));
return;
}
$results = _ctools_getReferencableEntities($entity_type, $entity_info, $string, 'LIKE', 10);
}
foreach ($results as $entity_id => $result) {
$matches[$result['label'] . " [id: $entity_id]"] = '<span class="autocomplete_title">' . check_plain($result['label']) . '</span>';
$matches[$result['label'] . " [id: $entity_id]"] .= isset($result['bundle']) ? ' <span class="autocomplete_bundle">(' . check_plain($result['bundle']) . ')</span>' : '';
}
drupal_json_output($matches);
}
}
/**
* Use EntityReference_SelectionHandler_Generic class to build our search query.
*/
function _ctools_buildQuery($entity_type, $entity_info, $match = NULL, $match_operator = 'CONTAINS') {
$base_table = $entity_info['base table'];
$label_key = $entity_info['entity keys']['label'];
$query = db_select($base_table)
->fields($base_table, array($entity_info['entity keys']['id']));
if (isset($match)) {
if (isset($label_key)) {
$query->condition($base_table . '.' . $label_key, '%' . $match . '%', $match_operator);
}
// This should never happen, but double check just in case.
else {
return array();
}
}
// Add a generic entity access tag to the query.
$query->addTag('ctools');
// We have to perform two checks. First check is a query alter (with tags)
// in an attempt to only return results that have access. However, this is
// not full-proof since entities many not implement hook_access query tag.
// This is why we have a second check after entity load, before we display
// the label of an entity.
if ($entity_type == 'comment') {
// Adding the 'comment_access' tag is sadly insufficient for comments: core
// requires us to also know about the concept of 'published' and
// 'unpublished'.
if (!user_access('administer comments')) {
$query->condition('comment.status', COMMENT_PUBLISHED);
}
// Join to a node if the user does not have node access bypass permissions
// to obey node published permissions.
if (!user_access('bypass node access')) {
$node_alias = $query->innerJoin('node', 'n', '%alias.nid = comment.nid');
$query->condition($node_alias . '.status', NODE_PUBLISHED);
}
$query->addTag('node_access');
}
else {
$query->addTag($entity_type . '_access');
}
// Add the sort option.
if (isset($label_key)) {
$query->orderBy($base_table . '.' . $label_key, 'ASC');
}
return $query;
}
/**
* Private function to get referencable entities. Based on code from the
* Entity Reference module.
*/
function _ctools_getReferencableEntities($entity_type, $entity_info, $match = NULL, $match_operator = 'LIKE', $limit = 0) {
global $user;
$account = $user;
$options = array();
// We're an entity ID, return the id.
if (is_numeric($match) && $match_operator == '=') {
if ($entity = array_shift(entity_load($entity_type, array($match)))) {
if (isset($entity_info['access callback']) && function_exists($entity_info['access callback'])) {
if ($entity_info['access callback']('view', $entity, $account, $entity_type)) {
$label = entity_label($entity_type, $entity);
return array(
$match => array(
'label' => !empty($label) ? $label : $entity->{$entity_info['entity keys']['id']},
'bundle' => !empty($entity_info['entity keys']['bundle']) ? check_plain($entity->{$entity_info['entity keys']['bundle']}) : NULL,
),
);
}
}
}
// If you don't have access, or an access callback or a valid entity, just
// Return back the Entity ID.
return array(
$match => array(
'label' => $match,
'bundle' => NULL,
),
);
}
// We have matches, build a query to fetch the result.
if ($query = _ctools_buildQuery($entity_type, $entity_info, $match, $match_operator)) {
if ($limit > 0) {
$query->range(0, $limit);
}
$results = $query->execute();
if (!empty($results)) {
foreach ($results as $record) {
$entities = entity_load($entity_type, array($record->{$entity_info['entity keys']['id']}));
$entity = array_shift($entities);
if (isset($entity_info['access callback']) && function_exists($entity_info['access callback'])) {
if ($entity_info['access callback']('view', $entity, $account, $entity_type)) {
$label = entity_label($entity_type, $entity);
$options[$record->{$entity_info['entity keys']['id']}] = array(
'label' => !empty($label) ? $label : $entity->{$entity_info['entity keys']['id']},
'bundle' => !empty($entity_info['entity keys']['bundle']) ? check_plain($entity->{$entity_info['entity keys']['bundle']}) : NULL,
);
}
}
}
}
return $options;
}
return array();
}
@@ -14,4 +14,4 @@ function ctools_content_plugin_type(&$items) {
'path' => drupal_get_path('module', 'ctools') . '/includes',
),
);
}
}
@@ -245,10 +245,10 @@ function ctools_access_admin_form_submit($form, &$form_state) {
// --------------------------------------------------------------------------
// AJAX menu entry points.
/**
* AJAX callback to add a new access test to the list.
*/
function ctools_access_ajax_add($fragment = NULL, $name = NULL) {
ctools_include('ajax');
ctools_include('modal');
@@ -263,7 +263,7 @@ function ctools_access_ajax_add($fragment = NULL, $name = NULL) {
ctools_ajax_render_error();
}
// Separate the fragment into 'module' and 'argument'
// Separate the fragment into 'module' and 'argument'.
if (strpos($fragment, '-') === FALSE) {
$module = $fragment;
$argument = NULL;
@@ -279,7 +279,7 @@ function ctools_access_ajax_add($fragment = NULL, $name = NULL) {
list($access, $contexts) = $function($argument);
// Make sure we have the logged in user context
// Make sure we have the logged in user context.
if (!isset($contexts['logged-in-user'])) {
$contexts['logged-in-user'] = ctools_access_get_loggedin_context();
}
@@ -306,6 +306,9 @@ function ctools_access_ajax_add($fragment = NULL, $name = NULL) {
);
$output = ctools_modal_form_wrapper('ctools_access_ajax_edit_item', $form_state);
$access = $form_state['access'];
$access['plugins'][$id] = $form_state['test'];
if (!isset($output[0])) {
$function = $module . '_ctools_access_set';
if (function_exists($function)) {
@@ -333,7 +336,7 @@ function ctools_access_ajax_edit($fragment = NULL, $id = NULL) {
ctools_ajax_render_error();
}
// Separate the fragment into 'module' and 'argument'
// Separate the fragment into 'module' and 'argument'.
if (strpos($fragment, '-') === FALSE) {
$module = $fragment;
$argument = NULL;
@@ -353,7 +356,7 @@ function ctools_access_ajax_edit($fragment = NULL, $id = NULL) {
ctools_ajax_render_error();
}
// Make sure we have the logged in user context
// Make sure we have the logged in user context.
if (!isset($contexts['logged-in-user'])) {
$contexts['logged-in-user'] = ctools_access_get_loggedin_context();
}
@@ -367,12 +370,14 @@ function ctools_access_ajax_edit($fragment = NULL, $id = NULL) {
'contexts' => $contexts,
'title' => t('Edit criteria'),
'ajax' => TRUE,
'ajax' => TRUE,
'modal' => TRUE,
'modal return' => TRUE,
);
$output = ctools_modal_form_wrapper('ctools_access_ajax_edit_item', $form_state);
$access = $form_state['access'];
$access['plugins'][$id] = $form_state['test'];
if (!isset($output[0])) {
$function = $module . '_ctools_access_set';
if (function_exists($function)) {
@@ -452,7 +457,7 @@ function ctools_access_ajax_delete($fragment = NULL, $id = NULL) {
ajax_render_error();
}
// Separate the fragment into 'module' and 'argument'
// Separate the fragment into 'module' and 'argument'.
if (strpos($fragment, '-') === FALSE) {
$module = $fragment;
$argument = NULL;
@@ -472,7 +477,7 @@ function ctools_access_ajax_delete($fragment = NULL, $id = NULL) {
unset($access['plugins'][$id]);
}
// re-cache
// re-cache.
$function = $module . '_ctools_access_set';
if (function_exists($function)) {
$function($argument, $access);
@@ -376,11 +376,11 @@ function ctools_context_ajax_item_add($mechanism = NULL, $type = NULL, $cache_ke
'path' => "ctools/context/ajax/add/$mechanism/$type/$cache_key/$name/%step",
'show cancel' => TRUE,
'default form' => 'ctools_edit_context_form_defaults',
'auto caching' => TRUE,
'auto cache' => TRUE,
'cache mechanism' => $mechanism,
'cache key' => $cache_key,
// This is stating what the cache will be referred to in $form_state
'cache storage' => 'object',
'cache location' => 'object',
);
if ($type == 'requiredcontext') {
@@ -395,7 +395,7 @@ function ctools_context_ajax_item_add($mechanism = NULL, $type = NULL, $cache_ke
if (!empty($form_state['cancel'])) {
$output = array(ctools_modal_command_dismiss());
}
else if (!empty($form_state['complete'])) {
elseif (!empty($form_state['complete'])) {
// Successful submit -- move temporary data to location.
// Create a reference to the place our context lives. Since this is fairly
@@ -416,12 +416,20 @@ function ctools_context_ajax_item_add($mechanism = NULL, $type = NULL, $cache_ke
ctools_cache_operation($mechanism, $cache_key, 'finalize', $object);
// Very irritating way to update the form for our contexts.
$arg_form_state = array('values' => array());
$arg_form_state = form_state_defaults() + array(
'values' => array(),
'process_input' => FALSE,
'complete form' => array(),
);
$rel_form_state = $arg_form_state;
$arg_form = array(
'#post' => array(),
'#programmed' => FALSE,
'#tree' => FALSE,
'#parents' => array(),
'#array_parents' => array(),
);
// Build a chunk of the form to merge into the displayed form
@@ -446,6 +454,8 @@ function ctools_context_ajax_item_add($mechanism = NULL, $type = NULL, $cache_ke
'#post' => array(),
'#programmed' => FALSE,
'#tree' => FALSE,
'#parents' => array(),
'#array_parents' => array(),
);
$rel_form['relationship'] = array(
@@ -460,7 +470,7 @@ function ctools_context_ajax_item_add($mechanism = NULL, $type = NULL, $cache_ke
$output = array();
if (!empty($available_relationships)) {
ctools_context_add_item_table_buttons('relationship', $mechanism, $rel_form, $available_relationships);
$rel_form = form_builder('dummy_form_id', $rel_form, $arg_form_state);
$rel_form = form_builder('dummy_form_id', $rel_form, $rel_form_state);
$output[] = ajax_command_replace('div#ctools-relationships-table div.buttons', drupal_render($rel_form));
}
@@ -551,11 +561,11 @@ function ctools_context_ajax_item_edit($mechanism = NULL, $type = NULL, $cache_k
'path' => "ctools/context/ajax/configure/$mechanism/$type/$cache_key/$position/%step",
'show cancel' => TRUE,
'default form' => 'ctools_edit_context_form_defaults',
'auto caching' => TRUE,
'auto cache' => TRUE,
'cache mechanism' => $mechanism,
'cache key' => $cache_key,
// This is stating what the cache will be referred to in $form_state
'cache storage' => 'object',
'cache location' => 'object',
);
if ($type == 'requiredcontext') {
@@ -570,7 +580,7 @@ function ctools_context_ajax_item_edit($mechanism = NULL, $type = NULL, $cache_k
if (!empty($form_state['cancel'])) {
$output = array(ctools_modal_command_dismiss());
}
else if (!empty($form_state['complete'])) {
elseif (!empty($form_state['complete'])) {
// successful submit
$ref[$position] = $conf;
if (isset($object->temporary)) {
@@ -582,8 +592,16 @@ function ctools_context_ajax_item_edit($mechanism = NULL, $type = NULL, $cache_k
$output = array();
$output[] = ctools_modal_command_dismiss();
$arg_form_state = form_state_defaults() + array(
'values' => array(),
'process_input' => FALSE,
'complete form' => array(),
);
$arg_form = array(
'#post' => array(),
'#parents' => array(),
'#array_parents' => array(),
'#programmed' => FALSE,
'#tree' => FALSE,
);
@@ -639,7 +657,7 @@ function ctools_context_get_defaults($plugin_definition, $object, $type) {
if (isset($plugin_definition['defaults'])) {
$defaults = $plugin_definition['defaults'];
}
else if (isset($subtype['defaults'])) {
elseif (isset($subtype['defaults'])) {
$defaults = $subtype['defaults'];
}
@@ -649,7 +667,7 @@ function ctools_context_get_defaults($plugin_definition, $object, $type) {
$conf += $settings;
}
}
else if (is_array($defaults)) {
elseif (is_array($defaults)) {
$conf += $defaults;
}
}
@@ -718,6 +736,15 @@ function ctools_edit_context_form_defaults($form, &$form_state) {
'#default_value' => $conf['keyword'],
);
if ($type_info['key'] == 'requiredcontexts') {
$form['optional'] = array(
'#type' => 'checkbox',
'#title' => t('Context is optional'),
'#default_value' => !empty($form_state['conf']['optional']),
'#description' => t('This context need not be present for the component to function.'),
);
}
$form['#submit'][] = 'ctools_edit_context_form_defaults_submit';
return $form;
@@ -734,6 +761,9 @@ function ctools_edit_context_form_defaults_submit(&$form, &$form_state) {
$form_state['conf']['default'] = $form_state['values']['default'];
$form_state['conf']['title'] = $form_state['values']['title'];
}
if ($form_state['type info']['key'] == 'requiredcontexts') {
$form_state['conf']['optional'] = $form_state['values']['optional'];
}
$form_state['conf']['identifier'] = $form_state['values']['identifier'];
$form_state['conf']['keyword'] = $form_state['values']['keyword'];
@@ -4,9 +4,9 @@
* @file
* Support for creating 'context' type task handlers.
*
* Context task handlers expect the task to provide 0 or more contexts. The
* task handler should use those contexts as selection rules, as well as
* rendering with them.
* Context task handlers expect the task to provide 0 or more contexts. The task
* handler should use those contexts as selection rules, as well as rendering
* with them.
*
* The functions and forms in this file should be common to every context type
* task handler made.
@@ -31,6 +31,7 @@
* If TRUE then this renderer owns the page and can use theme('page')
* for no blocks; if false, output is returned regardless of any no
* blocks settings.
*
* @return
* Either the output or NULL if there was output, FALSE if no handler
* accepted the task. If $page is FALSE then the $info block is returned instead.
@@ -84,7 +85,7 @@ function ctools_context_handler_get_render_handler($task, $subtask, $handlers, $
*/
function ctools_context_handler_default_test($handler, $base_contexts, $args) {
ctools_include('context');
// Add my contexts
// Add my contexts.
$contexts = ctools_context_handler_get_handler_contexts($base_contexts, $handler);
// Test.
@@ -128,7 +129,7 @@ function ctools_context_handler_render_handler($task, $subtask, $handler, $conte
'contexts' => $contexts,
'task' => $task,
'subtask' => $subtask,
'handler' => $handler
'handler' => $handler,
);
drupal_alter('ctools_render', $info, $page, $context);
@@ -141,12 +142,15 @@ function ctools_context_handler_render_handler($task, $subtask, $handler, $conte
switch ($info['response code']) {
case 403:
return MENU_ACCESS_DENIED;
case 404:
return MENU_NOT_FOUND;
case 410:
drupal_add_http_header('Status', '410 Gone');
drupal_exit();
break;
case 301:
case 302:
case 303:
@@ -161,8 +165,8 @@ function ctools_context_handler_render_handler($task, $subtask, $handler, $conte
'query' => $info['query'],
'fragment' => $info['fragment'],
);
return drupal_goto($info['destination'], $options, $info['response code']);
// @todo -- should other response codes be supported here?
drupal_goto($info['destination'], $options, $info['response code']);
// @todo -- should other response codes be supported here?
}
}
@@ -222,7 +226,7 @@ function ctools_context_handler_render_handler($task, $subtask, $handler, $conte
}
/**
* Default function to provide contextual link for a task as defined by the handler.
* Provides contextual link for a task as defined by the handler.
*
* This provides a simple link to th main content operation and is suitable
* for most normal handlers. Setting 'contextual link' to a function overrides
@@ -241,7 +245,7 @@ function ctools_task_handler_default_contextual_link($handler, $plugin, $context
if (is_array($plugin['tab operation'])) {
$trail = $plugin['tab operation'];
}
else if (function_exists($plugin['tab operation'])) {
elseif (function_exists($plugin['tab operation'])) {
$trail = $plugin['tab operation']($handler, $contexts, $args);
}
}
@@ -251,7 +255,8 @@ function ctools_task_handler_default_contextual_link($handler, $plugin, $context
'href' => $path,
'title' => $title,
'query' => drupal_get_destination(),
));
),
);
return $links;
}
@@ -259,17 +264,22 @@ function ctools_task_handler_default_contextual_link($handler, $plugin, $context
/**
* Called to execute actions that should happen before a handler is rendered.
*/
function ctools_context_handler_pre_render($handler, $contexts, $args) { }
function ctools_context_handler_pre_render($handler, $contexts, $args) {
foreach (module_implements('ctools_context_handler_pre_render') as $module) {
$function = $module . '_ctools_context_handler_pre_render';
$function($handler, $contexts, $args);
}
}
/**
* Compare arguments to contexts for selection purposes.
*
* @param $handler
* @param object $handler
* The handler in question.
* @param $contexts
* @param object $contexts
* The context objects provided by the task.
*
* @return
* @return bool
* TRUE if these contexts match the selection rules. NULL or FALSE
* otherwise.
*/
@@ -288,12 +298,15 @@ function ctools_context_handler_select($handler, $contexts) {
* These summary strings are used to communicate to the user what
* arguments the task handlers are selecting.
*
* @param $task
* @param object $task
* The loaded task plugin.
* @param $subtask
* @param object $subtask
* The subtask id.
* @param $handler
* @param object $handler
* The handler to be checked.
*
* @return array
* Returns array of summary strings for arguments selected by task handlers.
*/
function ctools_context_handler_summary($task, $subtask, $handler) {
if (empty($handler->conf['access']['plugins'])) {
@@ -320,7 +333,6 @@ function ctools_context_handler_summary($task, $subtask, $handler) {
// the task handler, for example) but sometimes we need them separately
// (when a task has contexts loaded and is trying out the task handlers,
// for example). Therefore there are two paths we can take to getting contexts.
/**
* Load the contexts for a task, using arguments.
*
@@ -368,7 +380,7 @@ function ctools_context_handler_get_all_contexts($task, $subtask, $handler) {
* expects things in a certain, kind of clunky format.
*/
function ctools_context_handler_get_handler_object($handler) {
$object = new stdClass;
$object = new stdClass();
$object->name = $handler->name;
$object->contexts = isset($handler->conf['contexts']) ? $handler->conf['contexts'] : array();
$object->relationships = isset($handler->conf['relationships']) ? $handler->conf['relationships'] : array();
@@ -382,7 +394,7 @@ function ctools_context_handler_get_handler_object($handler) {
* arguments from the task.
*/
function ctools_context_handler_get_task_object($task, $subtask, $handler) {
$object = new stdClass;
$object = new stdClass();
$object->name = !empty($handler->name) ? $handler->name : 'temp';
$object->base_contexts = ctools_context_handler_get_base_contexts($task, $subtask, TRUE);
$object->arguments = ctools_context_handler_get_task_arguments($task, $subtask);
@@ -456,7 +468,7 @@ function ctools_context_handler_edit_criteria($form, &$form_state) {
ctools_modal_add_plugin_js(ctools_get_access_plugins());
ctools_include('context-access-admin');
$form_state['module'] = (isset($form_state['module'])) ? $form_state['module'] : 'page_manager_task_handler';
// Encode a bunch of info into the argument so we can get our cache later
// Encode a bunch of info into the argument so we can get our cache later.
$form_state['callback argument'] = $form_state['task_name'] . '*' . $form_state['handler']->name;
$form_state['access'] = $form_state['handler']->conf['access'];
$form_state['no buttons'] = TRUE;
@@ -472,7 +484,7 @@ function ctools_context_handler_edit_criteria($form, &$form_state) {
}
/**
* Submit handler for rules selection
* Submit handler for rules selection.
*/
function ctools_context_handler_edit_criteria_submit(&$form, &$form_state) {
$form_state['handler']->conf['access']['logic'] = $form_state['values']['logic'];
@@ -537,4 +549,3 @@ function ctools_context_handler_edit_context_submit(&$form, &$form_state) {
unset($form_state['page']->context_cache[$cache_name]);
}
}
File diff suppressed because it is too large Load Diff
@@ -25,7 +25,7 @@ function ctools_context_menu(&$items) {
'page callback' => 'ctools_context_ajax_item_delete',
) + $base;
// For the access system
// For the access system.
$base['file'] = 'includes/context-access-admin.inc';
$items['ctools/context/ajax/access/add'] = array(
'page callback' => 'ctools_access_ajax_add',
@@ -19,7 +19,6 @@ function ctools_context_theme(&$theme) {
);
$theme['ctools_context_item_form'] = array(
'render element' => 'form',
// 'variables' => array('form' => NULL),
'file' => 'includes/context.theme.inc',
);
$theme['ctools_context_item_row'] = array(
@@ -27,7 +26,7 @@ function ctools_context_theme(&$theme) {
'file' => 'includes/context.theme.inc',
);
// For the access plugin
// For the access plugin.
$theme['ctools_access_admin_add'] = array(
'render element' => 'form',
'file' => 'includes/context-access-admin.inc',
@@ -62,10 +61,10 @@ function theme_ctools_context_item_row($vars) {
function theme_ctools_context_item_form($vars) {
$form = $vars['form'];
$output = '';
$type = $form['#ctools_context_type'];
$module = $form['#ctools_context_module'];
$cache_key = $form['#cache_key'];
$output = '';
$type = $form['#ctools_context_type'];
$module = $form['#ctools_context_module'];
$cache_key = $form['#cache_key'];
$type_info = ctools_context_info($type);
@@ -104,17 +103,17 @@ function theme_ctools_context_item_form($vars) {
if (!empty($form['buttons'])) {
// Display the add context item.
$row = array();
$row[] = array('data' => render($form['buttons'][$type]['item']), 'class' => array('title'));
$row[] = array('data' => render($form['buttons'][$type]['add']), 'class' => array('add'), 'width' => "60%");
$output .= '<div class="buttons">';
$output .= render($form['buttons'][$type]);
$theme_vars = array();
$theme_vars['header'] = array();
$theme_vars['rows'] = array($row);
$row = array();
$row[] = array('data' => render($form['buttons'][$type]['item']), 'class' => array('title'));
$row[] = array('data' => render($form['buttons'][$type]['add']), 'class' => array('add'), 'width' => "60%");
$output .= '<div class="buttons">';
$output .= render($form['buttons'][$type]);
$theme_vars = array();
$theme_vars['header'] = array();
$theme_vars['rows'] = array($row);
$theme_vars['attributes'] = array('id' => $type . '-add-table');
$output .= theme('table', $theme_vars);
$output .= '</div>';
$output .= theme('table', $theme_vars);
$output .= '</div>';
}
if (!empty($form['description'])) {
$output .= render($form['description']);
@@ -139,7 +138,7 @@ function theme_ctools_context_list($vars) {
$description = (!empty($vars['description'])) ? $vars['description'] : NULL;
$titles = array();
$output = '';
$count = 1;
$count = 1;
$contexts = ctools_context_load_contexts($object);
@@ -209,7 +208,7 @@ function theme_ctools_context_list($vars) {
}
}
// And relationships
// And relationships.
if (!empty($object->relationships)) {
foreach ($object->relationships as $relationship) {
$output .= '<tr>';
@@ -253,15 +252,15 @@ function theme_ctools_context_list($vars) {
}
/**
* ctools_context_list() but not in a table format because tabledrag
* won't let us have tables within tables and still drag.
* The ctools_context_list() function but not in a table format because
* tabledrag won't let us have tables within tables and still drag.
*/
function theme_ctools_context_list_no_table($vars) {
$object = $vars['object'];
ctools_add_css('context');
$titles = array();
$output = '';
$count = 1;
$count = 1;
// Describe 'built in' contexts.
if (!empty($object->base_contexts)) {
foreach ($object->base_contexts as $id => $context) {
@@ -312,7 +311,7 @@ function theme_ctools_context_list_no_table($vars) {
$count++;
}
}
// And relationships
// And relationships.
if (!empty($object->relationships)) {
foreach ($object->relationships as $relationship) {
$output .= '<div class="ctools-context-holder clearfix">';
@@ -341,4 +340,3 @@ function theme_ctools_context_list_no_table($vars) {
return $output;
}
@@ -0,0 +1,52 @@
<?php
/**
* @file
* Custom cache implementation for the CTools CSS cache.
*/
class CToolsCssCache implements DrupalCacheInterface {
/**
* {@inheritdoc}
*/
public function clear($cid = NULL, $wildcard = FALSE) {
// Only clear the caches if the wildcard is set, this ensures that the cache
// is only cleared when the full caches are cleared manually (eg by invoking
// drupal_flush_all_caches()), and not on a cron run.
// @see drupal_flush_all_caches()
// @see system_cron()
if ($wildcard) {
ctools_include('css');
ctools_css_flush_caches();
}
}
/**
* {@inheritdoc}
*/
public function get($cid) {
return FALSE;
}
/**
* {@inheritdoc}
*/
public function getMultiple(&$cids) {
return array();
}
/**
* {@inheritdoc}
*/
public function isEmpty() {
return FALSE;
}
/**
* {@inheritdoc}
*/
public function set($cid, $data, $expire = CACHE_PERMANENT) {
}
}
@@ -1,6 +1,6 @@
<?php
/*
/**
* @file
* CSS filtering functions. Contains a disassembler, filter, compressor, and
* decompressor.
@@ -77,9 +77,9 @@ function ctools_css_store($id, $css, $filter = TRUE) {
$filename = ctools_css_cache($css, $filter);
db_insert('ctools_css_cache')
db_merge('ctools_css_cache')
->key(array('cid' => $id))
->fields(array(
'cid' => $id,
'filename' => $filename,
'css' => $css,
'filter' => intval($filter),
@@ -149,11 +149,11 @@ function ctools_css_clear($id) {
*
* @param $css
* A chunk of well-formed CSS text to cache.
* @param $filter
* @param bool $filter
* If TRUE the css will be filtered. If FALSE the text will be cached
* as-is.
*
* @return $filename
* @return string
* The filename the CSS will be cached in.
*/
function ctools_css_cache($css, $filter = TRUE) {
@@ -164,7 +164,6 @@ function ctools_css_cache($css, $filter = TRUE) {
// Create the css/ within the files folder.
$path = 'public://ctools/css';
if (!file_prepare_directory($path, FILE_CREATE_DIRECTORY | FILE_MODIFY_PERMISSIONS)) {
// if (!file_prepare_directory($path, FILE_CREATE_DIRECTORY)) {
drupal_set_message(t('Unable to create CTools CSS cache directory. Check the permissions on your files directory.'), 'error');
return;
}
@@ -172,10 +171,12 @@ function ctools_css_cache($css, $filter = TRUE) {
// @todo Is this slow? Does it matter if it is?
$filename = $path . '/' . md5($css) . '.css';
// This will do renames if the file already exists, ensuring we don't
// accidentally overwrite other files who share the same md5. Yes this
// is a very miniscule chance but it's safe.
$filename = file_unmanaged_save_data($css, $filename);
// Generally md5 is considered unique enough to sign file downloads.
// So this replaces already existing files based on the assumption that two
// files with the same hash are identical content wise.
// If we rename, the cache folder can potentially fill up with thousands of
// files with the same content.
$filename = file_unmanaged_save_data($css, $filename, FILE_EXISTS_REPLACE);
return $filename;
}
@@ -211,7 +212,7 @@ function ctools_css_filter($css, $compressed = TRUE) {
* An array of css data, as produced by @see ctools_css_disassemble()
* disassembler and the @see ctools_css_filter_css_data() filter.
*
* @return string $css
* @return string
* css optimized for human viewing.
*/
function ctools_css_assemble($css_data) {
@@ -241,7 +242,7 @@ function ctools_css_assemble($css_data) {
* An array of css data, as produced by @see ctools_css_disassemble()
* disassembler and the @see ctools_css_filter_css_data() filter.
*
* @return string $css
* @return string
* css optimized for use.
*/
function ctools_css_compress($css_data) {
@@ -277,7 +278,7 @@ function ctools_css_compress($css_data) {
* @param string $css
* A string containing the css to be disassembled.
*
* @return array $disassembled_css
* @return array
* An array of disassembled, slightly cleaned-up/formatted css statements.
*/
function ctools_css_disassemble($css) {
@@ -383,7 +384,6 @@ function _ctools_css_disassemble_declaration($declaration) {
* An array of disassembled, filtered CSS.
*/
function ctools_css_filter_css_data($css, $allowed_properties = array(), $allowed_values = array(), $allowed_values_regex = '', $disallowed_values_regex = '') {
//function ctools_css_filter_css_data($css, &$filtered = NULL, $allowed_properties = array(), $allowed_values = array(), $allowed_values_regex = '', $disallowed_values_regex = '') {
// Retrieve the default list of allowed properties if none is provided.
$allowed_properties = !empty($allowed_properties) ? $allowed_properties : ctools_css_filter_default_allowed_properties();
// Retrieve the default list of allowed values if none is provided.
@@ -391,19 +391,18 @@ function ctools_css_filter_css_data($css, $allowed_properties = array(), $allowe
// Define allowed values regex if none is provided.
$allowed_values_regex = !empty($allowed_values_regex) ? $allowed_values_regex : '/(#[0-9a-f]+|rgb\(\d+%?,\d*%?,?\d*%?\)?|\d{0,2}\.?\d{0,2}(cm|em|ex|in|mm|pc|pt|px|%|,|\))?)/';
// Define disallowed url() value contents, if none is provided.
// $disallowed_values_regex = !empty($disallowed_values_regex) ? $disallowed_values_regex : '/[url|expression]\s*\(\s*[^\s)]+?\s*\)\s*/';
$disallowed_values_regex = !empty($disallowed_values_regex) ? $disallowed_values_regex : '/(url|expression)/';
foreach ($css as $selector_str => $declaration) {
foreach ($declaration as $property => $value) {
if (!in_array($property, $allowed_properties)) {
// $filtered['properties'][$selector_str][$property] = $value;
// $filtered['properties'][$selector_str][$property] = $value;.
unset($css[$selector_str][$property]);
continue;
}
$value = str_replace('!important', '', $value);
if (preg_match($disallowed_values_regex, $value) || !(in_array($value, $allowed_values) || preg_match($allowed_values_regex, $value))) {
// $filtered['values'][$selector_str][$property] = $value;
// $filtered['values'][$selector_str][$property] = $value;.
unset($css[$selector_str][$property]);
continue;
}
@@ -44,7 +44,7 @@
*
* A fuller example, that hides the menu title when no menu is selected:
* @code
*function ctools_dependent_example() {
* function ctools_dependent_example() {
* $form = array();
* $form['menu'] = array(
* '#type' => 'fieldset',
@@ -72,12 +72,12 @@
* );
*
* return system_settings_form($form);
*}
* }
* @endcode
*
* An example for hiding checkboxes using #prefix and #suffix:
* @code
*function ctools_dependent_example_checkbox() {
* function ctools_dependent_example_checkbox() {
* $form = array();
* $form['object'] = array(
* '#type' => 'fieldset',
@@ -111,7 +111,7 @@
* );
*
* return system_settings_form($form);
*}
* }
* @endcode
*
* Deprecated:
@@ -125,7 +125,6 @@
/**
* Process callback to add dependency to form items.
*
*/
function ctools_dependent_process($element, &$form_state, &$form) {
return $element;
@@ -75,7 +75,7 @@ function theme_links__ctools_dropbutton($vars) {
if (!empty($vars['links'])) {
$is_drop_button = (count($vars['links']) > 1);
// Add needed files
// Add needed files.
if ($is_drop_button) {
ctools_add_js('dropbutton');
ctools_add_css('dropbutton');
@@ -86,7 +86,7 @@ function theme_links__ctools_dropbutton($vars) {
static $id = 0;
$id++;
// Wrapping div
// Wrapping div.
$class = 'ctools-no-js';
$class .= ($is_drop_button) ? ' ctools-dropbutton' : '';
$class .= ' ctools-button';
@@ -98,21 +98,22 @@ function theme_links__ctools_dropbutton($vars) {
$output .= '<div class="' . $class . '" id="ctools-button-' . $id . '">';
// Add a twisty if this is a dropbutton
// Add a twisty if this is a dropbutton.
if ($is_drop_button) {
$vars['title'] = ($vars['title'] ? check_plain($vars['title']) : t('open'));
$output .= '<div class="ctools-link">';
if ($vars['image']) {
$output .= '<a href="#" class="ctools-twisty ctools-image">' . $vars['title'] . '</a>';
$output .= '<a href="#" class="ctools-twisty ctools-image"><span class="element-invisible">' . $vars['title'] . '</span></a>';
}
else {
$output .= '<a href="#" class="ctools-twisty ctools-text">' . $vars['title'] . '</a>';
$output .= '<a href="#" class="ctools-twisty ctools-text"><span class="element-invisible">' . $vars['title'] . '</span></a>';
}
$output .= '</div>'; // ctools-link
// ctools-link.
$output .= '</div>';
}
// The button content
// The button content.
$output .= '<div class="ctools-content">';
// Check for attributes. theme_links expects an array().
@@ -132,12 +133,11 @@ function theme_links__ctools_dropbutton($vars) {
// Call theme_links to render the list of links.
$output .= theme_links(array('links' => $vars['links'], 'attributes' => $vars['attributes'], 'heading' => ''));
$output .= '</div>'; // ctools-content
$output .= '</div>'; // ctools-dropbutton
$output .= '</div>'; // ctools-content.
$output .= '</div>'; // ctools-dropbutton.
return $output;
}
else {
return '';
}
}
@@ -44,20 +44,21 @@ function ctools_dropdown_theme(&$items) {
/**
* Create a dropdown menu.
*
* @param $title
* The text to place in the clickable area to activate the dropdown.
* @param $links
* A list of links to provide within the dropdown, suitable for use
* in via Drupal's theme('links').
* @param $image
* If true, the dropdown link is an image and will not get extra decorations
* that a text dropdown link will.
* @param $class
* An optional class to add to the dropdown's container div to allow you
* to style a single dropdown however you like without interfering with
* other dropdowns.
* @param array $variables
* An associative array containing:
* - title: The text to place in the clickable area to activate the dropdown.
* - links: A list of links to provide within the dropdown, suitable for use
* in via Drupal's theme('links').
* - image: If true, the dropdown link is an image and will not get extra
* decorations that a text dropdown link will.
* - class: An optional class to add to the dropdown's container div to allow
* you to style a single dropdown however you like without interfering with
* other dropdowns.
*
* @return string
* Returns HTML for a language configuration form.
*/
function theme_ctools_dropdown($vars) {
function theme_ctools_dropdown($vars) {
// Provide a unique identifier for every dropdown on the page.
static $id = 0;
$id++;
@@ -67,9 +68,7 @@ function theme_ctools_dropdown($vars) {
ctools_add_js('dropdown');
ctools_add_css('dropdown');
$output = '';
$output .= '<div class="' . $class . '" id="ctools-dropdown-' . $id . '">';
$output = '<div class="' . $class . '" id="ctools-dropdown-' . $id . '">';
$output .= '<div class="ctools-dropdown-link-wrapper">';
if ($vars['image']) {
$output .= '<a href="#" class="ctools-dropdown-link ctools-dropdown-image-link">' . $vars['title'] . '</a>';
@@ -77,14 +76,13 @@ function theme_ctools_dropdown($vars) {
else {
$output .= '<a href="#" class="ctools-dropdown-link ctools-dropdown-text-link">' . check_plain($vars['title']) . '</a>';
}
$output .= '</div>'; // wrapper
$output .= '</div>';
$output .= '<div class="ctools-dropdown-container-wrapper">';
$output .= '<div class="ctools-dropdown-container">';
$output .= theme_links(array('links' => $vars['links'], 'attributes' => array(), 'heading' => ''));
$output .= '</div>'; // container
$output .= '</div>'; // container wrapper
$output .= '</div>'; // dropdown
$output .= '</div>';
$output .= '</div>';
$output .= '</div>';
return $output;
}
@@ -0,0 +1,154 @@
<?php
/**
* @file
* Provides various callbacks for the whole core module integration.
* This is a copy of Entity API's functionality for use when Entity API isn't
* Enabled, and only works on view functions.
*/
/**
* Core hack to include entity api-esque 'access callback' functions to core
* entities without needing to rely on entity api.
* Exception: We don't touch file entity. You must have entity API enabled to
* view files.
*/
function _ctools_entity_access(&$entity_info, $entity_type) {
// If the access callback is already set, don't change anything.
if (isset($entity_info['access callback'])) {
return;
}
switch ($entity_type) {
case 'node':
// Sad panda, we don't use Entity API, lets manually add access callbacks.
$entity_info['access callback'] = 'ctools_metadata_no_hook_node_access';
break;
case 'user':
$entity_info['access callback'] = 'ctools_metadata_user_access';
break;
case 'comment':
if (module_exists('comment')) {
$entity_info['access callback'] = 'ctools_metadata_comment_access';
}
break;
case 'taxonomy_term':
if (module_exists('taxonomy')) {
$entity_info['access callback'] = 'ctools_metadata_taxonomy_access';
}
break;
case 'taxonomy_vocabulary':
if (module_exists('taxonomy')) {
$entity_info['access callback'] = 'ctools_metadata_taxonomy_access';
}
break;
}
}
/**
* Access callback for the node entity.
*
* This function does not implement hook_node_access(), thus it may not be
* called ctools_metadata_node_access().
*
* @see entity_access()
*
* @param $op
* The operation being performed. One of 'view', 'update', 'create' or
* 'delete'.
* @param $node
* A node to check access for. Must be a node object. Must have nid,
* except in the case of 'create' operations.
* @param $account
* The user to check for. Leave it to NULL to check for the global user.
*
* @throws EntityMalformedException
*
* @return bool
* TRUE if access is allowed, FALSE otherwise.
*/
function ctools_metadata_no_hook_node_access($op, $node = NULL, $account = NULL) {
// First deal with the case where a $node is provided.
if (isset($node)) {
// If a non-default revision is given, incorporate revision access.
$default_revision = node_load($node->nid);
if ($node->vid !== $default_revision->vid) {
return _node_revision_access($node, $op, $account);
}
else {
return node_access($op, $node, $account);
}
}
// No node is provided. Check for access to all nodes.
if (user_access('bypass node access', $account)) {
return TRUE;
}
if (!user_access('access content', $account)) {
return FALSE;
}
if ($op == 'view' && node_access_view_all_nodes($account)) {
return TRUE;
}
return FALSE;
}
/**
* Access callback for the user entity.
*/
function ctools_metadata_user_access($op, $entity = NULL, $account = NULL, $entity_type) {
$account = isset($account) ? $account : $GLOBALS['user'];
// Grant access to the users own user account and to the anonymous one.
if (isset($entity) && $op != 'delete' && (($entity->uid == $account->uid && $entity->uid) || (!$entity->uid && $op == 'view'))) {
return TRUE;
}
if (user_access('administer users', $account) || user_access('access user profiles', $account) && $op == 'view' && $entity->status) {
return TRUE;
}
return FALSE;
}
/**
* Access callback for the comment entity.
*/
function ctools_metadata_comment_access($op, $entity = NULL, $account = NULL) {
// When determining access to a comment, if comment has an associated node,
// the user must be able to view the node in order to access the comment.
if (isset($entity->nid)) {
if (!node_access('view', node_load($entity->nid), $account)) {
return FALSE;
}
}
// Comment administrators are allowed to perform all operations on all
// comments.
if (user_access('administer comments', $account)) {
return TRUE;
}
// Unpublished comments can never be accessed by non-admins.
if (isset($entity->status) && $entity->status == COMMENT_NOT_PUBLISHED) {
return FALSE;
}
if (user_access('access comments', $account) && $op == 'view') {
return TRUE;
}
return FALSE;
}
/**
* Access callback for the taxonomy entities.
*/
function ctools_metadata_taxonomy_access($op, $entity = NULL, $account = NULL, $entity_type) {
if ($entity_type == 'taxonomy_vocabulary') {
return user_access('administer taxonomy', $account);
}
if (user_access('administer taxonomy', $account) || user_access('access content', $account) && $op == 'view') {
return TRUE;
}
return FALSE;
}
@@ -81,7 +81,6 @@ function ctools_export_ui_process(&$plugin, $info) {
// Add some default fields that appear often in exports
// If these use different keys they can easily be specified in the
// $plugin.
if (empty($plugin['export']['admin_title']) && !empty($schema['fields']['admin_title'])) {
$plugin['export']['admin_title'] = 'admin_title';
}
@@ -297,7 +296,6 @@ function ctools_export_ui_process(&$plugin, $info) {
);
// Define strings.
// For all strings, %title may be filled in at a later time via str_replace
// since we do not know the title now.
$plugin['strings'] += array(
@@ -335,7 +333,7 @@ function ctools_export_ui_process(&$plugin, $info) {
$plugin['strings']['confirmation']['delete'] += array(
'question' => t('Are you sure you want to delete %title?'),
'information' => t('This action will permanently remove this item from your database..'),
'information' => t('This action will permanently remove this item from your database.'),
'success' => t('The item has been deleted.'),
);
@@ -414,6 +412,7 @@ function ctools_export_ui_plugin_base_path($plugin) {
* The id in the menu items from the plugin.
* @param $export_key
* The export key of the item being edited, if it exists.
*
* @return
* The menu path to the plugin's list.
*/
@@ -429,12 +428,11 @@ function ctools_export_ui_plugin_menu_path($plugin, $item_id, $export_key = NULL
* Helper function to include CTools plugins and get an export-ui exportable.
*
* @param $plugin_name
* The plugin that should be laoded.
* The plugin that should be loaded.
*/
function ctools_get_export_ui($plugin_name) {
ctools_include('plugins');
return ctools_get_plugins('ctools', 'export_ui', $plugin_name);
}
/**
@@ -456,14 +454,14 @@ function ctools_export_ui_switcher_page($plugin_name, $op) {
$args = func_get_args();
$js = !empty($_REQUEST['js']);
// Load the $plugin information
// Load the $plugin information.
$plugin = ctools_get_export_ui($plugin_name);
$handler = ctools_export_ui_get_handler($plugin);
if ($handler) {
$method = $op . '_page';
if (method_exists($handler, $method)) {
// replace the first two arguments:
// Replace the first two arguments:
$args[0] = $js;
$args[1] = $_POST;
return call_user_func_array(array($handler, $method), $args);
@@ -1,5 +1,9 @@
<?php
/**
* @file
*/
/**
* Delegated implementation of hook_menu().
*/
@@ -17,4 +17,4 @@ function ctools_export_ui_plugin_type(&$items) {
),
'classes' => array('handler'),
);
}
}
@@ -4,7 +4,7 @@
* @file
* Contains code to make it easier to have exportable objects.
*
* Documentation for exportable objects is contained in help/export.html
* Documentation for exportable objects is contained in help/export.html.
*/
/**
@@ -126,6 +126,7 @@ function ctools_export_crud_load_multiple($table, array $names) {
* If TRUE, the static cache of all objects will be flushed prior to
* loading all. This can be important on listing pages where items
* might have changed on the page load.
*
* @return
* An array of all loaded objects, keyed by the unique IDs of the export key.
*/
@@ -328,7 +329,6 @@ function ctools_export_crud_set_status($table, $object, $status) {
}
/**
* Enable a certain object.
*
@@ -426,7 +426,7 @@ function ctools_export_load_object($table, $type = 'all', $args = array()) {
}
}
// Build the query
// Build the query.
$query = db_select($table, 't__0')->fields('t__0');
$alias_count = 1;
if (!empty($schema['join'])) {
@@ -451,7 +451,7 @@ function ctools_export_load_object($table, $type = 'all', $args = array()) {
if ($type == 'names') {
$query->condition($export['key'], $args, 'IN');
}
else if ($type == 'conditions') {
elseif ($type == 'conditions') {
foreach ($args as $key => $value) {
if (isset($schema['fields'][$key])) {
$query->condition($key, $value);
@@ -499,7 +499,7 @@ function ctools_export_load_object($table, $type = 'all', $args = array()) {
if ($defaults) {
foreach ($defaults as $object) {
if ($type == 'conditions') {
// if this does not match all of our conditions, skip it.
// If this does not match all of our conditions, skip it.
foreach ($args as $key => $value) {
if (!isset($object->$key)) {
continue 2;
@@ -509,12 +509,12 @@ function ctools_export_load_object($table, $type = 'all', $args = array()) {
continue 2;
}
}
else if ($object->$key != $value) {
elseif ($object->$key != $value) {
continue 2;
}
}
}
else if ($type == 'names') {
elseif ($type == 'names') {
if (!in_array($object->{$export['key']}, $args)) {
continue;
}
@@ -561,7 +561,6 @@ function ctools_export_load_object($table, $type = 'all', $args = array()) {
}
}
// For conditions,
return $return;
}
@@ -807,10 +806,10 @@ function _ctools_export_get_some_defaults($table, $export, $names) {
function _ctools_export_unpack_object($schema, $data, $object = 'stdClass') {
if (is_string($object)) {
if (class_exists($object)) {
$object = new $object;
$object = new $object();
}
else {
$object = new stdClass;
$object = new stdClass();
}
}
@@ -873,14 +872,14 @@ function ctools_var_export($var, $prefix = '') {
$output .= $prefix . ')';
}
}
else if (is_object($var) && get_class($var) === 'stdClass') {
elseif (is_object($var) && get_class($var) === 'stdClass') {
// var_export() will export stdClass objects using an undefined
// magic method __set_state() leaving the export broken. This
// workaround avoids this by casting the object as an array for
// export and casting it back to an object when evaluated.
$output = '(object) ' . ctools_var_export((array) $var, $prefix);
}
else if (is_bool($var)) {
elseif (is_bool($var)) {
$output = $var ? 'TRUE' : 'FALSE';
}
else {
@@ -902,7 +901,8 @@ function ctools_export_object($table, $object, $indent = '', $identifier = NULL,
$output = $indent . '$' . $identifier . ' = new ' . get_class($object) . "();\n";
if ($schema['export']['can disable']) {
$output .= $indent . '$' . $identifier . '->disabled = FALSE; /* Edit this to true to make a default ' . $identifier . ' disabled initially */' . "\n";
$disabled = !isset($object->disabled) || $object->disabled != TRUE ? 'FALSE' : 'TRUE';
$output .= $indent . '$' . $identifier . '->disabled = ' . $disabled . '; /* Edit this to true to make a default ' . $identifier . ' disabled initially */' . "\n";
}
if (!empty($schema['export']['api']['current_version'])) {
$output .= $indent . '$' . $identifier . '->api_version = ' . $schema['export']['api']['current_version'] . ";\n";
@@ -945,14 +945,20 @@ function ctools_export_object($table, $object, $indent = '', $identifier = NULL,
else {
$value = $object->$field;
if ($info['type'] == 'int') {
$value = (isset($info['size']) && $info['size'] == 'tiny') ? (bool) $value : (int) $value;
if (isset($info['size']) && $info['size'] == 'tiny') {
$info['boolean'] = (!isset($info['boolean'])) ? $schema['export']['boolean'] : $info['boolean'];
$value = ($info['boolean']) ? (bool) $value : (int) $value;
}
else {
$value = (int) $value;
}
}
$output .= $indent . '$' . $identifier . '->' . $field . ' = ' . ctools_var_export($value, $indent) . ";\n";
}
}
// And bottom additions here
// And bottom additions here.
foreach ($additions2 as $field => $value) {
$output .= $indent . '$' . $identifier . '->' . $field . ' = ' . ctools_var_export($value, $indent) . ";\n";
}
@@ -967,7 +973,12 @@ function ctools_export_object($table, $object, $indent = '', $identifier = NULL,
* that it's easily available.
*/
function ctools_export_get_schema($table) {
$cache = &drupal_static(__FUNCTION__);
static $drupal_static_fast;
if (!isset($drupal_static_fast)) {
$drupal_static_fast['cache'] = &drupal_static(__FUNCTION__);
}
$cache = &$drupal_static_fast['cache'];
if (empty($cache[$table])) {
$schema = drupal_get_schema($table);
@@ -975,7 +986,7 @@ function ctools_export_get_schema($table) {
// simply hasn't been cached. If we've been asked, let's force the
// issue.
if (!$schema || empty($schema['export'])) {
// force a schema reset:
// Force a schema reset:
$schema = drupal_get_schema($table, TRUE);
}
@@ -987,7 +998,7 @@ function ctools_export_get_schema($table) {
return array();
}
// Add some defaults
// Add some defaults.
$schema['export'] += array(
'key' => 'name',
'key name' => 'Name',
@@ -1003,6 +1014,7 @@ function ctools_export_get_schema($table) {
'cache defaults' => FALSE,
'default cache bin' => 'cache',
'export type string' => 'type',
'boolean' => TRUE,
);
// If the export definition doesn't have the "primary key" then the CRUD
@@ -1094,7 +1106,7 @@ function ctools_export_set_object_status($object, $new_status = TRUE) {
$export = $schema['export'];
$status = variable_get($export['status'], array());
// Compare
// Compare.
if (!$new_status && $object->export_type & EXPORT_IN_DATABASE) {
unset($status[$object->{$export['key']}]);
}
@@ -1137,12 +1149,12 @@ function ctools_export_new_object($table, $set_defaults = TRUE) {
$schema = ctools_export_get_schema($table);
$export = $schema['export'];
$object = new $export['object'];
$object = new $export['object']();
foreach ($schema['fields'] as $field => $info) {
if (isset($info['object default'])) {
$object->$field = $info['object default'];
}
else if (isset($info['default'])) {
elseif (isset($info['default'])) {
$object->$field = $info['default'];
}
else {
@@ -1167,11 +1179,11 @@ function ctools_export_new_object($table, $set_defaults = TRUE) {
function ctools_export_to_hook_code(&$code, $table, $names = array(), $name = 'foo') {
$schema = ctools_export_get_schema($table);
$export = $schema['export'];
// Use the schema-specified function for generating hook code, if one exists
// Use the schema-specified function for generating hook code, if one exists.
if (function_exists($export['to hook code callback'])) {
$output = $export['to hook code callback']($names, $name);
}
// Otherwise, the following code generates basic hook code
// Otherwise, the following code generates basic hook code.
else {
$output = ctools_export_default_to_hook_code($schema, $table, $names, $name);
}
@@ -1215,7 +1227,7 @@ function ctools_export_default_to_hook_code($schema, $table, $names, $name) {
$output .= " \${$export['identifier']}s = array();\n\n";
foreach ($objects as $object) {
$output .= ctools_export_crud_export($table, $object, ' ');
$output .= " \${$export['identifier']}s['" . check_plain($object->$export['key']) . "'] = \${$export['identifier']};\n\n";
$output .= " \${$export['identifier']}s['" . check_plain($object->{$export['key']}) . "'] = \${$export['identifier']};\n\n";
}
$output .= " return \${$export['identifier']}s;\n";
$output .= "}\n";
@@ -1223,6 +1235,7 @@ function ctools_export_default_to_hook_code($schema, $table, $names, $name) {
return $output;
}
/**
* Default function for listing bulk exportable objects.
*/
@@ -5,7 +5,6 @@
* Extend core fields with some helper functions to reduce code complexity within views and ctools plugins.
*/
/**
* Fake an instance of a field.
*
@@ -75,14 +74,30 @@ function ctools_fields_get_field_formatter_settings_form($field, $formatter_type
$conf['formatter_settings'] += $formatter['settings'];
}
$function = $formatter['module'] . '_field_formatter_settings_form';
$instance = ctools_fields_fake_field_instance($field['field_name'], $view_mode, $formatter_type, $conf['formatter_settings']);
if (function_exists($function)) {
$instance = ctools_fields_fake_field_instance($field['field_name'], $view_mode, $formatter_type, $conf['formatter_settings']);
$settings_form = $function($field, $instance, $view_mode, $form, $form_state);
if ($settings_form) {
$form['ctools_field_list']['#value'][] = $field;
$form += $settings_form;
}
}
if (empty($settings_form)) {
$settings_form = array();
}
// Allow other modules to alter the formatter settings form.
$context = array(
'module' => $formatter['module'],
'formatter' => $formatter,
'field' => $field,
'instance' => $instance,
'view_mode' => $view_mode,
'form' => $form,
'form_state' => $form_state,
);
drupal_alter('field_formatter_settings_form', $settings_form, $context);
$settings_form['#tree'] = TRUE;
$form['ctools_field_list']['#value'][] = $field;
$form += $settings_form;
if (isset($field['cardinality']) && $field['cardinality'] != 1) {
list($prefix, $suffix) = explode('@count', t('Skip the first @count item(s)'));
@@ -124,7 +139,7 @@ function ctools_fields_get_field_formatter_settings_form($field, $formatter_type
*/
function ctools_fields_get_field_formatter_info($fields) {
$info = array();
$field_info = module_invoke_all('field_formatter_info');
$field_info = field_info_formatter_types();
foreach ($fields as $field) {
foreach ($field_info as $format_name => $formatter_info) {
if (in_array($field['type'], $formatter_info['field types'])) {
@@ -132,7 +147,6 @@ function ctools_fields_get_field_formatter_info($fields) {
}
}
}
drupal_alter('field_formatter_info', $info);
return $info;
}
@@ -196,15 +210,15 @@ function ctools_field_label($field_name) {
* - Otherwise NULL.
* @param $options
* An associative array of additional options, with the following keys:
* - 'field_name': The name of the field whose operation should be
* - 'field_name': The name of the field whose operation should be
* invoked. By default, the operation is invoked on all the fields
* in the entity's bundle. NOTE: This option is not compatible with
* the 'deleted' option; the 'field_id' option should be used
* instead.
* - 'field_id': The id of the field whose operation should be
* - 'field_id': The id of the field whose operation should be
* invoked. By default, the operation is invoked on all the fields
* in the entity's' bundles.
* - 'default': A boolean value, specifying which implementation of
* - 'default': A boolean value, specifying which implementation of
* the operation should be invoked.
* - if FALSE (default), the field types implementation of the operation
* will be invoked (hook_field_[op])
@@ -212,10 +226,10 @@ function ctools_field_label($field_name) {
* will be invoked (field_default_[op])
* Internal use only. Do not explicitely set to TRUE, but use
* _field_invoke_default() instead.
* - 'deleted': If TRUE, the function will operate on deleted fields
* - 'deleted': If TRUE, the function will operate on deleted fields
* as well as non-deleted fields. If unset or FALSE, only
* non-deleted fields are operated on.
* - 'language': A language code or an array of language codes keyed by field
* - 'language': A language code or an array of language codes keyed by field
* name. It will be used to narrow down to a single value the available
* languages to act on.
*
@@ -328,7 +342,7 @@ function ctools_field_foreign_keys($field_name) {
$foreign_keys[$field_name] = $field['foreign keys'];
}
else {
// try to fetch foreign keys from schema, as not everything
// Try to fetch foreign keys from schema, as not everything
// stores foreign keys properly in the field info.
$module = $field['module'];
@@ -8,7 +8,6 @@
* if javascript is in use. Each item is keyed to the href that the button
* should go to. With javascript, the page is immediately redirected. Without
* javascript, the form is submitted and a drupal_goto() is given.
*
*/
/**
@@ -51,7 +50,7 @@ function ctools_jump_menu($form, &$form_state, $select, $options = array()) {
'hide' => TRUE,
);
ctools_add_js('jump-menu');
$form['#attached']['js'][] = ctools_attach_js('jump-menu');
if (!empty($options['choose'])) {
$select = array('' => $options['choose']) + $select;
@@ -127,7 +126,7 @@ function ctools_jump_menu_submit($form, &$form_state) {
// This allows duplicate paths to be used in jump menus for multiple options.
$redirect_array = explode("::", $form_state['values']['jump']);
if(isset($redirect_array[1]) && !empty($redirect_array[1])){
if (isset($redirect_array[1]) && !empty($redirect_array[1])) {
$redirect = $redirect_array[1];
}
else {
@@ -1,5 +1,9 @@
<?php
/**
* @file
*/
/**
* Returns array of language names.
*
@@ -32,7 +36,6 @@ function ctools_language_list($field = 'name', $all = FALSE) {
* Returns an array of language names similar to ctools_language_list() except
* that additional choices have been added for ease of use.
*/
function ctools_language_list_all() {
$languages = array(
'***CURRENT_LANGUAGE***' => t("Current user's language"),
@@ -41,4 +44,4 @@ function ctools_language_list_all() {
);
$languages = array_merge($languages, ctools_language_list());
return $languages;
}
}
@@ -99,7 +99,10 @@ class ctools_math_expr {
'sqrt','abs','ln','log',
'time', 'ceil', 'floor', 'min', 'max', 'round');
function ctools_math_expr() {
/**
* ctools_math_expr constructor.
*/
function __construct() {
// make the variables a little more accurate
$this->v['pi'] = pi();
$this->v['e'] = exp(1);
@@ -271,7 +274,7 @@ class ctools_math_expr {
} elseif (in_array($op, $ops) and !$expecting_op) {
return $this->trigger("unexpected operator '$op'");
} else { // I don't even want to know what you did to get here
return $this->trigger("an unexpected error occured");
return $this->trigger("an unexpected error occurred");
}
if ($index == strlen($expr)) {
if (in_array($op, $ops)) { // did we end with an operator? bad.
@@ -55,9 +55,9 @@ function ctools_modal_add_js() {
'alt' => t('Close window'),
)),
'throbber' => theme('image', array(
'path' => ctools_image_path('throbber.gif'),
'title' => t('Loading...'),
'alt' => t('Loading'),
'path' => ctools_image_path('throbber.gif'),
'title' => t('Loading...'),
'alt' => t('Loading'),
)),
),
);
@@ -66,6 +66,7 @@ function ctools_modal_add_js() {
drupal_add_library('system', 'jquery.form');
drupal_add_library('system', 'drupal.progress');
drupal_add_library('system', 'drupal.ajax');
drupal_add_library('system', 'ui');
ctools_add_js('modal');
ctools_add_css('modal');
@@ -84,7 +85,7 @@ function ctools_modal_add_plugin_js($plugins) {
if (file_exists($file)) {
$js[$file] = TRUE;
}
else if (file(exists($subtype['path'] . '/' . $file))) {
elseif (file(exists($subtype['path'] . '/' . $file))) {
$js[$subtype['path'] . '/' . $file] = TRUE;
}
}
@@ -94,7 +95,7 @@ function ctools_modal_add_plugin_js($plugins) {
if (file_exists($file)) {
$css[$file] = TRUE;
}
else if (file(exists($subtype['path'] . '/' . $file))) {
elseif (file(exists($subtype['path'] . '/' . $file))) {
$css[$subtype['path'] . '/' . $file] = TRUE;
}
}
@@ -139,7 +140,7 @@ function ctools_modal_command_dismiss() {
}
/**
* Display loading screen in the modal
* Display loading screen in the modal.
*/
function ctools_modal_command_loading() {
return array(
@@ -187,18 +188,32 @@ function ctools_modal_text_button($text, $dest, $alt, $class = '') {
/**
* Wrap a form so that we can use it properly with AJAX. Essentially if the
* form wishes to render, it automatically does that, otherwise it returns
* so we can see submission results.
* the render array so we can see submission results.
*
* @return
* @param array $form
* An associative array containing the structure of the form.
* @param array $form_state
* An associative array containing the current state of the form.
* If the 'reset_html_ids' key is set to TRUE, it will prevent HTML IDs in
* forms from being incremented.
*
* @return mixed
* The output of the form, if it was rendered. If $form_state['ajax']
* is set, this will use ctools_modal_form_render so it will be
* a $command object suitable for ajax_render already.
*
* The return will be NULL if the form was successfully submitted unless
* you specifically set re_render = TRUE. If ajax is set the
* form will never be redirected.
* If the form was not rendered, the raw render array will be returned.
*
* If ajax is set the form will never be redirected.
*/
function ctools_modal_form_wrapper($form_id, &$form_state) {
// Since this will run again on form rebuild while still in the modal, prevent
// form IDs from being incremented.
// @todo https://drupal.org/node/1305882
if (!empty($form_state['reset_html_ids']) && !empty($_POST['ajax_html_ids'])) {
unset($_POST['ajax_html_ids']);
}
// This won't override settings already in.
$form_state += array(
're_render' => FALSE,
@@ -206,8 +221,8 @@ function ctools_modal_form_wrapper($form_id, &$form_state) {
);
$output = drupal_build_form($form_id, $form_state);
if (!empty($form_state['ajax']) && (!$form_state['executed'] || $form_state['rebuild'])) {
return ctools_modal_form_render($form_state, $output);
if (!empty($form_state['ajax']) && (!$form_state['executed'] || $form_state['rebuild'])) {
return ctools_modal_form_render($form_state, $output);
}
return $output;
@@ -27,6 +27,7 @@
* defaults to session_id().
*
* @deprecated $skip_cache is deprecated in favor of drupal_static*
*
* @return
* The data that was cached.
*/
@@ -42,8 +43,11 @@ function ctools_object_cache_get($obj, $name, $skip_cache = FALSE, $sid = NULL)
}
if (!array_key_exists($key, $cache)) {
$data = db_query('SELECT * FROM {ctools_object_cache} WHERE sid = :session_id AND obj = :object AND name = :name', array(':session_id' => $sid, ':object' => $obj, ':name' => $name))
->fetchObject();
$data = db_query('SELECT * FROM {ctools_object_cache} WHERE sid = :session_id AND obj = :object AND name = :name', array(
':session_id' => $sid,
':object' => $obj,
':name' => md5($name),
))->fetchObject();
if ($data) {
$cache[$key] = unserialize($data->data);
}
@@ -83,7 +87,7 @@ function ctools_object_cache_set($obj, $name, $cache, $sid = NULL) {
->fields(array(
'sid' => $sid,
'obj' => $obj,
'name' => $name,
'name' => md5($name),
'data' => serialize($cache),
'updated' => REQUEST_TIME,
))
@@ -91,7 +95,7 @@ function ctools_object_cache_set($obj, $name, $cache, $sid = NULL) {
}
/**
* Remove an object from the non-volatile ctools cache
* Remove an object from the non-volatile ctools cache.
*
* @param $obj
* A 128 character or less string to define what kind of object is being
@@ -103,7 +107,6 @@ function ctools_object_cache_set($obj, $name, $cache, $sid = NULL) {
* defaults to session_id().
*/
function ctools_object_cache_clear($obj, $name, $sid = NULL) {
if (!$sid) {
$sid = session_id();
}
@@ -111,13 +114,12 @@ function ctools_object_cache_clear($obj, $name, $sid = NULL) {
db_delete('ctools_object_cache')
->condition('sid', $sid)
->condition('obj', $obj)
->condition('name', $name)
->condition('name', md5($name))
->execute();
// Ensure the static cache is emptied of this obj:name set.
drupal_static_reset('ctools_object_cache_get');
}
/**
* Determine if another user has a given object cached.
*
@@ -142,8 +144,11 @@ function ctools_object_cache_test($obj, $name, $sid = NULL) {
$sid = session_id();
}
return db_query('SELECT s.uid, c.updated FROM {ctools_object_cache} c INNER JOIN {sessions} s ON c.sid = s.sid WHERE s.sid <> :session_id AND c.obj = :obj AND c.name = :name ORDER BY c.updated ASC', array(':session_id' => $sid, ':obj' => $obj, ':name' => $name))
->fetchObject();
return db_query('SELECT s.uid, c.updated FROM {ctools_object_cache} c INNER JOIN {sessions} s ON c.sid = s.sid WHERE s.sid <> :session_id AND c.obj = :obj AND c.name = :name ORDER BY c.updated ASC', array(
':session_id' => $sid,
':obj' => $obj,
':name' => md5($name),
))->fetchObject();
}
/**
@@ -162,6 +167,7 @@ function ctools_object_cache_test($obj, $name, $sid = NULL) {
* An array of objects containing the UID and updated date for each name found.
*/
function ctools_object_cache_test_objects($obj, $names) {
array_walk($names, 'md5');
return db_query("SELECT c.name, s.uid, c.updated FROM {ctools_object_cache} c INNER JOIN {sessions} s ON c.sid = s.sid WHERE c.obj = :obj AND c.name IN (:names) ORDER BY c.updated ASC", array(':obj' => $obj, ':names' => $names))
->fetchAllAssoc('name');
}
@@ -180,7 +186,7 @@ function ctools_object_cache_test_objects($obj, $names) {
function ctools_object_cache_clear_all($obj, $name) {
db_delete('ctools_object_cache')
->condition('obj', $obj)
->condition('name', $name)
->condition('name', md5($name))
->execute();
// Ensure the static cache is emptied of this obj:name set.
$cache = &drupal_static('ctools_object_cache_get', array());
@@ -197,7 +203,8 @@ function ctools_object_cache_clear_all($obj, $name) {
*/
function ctools_object_cache_clean($age = NULL) {
if (empty($age)) {
$age = 86400 * 7; // 7 days
// 7 days.
$age = 86400 * 7;
}
db_delete('ctools_object_cache')
->condition('updated', REQUEST_TIME - $age, '<')
@@ -1,5 +1,9 @@
<?php
/**
* @file
*/
/**
* Fetch metadata on a specific page_wizard plugin.
*
@@ -53,7 +57,7 @@ function page_manager_get_wizard_cache($plugin) {
}
function page_manager_make_wizard_cache($plugin) {
$cache = new stdClass;
$cache = new stdClass();
$cache->plugin = $plugin;
if ($function = ctools_plugin_get_function($plugin, 'default cache')) {
$function($cache);
@@ -10,6 +10,7 @@
*
* Implementing this
*/
/**
* Get a plugin configuration form.
*
@@ -100,7 +101,7 @@ function _ctools_plugin_configure_create_form_info(&$form_info, $plugin_definiti
if (empty($plugin_definition['title'])) {
$title = t('Configure');
}
else if ($op == 'add') {
elseif ($op == 'add') {
$title = t('Configure new !plugin_title', array('!plugin_title' => $plugin_definition['title']));
}
else {
@@ -134,10 +135,10 @@ function _ctools_plugin_configure_create_form_info(&$form_info, $plugin_definiti
$form_info['forms']['form']['wrapper'] = 'ctools_plugins_default_form_wrapper';
}
}
else if (is_array($info)) {
if (empty($form_info['order'])) {
$form_info['order'] = array();
}
elseif (is_array($info)) {
if (empty($form_info['order'])) {
$form_info['order'] = array();
}
if (empty($form_info['forms'])) {
$form_info['forms'] = array();
}
@@ -2,7 +2,6 @@
/**
* @file
*
* Contains routines to organize and load plugins. It allows a special
* variation of the hook system so that plugins can be kept in separate
* .inc files, and can be either loaded all at once or loaded only when
@@ -70,7 +69,7 @@ function ctools_plugin_api_info($owner, $api, $minimum_version, $current_version
if (isset($info['version'])) {
$version = $info['version'];
}
else if (isset($info['api'])) {
elseif (isset($info['api'])) {
$version = $info['api'];
}
@@ -79,7 +78,9 @@ function ctools_plugin_api_info($owner, $api, $minimum_version, $current_version
}
// Only process if version is between minimum and current, inclusive.
if (version_compare($version, $minimum_version, '>=') && version_compare($version, $current_version, '<=')) {
if (($version == $minimum_version) || ($version == $current_version)
|| (version_compare($version, $minimum_version, '>=')
&& version_compare($version, $current_version, '<='))) {
if (!isset($info['path'])) {
$info['path'] = drupal_get_path('module', $module);
}
@@ -97,7 +98,7 @@ function ctools_plugin_api_info($owner, $api, $minimum_version, $current_version
}
// Only process if version is between minimum and current, inclusive.
if (version_compare($info['version'], $minimum_version, '>=') && version_compare($info['version'], $current_version, '<=')) {
if (version_compare($info['version'], $minimum_version, '>=') && version_compare($info['version'], $current_version, '<=')) {
if (!isset($info['path'])) {
$info['path'] = '';
}
@@ -110,7 +111,7 @@ function ctools_plugin_api_info($owner, $api, $minimum_version, $current_version
}
// Allow other modules to hook in.
drupal_alter($hook, $cache[$owner][$api]);
drupal_alter($hook, $cache[$owner][$api], $owner, $api);
}
return $cache[$owner][$api];
@@ -149,7 +150,7 @@ function ctools_plugin_api_include($owner, $api, $minimum_version, $current_vers
if (isset($plugin_info["$api file"])) {
$file = $plugin_info["$api file"];
}
else if (isset($plugin_info['file'])) {
elseif (isset($plugin_info['file'])) {
$file = $plugin_info['file'];
}
else {
@@ -159,7 +160,7 @@ function ctools_plugin_api_include($owner, $api, $minimum_version, $current_vers
if (file_exists(DRUPAL_ROOT . "/$plugin_info[path]/$file")) {
require_once DRUPAL_ROOT . "/$plugin_info[path]/$file";
}
else if (file_exists(DRUPAL_ROOT . "/$file")) {
elseif (file_exists(DRUPAL_ROOT . "/$file")) {
require_once DRUPAL_ROOT . "/$file";
}
$already_done[$owner][$api][$module] = TRUE;
@@ -182,7 +183,7 @@ function ctools_plugin_api_get_hook($owner, $api) {
if (function_exists($function = $owner . '_' . $api . '_hook_name')) {
$hook = $function();
}
else if (function_exists($function = $owner . '_ctools_plugin_api_hook_name')) {
elseif (function_exists($function = $owner . '_ctools_plugin_api_hook_name')) {
$hook = $function();
}
@@ -198,29 +199,38 @@ function ctools_plugin_api_get_hook($owner, $api) {
/**
* Fetch a group of plugins by name.
*
* @param $module
* The name of the module that utilizes this plugin system. It will be
* used to call hook_ctools_plugin_$plugin() to get more data about the plugin.
* @param $type
* @param string $module
* The name of the module that utilizes this plugin system. It will be used to
* get more data about the plugin as defined on hook_ctools_plugin_type().
* @param string $type
* The type identifier of the plugin.
* @param $id
* @param string $id
* If specified, return only information about plugin with this identifier.
* The system will do its utmost to load only plugins with this id.
*
* @return
* An array of information arrays about the plugins received. The contents
* of the array are specific to the plugin.
* @return array
* An array of information arrays about the plugins received. The contents of
* the array are specific to the plugin.
*/
function ctools_get_plugins($module, $type, $id = NULL) {
// Store local caches of plugins and plugin info so we don't have to do full
// lookups everytime.
$plugins = &drupal_static('ctools_plugins', array());
// lookups every time.
static $drupal_static_fast;
if (!isset($drupal_static_fast)) {
$drupal_static_fast['plugins'] = &drupal_static('ctools_plugins', array());
}
$plugins = &$drupal_static_fast['plugins'];
$info = ctools_plugin_get_plugin_type_info();
// Bail out noisily if an invalid module/type combination is requested.
if (!isset($info[$module][$type])) {
watchdog('ctools', 'Invalid plugin module/type combination requested: module @module and type @type', array('@module' => $module, '@type' => $type), WATCHDOG_ERROR);
return array();
// If we don't find the plugin we attempt a cache rebuild before bailing out.
$info = ctools_plugin_get_plugin_type_info(TRUE);
// Bail out noisily if an invalid module/type combination is requested.
if (!isset($info[$module][$type])) {
watchdog('ctools', 'Invalid plugin module/type combination requested: module @module and type @type', array('@module' => $module, '@type' => $type), WATCHDOG_ERROR);
return array();
}
}
// Make sure our plugins array is populated.
@@ -228,8 +238,8 @@ function ctools_get_plugins($module, $type, $id = NULL) {
$plugins[$module][$type] = array();
}
// Attempt to shortcut this whole piece of code if we already have
// the requested plugin:
// Attempt to shortcut this whole piece of code if we already have the
// requested plugin:
if ($id && array_key_exists($id, $plugins[$module][$type])) {
return $plugins[$module][$type][$id];
}
@@ -247,9 +257,9 @@ function ctools_get_plugins($module, $type, $id = NULL) {
if (!empty($cache->data)) {
// Cache load succeeded so use the cached plugin list.
$plugins[$module][$type] = $cache->data;
$plugins[$module][$type] = $cache->data;
// Set $setup to true so we know things where loaded.
$setup[$module][$type] = TRUE;
$setup[$module][$type] = TRUE;
}
else {
// Cache load failed so store that we need to build and write the cache.
@@ -264,8 +274,8 @@ function ctools_get_plugins($module, $type, $id = NULL) {
$plugins[$module][$type] = ctools_plugin_load_hooks($info[$module][$type]);
}
// Then see if we should load all files. We only do this if we
// want a list of all plugins or there was a cache miss.
// Then see if we should load all files. We only do this if we want a list of
// all plugins or there was a cache miss.
if (empty($setup[$module][$type]) && ($build_cache || !$id)) {
$setup[$module][$type] = TRUE;
$plugins[$module][$type] = array_merge($plugins[$module][$type], ctools_plugin_load_includes($info[$module][$type]));
@@ -288,9 +298,8 @@ function ctools_get_plugins($module, $type, $id = NULL) {
}
}
// If we were told earlier that this is cacheable and the cache was
// empty, give something back.
// If we were told earlier that this is cacheable and the cache was empty,
// give something back.
if ($build_cache) {
cache_set("plugins:$module:$type", $plugins[$module][$type], $info[$module][$type]['cache table']);
}
@@ -302,7 +311,7 @@ function ctools_get_plugins($module, $type, $id = NULL) {
return array_filter($plugins[$module][$type]);
}
// Check to see if we need to look for the file
// Check to see if we need to look for the file.
if (!array_key_exists($id, $plugins[$module][$type])) {
// If we can have child plugins, check to see if the plugin name is in the
// format of parent:child and break it up if it is.
@@ -343,8 +352,13 @@ function ctools_get_plugins($module, $type, $id = NULL) {
* name and each inner array keyed on plugin type name.
*/
function ctools_plugin_get_plugin_type_info($flush = FALSE) {
$info_loaded = &drupal_static('ctools_plugin_type_info_loaded', FALSE);
$all_type_info = &drupal_static('ctools_plugin_type_info', array());
static $drupal_static_fast;
if (!isset($drupal_static_fast)) {
$drupal_static_fast['info_loaded'] = &drupal_static('ctools_plugin_type_info_loaded', FALSE);
$drupal_static_fast['all_type_info'] = &drupal_static('ctools_plugin_type_info', array());
}
$info_loaded = &$drupal_static_fast['info_loaded'];
$all_type_info = &$drupal_static_fast['all_type_info'];
// Only trigger info loading once.
if ($info_loaded && !$flush) {
@@ -403,40 +417,31 @@ function ctools_get_plugins_reset() {
/**
* Load plugins from a directory.
*
* @param $info
* @param array $info
* The plugin info as returned by ctools_plugin_get_info()
* @param $file
* @param string $filename
* The file to load if we're looking for just one particular plugin.
*
* @return
* An array of information created for this plugin.
* @return array
* A (possibly empty) array of information created for this plugin.
*/
function ctools_plugin_load_includes($info, $filename = NULL) {
// Keep a static array so we don't hit file_scan_directory more than necessary.
$all_files = &drupal_static(__FUNCTION__, array());
// store static of plugin arrays for reference because they can't be reincluded.
// Store static of plugin arrays for reference because they can't be
// reincluded, so there is no point in using drupal_static().
static $plugin_arrays = array();
// If we're being asked for all plugins of a type, skip any caching
// we may have done because this is an admin task and it's ok to
// spend the extra time.
if (!isset($filename)) {
$all_files[$info['module']][$info['type']] = NULL;
}
if (!isset($all_files[$info['module']][$info['type']])) {
// If a filename was set, we will try to load our list of files from
// cache. This is considered normal operation and we try to reduce
// the time spent finding files.
if (isset($filename)) {
$cache = cache_get("ctools_plugin_files:$info[module]:$info[type]");
if ($cache) {
$all_files[$info['module']][$info['type']] = $cache->data;
}
$cache = cache_get("ctools_plugin_files:$info[module]:$info[type]");
if ($cache) {
$all_files[$info['module']][$info['type']] = $cache->data;
}
if (!isset($all_files[$info['module']][$info['type']])) {
// Do not attempt any file scan even if the cached entry was empty.
// A NULL entry here would mean the plugin just does not exists, and we
// cannot afford to run file scan on production sites normal run.
elseif (!isset($all_files[$info['module']][$info['type']])) {
$all_files[$info['module']][$info['type']] = array();
// Load all our plugins.
$directories = ctools_plugin_get_directories($info);
@@ -460,24 +465,23 @@ function ctools_plugin_load_includes($info, $filename = NULL) {
}
foreach ($files as $file) {
if (!empty($info['info file'])) {
// Parse a .info file
// Parse a .info file.
$result = ctools_plugin_process_info($info, $module, $file);
}
else {
// Parse a hook.
$plugin = NULL; // ensure that we don't have something leftover from earlier.
// Ensure that we don't have something leftover from earlier.
$plugin = NULL;
if (isset($plugin_arrays[$file->uri])) {
$identifier = $plugin_arrays[$file->uri];
}
else {
require_once DRUPAL_ROOT . '/' . $file->uri;
include_once DRUPAL_ROOT . '/' . $file->uri;
// .inc files have a special format for the hook identifier.
// For example, 'foo.inc' in the module 'mogul' using the plugin
// whose hook is named 'borg_type' should have a function named (deep breath)
// mogul_foo_borg_type()
// whose hook is named 'borg_type' should have a function named
// (deep breath) mogul_foo_borg_type().
// If, however, the .inc file set the quasi-global $plugin array, we
// can use that and not even call a function. Set the $identifier
// appropriately and ctools_plugin_process() will handle it.
@@ -490,7 +494,8 @@ function ctools_plugin_load_includes($info, $filename = NULL) {
}
}
$result = ctools_plugin_process($info, $module, $identifier, dirname($file->uri), basename($file->uri), $file->name);
$result = ctools_plugin_process($info, $module, $identifier,
dirname($file->uri), basename($file->uri), $file->name);
}
if (is_array($result)) {
$plugins = array_merge($plugins, $result);
@@ -510,7 +515,7 @@ function ctools_plugin_load_includes($info, $filename = NULL) {
* @param $info
* The $info array for the plugin as returned by ctools_plugin_get_info().
*
* @return array $directories
* @return array
* An array of directories to search.
*/
function ctools_plugin_get_directories($info) {
@@ -536,10 +541,9 @@ function ctools_plugin_get_directories($info) {
}
/**
* Helper function to build a ctools-friendly list of themes capable of
* providing plugins.
* Helper to build a ctools-friendly list of themes capable of providing plugins.
*
* @return array $themes
* @return array
* A list of themes that can act as plugin providers, sorted parent-first with
* the active theme placed last.
*/
@@ -550,7 +554,7 @@ function _ctools_list_themes() {
$themes = $active = array();
$all_themes = list_themes();
foreach ($all_themes as $name => $theme) {
// Only search from active themes
// Only search from active themes.
if (empty($theme->status) && $theme->name != $current) {
continue;
}
@@ -561,19 +565,19 @@ function _ctools_list_themes() {
}
}
// Construct a parent-first list of all themes
// Construct a parent-first list of all themes.
foreach ($active as $name => $theme) {
$base_themes = isset($theme->base_themes) ? $theme->base_themes : array();
$themes = array_merge($themes, $base_themes, array($name => $theme->info['name']));
}
// Put the actual theme info objects into the array
// Put the actual theme info objects into the array.
foreach (array_keys($themes) as $name) {
if (isset($all_themes[$name])) {
$themes[$name] = $all_themes[$name];
}
}
// Make sure the current default theme always gets the last word
// Make sure the current default theme always gets the last word.
if ($current_key = array_search($current, array_keys($themes))) {
$themes += array_splice($themes, $current_key, 1);
}
@@ -581,7 +585,6 @@ function _ctools_list_themes() {
return $themes;
}
/**
* Find all the base themes for the specified theme.
*
@@ -597,9 +600,10 @@ function _ctools_list_themes() {
* The name of the theme whose base we are looking for.
* @param $used_keys
* A recursion parameter preventing endless loops.
* @return
*
* @return array
* Returns an array of all of the theme's ancestors; the first element's value
* will be NULL if an error occurred.
* will be NULL if an error occurred. (Note: this is NOT $arr[0]).
*/
function ctools_find_base_themes($themes, $key, $used_keys = array()) {
$base_key = $themes[$key]->info['base theme'];
@@ -627,7 +631,6 @@ function ctools_find_base_themes($themes, $key, $used_keys = array()) {
return $current_base_theme;
}
/**
* Load plugin info for the provided hook; this is handled separately from
* plugins from files.
@@ -652,22 +655,28 @@ function ctools_plugin_load_hooks($info) {
/**
* Process a single hook implementation of a ctools plugin.
*
* @param $info
* @param array $info
* The $info array about the plugin as returned by ctools_plugin_get_info()
* @param $module
* @param string $module
* The module that implements the plugin being processed.
* @param $identifier
* The plugin identifier, which is used to create the name of the hook
* function being called.
* @param $path
* @param string|array $identifier
* Used to create the base setting of return value. If:
* - $identifier is a string, a hook name is created from this and the 'hook'
* key of the $info array, and the return value of that hook function is
* used. The hook is called like this: $identifier_$hook($info);
* - $identifier is an array, this array is used directly.
* @param string $path
* The path where files utilized by this plugin will be found.
* @param $file
* @param string $file
* The file that was loaded for this plugin, if it exists.
* @param $base
* @param string $base
* The base plugin name to use. If a file was loaded for the plugin, this
* is the plugin to assume must be present. This is used to automatically
* translate the array to make the syntax more friendly to plugin
* implementors.
*
* @return null|array
* NULL on failure, otherwise an array containing the results keyed by name.
*/
function ctools_plugin_process($info, $module, $identifier, $path, $file = NULL, $base = NULL) {
if (is_array($identifier)) {
@@ -678,7 +687,7 @@ function ctools_plugin_process($info, $module, $identifier, $path, $file = NULL,
if (!function_exists($function)) {
return NULL;
}
$result = $function();
$result = $function($info);
if (!isset($result) || !is_array($result)) {
return NULL;
}
@@ -735,9 +744,19 @@ function _ctools_process_data($result, $plugin_type_info, $module, $path, $file)
return $result;
}
/**
* Process an info file for plugin information, rather than a hook.
*
* @param array $info
* The $info array about the plugin as returned by ctools_plugin_get_info()
* @param string $module
* The module that implements the plugin being processed.
* @param object $file
* An object containing 'uri' and 'name' properties. 'uri' is the name of the
* 'info' file to process. 'name' is the plugin key-name.
*
* @return null|array
* NULL on failure, otherwise an array containing the results keyed by name.
*/
function ctools_plugin_process_info($info, $module, $file) {
$result = drupal_parse_info_file($file->uri);
@@ -764,7 +783,7 @@ function ctools_plugin_get_info($module, $type) {
* @param $function_name
* The identifier of the function. For example, 'settings form'.
*
* @return
* @return string
* The actual name of the function to call, or NULL if the function
* does not exist.
*/
@@ -781,7 +800,7 @@ function ctools_plugin_get_function($plugin_definition, $function_name) {
}
if (!isset($plugin_definition[$function_name])) {
return;
return NULL;
}
if (is_array($plugin_definition[$function_name]) && isset($plugin_definition[$function_name]['function'])) {
@@ -816,7 +835,7 @@ function ctools_plugin_get_function($plugin_definition, $function_name) {
* @param $function_name
* The identifier of the function. For example, 'settings form'.
*
* @return
* @return string
* The actual name of the function to call, or NULL if the function
* does not exist.
*/
@@ -834,7 +853,7 @@ function ctools_plugin_load_function($module, $type, $id, $function_name) {
* @param $class_name
* The identifier of the class. For example, 'handler'.
*
* @return
* @return string
* The actual name of the class to call, or NULL if the class does not exist.
*/
function ctools_plugin_get_class($plugin_definition, $class_name) {
@@ -853,11 +872,11 @@ function ctools_plugin_get_class($plugin_definition, $class_name) {
if (!isset($plugin_definition[$class_name])) {
return;
}
else if (is_string($plugin_definition[$class_name])) {
elseif (is_string($plugin_definition[$class_name])) {
// Plugin uses the string form shorthand.
$return = $plugin_definition[$class_name];
}
else if (isset($plugin_definition[$class_name]['class'])) {
elseif (isset($plugin_definition[$class_name]['class'])) {
// Plugin uses the verbose array form.
$return = $plugin_definition[$class_name]['class'];
}
@@ -879,7 +898,7 @@ function ctools_plugin_get_class($plugin_definition, $class_name) {
* @param $class_name
* The identifier of the class. For example, 'handler'.
*
* @return
* @return string
* The actual name of the class to call, or NULL if the class does not exist.
*/
function ctools_plugin_load_class($module, $type, $id, $class_name) {
@@ -2,7 +2,6 @@
/**
* @file
*
* Registry magic. In a separate file to minimize unnecessary code loading.
*/
@@ -202,7 +202,7 @@ function ctools_stylizer_get_settings_name($settings) {
}
/**
* Get the path where images will be stored for a given style plugin and settings.
* Get the path where images will be stored for a style plugin and settings.
*
* This function will make sure the path exists.
*/
@@ -249,7 +249,7 @@ class ctools_stylizer_image_processor {
if (is_string($plugin['actions']) && function_exists($plugin['actions'])) {
$actions = $plugin['actions']($plugin, $settings);
}
else if (is_array($plugin['actions'])) {
elseif (is_array($plugin['actions'])) {
$actions = $plugin['actions'];
}
@@ -318,7 +318,7 @@ class ctools_stylizer_image_processor {
function command_load($name, $file) {
$this->log("New workspace: $name (from $file)");
if (!file_exists($file)) {
// Try it relative to the plugin
// Try it relative to the plugin.
$file = $this->plugin['path'] . '/' . $file;
if (!file_exists($file)) {
$this->log("Unable to open $file");
@@ -336,7 +336,7 @@ class ctools_stylizer_image_processor {
}
/**
* Create a new workspace using the properties of an existing workspace
* Create a new workspace using the properties of an existing workspace.
*/
function command_new_from($name, $workspace) {
$this->log("New workspace: $name from existing $workspace");
@@ -372,7 +372,7 @@ class ctools_stylizer_image_processor {
function command_merge_from($workspace, $x = 0, $y = 0) {
$this->log("Merge from: $workspace ($x, $y)");
if (empty($this->workspaces[$workspace])) {
$this->log("Workspace $name does not exist.", 'error');
$this->log("Workspace $workspace does not exist.", 'error');
return;
}
@@ -382,7 +382,7 @@ class ctools_stylizer_image_processor {
function command_merge_to($workspace, $x = 0, $y = 0) {
$this->log("Merge to: $workspace ($x, $y)");
if (empty($this->workspaces[$workspace])) {
$this->log("Workspace $name does not exist.", 'error');
$this->log("Workspace $workspace does not exist.", 'error');
return;
}
@@ -500,7 +500,7 @@ class ctools_stylizer_image_processor {
$palette[$luminosity_input]['green'] = $green;
$palette[$luminosity_input]['blue'] = $blue;
// Now we complete the palette, first we'll do it tothe black, and then to
// Now we complete the palette, first we'll do it to the black, and then to
// the white.
// From input to black
@@ -822,7 +822,7 @@ function ctools_stylizer_add_plugin_forms(&$form_info, $plugin, $op) {
if ($op == 'add' && isset($plugin['add form'])) {
$id = $plugin['add form'];
}
else if (isset($plugin['edit form'])) {
elseif (isset($plugin['edit form'])) {
$id = $plugin['edit form'];
}
else {
@@ -25,4 +25,3 @@ function ctools_stylizer_theme(&$theme) {
'file' => 'includes/stylizer.inc',
);
}
@@ -23,22 +23,9 @@ function ctools_passthrough($module, $type, &$items) {
require_once DRUPAL_ROOT . '/' . $file->uri;
list($tool) = explode('.', $file->name, 2);
$function = $module . '_' . str_replace ('-', '_', $tool) . '_' . str_replace('-', '_', $type);
$function = $module . '_' . str_replace('-', '_', $tool) . '_' . str_replace('-', '_', $type);
if (function_exists($function)) {
$function($items);
}
}
}
/**
* Implementation of hook_theme_registry_alter()
*/
function ctools_theme_registry_alter(&$registry) {
// Move this one last last last so it can catch changes made by modules and themes.
$key = array_search('ctools_preprocess_page', $registry['page']['preprocess functions']);
if ($key) {
unset($registry['page']['preprocess functions'][$key]);
}
$registry['page']['preprocess functions'][] = 'ctools_preprocess_page';
}
@@ -0,0 +1,71 @@
<?php
/**
* @file
* Enables ctools generated modules to use UUIDs without the UUID module enabled.
* Per the ctools.module, this file only gets included if UUID doesn't exist.
*/
/**
* Pattern for detecting a valid UUID.
*/
if (!defined('UUID_PATTERN')) {
define('UUID_PATTERN', '[0-9a-f]{8}-([0-9a-f]{4}-){3}[0-9a-f]{12}');
}
/**
* Generates a UUID using the Windows internal GUID generator.
*
* @see http://php.net/com_create_guid
*/
function _ctools_uuid_generate_com() {
// Remove {} wrapper and make lower case to keep result consistent.
return drupal_strtolower(trim(com_create_guid(), '{}'));
}
/**
* Generates an universally unique identifier using the PECL extension.
*/
function _ctools_uuid_generate_pecl() {
$uuid_type = UUID_TYPE_DEFAULT;
return uuid_create($uuid_type);
}
/**
* Generates a UUID v4 using PHP code.
*
* Based on code from @see http://php.net/uniqid#65879 , but corrected.
*/
function _ctools_uuid_generate_php() {
// The field names refer to RFC 4122 section 4.1.2.
return sprintf('%04x%04x-%04x-4%03x-%04x-%04x%04x%04x',
// 32 bits for "time_low".
mt_rand(0, 65535), mt_rand(0, 65535),
// 16 bits for "time_mid".
mt_rand(0, 65535),
// 12 bits after the 0100 of (version) 4 for "time_hi_and_version".
mt_rand(0, 4095),
bindec(substr_replace(sprintf('%016b', mt_rand(0, 65535)), '10', 0, 2)),
// 8 bits, the last two of which (positions 6 and 7) are 01, for "clk_seq_hi_res"
// (hence, the 2nd hex digit after the 3rd hyphen can only be 1, 5, 9 or d)
// 8 bits for "clk_seq_low" 48 bits for "node".
mt_rand(0, 65535), mt_rand(0, 65535), mt_rand(0, 65535)
);
}
// This is wrapped in an if block to avoid conflicts with PECL's uuid_is_valid().
/**
* Check that a string appears to be in the format of a UUID.
*
* @param $uuid
* The string to test.
*
* @return
* TRUE if the string is well formed.
*/
if (!function_exists('uuid_is_valid')) {
function uuid_is_valid($uuid) {
return preg_match('/^' . UUID_PATTERN . '$/', $uuid);
}
}
@@ -1,5 +1,9 @@
<?php
/**
* @file
*/
/**
* Generate new context classes by argument settings on the view.
*/
@@ -47,7 +47,7 @@ function ctools_wizard_multistep_form($form_info, $step, &$form_state) {
// with form caching.
ctools_form_include($form_state, 'wizard');
// allow order array to be optional
// Allow order array to be optional.
if (empty($form_info['order'])) {
foreach ($form_info['forms'] as $step_id => $params) {
$form_info['order'][$step_id] = $params['title'];
@@ -83,7 +83,7 @@ function ctools_wizard_multistep_form($form_info, $step, &$form_state) {
$form_info['cache location'] = 'storage';
}
// If absolutely nothing was set for the cache area to work on
// If absolutely nothing was set for the cache area to work on.
if (!isset($form_state[$form_info['cache location']])) {
ctools_include('cache');
$form_state[$form_info['cache location']] = ctools_cache_get($form_info['cache mechanism'], $form_info['cache key']);
@@ -199,7 +199,7 @@ function ctools_wizard_multistep_form($form_info, $step, &$form_state) {
}
}
}
else if (isset($form_state['ajax next'])) {
elseif (isset($form_state['ajax next'])) {
// Clear a few items off the form state so we don't double post:
$next = $form_state['ajax next'];
unset($form_state['ajax next']);
@@ -274,7 +274,7 @@ function ctools_wizard_wrapper($form, &$form_state) {
if (!empty($form_info['show trail'])) {
ctools_add_css('wizard');
$form['ctools_trail'] = array(
'#markup' => theme(array('ctools_wizard_trail__' . $form_info['id'], 'ctools_wizard_trail'), array('trail' => $trail)),
'#markup' => theme(array('ctools_wizard_trail__' . $form_info['id'], 'ctools_wizard_trail'), array('trail' => $trail, 'form_info' => $form_info)),
'#weight' => -1000,
);
}
@@ -299,7 +299,7 @@ function ctools_wizard_wrapper($form, &$form_state) {
'#wizard type' => 'next',
'#weight' => -2000,
'#limit_validation_errors' => array(),
// hardcode the submit so that it doesn't try to save data.
// Hardcode the submit so that it doesn't try to save data.
'#submit' => array('ctools_wizard_submit'),
'#attributes' => $button_attributes,
);
@@ -325,19 +325,18 @@ function ctools_wizard_wrapper($form, &$form_state) {
// end of the form list (i.e, there is a next) then it's "update and return"
// to be clear. If this is the end of the path and there is no next, we
// call it 'Finish'.
// Even if there is no direct return path (some forms may not want you
// leaving in the middle) the final button is always a Finish and it does
// whatever the return action is.
if (!empty($form_info['show return']) && !empty($form_state['next'])) {
$form['buttons']['return'] = array(
'#type' => 'submit',
'#value' => $form_info['return text'],
'#value' => $form_info['return text'],
'#wizard type' => 'return',
'#attributes' => $button_attributes,
);
}
else if (empty($form_state['next']) || !empty($form_info['free trail'])) {
elseif (empty($form_state['next']) || !empty($form_info['free trail'])) {
$form['buttons']['return'] = array(
'#type' => 'submit',
'#value' => $form_info['finish text'],
@@ -352,7 +351,7 @@ function ctools_wizard_wrapper($form, &$form_state) {
'#type' => 'submit',
'#value' => $form_info['cancel text'],
'#wizard type' => 'cancel',
// hardcode the submit so that it doesn't try to save data.
// Hardcode the submit so that it doesn't try to save data.
'#limit_validation_errors' => array(),
'#submit' => array('ctools_wizard_submit'),
'#attributes' => $button_attributes,
@@ -370,7 +369,6 @@ function ctools_wizard_wrapper($form, &$form_state) {
// Set up our submit handler after theirs. Since putting something here will
// skip Drupal's autodetect, we autodetect for it.
// We make sure ours is after theirs so that they get to change #next if
// the want to.
$form['#submit'] = array();
@@ -398,7 +396,7 @@ function ctools_wizard_wrapper($form, &$form_state) {
$params = array($url, $options);
}
$form['#action'] = call_user_func_array('url', $params);
$form['#action'] = call_user_func_array('url', $params);
}
if (isset($info['wrapper']) && function_exists($info['wrapper'])) {
@@ -418,7 +416,7 @@ function ctools_wizard_submit(&$form, &$form_state) {
if (isset($form_state['clicked_button']['#wizard type'])) {
$type = $form_state['clicked_button']['#wizard type'];
// if AJAX enabled, we proceed slightly differently here.
// If AJAX enabled, we proceed slightly differently here.
if (!empty($form_state['ajax'])) {
if ($type == 'next') {
$form_state['ajax next'] = $form_state['clicked_button']['#next'];
@@ -428,7 +426,7 @@ function ctools_wizard_submit(&$form, &$form_state) {
if ($type == 'cancel' && isset($form_state['form_info']['cancel path'])) {
$form_state['redirect'] = $form_state['form_info']['cancel path'];
}
else if ($type == 'next') {
elseif ($type == 'next') {
$form_state['redirect'] = ctools_wizard_get_path($form_state['form_info'], $form_state['clicked_button']['#next']);
if (!empty($_GET['destination'])) {
// We don't want drupal_goto redirect this request
@@ -437,10 +435,10 @@ function ctools_wizard_submit(&$form, &$form_state) {
unset($_GET['destination']);
}
}
else if (isset($form_state['form_info']['return path'])) {
elseif (isset($form_state['form_info']['return path'])) {
$form_state['redirect'] = $form_state['form_info']['return path'];
}
else if ($type == 'finish' && isset($form_state['form_info']['cancel path'])) {
elseif ($type == 'finish' && isset($form_state['form_info']['cancel path'])) {
$form_state['redirect'] = $form_state['form_info']['cancel path'];
}
}
@@ -469,10 +467,8 @@ function ctools_wizard_get_path($form_info, $step) {
if (!isset($path[1]) || !is_array($path[1])) {
$path[1] = array();
}
// Ensure that the query part of options is an array.
$path[1] += array('query' => array());
// Add the destination parameter, if not set already.
$path[1]['query'] += drupal_get_destination();
$path[1] += drupal_get_destination();
}
return $path;
@@ -505,15 +501,15 @@ function ctools_wizard_defaults(&$form_info) {
}
$form_info = $form_info + $defaults;
// set form callbacks if they aren't defined
// Set form callbacks if they aren't defined.
foreach ($form_info['forms'] as $step => $params) {
if (!$params['form id']) {
$form_callback = $hook . '_' . $step . '_form';
$form_info['forms'][$step]['form id'] = $form_callback;
if (empty($params['form id'])) {
$form_callback = $hook . '_' . $step . '_form';
$form_info['forms'][$step]['form id'] = $form_callback;
}
}
// set button callbacks
// Set button callbacks.
$callbacks = array(
'back callback' => '_back',
'next callback' => '_next',
@@ -523,10 +519,10 @@ function ctools_wizard_defaults(&$form_info) {
);
foreach ($callbacks as $key => $callback) {
// never overwrite if explicity defined
// Never overwrite if explicity defined.
if (empty($form_info[$key])) {
$wizard_callback = $hook . $callback;
if (function_exists($wizard_callback)) {
if (function_exists($wizard_callback)) {
$form_info[$key] = $wizard_callback;
}
}
@@ -7,19 +7,16 @@
function ctools_wizard_theme(&$theme) {
$theme['ctools_wizard_trail'] = array(
'variables' => array('trail' => NULL),
'variables' => array('trail' => NULL, 'form_info' => NULL, 'divider' => ' » '),
'file' => 'includes/wizard.theme.inc',
);
}
/**
* Themable display of the 'breadcrumb' trail to show the order of the
* forms.
* Themable display of the 'breadcrumb' trail to show the order of the forms.
*/
function theme_ctools_wizard_trail($vars) {
$trail = $vars['trail'];
if (!empty($trail)) {
return '<div class="wizard-trail">' . implode(' » ', $trail) . '</div>';
if (!empty($vars['trail'])) {
return '<div class="wizard-trail">' . implode($vars['divider'], $vars['trail']) . '</div>';
}
}
@@ -36,9 +36,11 @@ Drupal.behaviors.CToolsAutoSubmit = {
attach: function(context) {
// 'this' references the form element
function triggerSubmit (e) {
var $this = $(this);
if (!$this.hasClass('ctools-ajaxing')) {
$this.find('.ctools-auto-submit-click').click();
if ($.contains(document.body, this)) {
var $this = $(this);
if (!$this.hasClass('ctools-ajaxing')) {
$this.find('.ctools-auto-submit-click').click();
}
}
}
@@ -212,6 +212,7 @@
content.slideToggle(100, afterToggle);
}
$container.toggleClass('ctools-collapsed');
toggle.toggleClass('ctools-toggle-collapsed');
// If we're supposed to remember the state of this class, do so.
@@ -40,7 +40,7 @@
Drupal.CTools.dependent.autoAttach = function() {
// Clear active bindings and triggers.
for (i in Drupal.CTools.dependent.activeTriggers) {
$(Drupal.CTools.dependent.activeTriggers[i]).unbind('change');
$(Drupal.CTools.dependent.activeTriggers[i]).unbind('change.ctools-dependent');
}
Drupal.CTools.dependent.activeTriggers = [];
Drupal.CTools.dependent.activeBindings = {};
@@ -97,7 +97,13 @@
else {
switch ($(trigger).attr('type')) {
case 'checkbox':
var val = $(trigger).attr('checked') ? true : false;
// **This check determines if using a jQuery version 1.7 or newer which requires the use of the prop function instead of the attr function when not called on an attribute
if ($().prop) {
var val = $(trigger).prop('checked') ? true : false;
}
else {
var val = $(trigger).attr('checked') ? true : false;
}
if (val) {
$(trigger).siblings('label').removeClass('hidden-options').addClass('expanded-options');
@@ -148,34 +154,41 @@
len++;
}
var object = $('#' + id + '-wrapper');
if (!object.size()) {
// Some elements can't use the parent() method or they can
// damage things. They are guaranteed to have wrappers but
// only if dependent.inc provided them. This check prevents
// problems when multiple AJAX calls cause settings to build
// up.
var $original = $('#' + id);
if ($original.is('fieldset') || $original.is('textarea')) {
continue;
}
object = $('#' + id).parent();
var $original = $('#' + id);
if ($original.is('fieldset') || $original.is('textarea')) {
continue;
}
var object = $original.parent();
if (Drupal.settings.CTools.dependent[id].type == 'disable') {
if (Drupal.settings.CTools.dependent[id].num <= len) {
// Show if the element if criteria is matched
object.attr('disabled', false);
object.addClass('dependent-options');
object.children().attr('disabled', false);
// **This check determines if using a jQuery version 1.7 or newer which requires the use of the prop function instead of the attr function when not called on an attribute
if (typeof $().prop == 'function') {
object.prop('disabled', false);
object.addClass('dependent-options');
object.children().prop('disabled', false);
}
else {
object.attr('disabled', false);
object.addClass('dependent-options');
object.children().attr('disabled', false);
}
}
else {
// Otherwise hide. Use css rather than hide() because hide()
// does not work if the item is already hidden, for example,
// in a collapsed fieldset.
object.attr('disabled', true);
object.children().attr('disabled', true);
// **This check determines if using a jQuery version 1.7 or newer which requires the use of the prop function instead of the attr function when not called on an attribute
if (typeof $().prop == 'function') {
object.prop('disabled', true);
object.children().prop('disabled', true);
}
else {
object.attr('disabled', true);
object.children().attr('disabled', true);
}
}
}
else {
@@ -194,7 +207,7 @@
}
}
$(trigger_id).change(function() {
$(trigger_id).bind('change.ctools-dependent', function() {
// Trigger the internal change function
// the attr('id') is used because closures are more confusing
changeTrigger(trigger_id, bind_id);
@@ -215,7 +228,7 @@
// is a sort of hacked one that's faster but much less flexible.
$("select.ctools-master-dependent")
.once('ctools-dependent')
.change(function() {
.bind('change.ctools-dependent', function() {
var val = $(this).val();
if (val == 'all') {
$('.ctools-dependent-all').show(0);
@@ -225,7 +238,7 @@
$('.ctools-dependent-' + val).show(0);
}
})
.trigger('change');
.trigger('change.ctools-dependent');
}
}
})(jQuery);
+220 -48
View File
@@ -48,7 +48,8 @@
modalOptions: {
opacity: .55,
background: '#fff'
}
},
modalClass: 'default'
};
var settings = {};
@@ -97,8 +98,13 @@
resize();
$('span.modal-title', Drupal.CTools.Modal.modal).html(Drupal.CTools.Modal.currentSettings.loadingText);
Drupal.CTools.Modal.modalContent(Drupal.CTools.Modal.modal, settings.modalOptions, settings.animation, settings.animationSpeed);
$('#modalContent .modal-content').html(Drupal.theme(settings.throbberTheme));
Drupal.CTools.Modal.modalContent(Drupal.CTools.Modal.modal, settings.modalOptions, settings.animation, settings.animationSpeed, settings.modalClass);
$('#modalContent .modal-content').html(Drupal.theme(settings.throbberTheme)).addClass('ctools-modal-loading');
// Position autocomplete results based on the scroll position of the modal.
$('#modalContent .modal-content').delegate('input.form-autocomplete', 'keyup', function() {
$('#autocomplete').css('top', $(this).position().top + $(this).outerHeight() + $(this).offsetParent().filter('#modal-content').scrollTop());
});
};
/**
@@ -115,18 +121,18 @@
*/
Drupal.theme.prototype.CToolsModalDialog = function () {
var html = ''
html += ' <div id="ctools-modal">'
html += ' <div class="ctools-modal-content">' // panels-modal-content
html += ' <div class="modal-header">';
html += ' <a class="close" href="#">';
html += Drupal.CTools.Modal.currentSettings.closeText + Drupal.CTools.Modal.currentSettings.closeImage;
html += ' </a>';
html += ' <span id="modal-title" class="modal-title">&nbsp;</span>';
html += ' </div>';
html += ' <div id="modal-content" class="modal-content">';
html += ' </div>';
html += '<div id="ctools-modal">'
html += ' <div class="ctools-modal-content">' // panels-modal-content
html += ' <div class="modal-header">';
html += ' <a class="close" href="#">';
html += Drupal.CTools.Modal.currentSettings.closeText + Drupal.CTools.Modal.currentSettings.closeImage;
html += ' </a>';
html += ' <span id="modal-title" class="modal-title">&nbsp;</span>';
html += ' </div>';
html += ' <div id="modal-content" class="modal-content">';
html += ' </div>';
html += ' </div>';
html += '</div>';
return html;
}
@@ -136,11 +142,11 @@
*/
Drupal.theme.prototype.CToolsModalThrobber = function () {
var html = '';
html += ' <div id="modal-throbber">';
html += ' <div class="modal-throbber-wrapper">';
html += Drupal.CTools.Modal.currentSettings.throbber;
html += ' </div>';
html += '<div id="modal-throbber">';
html += ' <div class="modal-throbber-wrapper">';
html += Drupal.CTools.Modal.currentSettings.throbber;
html += ' </div>';
html += '</div>';
return html;
};
@@ -222,7 +228,11 @@
// AJAX submits specified in this manner automatically submit to the
// normal form action.
element_settings.url = Drupal.CTools.Modal.findURL(this);
if (element_settings.url == '') {
element_settings.url = $(this).closest('form').attr('action');
}
element_settings.event = 'click';
element_settings.setClick = true;
var base = $this.attr('id');
Drupal.ajax[base] = new Drupal.ajax(base, this, element_settings);
@@ -249,9 +259,16 @@
$('input[type=submit], button', this).click(function(event) {
Drupal.ajax[base].element = this;
this.form.clk = this;
// Stop autocomplete from submitting.
if (Drupal.autocompleteSubmit && !Drupal.autocompleteSubmit()) {
return false;
}
// An empty event means we were triggered via .click() and
// in jquery 1.4 this won't trigger a submit.
if (event.bubbles == undefined) {
// We also have to check jQuery version to prevent
// IE8 + jQuery 1.4.4 to break on other events
// bound to the submit button.
if (jQuery.fn.jquery.substr(0, 3) === '1.4' && typeof event.bubbles === "undefined") {
$(this.form).trigger('submit');
return false;
}
@@ -282,7 +299,21 @@
// content. This is helpful for allowing users to see error messages at the
// top of a form, etc.
$('#modal-content').html(response.output).scrollTop(0);
Drupal.attachBehaviors();
// Attach behaviors within a modal dialog.
var settings = response.settings || ajax.settings || Drupal.settings;
Drupal.attachBehaviors($('#modalContent'), settings);
if ($('#modal-content').hasClass('ctools-modal-loading')) {
$('#modal-content').removeClass('ctools-modal-loading');
}
else {
// If the modal was already shown, and we are simply replacing its
// content, then focus on the first focusable element in the modal.
// (When first showing the modal, focus will be placed on the close
// button by the show() function called above.)
$('#modal-content :focusable:first').focus();
}
}
/**
@@ -333,8 +364,9 @@
* @param css obj of css attributes
* @param animation (fadeIn, slideDown, show)
* @param speed (valid animation speeds slow, medium, fast or # in ms)
* @param modalClass class added to div#modalContent
*/
Drupal.CTools.Modal.modalContent = function(content, css, animation, speed) {
Drupal.CTools.Modal.modalContent = function(content, css, animation, speed, modalClass) {
// If our animation isn't set, make it just show/pop
if (!animation) {
animation = 'show';
@@ -346,7 +378,7 @@
}
}
if (!speed) {
if (!speed && 0 !== speed) {
speed = 'fast';
}
@@ -363,9 +395,9 @@
css.filter = 'alpha(opacity=' + (100 * css.opacity) + ')';
content.hide();
// if we already ahve a modalContent, remove it
if ( $('#modalBackdrop')) $('#modalBackdrop').remove();
if ( $('#modalContent')) $('#modalContent').remove();
// If we already have modalContent, remove it.
if ($('#modalBackdrop').length) $('#modalBackdrop').remove();
if ($('#modalContent').length) $('#modalContent').remove();
// position code lifted from http://www.quirksmode.org/viewport/compatibility.html
if (self.pageYOffset) { // all except Explorer
@@ -386,9 +418,56 @@
if( docHeight < winHeight ) docHeight = winHeight;
// Create our divs
$('body').append('<div id="modalBackdrop" style="z-index: 1000; display: none;"></div><div id="modalContent" style="z-index: 1001; position: absolute;">' + $(content).html() + '</div>');
$('body').append('<div id="modalBackdrop" class="backdrop-' + modalClass + '" style="z-index: 1000; display: none;"></div><div id="modalContent" class="modal-' + modalClass + '" style="z-index: 1001; position: absolute;">' + $(content).html() + '</div>');
// Keyboard and focus event handler ensures focus stays on modal elements only
// Get a list of the tabbable elements in the modal content.
var getTabbableElements = function () {
var tabbableElements = $('#modalContent :tabbable'),
radioButtons = tabbableElements.filter('input[type="radio"]');
// The list of tabbable elements from jQuery is *almost* right. The
// exception is with groups of radio buttons. The list from jQuery will
// include all radio buttons, when in fact, only the selected radio button
// is tabbable, and if no radio buttons in a group are selected, then only
// the first is tabbable.
if (radioButtons.length > 0) {
// First, build up an index of which groups have an item selected or not.
var anySelected = {};
radioButtons.each(function () {
var name = this.name;
if (typeof anySelected[name] === 'undefined') {
anySelected[name] = radioButtons.filter('input[name="' + name + '"]:checked').length !== 0;
}
});
// Next filter out the radio buttons that aren't really tabbable.
var found = {};
tabbableElements = tabbableElements.filter(function () {
var keep = true;
if (this.type == 'radio') {
if (anySelected[this.name]) {
// Only keep the selected one.
keep = this.checked;
}
else {
// Only keep the first one.
if (found[this.name]) {
keep = false;
}
found[this.name] = true;
}
}
return keep;
});
}
return tabbableElements.get();
};
// Keyboard and focus event handler ensures only modal elements gain focus.
modalEventHandler = function( event ) {
target = null;
if ( event ) { //Mozilla
@@ -405,26 +484,85 @@
return true;
}
}
if( $(target).filter('*:visible').parents('#modalContent').size()) {
// allow the event only if target is a visible child node of #modalContent
if ($(target).is('#modalContent, body') || $(target).filter('*:visible').parents('#modalContent').length) {
// Allow the event only if target is a visible child node
// of #modalContent.
return true;
}
if ( $('#modalContent')) $('#modalContent').get(0).focus();
return false;
else {
getTabbableElements()[0].focus();
}
event.preventDefault();
};
$('body').bind( 'focus', modalEventHandler );
$('body').bind( 'keypress', modalEventHandler );
// Keypress handler Ensures you can only TAB to elements within the modal.
// Based on the psuedo-code from WAI-ARIA 1.0 Authoring Practices section
// 3.3.1 "Trapping Focus".
modalTabTrapHandler = function (evt) {
// We only care about the TAB key.
if (evt.which != 9) {
return true;
}
var tabbableElements = getTabbableElements(),
firstTabbableElement = tabbableElements[0],
lastTabbableElement = tabbableElements[tabbableElements.length - 1],
singleTabbableElement = firstTabbableElement == lastTabbableElement,
node = evt.target;
// If this is the first element and the user wants to go backwards, then
// jump to the last element.
if (node == firstTabbableElement && evt.shiftKey) {
if (!singleTabbableElement) {
lastTabbableElement.focus();
}
return false;
}
// If this is the last element and the user wants to go forwards, then
// jump to the first element.
else if (node == lastTabbableElement && !evt.shiftKey) {
if (!singleTabbableElement) {
firstTabbableElement.focus();
}
return false;
}
// If this element isn't in the dialog at all, then jump to the first
// or last element to get the user into the game.
else if ($.inArray(node, tabbableElements) == -1) {
// Make sure the node isn't in another modal (ie. WYSIWYG modal).
var parents = $(node).parents().get();
for (var i = 0; i < parents.length; ++i) {
var position = $(parents[i]).css('position');
if (position == 'absolute' || position == 'fixed') {
return true;
}
}
if (evt.shiftKey) {
lastTabbableElement.focus();
}
else {
firstTabbableElement.focus();
}
}
};
$('body').bind('keydown', modalTabTrapHandler);
// Create our content div, get the dimensions, and hide it
var modalContent = $('#modalContent').css('top','-1000px');
var mdcTop = wt + ( winHeight / 2 ) - ( modalContent.outerHeight() / 2);
var $modalHeader = modalContent.find('.modal-header');
var mdcTop = wt + Math.max((winHeight / 2) - (modalContent.outerHeight() / 2), 0);
var mdcLeft = ( winWidth / 2 ) - ( modalContent.outerWidth() / 2);
$('#modalBackdrop').css(css).css('top', 0).css('height', docHeight + 'px').css('width', docWidth + 'px').show();
modalContent.css({top: mdcTop + 'px', left: mdcLeft + 'px'}).hide()[animation](speed);
// Bind a click for closing the modalContent
modalContentClose = function(){close(); return false;};
$('.close').bind('click', modalContentClose);
$('.close', $modalHeader).bind('click', modalContentClose);
// Bind a keypress on escape for closing the modalContent
modalEventEscapeCloseHandler = function(event) {
@@ -436,31 +574,63 @@
$(document).bind('keydown', modalEventEscapeCloseHandler);
// Per WAI-ARIA 1.0 Authoring Practices, initial focus should be on the
// close button, but we should save the original focus to restore it after
// the dialog is closed.
var oldFocus = document.activeElement;
$('.close', $modalHeader).focus();
// Close the open modal content and backdrop
function close() {
// Unbind the events
$(window).unbind('resize', modalContentResize);
$('body').unbind( 'focus', modalEventHandler);
$('body').unbind( 'keypress', modalEventHandler );
$('.close').unbind('click', modalContentClose);
$('body').unbind('keypress', modalEventEscapeCloseHandler);
$('body').unbind( 'keydown', modalTabTrapHandler );
$('.close', $modalHeader).unbind('click', modalContentClose);
$(document).unbind('keydown', modalEventEscapeCloseHandler);
$(document).trigger('CToolsDetachBehaviors', $('#modalContent'));
// Set our animation parameters and use them
if ( animation == 'fadeIn' ) animation = 'fadeOut';
if ( animation == 'slideDown' ) animation = 'slideUp';
if ( animation == 'show' ) animation = 'hide';
// Closing animation.
switch (animation) {
case 'fadeIn':
modalContent.fadeOut(speed, modalContentRemove);
break;
// Close the content
modalContent.hide()[animation](speed);
case 'slideDown':
modalContent.slideUp(speed, modalContentRemove);
break;
// Remove the content
case 'show':
modalContent.hide(speed, modalContentRemove);
break;
}
}
// Remove the content.
modalContentRemove = function () {
$('#modalContent').remove();
$('#modalBackdrop').remove();
// Restore focus to where it was before opening the dialog.
$(oldFocus).focus();
};
// Move and resize the modalBackdrop and modalContent on resize of the window
modalContentResize = function(){
// Move and resize the modalBackdrop and modalContent on window resize.
modalContentResize = function () {
// Reset the backdrop height/width to get accurate document size.
$('#modalBackdrop').css('height', '').css('width', '');
// Position code lifted from:
// http://www.quirksmode.org/viewport/compatibility.html
if (self.pageYOffset) { // all except Explorer
var wt = self.pageYOffset;
} else if (document.documentElement && document.documentElement.scrollTop) { // Explorer 6 Strict
var wt = document.documentElement.scrollTop;
} else if (document.body) { // all other Explorers
var wt = document.body.scrollTop;
}
// Get our heights
var docHeight = $(document).height();
var docWidth = $(document).width();
@@ -470,7 +640,7 @@
// Get where we should move content to
var modalContent = $('#modalContent');
var mdcTop = ( winHeight / 2 ) - ( modalContent.outerHeight() / 2);
var mdcTop = wt + Math.max((winHeight / 2) - (modalContent.outerHeight() / 2), 0);
var mdcLeft = ( winWidth / 2 ) - ( modalContent.outerWidth() / 2);
// Apply the changes
@@ -478,8 +648,6 @@
modalContent.css('top', mdcTop + 'px').css('left', mdcLeft + 'px').show();
};
$(window).bind('resize', modalContentResize);
$('#modalContent').focus();
};
/**
@@ -502,8 +670,12 @@
$(window).unbind('resize', modalContentResize);
$('body').unbind('focus', modalEventHandler);
$('body').unbind('keypress', modalEventHandler);
$('.close').unbind('click', modalContentClose);
$(document).trigger('CToolsDetachBehaviors', $('#modalContent'));
$('body').unbind( 'keydown', modalTabTrapHandler );
var $modalContent = $('#modalContent');
var $modalHeader = $modalContent.find('.modal-header');
$('.close', $modalHeader).unbind('click', modalContentClose);
$('body').unbind('keypress', modalEventEscapeCloseHandler);
$(document).trigger('CToolsDetachBehaviors', $modalContent);
// jQuery magic loop through the instances and run the animations or removal.
content.each(function(){
@@ -0,0 +1,43 @@
/**
* @file
* Custom state for handling visibility
*/
/**
* Add a new state to Drupal #states. We use this to toggle element-invisible
* to show/hidden #states elements. This allows elements to be visible to
* screen readers.
*
* To use:
* $form['my_form_field'] = array(
* ..
* // Only show this field if 'some_other_field' is checked.
* '#states => array(
* 'show' => array(
* 'some-other-field' => array('checked' => TRUE),
* ),
* ),
* ..
* // Required to load the 'show' state handler.
* '#attached' => array(
* 'js' => array(ctools_attach_js('states-show')),
* ),
* );
*/
(function ($) {
'use strict';
Drupal.states.State.aliases.hidden = '!show';
// Show/hide form items by toggling the 'element-invisible' class. This is a
// more accessible option than the core 'visible' state.
$(document).bind('state:show', function(e) {
if (e.trigger) {
var element = $(e.target).closest('.form-item, .form-submit, .form-wrapper');
element.toggle(e.value);
e.value === true ? element.removeClass('element-invisible') : element.addClass('element-invisible');
}
});
})(jQuery);
@@ -5,7 +5,7 @@
Drupal.CTools.Stylizer.addFarbtastic = function(context) {
// This behavior attaches by ID, so is only valid once on a page.
if ($('ctools_stylizer_color_scheme_form .color-form.Stylizer-processed').size()) {
if ($('#ctools_stylizer_color_scheme_form .color-form.Stylizer-processed').size()) {
return;
}
@@ -100,7 +100,7 @@ body form#page-manager-list-pages-form {
#page-manager-edit .page-manager-edit-operations li {
list-style: none;
background: #F6F6F6;
background: #f6f6f6;
border-top: 1px solid #aaa;
border-left: 1px solid #aaa;
border-right: 1px solid #aaa;
@@ -111,7 +111,7 @@ body form#page-manager-list-pages-form {
#page-manager-edit .page-manager-edit-operations li.active,
#page-manager-edit .page-manager-edit-operations li.active-group .page-manager-group-title {
background: #FFFFFF url(../images/arrow-active.png) no-repeat scroll right center;
background: #ffffff url(../images/arrow-active.png) no-repeat scroll right center;
}
#page-manager-edit .page-manager-edit-operations li.changed,
@@ -123,7 +123,7 @@ body form#page-manager-list-pages-form {
/** provide a reset for non active stray paths */
#page-manager-edit .page-manager-edit-operations li.active-group li.not-active .page-manager-group-title,
#page-manager-edit .page-manager-edit-operations li.changed-group li.not-changed .page-manager-group-title {
background: #F6F6F6;
background: #f6f6f6;
}
#page-manager-edit .page-manager-edit-operations li.active {
@@ -132,7 +132,7 @@ body form#page-manager-list-pages-form {
#page-manager-edit .page-manager-edit-operations li.active a,
#page-manager-edit .page-manager-edit-operations li.active a:hover {
background: #FFFFFF url(../images/arrow-active.png) no-repeat scroll right center;
background: #ffffff url(../images/arrow-active.png) no-repeat scroll right center;
color: #000000;
font-weight: bold;
}
@@ -271,8 +271,8 @@ body form#page-manager-list-pages-form {
#page-manager-edit .actions li a {
display: block;
padding: 0.2em 0.5em;
color:#0062A0;
background-color: #F6F6F6;
color: #0062a0;
background-color: #f6f6f6;
}
#page-manager-edit .page-manager-changed {

Some files were not shown because too many files have changed in this diff Show More