Commit adf534e1 authored by Riccardo Padovani's avatar Riccardo Padovani

Updated module ctools to version 7.x-1.4

parent 36882cf6
File mode changed from 100644 to 100755
......@@ -4,9 +4,9 @@ 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 2014-02-12
version = "7.x-1.4"
core = "7.x"
project = "ctools"
datestamp = "1365013512"
datestamp = "1392220730"
......@@ -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;
......
......@@ -6,9 +6,9 @@ files[] = includes/context.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"
; Information added by Drupal.org packaging script on 2014-02-12
version = "7.x-1.4"
core = "7.x"
project = "ctools"
datestamp = "1365013512"
datestamp = "1392220730"
......@@ -37,7 +37,7 @@ function ctools_requirements($phase) {
}
/**
* Implements hook_schemea
* Implements hook_schema().
*/
function ctools_schema() {
return ctools_schema_2();
......
......@@ -367,6 +367,59 @@ 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.
*
......
......@@ -4,9 +4,9 @@ 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 2014-02-12
version = "7.x-1.4"
core = "7.x"
project = "ctools"
datestamp = "1365013512"
datestamp = "1392220730"
......@@ -4,9 +4,9 @@ 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 2014-02-12
version = "7.x-1.4"
core = "7.x"
project = "ctools"
datestamp = "1365013512"
datestamp = "1392220730"
......@@ -4,9 +4,9 @@ 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 2014-02-12
version = "7.x-1.4"
core = "7.x"
project = "ctools"
datestamp = "1365013512"
datestamp = "1392220730"
......@@ -36,6 +36,26 @@ function ctools_custom_content_ctools_plugin_directory($module, $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.
*
......
......@@ -7,9 +7,9 @@ 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 2014-02-12
version = "7.x-1.4"
core = "7.x"
project = "ctools"
datestamp = "1365013512"
datestamp = "1392220730"
......@@ -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>
......
......@@ -156,6 +156,9 @@ function mymodule_schema() {
<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>
<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>
......
......@@ -687,6 +687,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;
}
......
......@@ -24,67 +24,116 @@ function ctools_content_menu(&$items) {
* Helper function for autocompletion of entity titles.
*/
function ctools_content_autocomplete_entity($type, $string = '') {
$entity = entity_get_info($type);
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);
}
global $user;
$entity_info = entity_get_info($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]);
$entity_id = $preg_matches[1];
$entity = entity_load($type, array($entity_id));
// Format results in an array so later we could add attributes to the
// autocomplete text that is returned.
$results = array($entity_id => array(
'label' => $entity[$entity_id]->$entity_info['entity keys']['label'],
));
}
elseif ($entity['entity keys']['label']) {
$query->condition('b.' . $entity['entity keys']['label'], '%' . db_like($string) . '%', 'LIKE');
else {
$results = _ctools_getReferencableEntities($type, $entity_info, $string, 'LIKE', 10);
}
$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)
);
foreach($results as $entity_id => $result) {
if (!$entity_info['entity keys']['label']) {
$matches["[id: $entity_id]"] = '<span class="autocomplete_title">' . $entity_id . '</span>';
}
else {
// If not, restrict the query to published nodes.
$query->condition('b.status', NODE_PUBLISHED);
$matches[$result['label'] . " [id: $entity_id]"] = '<span class="autocomplete_title">' . check_plain($result['label']) . '</span>';
}
}
$query->addTag('node_access');
$query->join('users', 'u', 'b.uid = u.uid');
$query->addField('u', 'name', 'name');
drupal_json_output($matches);
}
}
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>';
/*
* Use well known/tested entity reference code to build our search query
* From EntityReference_SelectionHandler_Generic class
*/
function _ctools_buildQuery($entity_type, $entity_info, $match = NULL, $match_operator = 'CONTAINS') {
$base_table = $entity_info['base table'];
$query = db_select($base_table)
->fields($base_table, array($entity_info['entity keys']['id']));
if (isset($match)) {
if (isset($entity_info['entity keys']['label'])) {
$query->condition($base_table .'.'. $entity_info['entity keys']['label'], '%' . $match . '%' , $match_operator);
}
}
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>';
// Add a label to the query, if the label exists
if (isset($entity_info['entity keys']['label'])) {
$query->fields($base_table, array($entity_info['entity keys']['label']));
}
// Add a generic entity access tag to the query.
$query->addTag('ctools');
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') && !count(module_implements('node_grants'))) {
$node_alias = $query->innerJoin('node', 'n', '%alias.nid = comment.nid');
$query->condition($node_alias . '.status', NODE_PUBLISHED);
}
$query->addTag('node_access');
}
else {
$matches["[id: $id]"] = '<span class="autocomplete_title">' . check_plain($item->{$entity['entity keys']['id']}) . '</span>';
$query->addTag($entity_type . '_access');
}
// Add the sort option.
if(isset($entity_info['entity keys']['label'])) {
$query->orderBy($base_table .'.'. $entity_info['entity keys']['label'], '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) {
$options = array();
$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) {
$options[$record->{$entity_info['entity keys']['id']}] = array(
'label' => isset($entity_info['entity keys']['label']) ? check_plain($record->{$entity_info['entity keys']['label']}) : $record->{$entity_info['entity keys']['id']},
);
}
drupal_json_output($matches);
}
return $options;
}
\ No newline at end of file
......@@ -416,12 +416,19 @@ 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 = array(
'values' => array(),
'programmed' => FALSE,
'process_input' => FALSE,
'complete form' => array(),
);
$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 +453,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(
......
......@@ -161,7 +161,7 @@ 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']);
drupal_goto($info['destination'], $options, $info['response code']);
// @todo -- should other response codes be supported here?
}
}
......
......@@ -1400,8 +1400,7 @@ function ctools_get_relevant_access_plugins($contexts) {
* Create a context for the logged in user.
*/
function ctools_access_get_loggedin_context() {
global $user;
$context = ctools_context_create('entity:user', $user);
$context = ctools_context_create('entity:user', array('type' => 'current'), TRUE);
$context->identifier = t('Logged in user');
$context->keyword = 'viewer';
$context->id = 0;
......
......@@ -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),
......
......@@ -945,7 +945,13 @@ 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";
......@@ -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);
......@@ -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
......
......@@ -343,8 +343,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) {
......
<?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.
*/
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() {
return uuid_create(UUID_TYPE_DEFAULT);
}
/**
* 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);
}
}
......@@ -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.
......
......@@ -99,6 +99,11 @@
$('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));
// 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());
});
};
/**
......@@ -222,7 +227,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);
......@@ -282,7 +291,10 @@
// 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);
}
/**
......
......@@ -14,7 +14,7 @@
function page_manager_list_page($js = NULL) {
// Prevent this page from showing up when random other links fail.
if ($js && $js != 'ajax' && $js != 'nojs') {
return drupal_not_found();
return MENU_NOT_FOUND;
}
// TRUE if 'ajax', FALSE if otherwise.
......@@ -62,7 +62,7 @@ function page_manager_list_page($js = NULL) {
if (isset($input['op']) && $input['op'] == t('Reset')) {
unset($_SESSION['page_manager']['#admin']);
if (!$js) {
return drupal_goto($_GET['q']);
drupal_goto($_GET['q']);
}
// clear everything but form id, form build id and form token:
$keys = array_keys($input);
......@@ -930,7 +930,7 @@ function _page_manager_get_operation_content($js, &$page, $active, $operation, $
$output = drupal_render($built_form);
$title = empty($form_state['title']) ? $operation['title'] : $form_state['title'];
$titles[] = $title;
$title = implode(' &raquo ', array_filter($titles));
$title = implode(' &raquo; ', array_filter($titles));
// If there are messages for the form, render them.
if ($messages = theme('status_messages')) {
......
......@@ -4,9 +4,9 @@ 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 2014-02-12
version = "7.x-1.4"
core = "7.x"
project = "ctools"
datestamp = "1365013512"
datestamp = "1392220730"
......@@ -237,7 +237,7 @@ function page_manager_page_add_subtask($task_name = NULL, $step = NULL) {
if ($task_name) {
$page = page_manager_get_page_cache($task_name);
if (empty($page)) {
return drupal_not_found();
return MENU_NOT_FOUND;
}
$form_info['path'] = "admin/structure/pages/add/$task_name/%step";
......
......@@ -321,7 +321,7 @@ function page_manager_page_execute($subtask_id) {
ctools_include('context-task-handler');
$output = ctools_context_handler_render($task, $subtask, $contexts, $args);
if ($output === FALSE) {
return drupal_not_found();
return MENU_NOT_FOUND;
}
return $output;
......
......@@ -138,7 +138,7 @@ function page_manager_term_view_page($term, $depth = NULL) {
$contexts = ctools_context_handler_get_task_contexts($task, '', array($term, $depth));
if (empty($contexts)) {
return drupal_not_found();
return MENU_NOT_FOUND;
}
// Build the full output using the configured CTools plugin.
......
......@@ -139,6 +139,12 @@ function ctools_entity_field_value_ctools_access_settings_submit($form, &$form_s
* Check for access.
*/
function ctools_entity_field_value_ctools_access_check($conf, $context, $plugin) {
if (!isset($context->data)) {
// If the context doesn't exist -- for example, a newly added entity
// reference is used as a pane visibility criteria -- we deny access.
return FALSE;
}
list($parent, $entity_type, $bundle_type, $field_name) = explode(':', $plugin['name']);
if ($field_items = field_get_items($entity_type, $context->data, $field_name)) {
......
......@@ -17,7 +17,11 @@ $plugin = array(
'settings form' => 'ctools_term_vocabulary_ctools_access_settings',
'settings form submit' => 'ctools_term_vocabulary_ctools_access_settings_submit',
'summary' => 'ctools_term_vocabulary_ctools_access_summary',
'required context' => new ctools_context_required(t('Vocabulary'), array('taxonomy_term', 'terms', 'taxonomy_vocabulary')),
'required context' => new ctools_context_required(t('Vocabulary'), array(
'taxonomy_term',
'terms',
'taxonomy_vocabulary'
)),
);
/**
......@@ -27,15 +31,17 @@ function ctools_term_vocabulary_ctools_access_settings($form, &$form_state, $con
$options = array();
$vocabularies = taxonomy_get_vocabularies();
foreach ($vocabularies as $voc) {
$options[$voc->vid] = check_plain($voc->name);
$options[$voc->machine_name] = check_plain($voc->name);
}
$form['settings']['vids'] = array(
_ctools_term_vocabulary_ctools_access_map_vids($conf);
$form['settings']['machine_name'] = array(
'#type' => 'checkboxes',
'#title' => t('Vocabularies'),
'#options' => $options,
'#description' => t('Only the checked vocabularies will be valid.'),
'#default_value' => $conf['vids'],
'#default_value' => $conf['machine_name'],
);
return $form;
}
......@@ -44,7 +50,7 @@ function ctools_term_vocabulary_ctools_access_settings($form, &$form_state, $con
* Compress the term_vocabularys allowed to the minimum.
*/
function ctools_term_vocabulary_ctools_access_settings_submit($form, &$form_state) {
$form_state['values']['settings']['vids'] = array_filter($form_state['values']['settings']['vids']);
$form_state['values']['settings']['machine_name'] = array_filter($form_state['values']['settings']['machine_name']);
}
/**
......@@ -53,11 +59,13 @@ function ctools_term_vocabulary_ctools_access_settings_submit($form, &$form_stat
function ctools_term_vocabulary_ctools_access_check($conf, $context) {
// As far as I know there should always be a context at this point, but this
// is safe.
if (empty($context) || empty($context->data) || empty($context->data->vid)) {
if (empty($context) || empty($context->data) || empty($context->data->vocabulary_machine_name)) {
return FALSE;
}
if (array_filter($conf['vids']) && empty($conf['vids'][$context->data->vid])) {
_ctools_term_vocabulary_ctools_access_map_vids($conf);
if (array_filter($conf['machine_name']) && empty($conf['machine_name'][$context->data->vocabulary_machine_name])) {
return FALSE;
}
......@@ -73,15 +81,47 @@ function ctools_term_vocabulary_ctools_access_summary($conf, $context) {
}
$vocabularies = taxonomy_get_vocabularies();
_ctools_term_vocabulary_ctools_access_map_vids($conf);
$names = array();
foreach (array_filter($conf['vids']) as $vid) {
$names[] = check_plain($vocabularies[$vid]->name);
if (!empty($conf['machine_name'])) {
foreach (array_filter($conf['machine_name']) as $machine_name) {
foreach ($vocabularies as $vocabulary) {
if ($vocabulary->machine_name === $machine_name) {
$names[] = check_plain($vocabulary->name);
continue;
}
}
}
}
if (empty($names)) {
return t('@identifier is any vocabulary', array('@identifier' => $context->identifier));
}
return format_plural(count($names), '@identifier vocabulary is "@vids"', '@identifier vocabulary is one of "@vids"', array('@vids' => implode(', ', $names), '@identifier' => $context->identifier));
return format_plural(count($names), '@identifier vocabulary is "@machine_names"', '@identifier vocabulary is one of "@machine_names"', array(
'@machine_names' => implode(', ', $names),
'@identifier' => $context->identifier
));
}
/**
* Helper function to map the vids from old features to the new machine_name.
*
* Add the machine_name key to $conf if the vids key exist.
*
* @param array $conf
* The configuration of this plugin.
*/
function _ctools_term_vocabulary_ctools_access_map_vids(&$conf) {
if (!empty($conf['vids'])) {
$conf['machine_name'] = array();
$vocabularies = taxonomy_get_vocabularies();
foreach ($conf['vids'] as $vid) {
$machine_name = $vocabularies[$vid]->machine_name;
$conf['machine_name'][$machine_name] = $vocabularies[$vid]->machine_name;
}
}
}
......@@ -39,7 +39,7 @@ function ctools_argument_rid_context($arg = NULL, $conf = NULL, $empty = FALSE)
return FALSE;
}
$nid = db_query('SELECT nid FROM {node_revisions} WHERE vid = :vid', array(':vid' => $arg))->fetchField();
$nid = db_query('SELECT nid FROM {node_revision} WHERE vid = :vid', array(':vid' => $arg))->fetchField();
$node = node_load($nid, $arg);
if (!$node) {
return FALSE;
......
......@@ -40,6 +40,11 @@ function ctools_block_content_type_content_type($subtype_id) {
* of the form "$module . '_ctools_block_info'".
*/
function ctools_block_content_type_content_types() {
$types = &drupal_static(__FUNCTION__);
if (isset($types)) {
return $types;
}
$types = array();
foreach (module_implements('block_info') as $module) {
$module_blocks = module_invoke($module, 'block_info');
......@@ -156,6 +161,7 @@ function ctools_block_content_type_render($subtype, $conf) {
$block->module = $module;
$block->delta = $delta;
if (!isset($block->title)) {
if ($module == 'block' && !empty($info) && isset($info->title)) {
$block->title = $info->title;
}
......@@ -165,6 +171,7 @@ function ctools_block_content_type_render($subtype, $conf) {
else {
$block->title = NULL;
}
}
if (module_exists('block') && user_access('administer blocks')) {
$block->admin_links = array(
......@@ -286,13 +293,18 @@ function ctools_block_content_type_admin_info($subtype, $conf) {
list($module, $delta) = _ctools_block_get_module_delta($subtype, $conf);
$block = (object) module_invoke($module, 'block_view', $delta);
if (!empty($block)) {
// Sanitize the block because <script> tags can hose javascript up:
if (!empty($block->content)) {
$block->content = filter_xss_admin($block->content);
$block->content = filter_xss_admin(render($block->content));
}
if (!empty($block) && !empty($block->subject)) {
if (!empty($block->subject)) {
$block->title = $block->subject;
}
elseif (empty($block->title)) {
$block->title = t('No title');
}
return $block;
}
}
......
......@@ -25,7 +25,7 @@ if (module_exists('comment')) {
function ctools_comment_reply_form_content_type_render($subtype, $conf, $panel_args, $context) {
$comment = ($context[1]->identifier == 'No context') ? NULL : clone($context[1]->data);
$comment = ($context[1]->identifier == t('No context')) ? NULL : clone($context[1]->data);
$block = new stdClass();
$block->module = 'comments';
if ($comment) $block->delta = $comment->cid;
......
......@@ -45,6 +45,11 @@ function ctools_custom_content_type_content_type($subtype_id) {
* Return all custom content types available.
*/
function ctools_custom_content_type_content_types() {
$types = &drupal_static(__FUNCTION__);
if (isset($types)) {
return $types;
}
ctools_include('export');
$types = array();
$types['custom'] = _ctools_default_content_type_content_type();
......
......@@ -38,27 +38,33 @@ function ctools_entity_field_content_type_content_types() {
$context_types = array();
$entities = entity_get_info();
$description = t('Field on the referenced entity.');
$styles = t('Formatter Styles');
$categories = array();
foreach ($entities as $entity_type => $entity) {
$category = t(ucfirst($entity_type));
$categories[$entity_type] = $category;
foreach ($entity['bundles'] as $type => $bundle) {
foreach (field_info_instances($entity_type, $type) as $field_name => $field) {
if (!isset($types[$entity_type . ':' . $field_name])) {
$label = t($field['label']);
$types[$entity_type . ':' . $field_name] = array(
'category' => t(ucfirst($entity_type)),
'category' => $category,
'icon' => 'icon_field.png',
'title' => t('Field: @widget_label (@field_name)', array(
'@widget_label' => t($field['label']),
'@widget_label' => $label,
'@field_name' => $field_name,
)),
'description' => t('Field on the referenced entity.'),
'description' => $description,
'edit form' => array(
'ctools_entity_field_content_type_formatter_options' => array(
'default' => TRUE,
'title' => t('Formatter options for: @widget_label (@field_name)', array(
'@widget_label' => t($field['label']),
'@widget_label' => $label,
'@field_name' => $field_name,
)),
),
'ctools_entity_field_content_type_formatter_styles' => t('Formatter Styles'),
'ctools_entity_field_content_type_formatter_styles' => $styles,
),
);
}
......@@ -70,7 +76,7 @@ function ctools_entity_field_content_type_content_types() {
// Create the required context for each field related to the bundle types.
foreach ($types as $key => $field_content_type) {
list($entity_type, $field_name) = explode(':', $key, 2);
$types[$key]['required context'] = new ctools_context_required(t(ucfirst($entity_type)), $entity_type, array(
$types[$key]['required context'] = new ctools_context_required($categories[$entity_type], $entity_type, array(
'type' => array_keys($context_types[$key]['types']),
));
unset($context_types[$key]['types']);
......
......@@ -25,6 +25,11 @@ function ctools_entity_field_extra_content_type_content_type($subtype) {
*/
function ctools_entity_field_extra_content_type_content_types() {
// This will hold all the individual field content types.
$types = &drupal_static(__FUNCTION__);
if (isset($types)) {
return $types;
}
$types = array();
$context_types = array();
$entities = entity_get_info();
......@@ -97,13 +102,20 @@ function ctools_entity_field_extra_content_type_render($subtype, $conf, $panel_a
$entity = clone $context->data;
list($entity_type, $field_name) = explode(':', $subtype, 2);
list($id, $vid, $bundle) = entity_extract_ids($entity_type, $entity);
$langcode = $GLOBALS['language_content']->language;
$function = $entity_type . '_view';
if (in_array($entity_type, array('node', 'taxonomy_term', 'user')) && function_exists($function)) {
// Call known ENTITY_view() to get the extra field.
$entity->content = $function($entity, $conf['view_mode'], $langcode);
}
else {
// Invoke the view-hook to get the extra field.
$entity->content = array();
$langcode = $GLOBALS['language_content']->language;
module_invoke_all($entity_type . '_view', $entity, $conf['view_mode'], $langcode);
module_invoke_all('entity_view', $entity, $entity_type, $conf['view_mode'], $langcode);
}
if (isset($entity->content[$field_name])) {
// Build the content type block.
......
......@@ -30,6 +30,11 @@ function ctools_entity_form_field_content_type_content_type($subtype) {
*/
function ctools_entity_form_field_content_type_content_types() {
// This will hold all the individual field content types.
$types = &drupal_static(__FUNCTION__);
if (isset($types)) {
return $types;
}
$types = array();
$content_types = array();
$entities = entity_get_info();
......
......@@ -14,7 +14,7 @@ $plugin = array(
'title' => t('Site slogan'),
'single' => TRUE,
'icon' => 'icon_page.png',
'description' => t('Add the slogan trail as content.'),
'description' => t("Add the site's slogan as content."),
'category' => t('Page elements'),
'render last' => TRUE,
);
......@@ -26,7 +26,7 @@ $plugin = array(
*/
function ctools_page_slogan_content_type_render($subtype, $conf, $panel_args) {
$block = new stdClass();
$block->content = (theme_get_setting('toggle_slogan') ? filter_xss_admin(variable_get('site_slogan', '')) : '');
$block->content = filter_xss_admin(variable_get('site_slogan', ''));
return $block;
}
......@@ -33,19 +33,26 @@ function ctools_token_content_type_content_type($subtype) {
*/
function ctools_token_content_type_content_types() {
// This will hold all the properties.
$types = &drupal_static(__FUNCTION__);
if (isset($types)) {
return $types;
}
$types = array();
$info = token_info();
foreach ($info['tokens'] as $entity_type => $tokens) {
$category = t('@entity (tokens)', array('@entity' => ucfirst($entity_type)));
$context = new ctools_context_required(t(ucfirst($entity_type)), $entity_type);
foreach ($tokens as $name => $token) {
if (!empty($token['name'])) {
$token += array('description' => '');
$types[$entity_type . ':' . $name] = array(
'category' => t('@entity (tokens)', array('@entity' => ucfirst($entity_type))),
'category' => $category,
'icon' => 'icon_token.png',
'title' => $token['name'],
'description' => $token['description'],
'required context' => new ctools_context_required(t(ucfirst($entity_type)), $entity_type),
'required context' => $context,
);
}
}
......
<?php
if (module_exists('profile') && !is_null(profile_user_categories())) {
if (module_exists('profile') && !(defined('MAINTENANCE_MODE') && MAINTENANCE_MODE == 'update') && !is_null(profile_user_categories())) {
/**
* Plugins are described by creating a $plugin array which will be used
* by the system that includes this file.
......
......@@ -51,8 +51,9 @@ function ctools_context_token_convert_list() {
function ctools_context_token_convert($context, $token) {
$tokens = token_info();
list($type, $token) = explode(':', $token, 2);
$parts = explode(':', $token, 2);
$real_type = isset($tokens['types'][$type]['type']) ? $tokens['types'][$type]['type'] : $type;
if (isset($tokens['tokens'][$real_type][$token])) {
if (isset($tokens['tokens'][$real_type][$parts[0]])) {
$values = token_generate($type, array($token => $token));
if (isset($values[$token])) {
return $values[$token];
......
......@@ -152,7 +152,7 @@ class ctools_export_ui {
if (isset($input['op']) && $input['op'] == t('Reset')) {
unset($_SESSION['ctools_export_ui'][$this->plugin['name']]);
if (!$js) {
return drupal_goto($_GET['q']);
drupal_goto($_GET['q']);
}
// clear everything but form id, form build id and form token:
$keys = array_keys($input);
......@@ -665,7 +665,7 @@ class ctools_export_ui {
);
$output = $this->edit_execute_form($form_state);
if (!empty($form_state['executed'])) {
if (!empty($form_state['executed']) && empty($form_state['rebuild'])) {
$this->redirect($form_state['op'], $form_state['item']);
}
......@@ -701,7 +701,7 @@ class ctools_export_ui {
);
$output = $this->edit_execute_form($form_state);
if (!empty($form_state['executed'])) {
if (!empty($form_state['executed']) && empty($form_state['rebuild'])) {
$this->redirect($form_state['op'], $form_state['item']);
}
......@@ -749,7 +749,7 @@ class ctools_export_ui {
);
$output = $this->edit_execute_form($form_state);
if (!empty($form_state['executed'])) {
if (!empty($form_state['executed']) && empty($form_state['rebuild'])) {
$this->redirect($form_state['op'], $form_state['item']);
}
......@@ -778,7 +778,7 @@ class ctools_export_ui {
*/
function edit_execute_form_standard(&$form_state) {
$output = drupal_build_form('ctools_export_ui_edit_item_form', $form_state);
if (!empty($form_state['executed'])) {
if (!empty($form_state['executed']) && empty($form_state['rebuild'])) {
$this->edit_save_form($form_state);
}
......
......@@ -42,9 +42,11 @@ function ctools_book_parent_context($context, $conf) {
// Load the node.
$node = node_load($nid);
// Generate the context.
if (node_access('view', $node)) {
return ctools_context_create('node', $node);
}
}
}
else {
return ctools_context_create_empty('node');
}
......
......@@ -173,12 +173,18 @@ function ctools_entity_from_field_context($context, $conf) {
if (isset($items[$delta])) {
ctools_include('fields');
$to_entity_info = entity_get_info($to_entity);
$plugin_info = ctools_get_relationship($conf['name']);
$to_entity_id = $items[$delta][$plugin_info['source key']];
$loaded_to_entity = array_shift(entity_load($to_entity, array($to_entity_id)));
if(function_exists($to_entity_info['access callback']) && !call_user_func($to_entity_info['access callback'], 'view', $loaded_to_entity)) {
return ctools_context_create_empty('entity:' . $to_entity, NULL);
}
else {
// Send it to ctools.
return ctools_context_create('entity:' . $to_entity, $to_entity_id);
}
}
else {
// In case that delta was empty.
return ctools_context_create_empty('entity:' . $to_entity, NULL);
......
......@@ -35,7 +35,7 @@ function ctools_terms_from_node_context($context, $conf) {
$fields = field_info_instances('node', $node->type);
foreach ($fields as $name => $info) {
$field_info = field_info_field($name);
if ($field_info['type'] == 'taxonomy_term_reference' && (empty($conf['vocabulary']) || $conf['vocabulary'][$field_info['settings']['allowed_values'][0]['vocabulary']])) {
if ($field_info['type'] == 'taxonomy_term_reference' && (empty($conf['vocabulary']) || !empty($conf['vocabulary'][$field_info['settings']['allowed_values'][0]['vocabulary']]))) {
$items = field_get_items('node', $node, $name);
if (is_array($items)) {
foreach ($items as $item) {
......
......@@ -5,9 +5,9 @@ package = Chaos tool suite
dependencies[] = ctools
dependencies[] = color
; Information added by drupal.org packaging script on 2013-04-03
version = "7.x-1.3"
; Information added by Drupal.org packaging script on 2014-02-12
version = "7.x-1.4"
core = "7.x"
project = "ctools"
datestamp = "1365013512"
datestamp = "1392220730"
<?php
/**
* @file
* Plugin to provide access control based upon a parent term.
*/
/**
* Plugins are described by creating a $plugin array which will be used
* by the system that includes this file.
*/
$plugin = array(
'title' => t("Taxonomy: term depth"),
'description' => t('Control access by the depth of a term.'),
'callback' => 'term_depth_term_depth_ctools_access_check',
'default' => array('vid' => array(), 'depth' => 0),
'settings form' => 'term_depth_term_depth_ctools_access_settings',
'settings form validation' => 'term_depth_term_depth_ctools_access_settings_validate',
'settings form submit' => 'term_depth_term_depth_ctools_access_settings_submit',
'summary' => 'term_depth_term_depth_ctools_access_summary',
'required context' => new ctools_context_required(t('Term'), array('taxonomy_term', 'terms')),
);
/**
* Settings form for the 'term depth' access plugin.
*/
function term_depth_term_depth_ctools_access_settings($form, &$form_state, $conf) {
// If no configuration was saved before, set some defaults.
if (empty($conf)) {
$conf = array(
'vid' => 0,
);
}
if (!isset($conf['vid'])) {
$conf['vid'] = 0;
}
// Loop over each of the configured vocabularies.
foreach (taxonomy_get_vocabularies() as $vid => $vocabulary) {
$options[$vid] = $vocabulary->name;
}
$form['settings']['vid'] = array(
'#title' => t('Vocabulary'),
'#type' => 'select',
'#options' => $options,
'#description' => t('Select the vocabulary for this form. If there exists a parent term in that vocabulary, this access check will succeed.'),
'#id' => 'ctools-select-vid',
'#default_value' => $conf['vid'],
'#required' => TRUE,
);
$form['settings']['depth'] = array(
'#title' => t('Depth'),
'#type' => 'textfield',
'#description' => t('Set the required depth of the term. If the term exists at the correct depth, this access check will succeed.'),
'#default_value' => $conf['depth'],
'#required' => TRUE,
);
return $form;
}
/**
* Submit function for the access plugins settings.
*
* We cast all settings to numbers to ensure they can be safely handled.
*/
function term_depth_term_depth_ctools_access_settings_submit($form, $form_state) {
foreach (array('depth', 'vid') as $key) {
$form_state['conf'][$key] = (integer) $form_state['values']['settings'][$key];
}
}
/**
* Check for access.
*/
function term_depth_term_depth_ctools_access_check($conf, $context) {
// As far as I know there should always be a context at this point, but this
// is safe.
if (empty($context) || empty($context->data) || empty($context->data->vid) || empty($context->data->tid)) {
return FALSE;
}
// Get the $vid.
if (!isset($conf['vid'])) {
return FALSE;
}
$depth = _term_depth($context->data->tid);
return ($depth == $conf['depth']);
}
/**
* Provide a summary description based upon the checked terms.
*/
function term_depth_term_depth_ctools_access_summary($conf, $context) {
$vocab = taxonomy_vocabulary_load($conf['vid']);
return t('"@term" has parent in vocabulary "@vocab" at @depth', array(
'@term' => $context->identifier,
'@vocab' => $vocab->name,
'@depth' => $conf['depth'],
));
}
/**
* Find the depth of a term.
*/
function _term_depth($tid) {
static $depths = array();
if (!isset($depths[$tid])) {
$parent = db_select('taxonomy_term_hierarchy', 'th')
->fields('th', array('parent'))
->condition('tid', $tid)
->execute()->fetchField();
if ($parent == 0) {
$depths[$tid] = 1;
}
else {
$depths[$tid] = 1 + _term_depth($parent);
}
}
return $depths[$tid];
}
name = Term Depth access
description = Controls access to context based upon term depth
core = 7.x
dependencies[] = ctools
package = Chaos tool suite
; Information added by Drupal.org packaging script on 2014-02-12
version = "7.x-1.4"
core = "7.x"
project = "ctools"
datestamp = "1392220730"
<?php
function term_depth_ctools_plugin_directory($owner, $plugin) {
if ($owner == 'ctools' && $plugin == 'access') {
return 'plugins/' . $plugin;
}
}
......@@ -7,9 +7,9 @@ hidden = TRUE
files[] = ctools_export.test
; Information added by drupal.org packaging script on 2013-04-03
version = "7.x-1.3"
; Information added by Drupal.org packaging script on 2014-02-12
version = "7.x-1.4"
core = "7.x"
project = "ctools"
datestamp = "1365013512"
datestamp = "1392220730"
......@@ -11,9 +11,9 @@ files[] = math_expression.test
files[] = math_expression_stack.test
hidden = TRUE
; Information added by drupal.org packaging script on 2013-04-03
version = "7.x-1.3"
; Information added by Drupal.org packaging script on 2014-02-12
version = "7.x-1.4"
core = "7.x"
project = "ctools"
datestamp = "1365013512"
datestamp = "1392220730"
......@@ -145,12 +145,12 @@ function views_content_views_content_type_render($subtype, $conf, $panel_args, $
}
if (!empty($contexts[$cid])) {
$arg = ctools_context_convert_context($contexts[$cid], $converter, array('sanitize' => FALSE));
array_splice($args, $count, 0, array($arg));
}
else {
// Make sure we put an argument in even if it was not there.
$arg = NULL;
}
array_splice($args, $count, 0, array($arg));
}
}
......
......@@ -83,7 +83,7 @@ function views_content_views_panes_content_type_content_type($subtype, $plugin)
function _views_content_panes_content_type($view, $display) {
// Ensure the handler is the right type, as Views will fall back to
// the default display if something is broken:
if (get_class($display->handler) != 'views_content_plugin_display_panel_pane') {
if (!is_a($display->handler, 'views_content_plugin_display_panel_pane')) {
return;
}
......@@ -139,7 +139,7 @@ function views_content_views_panes_content_type_render($subtype, $conf, $panel_a
$view->set_display($display);
views_content_views_panes_add_defaults($conf, $view);
if (!$view->display_handler->access($GLOBALS['user']) || !$view->display_handler->panel_pane_display) {
if (!$view->display_handler->access($GLOBALS['user']) || empty($view->display_handler->panel_pane_display)) {
return;
}
......@@ -162,6 +162,9 @@ function views_content_views_panes_content_type_render($subtype, $conf, $panel_a
$args[] = $contexts[$key]->argument;
}
}
else {
$args[] = isset($arguments[$id]['exception']['value']) ? $arguments[$id]['exception']['value'] : 'all';
}
break;
case 'fixed':
......@@ -252,7 +255,7 @@ function views_content_views_panes_content_type_render($subtype, $conf, $panel_a
if ($conf['use_pager']) {
if (!isset($pager['options']['id']) || (isset($conf['pager_id']) && $pager['options']['id'] != $conf['pager_id'])) {
$pager['options']['id'] = $conf['pager_id'];
$pager['options']['id'] = (int) $conf['pager_id'];
}
}
......
......@@ -9,9 +9,9 @@ files[] = plugins/views/views_content_plugin_display_ctools_context.inc
files[] = plugins/views/views_content_plugin_display_panel_pane.inc
files[] = plugins/views/views_content_plugin_style_ctools_context.inc
; Information added by drupal.org packaging script on 2013-04-03
version = "7.x-1.3"
; Information added by Drupal.org packaging script on 2014-02-12
version = "7.x-1.4"
core = "7.x"
project = "ctools"
datestamp = "1365013512"
datestamp = "1392220730"
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment