';
diff --git a/sites/all/modules/contrib/media/modules/media_wysiwyg/js/media_wysiwyg.filter.js b/sites/all/modules/contrib/media/modules/media_wysiwyg/js/media_wysiwyg.filter.js
index 02e8cd2da..f3df9363c 100644
--- a/sites/all/modules/contrib/media/modules/media_wysiwyg/js/media_wysiwyg.filter.js
+++ b/sites/all/modules/contrib/media/modules/media_wysiwyg/js/media_wysiwyg.filter.js
@@ -175,7 +175,8 @@
Drupal.media.filter.ensure_tagmap();
// Locate and process all the media placeholders in the WYSIWYG content.
- var contentElements = $('').html(content); // TODO: once baseline jQuery is 1.8+, switch to using $.parseHTML(content)
+ var contentElements = $(''); // TODO: once baseline jQuery is 1.8+, switch to using $.parseHTML(content)
+ contentElements.get(0).innerHTML = content;
var mediaElements = contentElements.find('.media-element');
if (mediaElements) {
$(mediaElements).each(function (i) {
@@ -238,6 +239,11 @@
if (info.attributes[a]) {
element.attr(a, info.attributes[a]);
}
+ else if (element.attr(a)) {
+ // If the element has the attribute, but the value is empty, be
+ // sure to clear it.
+ element.removeAttr(a);
+ }
});
delete(info.attributes);
diff --git a/sites/all/modules/contrib/media/modules/media_wysiwyg/media_wysiwyg.info b/sites/all/modules/contrib/media/modules/media_wysiwyg/media_wysiwyg.info
index 482500d2a..05622b88e 100644
--- a/sites/all/modules/contrib/media/modules/media_wysiwyg/media_wysiwyg.info
+++ b/sites/all/modules/contrib/media/modules/media_wysiwyg/media_wysiwyg.info
@@ -12,12 +12,13 @@ test_dependencies[] = wysiwyg
files[] = media_wysiwyg.test
files[] = tests/media_wysiwyg.file_usage.test
files[] = tests/media_wysiwyg.macro.test
+files[] = tests/media_wysiwyg.paragraph_fix_filter.test
configure = admin/config/media/browser
-; Information added by Drupal.org packaging script on 2017-03-05
-version = "7.x-2.0-rc12"
+; Information added by Drupal.org packaging script on 2017-05-25
+version = "7.x-2.4"
core = "7.x"
project = "media"
-datestamp = "1488724088"
+datestamp = "1495749189"
diff --git a/sites/all/modules/contrib/media/modules/media_wysiwyg/media_wysiwyg.module b/sites/all/modules/contrib/media/modules/media_wysiwyg/media_wysiwyg.module
index ceab9d120..483e2d0f2 100644
--- a/sites/all/modules/contrib/media/modules/media_wysiwyg/media_wysiwyg.module
+++ b/sites/all/modules/contrib/media/modules/media_wysiwyg/media_wysiwyg.module
@@ -333,7 +333,7 @@ function media_wysiwyg_admin_config_browser_pre_submit(&$form, &$form_state) {
function media_wysiwyg_filter_info() {
$filters['media_filter'] = array(
'title' => t('Convert Media tags to markup'),
- 'description' => t('This filter will convert [[{type:media... ]] tags into markup. This must be enabled for the Media WYSIWYG integration to work with this input format.'),
+ 'description' => t('This filter will convert [[{type:media... ]] tags into markup. This must be enabled for the Media WYSIWYG integration to work with this input format. It is recommended to run this before the "@convert_urls" filter.', array('@convert_urls' => 'Convert URLs into links')),
'process callback' => 'media_wysiwyg_filter',
'weight' => 2,
// @TODO not implemented
@@ -342,8 +342,12 @@ function media_wysiwyg_filter_info() {
$filters['media_filter_paragraph_fix'] = array(
'title' => t('Ensure that embedded Media tags are not contained in paragraphs'),
- 'description' => t('This filter will strip any paragraph tags surrounding embedded Media tags. This helps to avoid the chopped up markup that can result from unexpectedly closed paragraph tags. This filter should be positioned above (before) the "Convert Media tags to markup" filter.'),
+ 'description' => t('This filter will fix any paragraph tags surrounding embedded Media tags. This helps to avoid the chopped up markup that can result from unexpectedly closed paragraph tags. This filter should be positioned above (before) the "Convert Media tags to markup" filter.'),
'process callback' => 'media_wysiwyg_filter_paragraph_fix',
+ 'settings callback' => '_media_filter_paragraph_fix_settings',
+ 'default settings' => array(
+ 'replace' => 0,
+ ),
'weight' => 1,
);
@@ -389,7 +393,7 @@ function media_wysiwyg_allowed_attributes() {
'data-delta',
));
drupal_alter('media_wysiwyg_allowed_attributes', $allowed_attributes);
- return $allowed_attributes;
+ return $allowed_attributes;
}
/**
@@ -603,7 +607,7 @@ function media_wysiwyg_form_file_entity_file_type_form_alter(&$form, &$form_stat
if (empty($form_state['build_info']['args'][0])) {
return;
}
-
+
$options = array();
// Add an option allowing users not to use a view mode.
@@ -694,3 +698,18 @@ function media_wysiwyg_form_file_entity_file_display_form_alter_submit(&$form, &
drupal_write_record('media_restrict_wysiwyg', $record);
}
}
+
+/**
+ * Implements hook_media_browser_params_alter().
+ */
+function media_wysiwyg_media_browser_params_alter(&$params) {
+ // Set the media browser options as defined in the interface.
+ if (!empty($params['id']) && $params['id'] === 'media_wysiwyg') {
+ $params = array(
+ 'enabledPlugins' => variable_get('media_wysiwyg_wysiwyg_browser_plugins', array()),
+ 'file_directory' => variable_get('media_wysiwyg_wysiwyg_upload_directory', ''),
+ 'types' => variable_get('media_wysiwyg_wysiwyg_allowed_types', array('audio', 'image', 'video', 'document')),
+ 'id' => 'media_wysiwyg',
+ ) + $params;
+ }
+}
diff --git a/sites/all/modules/contrib/media/modules/media_wysiwyg/media_wysiwyg.test b/sites/all/modules/contrib/media/modules/media_wysiwyg/media_wysiwyg.test
index 6b0aaa377..117aab57b 100644
--- a/sites/all/modules/contrib/media/modules/media_wysiwyg/media_wysiwyg.test
+++ b/sites/all/modules/contrib/media/modules/media_wysiwyg/media_wysiwyg.test
@@ -58,9 +58,11 @@ abstract class MediaWYSIWYGTestHelper extends DrupalWebTestCase {
);
// Create the file usage markup.
+ $markup .= '
';
return $markup;
}
diff --git a/sites/all/modules/contrib/media/modules/media_wysiwyg/tests/media_wysiwyg.paragraph_fix_filter.test b/sites/all/modules/contrib/media/modules/media_wysiwyg/tests/media_wysiwyg.paragraph_fix_filter.test
new file mode 100644
index 000000000..5c6f6c590
--- /dev/null
+++ b/sites/all/modules/contrib/media/modules/media_wysiwyg/tests/media_wysiwyg.paragraph_fix_filter.test
@@ -0,0 +1,165 @@
+]*media\-element\-container[^>]*>/i';
+
+ /**
+ * Defines the regex to test for in the raw body field source.
+ *
+ * @var string
+ */
+ protected $regexpPWrapped = '/
]*>
]*media\-element\-container[^>]*>/i';
+
+ /**
+ * Defines the regex to test for the P replacement filter.
+ *
+ * @var string
+ */
+ protected $regexpReplaced = '/
t('Media WYSIWYG Paragraph Filter Test'),
+ 'description' => t('Tests that this media filter is working.'),
+ 'group' => t('Media WYSIWYG'),
+ 'dependencies' => array('token'),
+ );
+ }
+
+ /**
+ * Set-up the system for testing without the filter enabled.
+ */
+ public function setUp() {
+ parent::setUp('token');
+
+ // Create and log in a user.
+ $account = $this->drupalCreateUser(array(
+ 'create article content',
+ 'administer filters',
+ 'use text format filtered_html',
+ ));
+ $this->drupalLogin($account);
+
+ // Enable the media filter for full html.
+ $edit = array(
+ 'filters[media_filter][status]' => TRUE,
+ 'filters[filter_autop][status]' => FALSE,
+ 'filters[filter_html][status]' => FALSE,
+ 'filters[filter_htmlcorrector][status]' => FALSE,
+ );
+ $this->drupalPost('admin/config/content/formats/filtered_html', $edit, t('Save configuration'));
+ }
+
+ /**
+ * Test image media overrides.
+ */
+ public function testMediaFilterParagraphFixMultipleImages() {
+ $files = $this->drupalGetTestFiles('image');
+ $file = file_save($files[0]);
+
+ // Create a node to test with 3 images.
+ $nid = $this->createNode($file->fid);
+ $node = node_load($nid);
+ $node->body[LANGUAGE_NONE][0]['value'] = $this->generateJsonTokenMarkup($file->fid, 3);
+ node_save($node);
+
+ // Check without the filter enabled.
+ $html = $this->drupalGet('node/' . $nid);
+ $count = preg_match_all($this->regexpMediaTag, $html);
+ $this->assertEqual($count, 3, t('Three media tags found, found @count.', array('@count' => $count)));
+
+ $count = preg_match_all($this->regexpPWrapped, $html);
+ $this->assertEqual($count, 3, t('Three media tags with original wrapping HTML present, found @count.', array('@count' => $count)));
+
+ $count = preg_match_all($this->regexpReplaced, $html);
+ $this->assertEqual($count, 0, t('No media tags with P replaced present, found @count.', array('@count' => $count)));
+
+ // Enable the default P fix filter.
+ $edit = array(
+ 'filters[media_filter_paragraph_fix][status]' => TRUE,
+ );
+ $this->drupalPost('admin/config/content/formats/filtered_html', $edit, t('Save configuration'));
+ $html = $this->drupalGet('node/' . $nid);
+
+ $count = preg_match_all($this->regexpMediaTag, $html);
+ $this->assertEqual($count, 3, t('Three media tags found, found @count.', array('@count' => $count)));
+
+ $count = preg_match_all($this->regexpPWrapped, $html);
+ $this->assertEqual($count, 0, t('No media tags with original wrapping HTML present, found @count.', array('@count' => $count)));
+
+ $count = preg_match_all($this->regexpReplaced, $html);
+ $this->assertEqual($count, 0, t('No media tags with P replaced present, found @count.', array('@count' => $count)));
+
+ // Enable the replace P fix filter option.
+ $edit = array(
+ 'filters[media_filter_paragraph_fix][settings][replace]' => TRUE,
+ );
+ $this->drupalPost('admin/config/content/formats/filtered_html', $edit, t('Save configuration'));
+ $html = $this->drupalGet('node/' . $nid);
+
+ $count = preg_match_all($this->regexpMediaTag, $html);
+ $this->assertEqual($count, 3, t('Three media tags found, found @count.', array('@count' => $count)));
+
+ $count = preg_match_all($this->regexpPWrapped, $html);
+ $this->assertEqual($count, 0, t('No media tags with original wrapping HTML present, found @count.', array('@count' => $count)));
+
+ $count = preg_match_all($this->regexpReplaced, $html);
+ $this->assertEqual($count, 3, t('Three media tags with P replaced present, found @count.', array('@count' => $count)));
+ }
+
+ /**
+ * Test image media overrides.
+ */
+ public function testMediaFilterParagraphFixDefault() {
+ $files = $this->drupalGetTestFiles('image');
+ $file = file_save($files[0]);
+
+ // Create a node to test with.
+ $nid = $this->createNode($file->fid);
+
+ // Check without the filter enabled.
+ $this->drupalGet('node/' . $nid);
+ $this->assertPattern($this->regexpPWrapped, t('Nested media DIV tags within paragraphs without filter.'));
+ $this->assertNoPattern($this->regexpReplaced, t('No replacement DIV tag found without filter.'));
+
+ // Enable the default P fix filter.
+ $edit = array(
+ 'filters[media_filter_paragraph_fix][status]' => TRUE,
+ );
+ $this->drupalPost('admin/config/content/formats/filtered_html', $edit, t('Save configuration'));
+
+ // Retest the content to check nested paragraphs are removed.
+ $this->drupalGet('node/' . $nid);
+ $this->assertNoPattern($this->regexpPWrapped, t('Nested media DIV tags within paragraphs with filter defaults.'));
+ $this->assertNoPattern($this->regexpReplaced, t('No replacement DIV tag found with filter defaults.'));
+
+ // Enable replacement option.
+ $edit = array(
+ 'filters[media_filter_paragraph_fix][settings][replace]' => TRUE,
+ );
+ $this->drupalPost('admin/config/content/formats/filtered_html', $edit, t('Save configuration'));
+
+ // Test that the replace text was found.
+ $this->drupalGet('node/' . $nid);
+ $this->assertNoPattern($this->regexpPWrapped, t('No nested media DIV tags within paragraphs with filter P replacement.'));
+ $this->assertPattern($this->regexpReplaced, t('No replacement DIV tag found with filter P replacement.'));
+ }
+
+}
diff --git a/sites/all/modules/contrib/media/modules/media_wysiwyg/wysiwyg_plugins/media.inc b/sites/all/modules/contrib/media/modules/media_wysiwyg/wysiwyg_plugins/media.inc
index 7e1f709be..d8acc0a3b 100644
--- a/sites/all/modules/contrib/media/modules/media_wysiwyg/wysiwyg_plugins/media.inc
+++ b/sites/all/modules/contrib/media/modules/media_wysiwyg/wysiwyg_plugins/media.inc
@@ -22,9 +22,6 @@ function media_wysiwyg_media_plugin() {
'css file' => 'media_wysiwyg.css',
'settings' => array(
'global' => array(
- 'enabledPlugins' => variable_get('media_wysiwyg_wysiwyg_browser_plugins', array()),
- 'file_directory' => variable_get('media_wysiwyg_wysiwyg_upload_directory', ''),
- 'types' => variable_get('media_wysiwyg_wysiwyg_allowed_types', array('audio', 'image', 'video', 'document')),
'id' => 'media_wysiwyg',
),
),
diff --git a/sites/all/modules/contrib/media/modules/media_wysiwyg_view_mode/media_wysiwyg_view_mode.info b/sites/all/modules/contrib/media/modules/media_wysiwyg_view_mode/media_wysiwyg_view_mode.info
index a14ee9ac2..e56373b25 100644
--- a/sites/all/modules/contrib/media/modules/media_wysiwyg_view_mode/media_wysiwyg_view_mode.info
+++ b/sites/all/modules/contrib/media/modules/media_wysiwyg_view_mode/media_wysiwyg_view_mode.info
@@ -3,9 +3,9 @@ description = DEPRECATED, this folder is only here so that the module can be uni
package = Media
core = 7.x
-; Information added by Drupal.org packaging script on 2017-03-05
-version = "7.x-2.0-rc12"
+; Information added by Drupal.org packaging script on 2017-05-25
+version = "7.x-2.4"
core = "7.x"
project = "media"
-datestamp = "1488724088"
+datestamp = "1495749189"
diff --git a/sites/all/modules/contrib/media/modules/mediafield/mediafield.info b/sites/all/modules/contrib/media/modules/mediafield/mediafield.info
index b7fdd7b96..b4f13b7fa 100644
--- a/sites/all/modules/contrib/media/modules/mediafield/mediafield.info
+++ b/sites/all/modules/contrib/media/modules/mediafield/mediafield.info
@@ -4,9 +4,9 @@ package = Media
core = 7.x
dependencies[] = media
-; Information added by Drupal.org packaging script on 2017-03-05
-version = "7.x-2.0-rc12"
+; Information added by Drupal.org packaging script on 2017-05-25
+version = "7.x-2.4"
core = "7.x"
project = "media"
-datestamp = "1488724088"
+datestamp = "1495749189"
diff --git a/sites/all/modules/contrib/media/tests/media.test b/sites/all/modules/contrib/media/tests/media.test
index 5aeea2425..a60e3adfa 100644
--- a/sites/all/modules/contrib/media/tests/media.test
+++ b/sites/all/modules/contrib/media/tests/media.test
@@ -685,19 +685,22 @@ class MediaBrowserSettingsTestCase extends MediaFileFieldTestCase {
foreach ($settings['extension'] as $extension) {
$file = $this->createFileEntity(array('scheme' => $scheme, 'uid' => $this->admin_user->uid, 'type' => $type, 'filemime' => media_get_extension_mimetype($extension)));
+ // Some of the settings such as the scheme and extension are unsafe to
+ // pass as query arguments, cache them and pass the cache ID.
$options = array(
- 'query' => array(
- 'enabledPlugins' => array(
- 'media_default--media_browser_1' => 'media_default--media_browser_1',
- ),
- 'schemes' => array($scheme),
- 'types' => array($type),
- 'file_extensions' => $extension,
+ 'enabledPlugins' => array(
+ 'media_default--media_browser_1' => 'media_default--media_browser_1',
),
+ 'schemes' => array($scheme),
+ 'types' => array($type),
+ 'file_extensions' => $extension,
);
+ $cid = drupal_get_token(drupal_random_bytes(32));
+ cache_set('media_options:' . $cid, $options, 'cache_form', REQUEST_TIME + 21600);
+
// Verify that the file is displayed.
- $this->drupalGet('media/browser', $options);
+ $this->drupalGet('media/browser', array('query' => array('options' => $cid)));
$this->assertResponse(200);
$xpath = $this->buildXPathQuery('//ul[@class="media-list-thumbnails"]/li/div[@data-fid=:fid]/@data-fid', array(
':fid' => $file->fid,
@@ -714,28 +717,29 @@ class MediaBrowserSettingsTestCase extends MediaFileFieldTestCase {
// Perform the tests with none and all of the restrictions.
foreach (array('none', 'all') as $restrictions) {
$options = array(
- 'query' => array(
- 'enabledPlugins' => array(
- 'media_default--media_browser_1' => 'media_default--media_browser_1',
- ),
+ 'enabledPlugins' => array(
+ 'media_default--media_browser_1' => 'media_default--media_browser_1',
),
);
switch ($restrictions) {
case 'none':
- $options['query']['schemes'] = array();
- $options['query']['types'] = array();
- $options['query']['file_extensions'] = array();
+ $options['schemes'] = array();
+ $options['types'] = array();
+ $options['file_extensions'] = array();
break;
case 'all':
- $options['query']['schemes'] = $settings['scheme'];
- $options['query']['types'] = $settings['type'];
- $options['query']['file_extensions'] = implode(' ', $settings['extension']);
+ $options['schemes'] = $settings['scheme'];
+ $options['types'] = $settings['type'];
+ $options['file_extensions'] = implode(' ', $settings['extension']);
break;
}
+ $cid = drupal_get_token(drupal_random_bytes(32));
+ cache_set('media_options:' . $cid, $options, 'cache_form', REQUEST_TIME + 21600);
+
// Verify that all of the files are displayed.
- $this->drupalGet('media/browser', $options);
+ $this->drupalGet('media/browser', array('query' => array('options' => $cid)));
$this->assertResponse(200);
$files = $this->xpath('//ul[@class="media-list-thumbnails"]/li/div[@data-fid]');
$this->assertEqual(count($files), 8, format_string('All of the files were displayed when %restrictions of the restrictions were enabled.', array('%restrictions' => $restrictions)));
@@ -749,18 +753,19 @@ class MediaBrowserSettingsTestCase extends MediaFileFieldTestCase {
$file = $this->createFileEntity(array('scheme' => $scheme, 'uid' => $this->admin_user->uid, 'type' => $type, 'filemime' => media_get_extension_mimetype($extension)));
$options = array(
- 'query' => array(
- 'enabledPlugins' => array(
- 'media_default--media_browser_1' => 'media_default--media_browser_1',
- ),
- 'schemes' => array($scheme, 'public'), // Include a local stream wrapper in order to trigger extension restrictions.
- 'types' => array($type),
- 'file_extensions' => 'fake', // Use an invalid file extension to ensure that it does not affect restrictions.
+ 'enabledPlugins' => array(
+ 'media_default--media_browser_1' => 'media_default--media_browser_1',
),
+ 'schemes' => array($scheme, 'public'), // Include a local stream wrapper in order to trigger extension restrictions.
+ 'types' => array($type),
+ 'file_extensions' => 'fake', // Use an invalid file extension to ensure that it does not affect restrictions.
);
+ $cid = drupal_get_token(drupal_random_bytes(32));
+ cache_set('media_options:' . $cid, $options, 'cache_form', REQUEST_TIME + 21600);
+
// Verify that the file is displayed.
- $this->drupalGet('media/browser', $options);
+ $this->drupalGet('media/browser', array('query' => array('options' => $cid)));
$this->assertResponse(200);
$xpath = $this->buildXPathQuery('//ul[@class="media-list-thumbnails"]/li/div[@data-fid=:fid]/@data-fid', array(
':fid' => $file->fid,
@@ -896,6 +901,73 @@ class MediaElementSettingsTestCase extends MediaFileFieldTestCase {
$this->assertTrue(strpos($javascript, $settings) > 0, 'Rendered media element adds the global settings.');
}
+ /**
+ * Tests that the field widget does not contain the insecure settings.
+ */
+ function testInsecureSettings() {
+ // Use 'page' instead of 'article', so that the 'article' image field does
+ // not conflict with this test. If in the future the 'page' type gets its
+ // own default file or image field, this test can be made more robust by
+ // using a custom node type.
+ $type_name = 'page';
+ $field_name = strtolower($this->randomName());
+ $this->createFileField($field_name, $type_name);
+ $this->drupalGet("node/add/$type_name");
+
+ $insecure_settings = array(
+ 'file_directory',
+ 'file_extensions',
+ 'max_filesize',
+ 'uri_scheme',
+ );
+ foreach ($insecure_settings as $setting) {
+ $this->assertNoRaw($setting, format_string('Media file field widget does not contain the insecure element-specific setting @setting.', array(
+ '@setting' => $setting,
+ )));
+ }
+ }
+
+ /**
+ * Tests that insecure settings are not processed when sent via query parameters.
+ */
+ function testBrowserInsecureQueryParameters() {
+ // Test file directory override.
+ $path = file_unmanaged_save_data('directorytest', 'temporary://directorytest.txt');
+ $data = array('files[upload]' => drupal_realpath($path));
+ $this->drupalPost('media/browser', $data, t('Upload'), array('query' => array('file_directory' => 'insecure_upload')));
+ // Verify that the file was placed in the normal public:// path instead of the folder we specified.
+ $this->assertFalse(is_file('public://insecure_upload/directorytest.txt'), 'File was not uploaded to the directory specified in the query parameters.');
+ $this->assertTrue(is_file('public://directorytest.txt'), 'File was uploaded to the default public directory.');
+
+ // Test file_extensions override.
+ $path = file_unmanaged_save_data('extensiontest', 'temporary://extensiontest.exe');
+ $data = array('files[upload]' => drupal_realpath($path));
+ $this->drupalPost('media/browser', $data, t('Upload'), array('query' => array('file_extensions' => 'exe')));
+ $this->assertFalse(is_file('public://extensiontest.exe'), 'File with extension passed via query parameter was not uploaded.');
+
+ // Test max_filesize override.
+ variable_set('file_entity_max_filesize', '8 bytes');
+ $path = file_unmanaged_save_data('maxfilesize', 'temporary://maxfilesize.txt');
+ $data = array('files[upload]' => drupal_realpath($path));
+ $this->drupalPost('media/browser', $data, t('Upload'), array('query' => array('max_filesize' => '100 bytes')));
+ $this->assertFalse(is_file('public://maxfilesize.txt'), 'File larger than max file size was not uploaded with larger query parameter.');
+ variable_del('file_entity_max_filesize');
+
+ // Test uri_scheme override.
+ $path = file_unmanaged_save_data('urischeme', 'temporary://urischeme.txt');
+ $data = array('files[upload]' => drupal_realpath($path));
+ $this->drupalPost('media/browser', $data, t('Upload'), array('query' => array('uri_scheme' => 'private')));
+ $this->assertFalse(is_file('private://urischeme.txt'), 'File was not uploaded to scheme set in URL.');
+ $this->assertTrue(is_file('public://urischeme.txt'), 'File was uploaded to default scheme instead of scheme set in URL.');
+
+ // Test upload_validators override.
+ $path = file_unmanaged_save_data('uploadvalidators', 'temporary://uploadvalidators.txt');
+ $data = array('files[upload]' => drupal_realpath($path));
+ $this->drupalPost('media/browser', $data, t('Upload'), array('query' => array('upload_validators' => array('file_move' => array('public://exploit.php')))));
+ $this->assertFalse(is_file('public://exploit.php'), 'file_move() was not triggered by upload_validators parameter.');
+ $this->assertTrue(is_file('public://uploadvalidators.txt'), 'File was uploaded without triggering file_move().');
+ }
+
/**
* Tests the media file field widget settings.
*/
@@ -934,7 +1006,19 @@ class MediaElementSettingsTestCase extends MediaFileFieldTestCase {
),
);
$settings = drupal_json_encode(drupal_array_merge_deep_array($field_widget));
- $this->assertTrue(strpos($javascript, $settings) > 0, 'Media file field widget adds element-specific settings.');
+ $string_with_options = '-0-upload":{"global":{"options":"';
+ $index_of_cid = strpos($javascript, $string_with_options) + strlen($string_with_options);
+ $index_end_of_cid = strpos($javascript, '"', $index_of_cid + 1);
+ $cid = substr($javascript, $index_of_cid, ($index_end_of_cid - $index_of_cid));
+
+ // Retrieve the security sensitive options from the cache using the cid parsed out from the $javascript variable
+ $retrieved_settings = cache_get('media_options:' . $cid, 'cache_form');
+ $retrieved_settings = array('.js-media-element-edit-' . $field_name . '-' . LANGUAGE_NONE . '-0-upload' => array(
+ 'global' => $retrieved_settings->data));
+ $retrieved_settings_json = drupal_json_encode($retrieved_settings);
+
+ $this->assertTrue($retrieved_settings_json == $settings, 'Media file field widget retrieved from cache and has element-specific settings.');
+ $this->assertTrue(strpos($javascript, $cid) > 0, 'Media file field widget is cached and its` cache id is found.');
}
}
diff --git a/sites/all/modules/contrib/media/tests/media_module_test.info b/sites/all/modules/contrib/media/tests/media_module_test.info
index f43c1df31..5fde716b9 100644
--- a/sites/all/modules/contrib/media/tests/media_module_test.info
+++ b/sites/all/modules/contrib/media/tests/media_module_test.info
@@ -6,9 +6,9 @@ hidden = TRUE
files[] = includes/MediaModuleTest.inc
-; Information added by Drupal.org packaging script on 2017-03-05
-version = "7.x-2.0-rc12"
+; Information added by Drupal.org packaging script on 2017-05-25
+version = "7.x-2.4"
core = "7.x"
project = "media"
-datestamp = "1488724088"
+datestamp = "1495749189"
diff --git a/sites/all/modules/contrib/mimemail/CHANGELOG.txt b/sites/all/modules/contrib/mimemail/CHANGELOG.txt
index a35cb6e5b..a7e42b9f9 100644
--- a/sites/all/modules/contrib/mimemail/CHANGELOG.txt
+++ b/sites/all/modules/contrib/mimemail/CHANGELOG.txt
@@ -1,6 +1,24 @@
Mime Mail 7.x-1.x, xxxx-xx-xx
-----------------------
+Mime Mail 7.x-1.0, 2017-05-14
+-----------------------
+- #2743229 by Bird-Kid, AdamPS: CSS doesn't get attached in PHP7
+- #2858390 by Munavijayalakshmi, Jigar.addweb: Fix coding standard issues
+- #2594743 by skipyT: Theme function called for plain messages also
+- #2374673 by smokris: Prevent processing of already embedded images
+- #1532352 by sgabe, Matt B: Add permission to view user specific settings
+- #2783815 by argiepiano: Add 'Reply-to' field to "Send HTML mail to all users of a role" action
+- #2796993 by Cauliflower: Return send status in Rules actions
+- #2796965 by Cauliflower: Allow NULL values in Rules actions
+- #1568680 by jamsilver: Use $message for themeing
+- #2721799 by igorik, sgabe: Minor typo
+- #2146513 by torotil, Anybody: Scan theme for other *css* file types
+- #2678818 by hoebekewim, das-peter: Mime Mail Compress has a deprecated constructor
+- #2553815 by nitrocad, anthonys: Imported font generates empty attachment
+- #2562181 by rrfegade: Remove unused varibles
+- #2562177 by rrfegade: Spelling errors
+
Mime Mail 7.x-1.0-beta4, 2015-08-02
-----------------------
- #2413495 by sgabe, siggi_kid: Public images not embedded when file default scheme is private
diff --git a/sites/all/modules/contrib/mimemail/README.txt b/sites/all/modules/contrib/mimemail/README.txt
index 1bb6aa47b..804e73d43 100644
--- a/sites/all/modules/contrib/mimemail/README.txt
+++ b/sites/all/modules/contrib/mimemail/README.txt
@@ -2,7 +2,7 @@
-- SUMMARY --
This is a Mime Mail component module (for use by other modules).
- * It permits users to recieve HTML email and can be used by other modules. The mail
+ * It permits users to receieve HTML email and can be used by other modules. The mail
functionality accepts an HTML message body, mime-endcodes it and sends it.
* If the HTML has embedded graphics, these graphics are MIME-encoded and included
as a message attachment.
diff --git a/sites/all/modules/contrib/mimemail/includes/mimemail.admin.inc b/sites/all/modules/contrib/mimemail/includes/mimemail.admin.inc
index ca71e54e3..7155e79a5 100644
--- a/sites/all/modules/contrib/mimemail/includes/mimemail.admin.inc
+++ b/sites/all/modules/contrib/mimemail/includes/mimemail.admin.inc
@@ -85,7 +85,7 @@ function mimemail_admin_settings() {
'#access' => count($formats) > 1,
'#attributes' => array('class' => array('filter-list')),
'#description' => t('The filter set that will be applied to the message body.
- If you are using Mime Mail as default mail sytem, make sure to enable
+ If you are using Mime Mail as default mail system, make sure to enable
"Convert line breaks into HTML" and "Convert URLs into links" with a long
enough maximum length for e.g. password reset URLs!'),
);
diff --git a/sites/all/modules/contrib/mimemail/includes/mimemail.incoming.inc b/sites/all/modules/contrib/mimemail/includes/mimemail.incoming.inc
index ff1d43f7e..43f98eb4a 100644
--- a/sites/all/modules/contrib/mimemail/includes/mimemail.incoming.inc
+++ b/sites/all/modules/contrib/mimemail/includes/mimemail.incoming.inc
@@ -75,13 +75,13 @@ function mimemail_parse($message) {
// We're dealing with a multi-part message.
$mail['parts'] = mimemail_parse_boundary($mail);
- foreach ($mail['parts'] as $i => $part_body) {
+ foreach ($mail['parts'] as $part_body) {
$part = mimemail_parse_headers($part_body);
$sub_parts = mimemail_parse_boundary($part);
// Content is encoded in a multipart/alternative section.
if (count($sub_parts) > 1) {
- foreach ($sub_parts as $j => $sub_part_body) {
+ foreach ($sub_parts as $sub_part_body) {
$sub_part = mimemail_parse_headers($sub_part_body);
if ($sub_part['content-type'] == 'text/plain') {
$mail['text'] = mimemail_parse_content($sub_part);
diff --git a/sites/all/modules/contrib/mimemail/includes/mimemail.mail.inc b/sites/all/modules/contrib/mimemail/includes/mimemail.mail.inc
index 04774faab..28bebfc80 100644
--- a/sites/all/modules/contrib/mimemail/includes/mimemail.mail.inc
+++ b/sites/all/modules/contrib/mimemail/includes/mimemail.mail.inc
@@ -29,7 +29,6 @@ class MimeMailSystem implements MailSystemInterface {
}
$engine = variable_get('mimemail_engine', 'mimemail');
- $mailengine = $engine . '_mailengine';
$engine_prepare_message = $engine . '_prepare_message';
if (function_exists($engine_prepare_message)) {
diff --git a/sites/all/modules/contrib/mimemail/mimemail.inc b/sites/all/modules/contrib/mimemail/mimemail.inc
index 3dbb0052d..dd7847ff8 100644
--- a/sites/all/modules/contrib/mimemail/mimemail.inc
+++ b/sites/all/modules/contrib/mimemail/mimemail.inc
@@ -112,7 +112,7 @@ function mimemail_headers($headers, $from = NULL) {
* )
*/
function mimemail_extract_files($html) {
- $pattern = '/(]+href=[\'"]?|
-
+
diff --git a/sites/all/modules/contrib/webform/templates/webform-mail.tpl.php b/sites/all/modules/contrib/webform/templates/webform-mail.tpl.php
index 578c82770..f7ed9837d 100644
--- a/sites/all/modules/contrib/webform/templates/webform-mail.tpl.php
+++ b/sites/all/modules/contrib/webform/templates/webform-mail.tpl.php
@@ -33,6 +33,6 @@
[submission:values]
-' : '') . t('The results of this submission may be viewed at:') . ($email['html'] ? '' : '') ?>
+' : '') . t('The results of this submission may be viewed at:') . ($email['html'] ? '' : ''); ?>
' : ''); ?>[submission:url]' : ''); ?>
diff --git a/sites/all/modules/contrib/webform/templates/webform-progressbar.tpl.php b/sites/all/modules/contrib/webform/templates/webform-progressbar.tpl.php
index fa695e767..a739a279d 100644
--- a/sites/all/modules/contrib/webform/templates/webform-progressbar.tpl.php
+++ b/sites/all/modules/contrib/webform/templates/webform-progressbar.tpl.php
@@ -25,7 +25,7 @@
-
+
diff --git a/sites/all/modules/contrib/webform/tests/WebformComponentsTestCase.test b/sites/all/modules/contrib/webform/tests/WebformComponentsTestCase.test
new file mode 100644
index 000000000..c802fea58
--- /dev/null
+++ b/sites/all/modules/contrib/webform/tests/WebformComponentsTestCase.test
@@ -0,0 +1,192 @@
+ t('Webform components'),
+ 'description' => t('Add and remove components from a webform.'),
+ 'group' => t('Webform'),
+ );
+ }
+
+ /**
+ * Webform module component tests.
+ */
+ function testWebformComponents() {
+ // Test webform_component_list().
+ // Create a form consisting of three textfields separated by pagebreaks.
+ $test_components = $this->webformComponents();
+ $textfield = $test_components['textfield']['component'];
+
+ // Page 1 textfield.
+ $textfield['page_num'] = 1;
+ $textfield['name'] = $this->randomName();
+ $textfield['form_key'] = $this->randomName();
+ $components[1] = $textfield;
+ // Page 2 break.
+ $components[2] = array(
+ 'type' => 'pagebreak',
+ 'form_key' => 'pagebreak_' . $this->randomName(),
+ 'pid' => 0,
+ 'name' => $this->randomName(),
+ 'page_num' => 2,
+ );
+ // Page 2 textfield.
+ $textfield['name'] = $this->randomName();
+ $textfield['form_key'] = $this->randomName();
+ $textfield['page_num'] = 2;
+ $components[3] = $textfield;
+ // Page 3 break.
+ $components[4] = array(
+ 'type' => 'pagebreak',
+ 'form_key' => 'pagebreak_' . $this->randomName(),
+ 'pid' => 0,
+ // Name is the cid of another component. Should get a space added when it
+ // is used as a key in the value returned from webform_component_list().
+ 'name' => '1',
+ 'page_num' => 3,
+ );
+ // Page 3 textfield.
+ $textfield['name'] = $this->randomName();
+ $textfield['form_key'] = $this->randomName();
+ $textfield['page_num'] = 3;
+ $components[5] = $textfield;
+ // Page 4 break.
+ $components[6] = array(
+ 'type' => 'pagebreak',
+ 'form_key' => 'pagebreak_' . $this->randomName(),
+ 'pid' => 0,
+ // Name is the same as Page 3 break. Tests that name is made unique.
+ 'name' => '1',
+ 'page_num' => 4,
+ );
+ // Page 4 textfield.
+ $textfield['name'] = $this->randomName();
+ $textfield['form_key'] = $this->randomName();
+ $textfield['page_num'] = 4;
+ $components[7] = $textfield;
+
+ // Generate a component list.
+ $node = new stdClass();
+ $node->webform['components'] = $components;
+ $webform_component_list = webform_component_list($node, NULL, TRUE, TRUE);
+ // Test return value.
+ $test_list = array(
+ 1 => $components[1]['name'],
+ $components[2]['name'] => array(2 => $components[2]['name'], 3 => $components[3]['name']),
+ $components[4]['name'] . ' ' => array(4 => $components[4]['name'], 5 => $components[5]['name']),
+ $components[6]['name'] . '_2' => array(6 => $components[6]['name'], 7 => $components[7]['name']),
+ );
+ $this->assertIdentical($webform_component_list, $test_list, 'webform_component_list() returns expected value.');
+
+ // Test webform_component_parent_keys().
+ $components = array(
+ 1 => array(
+ 'form_key' => $this->randomName(),
+ 'name' => $this->randomName(),
+ 'pid' => 0,
+ ),
+ 2 => array(
+ 'form_key' => $this->randomName(),
+ 'name' => $this->randomName(),
+ 'pid' => 1,
+ ),
+ 3 => array(
+ 'form_key' => $this->randomName(),
+ 'name' => $this->randomName(),
+ 'pid' => 2,
+ ),
+ );
+
+ $node = new stdClass();
+ $node->webform['components'] = $components;
+
+ $parents = webform_component_parent_keys($node, $components[3]);
+ $test_parents = array($components[1]['form_key'], $components[2]['form_key'], $components[3]['form_key']);
+ $this->assertIdentical($parents, $test_parents, 'webform_component_parent_keys() returns expected form_keys.');
+
+ $parents = webform_component_parent_keys($node, $components[3], 'name');
+ $test_parents = array($components[1]['name'], $components[2]['name'], $components[3]['name']);
+ $this->assertIdentical($parents, $test_parents, 'webform_component_parent_keys() returns expected names.');
+
+ $parents = webform_component_parent_keys($node, $components[3], TRUE);
+ $test_parents = array($components[1], $components[2], $components[3]);
+ $this->assertIdentical($parents, $test_parents, 'webform_component_parent_keys() returns expected component arrays.');
+
+
+ // Test webform_get_cid().
+ $settings = array(
+ 'title' => 'Test webform with multiple instances of a Form Key',
+ 'type' => 'webform',
+ );
+ $node = $this->drupalCreateNode($settings);
+
+ // Add a new textarea component.
+ $components = $this->webformComponents();
+ $textarea = $components['textarea'];
+ $textarea['type'] = 'textarea';
+ $textarea['form_key'] = 'testing_key';
+ $textarea['cid'] = 1;
+ $textarea['pid'] = 0;
+ $textarea = array_merge(webform_component_invoke('textarea', 'defaults'), $textarea);
+ $node->webform['components'][1] = $textarea;
+
+ // Add a new fieldset component.
+ $fieldset = array(
+ 'cid' => 2,
+ 'pid' => 0,
+ 'form_key' => 'another_key',
+ 'name' => 'Fieldset',
+ 'type' => 'fieldset',
+ 'value' => '',
+ 'required' => '0',
+ 'weight' => '0',
+ );
+ $node->webform['components'][2] = $fieldset;
+
+ // Add a new textfield component as child of the fieldset.
+ $textfield = $components['textfield'];
+ $textfield['type'] = 'textfield';
+ $textfield['form_key'] = 'testing_key';
+ $textfield['cid'] = 3;
+ $textfield['pid'] = 2;
+ $textfield = array_merge(webform_component_invoke('textarea', 'defaults'), $textfield);
+ $node->webform['components'][3] = $textfield;
+
+ // Add another textfield component.
+ $textfield = $components['textfield'];
+ $textfield['type'] = 'textfield';
+ $textfield['form_key'] = 'dummy_key';
+ $textfield['cid'] = 4;
+ $textfield['pid'] = 0;
+ $textfield = array_merge(webform_component_invoke('textarea', 'defaults'), $textfield);
+ $node->webform['components'][4] = $textfield;
+
+ node_save($node);
+
+ // Test webform_get_cid() with providing a parent cid.
+ $this->assertTrue(webform_get_cid($node, 'testing_key', 2) == 3, t('Returned expected Webform component id for a given form_key and parent (pid).'));
+
+ // Test webform_get_cid() without providing a parent cid.
+ $this->assertTrue(webform_get_cid($node, 'testing_key') == array(1, 3), t('Returned expected Webform component ids array for a given form_key.'));
+
+
+ // Create and visit a new Webform test node.
+ $node = $this->webformForm();
+ $this->drupalGet('node/' . $node->nid);
+
+ // Check that each label @for points to an element.
+ $labels = $this->xpath('//label/@for');
+ foreach ($labels as $label) {
+ $for = $this->xpath("//*[@id=':id']", array(':id' => $label['for']));
+ $this->assertTrue($for, 'Label with @for "' . $label['for'] . '" points to an element.');
+ }
+ }
+}
diff --git a/sites/all/modules/contrib/webform/tests/conditionals.test b/sites/all/modules/contrib/webform/tests/WebformConditionalsTestCase.test
similarity index 91%
rename from sites/all/modules/contrib/webform/tests/conditionals.test
rename to sites/all/modules/contrib/webform/tests/WebformConditionalsTestCase.test
index a13b77aed..2a8484c66 100644
--- a/sites/all/modules/contrib/webform/tests/conditionals.test
+++ b/sites/all/modules/contrib/webform/tests/WebformConditionalsTestCase.test
@@ -4,12 +4,9 @@
* @file
* Webform module conditional tests.
*/
-
-include_once(dirname(__FILE__) . '/webform.test');
-
class WebformConditionalsTestCase extends WebformTestCase {
/**
- * Implements getInfo().
+ * {@inheritdoc}
*/
public static function getInfo() {
return array(
@@ -19,20 +16,6 @@ class WebformConditionalsTestCase extends WebformTestCase {
);
}
- /**
- * Implements setUp().
- */
- function setUp($added_modules = array()) {
- parent::setUp($added_modules);
- }
-
- /**
- * Implements tearDown().
- */
- function tearDown() {
- parent::tearDown();
- }
-
/**
* Test that required fields with no default value can't be submitted as-is.
*/
@@ -40,7 +23,7 @@ class WebformConditionalsTestCase extends WebformTestCase {
$this->drupalLogin($this->webform_users['admin']);
$this->webformReset();
- $test_components = $this->testWebformComponents();
+ $test_components = $this->webformComponents();
$test_specs = array(
'match conditional values' => TRUE,
'mismatch conditional values' => FALSE,
@@ -78,9 +61,10 @@ class WebformConditionalsTestCase extends WebformTestCase {
* operation to trigger or not. If TRUE, the submission should succeed.
* If FALSE, validation errors are expected to be triggered. The input
* $value will be compared against the "sample values" input provided by
- * testWebformComponents().
- * @return
- * None. This function executes its own assert statements to show results.
+ * webformComponents().
+ *
+ * @return void
+ * This function executes its own assert statements to show results.
*/
private function webformTestConditionalComponent($component, $input_values, $operator, $conditional_values, $should_match) {
// Create the Webform test node and add a same-page conditional followed
@@ -97,7 +81,7 @@ class WebformConditionalsTestCase extends WebformTestCase {
$components = array();
$components[] = $component;
- $test_components = $this->testWebformComponents();
+ $test_components = $this->webformComponents();
$textfield = $test_components['textfield']['component'];
// Add a test textfield on the first page.
@@ -154,7 +138,7 @@ class WebformConditionalsTestCase extends WebformTestCase {
node_save($node);
// Submit our test data.
- $edit = $this->testWebformPost(array($component['form_key'] => $input_values));
+ $edit = $this->webformPost(array($component['form_key'] => $input_values));
$this->drupalPost('node/' . $node->nid, $edit, 'Next Page >', array(), array(), 'webform-client-form-' . $node->nid);
// Ensure we reached the second page for matched conditionals.
diff --git a/sites/all/modules/contrib/webform/tests/WebformGeneralTestCase.test b/sites/all/modules/contrib/webform/tests/WebformGeneralTestCase.test
new file mode 100644
index 000000000..2722c73ff
--- /dev/null
+++ b/sites/all/modules/contrib/webform/tests/WebformGeneralTestCase.test
@@ -0,0 +1,88 @@
+ t('Webform'),
+ 'description' => t('Checks global Webform settings and content types.'),
+ 'group' => t('Webform'),
+ );
+ }
+
+ /**
+ * Test creating a new Webform node.
+ */
+ function testWebformCreate() {
+ $settings = array(
+ 'title' => 'Test webform, no components',
+ 'type' => 'webform',
+ );
+ $node = $this->drupalCreateNode($settings);
+
+ // Because this is a "webform" type node, it should have an entry in the
+ // database even though it's using the default settings.
+ $this->assertTrue($this->webformRecordExists($node->nid), t('Webform record made in the database for the new webform node.'));
+
+ // Make a change to the node, ensure that the record stays intact.
+ $node->title .= '!';
+ node_save($node);
+ $this->assertTrue($this->webformRecordExists($node->nid), t('Webform record still in the database after modifying webform node.'));
+ }
+
+ /**
+ * Test webform-enabling a different node type and testing behavior.
+ */
+ function testWebformCreateNewType() {
+ // Enable webforms on the page content type.
+ variable_set('webform_node_webform', TRUE);
+ variable_set('webform_node_page', TRUE);
+
+ $settings = array(
+ 'title' => 'Test webform-enabled page',
+ 'type' => 'page',
+ );
+ $node = $this->drupalCreateNode($settings);
+
+ // Because this is a webform-enabled type node but does not yet have any
+ // components, it should not have an entry in the database because it is
+ // using the default settings.
+ $this->assertFalse($this->webformRecordExists($node->nid), t('Webform record not in the database for the new page node.'));
+
+ // Make a change to the node, ensure that the record stays empty.
+ $node->title .= '!';
+ node_save($node);
+ $this->assertFalse($this->webformRecordExists($node->nid), t('Webform record still not in the database after modifying page node.'));
+
+ // Add a new component to the node and check that a record is made in the
+ // webform table.
+ $components = $this->webformComponents();
+ $textarea = $components['textarea'];
+ $textarea['type'] = 'textarea';
+ $textarea['form_key'] = 'textarea';
+ $textarea['cid'] = 1;
+ $textarea['pid'] = 0;
+ $textarea = array_merge(webform_component_invoke('textarea', 'defaults'), $textarea);
+ $node->webform['components'][1] = $textarea;
+ node_save($node);
+ $this->assertTrue($this->webformRecordExists($node->nid), t('Webform record now exists after adding a new component.'));
+
+ // Remove the new component and ensure that the record is deleted.
+ $node->webform['components'] = array();
+ node_save($node);
+ $this->assertFalse($this->webformRecordExists($node->nid), t('Webform record deleted after deleting last component.'));
+ }
+
+ /**
+ * @return bool
+ */
+ function webformRecordExists($nid) {
+ return (bool) db_query("SELECT nid FROM {webform} WHERE nid = :nid", array(':nid' => $nid))->fetchField();
+ }
+}
diff --git a/sites/all/modules/contrib/webform/tests/permissions.test b/sites/all/modules/contrib/webform/tests/WebformPermissionsTestCase.test
similarity index 81%
rename from sites/all/modules/contrib/webform/tests/permissions.test
rename to sites/all/modules/contrib/webform/tests/WebformPermissionsTestCase.test
index a238059d8..9779ab72e 100644
--- a/sites/all/modules/contrib/webform/tests/permissions.test
+++ b/sites/all/modules/contrib/webform/tests/WebformPermissionsTestCase.test
@@ -4,12 +4,9 @@
* @file
* Webform module permission tests.
*/
-
-include_once(dirname(__FILE__) . '/webform.test');
-
class WebformPermissionsTestCase extends WebformTestCase {
/**
- * Implements getInfo().
+ * {@inheritdoc}
*/
public static function getInfo() {
return array(
@@ -19,26 +16,12 @@ class WebformPermissionsTestCase extends WebformTestCase {
);
}
- /**
- * Implements setUp().
- */
- function setUp($added_modules = array()) {
- parent::setUp($added_modules);
- }
-
- /**
- * Implements tearDown().
- */
- function tearDown() {
- parent::tearDown();
- }
-
/**
* Create a webform node in which authenticated users have access to submit.
- */
+ */
function testWebformSubmitAccess() {
$this->webformReset();
- $node = $this->testWebformForm();
+ $node = $this->webformForm();
$node->webform['roles'] = array(2);
node_save($node);
@@ -59,9 +42,4 @@ class WebformPermissionsTestCase extends WebformTestCase {
// Something in SimpleTest isn't handling the string correctly.
$this->assertText('to view this form.', t('Anonymous user is not allowed to submit form.'), t('Webform'));
}
-
- /**
- * Create webform
- */
-
}
diff --git a/sites/all/modules/contrib/webform/tests/submission.test b/sites/all/modules/contrib/webform/tests/WebformSubmissionTestCase.test
similarity index 73%
rename from sites/all/modules/contrib/webform/tests/submission.test
rename to sites/all/modules/contrib/webform/tests/WebformSubmissionTestCase.test
index c20413cf5..4e703db84 100644
--- a/sites/all/modules/contrib/webform/tests/submission.test
+++ b/sites/all/modules/contrib/webform/tests/WebformSubmissionTestCase.test
@@ -4,12 +4,9 @@
* @file
* Webform module submission tests.
*/
-
-include_once(dirname(__FILE__) . '/webform.test');
-
class WebformSubmissionTestCase extends WebformTestCase {
/**
- * Implements getInfo().
+ * {@inheritdoc}
*/
public static function getInfo() {
return array(
@@ -19,20 +16,6 @@ class WebformSubmissionTestCase extends WebformTestCase {
);
}
- /**
- * Implements setUp().
- */
- function setUp($added_modules = array()) {
- parent::setUp($added_modules);
- }
-
- /**
- * Implements tearDown().
- */
- function tearDown() {
- parent::tearDown();
- }
-
/**
* Test sending a submission and check database integrity.
*/
@@ -72,7 +55,7 @@ class WebformSubmissionTestCase extends WebformTestCase {
// Create the Webform test node, and set all components to be required
// with no default value.
- $node = $this->testWebformForm();
+ $node = $this->webformForm();
$node = node_load($node->nid);
foreach ($node->webform['components'] as &$component) {
$component['value'] = '';
@@ -95,6 +78,44 @@ class WebformSubmissionTestCase extends WebformTestCase {
$this->drupalLogout();
}
+ /**
+ * Test length validation.
+ */
+ function testWebformSubmissionComponentLength() {
+ $this->drupalLogin($this->webform_users['admin']);
+ $this->webformReset();
+
+ // Create the Webform test node.
+ $node = $this->webformForm();
+ $node = node_load($node->nid);
+
+ // Get the cid of the textfield component.
+ foreach ($node->webform['components'] as &$component) {
+ if ($component['form_key'] === 'textfield') {
+ $textfield_cid = $component['cid'];
+ break;
+ }
+ }
+
+ // Set length validation rules.
+ $node->webform['components'][$textfield_cid]['extra']['maxlength'] = 5;
+ $node->webform['components'][$textfield_cid]['extra']['minlength'] = 4;
+
+ node_save($node);
+
+ // Text value that is too long.
+ $this->drupalPost('node/' . $node->nid, array('submitted[textfield]' => '123456'), 'Submit', array(), array(), 'webform-client-form-' . $node->nid);
+ $this->assertRaw(t('!name cannot be longer than %max characters but is currently %length characters long.', array('!name' => $node->webform['components'][$textfield_cid]['name'], '%max' => 5, '%length' => 6)));
+
+ // Text value that is too short.
+ $this->drupalPost('node/' . $node->nid, array('submitted[textfield]' => '123'), 'Submit', array(), array(), 'webform-client-form-' . $node->nid);
+ $this->assertRaw(t('!name cannot be shorter than %min characters but is currently %length characters long.', array('!name' => $node->webform['components'][$textfield_cid]['name'], '%min' => 4, '%length' => 3)));
+
+ // Test value that meets validation rules has no error message.
+ $this->drupalPost('node/' . $node->nid, array('submitted[textfield]' => '12345'), 'Submit', array(), array(), 'webform-client-form-' . $node->nid);
+ $this->assertNoPattern('/ cannot be (longer|shorter) than /');
+ }
+
/**
* Execute the submission test.
*
@@ -106,8 +127,8 @@ class WebformSubmissionTestCase extends WebformTestCase {
module_load_include('inc', 'webform', 'includes/webform.submissions');
// Create a new Webform test node.
- $node = $this->testWebformForm();
- $submission_values = $value_type == 'sample' ? $this->testWebformPost() : array();
+ $node = $this->webformForm();
+ $submission_values = $value_type == 'sample' ? $this->webformPost() : array();
// Visit the node page with the "foo=bar" query, to test
// [current-page:query:?] default values.
@@ -129,7 +150,7 @@ class WebformSubmissionTestCase extends WebformTestCase {
drupal_static_reset('webform_get_submission');
$actual_submission = webform_get_submission($node->nid, $sid);
- $component_info = $this->testWebformComponents();
+ $component_info = $this->webformComponents();
foreach ($node->webform['components'] as $cid => $component) {
$stable_value = $value_type == 'sample' ? $component_info[$component['form_key']]['database values'] : $component_info[$component['form_key']]['database default values'];
$actual_value = $actual_submission->data[$cid];
@@ -151,12 +172,12 @@ class WebformSubmissionTestCase extends WebformTestCase {
module_load_include('inc', 'webform', 'includes/webform.submissions');
// Create a new Webform test node.
- $node = $this->testWebformForm();
+ $node = $this->webformForm();
// Visit the node page.
$this->drupalGet('node/' . $node->nid);
- foreach ($this->testWebformComponents() as $key => $component_info) {
+ foreach ($this->webformComponents() as $key => $component_info) {
if (isset($component_info['error values'])) {
foreach ($component_info['error values'] as $value => $error_message) {
$submission_values = array();
diff --git a/sites/all/modules/contrib/webform/tests/webform.test b/sites/all/modules/contrib/webform/tests/WebformTestCase.test
similarity index 90%
rename from sites/all/modules/contrib/webform/tests/webform.test
rename to sites/all/modules/contrib/webform/tests/WebformTestCase.test
index cfad13175..4d12f4250 100644
--- a/sites/all/modules/contrib/webform/tests/webform.test
+++ b/sites/all/modules/contrib/webform/tests/WebformTestCase.test
@@ -4,14 +4,13 @@
* @file
* Webform module tests.
*/
-
class WebformTestCase extends DrupalWebTestCase {
private $_webform_node;
private $_webform_components;
public $webform_users;
/**
- * Implements setUp().
+ * {@inheritdoc}
*/
function setUp($added_modules = array()) {
// Enable Webform and Token module if available.
@@ -81,7 +80,7 @@ class WebformTestCase extends DrupalWebTestCase {
}
/**
- * Implemenation of tearDown().
+ * {@inheritdoc}
*/
function tearDown() {
// Delete the webform admin and any created nodes.
@@ -100,9 +99,6 @@ class WebformTestCase extends DrupalWebTestCase {
parent::tearDown();
}
- /**
- *
- */
function webformReset() {
$this->_webform_node = NULL;
$this->_webform_components = NULL;
@@ -120,7 +116,7 @@ class WebformTestCase extends DrupalWebTestCase {
* @return array
* An array of each component settings.
*/
- function testWebformComponents() {
+ function webformComponents() {
if (isset($this->_webform_components)) {
return $this->_webform_components;
}
@@ -504,7 +500,7 @@ class WebformTestCase extends DrupalWebTestCase {
'pid' => '0',
'weight' => '-10',
),
- // TODO: I'd like to test a value, but SimpleTest can't set multiple values.
+ // @todo: I'd like to test a value, but SimpleTest can't set multiple values.
'sample values' => NULL,
'database values' => array('one', 'two'),
'database default values' => array('one', 'two'),
@@ -721,7 +717,7 @@ class WebformTestCase extends DrupalWebTestCase {
'weight' => '-15',
),
// Manually hard-code the input if token is not available.
- // TODO: Update after http://drupal.org/node/1347790 is finished.
+ // @todo: Update after http://drupal.org/node/1347790 is finished.
'sample values' => module_exists('token') ? NULL : 'bar',
'database values' => array('bar'),
'database default values' => module_exists('token') ? array('bar') : array(''),
@@ -742,7 +738,7 @@ class WebformTestCase extends DrupalWebTestCase {
'sample values' => 'Female',
'database values' => array('Female'),
// The default value will be blank if token does not exist.
- // TODO: Update after http://drupal.org/node/1347790 is finished.
+ // @todo: Update after http://drupal.org/node/1347790 is finished.
'database default values' => module_exists('token') ? array($this->webform_users['admin']->gender[LANGUAGE_NONE][0]['value']) : array(''),
),
@@ -990,7 +986,7 @@ class WebformTestCase extends DrupalWebTestCase {
return $this->_webform_components;
}
- function testWebformForm() {
+ function webformForm() {
if (isset($this->_webform_node)) {
return $this->_webform_node;
}
@@ -1014,7 +1010,7 @@ class WebformTestCase extends DrupalWebTestCase {
);
$cid = 0;
- foreach ($this->testWebformComponents() as $key => $component_info) {
+ foreach ($this->webformComponents() as $key => $component_info) {
$cid++;
$settings['webform']['components'][$cid] = $component_info['component'];
$settings['webform']['components'][$cid]['cid'] = $cid;
@@ -1031,14 +1027,14 @@ class WebformTestCase extends DrupalWebTestCase {
*
* @param $input_values
* An array of input values keyed by the component form key. If none
- * are specified, the defaults will be pulled from testWebformComponents().
+ * are specified, the defaults will be pulled from webformComponents().
*/
- function testWebformPost($input_values = NULL) {
+ function webformPost($input_values = NULL) {
$edit = array();
if (empty($input_values)) {
$input_values = array();
- foreach ($this->testWebformComponents() as $key => $component_info) {
+ foreach ($this->webformComponents() as $key => $component_info) {
$input_values[$key] = $component_info['sample values'];
}
}
@@ -1066,86 +1062,3 @@ class WebformTestCase extends DrupalWebTestCase {
$this->verbose($this->drupalGetContent());
}
}
-
-/**
- * Test general functionality of Webform.
- */
-class WebformGeneralTestCase extends WebformTestCase {
- /**
- * Implements getInfo().
- */
- public static function getInfo() {
- return array(
- 'name' => t('Webform'),
- 'description' => t('Checks global Webform settings and content types.'),
- 'group' => t('Webform'),
- );
- }
-
- /**
- * Test creating a new Webform node.
- */
- function testWebformCreate() {
- $settings = array(
- 'title' => 'Test webform, no components',
- 'type' => 'webform',
- );
- $node = $this->drupalCreateNode($settings);
-
- // Because this is a "webform" type node, it should have an entry in the
- // database even though it's using the default settings.
- $this->assertTrue($this->webformRecordExists($node->nid), t('Webform record made in the database for the new webform node.'));
-
- // Make a change to the node, ensure that the record stays intact.
- $node->title .= '!';
- node_save($node);
- $this->assertTrue($this->webformRecordExists($node->nid), t('Webform record still in the database after modifying webform node.'));
- }
-
- /**
- * Test webform-enabling a different node type and testing behavior.
- */
- function testWebformCreateNewType() {
- // Enable webforms on the page content type.
- variable_set('webform_node_webform', TRUE);
- variable_set('webform_node_page', TRUE);
-
- $settings = array(
- 'title' => 'Test webform-enabled page',
- 'type' => 'page',
- );
- $node = $this->drupalCreateNode($settings);
-
- // Because this is a webform-enabled type node but does not yet have any
- // components, it should not have an entry in the database because it is
- // using the default settings.
- $this->assertFalse($this->webformRecordExists($node->nid), t('Webform record not in the database for the new page node.'));
-
- // Make a change to the node, ensure that the record stays empty.
- $node->title .= '!';
- node_save($node);
- $this->assertFalse($this->webformRecordExists($node->nid), t('Webform record still not in the database after modifying page node.'));
-
- // Add a new component to the node and check that a record is made in the
- // webform table.
- $components = $this->testWebformComponents();
- $textarea = $components['textarea'];
- $textarea['type'] = 'textarea';
- $textarea['form_key'] = 'textarea';
- $textarea['cid'] = 1;
- $textarea['pid'] = 0;
- $textarea = array_merge(webform_component_invoke('textarea', 'defaults'), $textarea);
- $node->webform['components'][1] = $textarea;
- node_save($node);
- $this->assertTrue($this->webformRecordExists($node->nid), t('Webform record now exists after adding a new component.'));
-
- // Remove the new component and ensure that the record is deleted.
- $node->webform['components'] = array();
- node_save($node);
- $this->assertFalse($this->webformRecordExists($node->nid), t('Webform record deleted after deleting last component.'));
- }
-
- function webformRecordExists($nid) {
- return (bool) db_query("SELECT nid FROM {webform} WHERE nid = :nid", array(':nid' => $nid))->fetchField();
- }
-}
diff --git a/sites/all/modules/contrib/webform/tests/components.test b/sites/all/modules/contrib/webform/tests/components.test
deleted file mode 100644
index 143f44777..000000000
--- a/sites/all/modules/contrib/webform/tests/components.test
+++ /dev/null
@@ -1,37 +0,0 @@
- t('Webform components'),
- 'description' => t('Add and remove components from a webform.'),
- 'group' => t('Webform'),
- );
- }
-
- /**
- * Implements setUp().
- */
- function setUp($added_modules = array()) {
- parent::setUp($added_modules);
- }
-
- /**
- * Implements testWebformDummy(). if it is not present,
- * then the test runs fine, but when combined with other tests
- * the whole block fails, since there would be no output.
- */
- function testWebformDummy() {
- $this->pass = t('WebformComponentsTest pass.');
- }
-}
diff --git a/sites/all/modules/contrib/webform/views/default_views/webform_results.inc b/sites/all/modules/contrib/webform/views/default_views/webform_results.inc
index 2e381de52..737f4e09a 100644
--- a/sites/all/modules/contrib/webform/views/default_views/webform_results.inc
+++ b/sites/all/modules/contrib/webform/views/default_views/webform_results.inc
@@ -90,7 +90,7 @@ $handler->display->display_options['empty']['area_text_custom']['id'] = 'area_te
$handler->display->display_options['empty']['area_text_custom']['table'] = 'views';
$handler->display->display_options['empty']['area_text_custom']['field'] = 'area_text_custom';
$handler->display->display_options['empty']['area_text_custom']['empty'] = TRUE;
-$handler->display->display_options['empty']['area_text_custom']['content'] = 'There are no submissions for this form. View this form.';
+$handler->display->display_options['empty']['area_text_custom']['content'] = t('There are no submissions for this form. View this form.', array('!url' => url('node/')));
$handler->display->display_options['empty']['area_text_custom']['tokenize'] = TRUE;
/* Relationship: Webform submissions: User */
$handler->display->display_options['relationships']['uid']['id'] = 'uid';
@@ -142,7 +142,7 @@ $handler->display->display_options['arguments']['nid']['summary_options']['items
$handler->display->display_options['arguments']['nid']['specify_validation'] = TRUE;
$handler->display->display_options['arguments']['nid']['validate']['type'] = 'node';
$translatables['webform_results'] = array(
- t('Master'),
+ t('Master'),
t('more'),
t('Apply'),
t('Reset'),
diff --git a/sites/all/modules/contrib/webform/views/default_views/webform_submissions.inc b/sites/all/modules/contrib/webform/views/default_views/webform_submissions.inc
index 2c93d06d2..703768666 100644
--- a/sites/all/modules/contrib/webform/views/default_views/webform_submissions.inc
+++ b/sites/all/modules/contrib/webform/views/default_views/webform_submissions.inc
@@ -107,7 +107,7 @@ $handler->display->display_options['empty']['area_text_custom']['id'] = 'area_te
$handler->display->display_options['empty']['area_text_custom']['table'] = 'views';
$handler->display->display_options['empty']['area_text_custom']['field'] = 'area_text_custom';
$handler->display->display_options['empty']['area_text_custom']['empty'] = TRUE;
-$handler->display->display_options['empty']['area_text_custom']['content'] = 'There are no submissions for this form. View this form.';
+$handler->display->display_options['empty']['area_text_custom']['content'] = t('There are no submissions for this form. View this form.', array('!url' => url('node/')));
$handler->display->display_options['empty']['area_text_custom']['tokenize'] = TRUE;
/* Relationship: Webform submissions: User */
$handler->display->display_options['relationships']['uid']['id'] = 'uid';
diff --git a/sites/all/modules/contrib/webform/views/webform.views.inc b/sites/all/modules/contrib/webform/views/webform.views.inc
index 79ac3968f..fb062465d 100644
--- a/sites/all/modules/contrib/webform/views/webform.views.inc
+++ b/sites/all/modules/contrib/webform/views/webform.views.inc
@@ -6,10 +6,7 @@
*/
function webform_views_data() {
-
- /**
- * Webform table definitions.
- */
+ // Webform table definitions.
$data['webform']['table']['group'] = t('Webform');
$data['webform']['table']['base'] = array(
'field' => 'nid',
@@ -66,9 +63,7 @@ function webform_views_data() {
),
);
- /**
- * Submissions table definitions.
- */
+ // Submissions table definitions.
$data['webform_submissions']['table']['group'] = t('Webform submissions');
$data['webform_submissions']['table']['base'] = array(
'field' => 'sid',
@@ -342,9 +337,7 @@ function webform_views_data() {
),
);
- /**
- * Submission data table definitions.
- */
+ // Submission data table definitions.
$data['webform_submitted_data']['table']['group'] = t('Webform submission data');
// Raw access to the submitted values. This usually will only be used for
diff --git a/sites/all/modules/contrib/webform/views/webform_handler_field_submission_data.inc b/sites/all/modules/contrib/webform/views/webform_handler_field_submission_data.inc
index 87f66aa44..3366b6411 100644
--- a/sites/all/modules/contrib/webform/views/webform_handler_field_submission_data.inc
+++ b/sites/all/modules/contrib/webform/views/webform_handler_field_submission_data.inc
@@ -188,7 +188,7 @@ class webform_handler_field_submission_data extends views_handler_field {
$this->view->_webform_components[$nid][$submission->nid][$cid] = $component;
$submission_node = node_load($submission->nid);
foreach ($submission_node->webform['components'] as $sub_cid => $sub_component) {
- if ($sub_component['form_key'] == $component['form_key'] && $sub_component['type'] == $component['type']) {
+ if ((string) $sub_component['form_key'] === (string) $component['form_key'] && $sub_component['type'] == $component['type']) {
$this->view->_webform_components[$nid][$submission->nid]['webform'] = $submission_node;
$this->view->_webform_components[$nid][$submission->nid][$cid] = $sub_component;
break;
diff --git a/sites/all/modules/contrib/webform/views/webform_handler_numeric_data.inc b/sites/all/modules/contrib/webform/views/webform_handler_numeric_data.inc
index d3b15ba76..8c678ba7f 100644
--- a/sites/all/modules/contrib/webform/views/webform_handler_numeric_data.inc
+++ b/sites/all/modules/contrib/webform/views/webform_handler_numeric_data.inc
@@ -21,7 +21,7 @@ class webform_handler_field_numeric_data extends views_handler_field_numeric {
parent::construct();
$this->formula = TRUE;
}
-
+
/**
* Get the formula for this argument.
*
@@ -53,7 +53,7 @@ class webform_handler_field_numeric_data extends views_handler_field_numeric {
function get_field($field = NULL) {
return parent::get_field($this->get_formula());
}
-
+
}
/**
@@ -91,8 +91,8 @@ class webform_handler_filter_numeric_data extends views_handler_filter_numeric {
static $sequence = 1;
$param = ":value" . $sequence++;
$this->query->add_where_expression($this->options['group'],
- $field . $this->operator . $param,
- array($param => $this->value['value']));
+ $field . $this->operator . $param,
+ array($param => $this->value['value']));
}
/**
@@ -104,13 +104,13 @@ class webform_handler_filter_numeric_data extends views_handler_filter_numeric {
$max = ":max" . $sequence++;
if ($this->operator == 'between') {
$this->query->add_where_expression($this->options['group'],
- "($min <= $field AND $field <= $max)",
- array($min => $this->value['min'], $max => $this->value['max']));
+ "($min <= $field AND $field <= $max)",
+ array($min => $this->value['min'], $max => $this->value['max']));
}
else {
$this->query->add_where_expression($this->options['group'],
- "($min > $field OR $field > $max)",
- array($min => $this->value['min'], $max => $this->value['max']));
+ "($min > $field OR $field > $max)",
+ array($min => $this->value['min'], $max => $this->value['max']));
}
}
@@ -137,8 +137,8 @@ class webform_handler_filter_numeric_data extends views_handler_filter_numeric {
$param = ":expression" . $sequence++;
$this->query->add_where_expression($this->options['group'],
- "$field RLIKE $param",
- array($param => $this->value['value']));
+ "$field RLIKE $param",
+ array($param => $this->value['value']));
}
}
diff --git a/sites/all/modules/contrib/webform/webform.api.php b/sites/all/modules/contrib/webform/webform.api.php
index 70968e624..8691fcacb 100644
--- a/sites/all/modules/contrib/webform/webform.api.php
+++ b/sites/all/modules/contrib/webform/webform.api.php
@@ -24,12 +24,13 @@
* @see webform_options_example()
* @see hook_webform_select_options_info_alter()
*
- * @return
+ * @return array
* An array of callbacks that can be used for select list options. This array
* should be keyed by the "name" of the pre-defined list. The values should
* be an array with the following additional keys:
* - title: The translated title for this list.
- * - options callback: The name of the function that will return the list.
+ * - options callback: The name of a function implementing
+ * callback_webform_options() that will return the list.
* - options arguments: Any additional arguments to send to the callback.
* - file: Optional. The file containing the options callback, relative to
* the module root.
@@ -49,7 +50,7 @@ function hook_webform_select_options_info() {
/**
* Alter the list of select list options provided by Webform and other modules.
*
- * @see hook_webform_select_options_info().
+ * @see hook_webform_select_options_info()
*/
function hook_webform_select_options_info_alter(&$items) {
// Remove the days of the week options.
@@ -57,12 +58,9 @@ function hook_webform_select_options_info_alter(&$items) {
}
/**
- * This is an example function to demonstrate a webform options callback.
+ * Define a list of options that Webform may use in a select component.
*
- * This function returns a list of options that Webform may use in a select
- * component. In order to be called, the function name
- * ("webform_options_example" in this case), needs to be specified as a callback
- * in hook_webform_select_options_info().
+ * Callback for hook_webform_select_options_info().
*
* @param $component
* The Webform component array for the select component being displayed.
@@ -73,11 +71,12 @@ function hook_webform_select_options_info_alter(&$items) {
* without the nesting.
* @param $arguments
* The "options arguments" specified in hook_webform_select_options_info().
- * @return
+ *
+ * @return array
* An array of key => value pairs suitable for a select list's #options
* FormAPI property.
*/
-function webform_options_example($component, $flat, $arguments) {
+function callback_webform_options($component, $flat, $arguments) {
$options = array(
'one' => t('Pre-built option one'),
'two' => t('Pre-built option two'),
@@ -214,6 +213,9 @@ function hook_webform_submission_delete($node, $submission) {
* The Webform node on which this submission was made.
* @param $submission
* The Webform submission on which the actions may be performed.
+ *
+ * @return array
+ * List of action.
*/
function hook_webform_submission_actions($node, $submission) {
$actions= array();
@@ -428,7 +430,7 @@ function hook_webform_csv_data_alter(&$data, $component, $submission) {
/**
* Define components to Webform.
*
- * @return
+ * @return array
* An array of components, keyed by machine name. Required properties are
* "label" and "description". The "features" array defines which capabilities
* the component has, such as being displayed in e-mails or csv downloads.
@@ -613,7 +615,8 @@ function hook_webform_component_defaults_alter(&$defaults, $type) {
* - "list"
* @param $account
* A user account object.
- * @return
+ *
+ * @return bool
* TRUE if the current user has access to submission,
* or FALSE otherwise.
*/
@@ -642,13 +645,14 @@ function hook_webform_submission_access($node, $submission, $op = 'view', $accou
* Access via this hook is in addition (adds permission) to the standard
* webform access.
*
- * @see webform_results_access().
+ * @see webform_results_access()
*
* @param $node
* The Webform node to check access on.
* @param $account
* The user account to check access on.
- * @return
+ *
+ * @return bool
* TRUE or FALSE if the user can access the webform results.
*/
function hook_webform_results_access($node, $account) {
@@ -667,7 +671,7 @@ function hook_webform_results_access($node, $account) {
* Access via this hook is in addition (adds permission) to the standard
* webform access (delete all webform submissions).
*
- * @see webform_results_clear_access().
+ * @see webform_results_clear_access()
*
* @param object $node
* The Webform node to check access on.
@@ -695,7 +699,7 @@ function hook_webform_results_clear_access($node, $account) {
* access as this will be the only test. For example, 'return TRUE;' would grant
* annonymous access to creating webform components, which seldom be desired.
*
- * @see webform_node_update_access().
+ * @see webform_node_update_access()
*
* @param object $node
* The Webform node to check access on.
@@ -715,7 +719,6 @@ function hook_webform_update_access($node, $account) {
}
}
-
/**
* Return an array of files associated with the component.
*
@@ -726,7 +729,8 @@ function hook_webform_update_access($node, $account) {
* @param $value
* An array of information containing the submission result, directly
* correlating to the webform_submitted_data database schema.
- * @return
+ *
+ * @return array
* An array of files, each file is an array with following keys:
* - filepath: The relative path to the file.
* - filename: The name of the file including the extension.
@@ -746,7 +750,6 @@ function _webform_attachments_component($component, $value) {
return $files;
}
-
/**
* Alter default settings for a newly created webform node.
*
@@ -762,7 +765,7 @@ function hook_webform_node_defaults_alter(&$defaults) {
/**
* Add additional fields to submission data downloads.
*
- * @return
+ * @return array
* Keys and titles for default submission information.
*
* @see hook_webform_results_download_submission_information_data()
@@ -781,7 +784,7 @@ function hook_webform_results_download_submission_information_info() {
* The name of the token being replaced.
* @param $submission
* The data for an individual submission from webform_get_submissions().
- * @param $options
+ * @param array $options
* A list of options that define the output format. These are generally passed
* through from the GUI interface.
* @param $serial_start
@@ -789,7 +792,7 @@ function hook_webform_results_download_submission_information_info() {
* @param $row_count
* The number of the row being generated.
*
- * @return
+ * @return string
* Value for requested submission information field.
*
* @see hook_webform_results_download_submission_information_info()
@@ -819,7 +822,7 @@ function hook_webform_results_download_submission_information_data($token, $subm
/**
* Specify the default properties of a component.
*
- * @return
+ * @return array
* An array defining the default structure of a component.
*/
function _webform_defaults_component() {
@@ -853,7 +856,8 @@ function _webform_defaults_component() {
*
* @param $component
* A Webform component array.
- * @return
+ *
+ * @return array
* An array of form items to be displayed on the edit component page
*/
function _webform_edit_component($component) {
@@ -896,6 +900,9 @@ function _webform_edit_component($component) {
* needed. Used by _webform_render_date() to validate using the submission's
* completion date.
*
+ * @return array
+ * $form_item
+ *
* @see _webform_client_form_add_component()
*/
function _webform_render_component($component, $value = NULL, $filter = TRUE, $submission = NULL) {
@@ -950,7 +957,8 @@ function hook_webform_component_render_alter(&$element, &$component) {
* or other filtering functions when returning HTML.
* @param $submission
* The submission. Used to generate tokens.
- * @return
+ *
+ * @return array
* A renderable element containing at the very least these properties:
* - #title
* - #weight
@@ -1120,7 +1128,8 @@ function _webform_theme_component() {
* @param $join
* An optional SelectQuery object to be used to join with the submissions
* table to restrict the submissions being analyzed.
- * @return
+ *
+ * @return array
* An array containing one or more of the following keys:
* - table_rows: If this component has numeric data that can be represented in
* a grid, return the values here. This array assumes a 2-dimensional
@@ -1208,7 +1217,8 @@ function _webform_analysis_component($component, $sids = array(), $single = FALS
* @param $value
* An array of information containing the submission result, directly
* correlating to the webform_submitted_data database schema.
- * @return
+ *
+ * @return string
* Textual output formatted for human reading.
*/
function _webform_table_component($component, $value) {
@@ -1238,7 +1248,8 @@ function _webform_table_component($component, $value) {
* A Webform component array.
* @param $export_options
* An array of options that may configure export of this field.
- * @return
+ *
+ * @return array
* An array of data to be displayed in the first three rows of a CSV file, not
* including either prefixed or trailing commas.
*/
@@ -1275,7 +1286,8 @@ function _webform_csv_headers_component($component, $export_options) {
* @param $value
* An array of information containing the submission result, directly
* correlating to the webform_submitted_data database schema.
- * @return
+ *
+ * @return array
* An array of items to be added to the CSV file. Each value within the array
* will be another column within the file. This function is called once for
* every row of data.
diff --git a/sites/all/modules/contrib/webform/webform.drush.inc b/sites/all/modules/contrib/webform/webform.drush.inc
index 9a95901ed..b8435f741 100644
--- a/sites/all/modules/contrib/webform/webform.drush.inc
+++ b/sites/all/modules/contrib/webform/webform.drush.inc
@@ -2,9 +2,12 @@
/**
* @file
- * Implementation of hook_drush_command().
+ * Functions relating to Drush integration.
*/
+/**
+ * Implements hook_drush_command().
+ */
function webform_drush_command() {
return array(
'webform-export' => array(
@@ -46,8 +49,11 @@ function webform_drush_command() {
* Exports a webform via drush, useful for large data dumps that would otherwise
* time out due to memory consumption.
*
- * @param int $nid
+ * @param bool|int $nid
* Node ID of the webform that we want to export.
+ *
+ * @return
+ * The value returned from drush_set_error().
*/
function drush_webform_export($nid = FALSE) {
if (!$nid) {
@@ -102,16 +108,16 @@ function drush_webform_export($nid = FALSE) {
array('!opt' => "range-$option_name", '!val' => $option_value)));
}
}
-
+
// Determine the range type based on provided input, if not explicitly set.
if (empty($options['range']['range_type'])) {
$options['range']['range_type'] = isset($options['range']['start'])
- ? 'range'
- : (isset($options['range']['latest'])
- ? 'latest'
- : 'all');
+ ? 'range'
+ : (isset($options['range']['latest'])
+ ? 'latest'
+ : 'all');
}
-
+
// Set defaults for any missing range arguments.
switch ($options['range']['range_type']) {
case 'latest':
@@ -134,7 +140,7 @@ function drush_webform_export($nid = FALSE) {
}
// Get the preferred completion type
- $options['range']['completion_type'] = drush_get_option('completion-type', NULL);
+ $options['range']['completion_type'] = drush_get_option('completion-type', NULL);
if (isset($options['range']['completion_type']) && !in_array($options['range']['completion_type'], array('finished', 'draft', 'all'))) {
return drush_set_error('Unsupported completion-type. The available options are "finished", "draft", or "all".');
}
@@ -189,10 +195,21 @@ function drush_webform_clear($nid = FALSE) {
}
/**
- * Implements hook_drush_sql_sync_sanitize.
+ * Implements hook_drush_sql_sync_sanitize().
*/
function webform_drush_sql_sync_sanitize($source) {
+ // Fetch list of all table.
+ $all_tables = drush_sql_get_class()->listTables();
+ $tables_to_truncate = array('webform_submitted_data', 'webform_submissions');
+
+ $truncate_webform_tables_query = array();
+ foreach ($tables_to_truncate as $table) {
+ if (in_array($table, $all_tables, TRUE)) {
+ $truncate_webform_tables_query[] = 'TRUNCATE ' . $table . ';';
+ }
+ }
+
drush_sql_register_post_sync_op('webform_submitted_data',
dt('Delete all data submitted to webforms (depending on the site config, may contain sensitive data).'),
- "TRUNCATE webform_submitted_data; TRUNCATE webform_submissions;");
+ implode(' ', $truncate_webform_tables_query));
}
diff --git a/sites/all/modules/contrib/webform/webform.info b/sites/all/modules/contrib/webform/webform.info
index 873a63a79..ad3d1fe15 100644
--- a/sites/all/modules/contrib/webform/webform.info
+++ b/sites/all/modules/contrib/webform/webform.info
@@ -1,4 +1,3 @@
-; $Id: $
name = Webform
description = Enables the creation of forms and questionnaires.
core = 7.x
@@ -34,15 +33,16 @@ files[] = views/webform_handler_relationship_submission_data.inc
files[] = views/webform_plugin_row_submission_view.inc
files[] = views/webform.views.inc
-files[] = tests/components.test
-files[] = tests/conditionals.test
-files[] = tests/permissions.test
-files[] = tests/submission.test
-files[] = tests/webform.test
+files[] = tests/WebformComponentsTestCase.test
+files[] = tests/WebformConditionalsTestCase.test
+files[] = tests/WebformGeneralTestCase.test
+files[] = tests/WebformPermissionsTestCase.test
+files[] = tests/WebformSubmissionTestCase.test
+files[] = tests/WebformTestCase.test
-; Information added by Drupal.org packaging script on 2016-08-28
-version = "7.x-4.14"
+; Information added by Drupal.org packaging script on 2017-04-13
+version = "7.x-4.15"
core = "7.x"
project = "webform"
-datestamp = "1472386754"
+datestamp = "1492107249"
diff --git a/sites/all/modules/contrib/webform/webform.module b/sites/all/modules/contrib/webform/webform.module
index b0971bed7..48a151651 100644
--- a/sites/all/modules/contrib/webform/webform.module
+++ b/sites/all/modules/contrib/webform/webform.module
@@ -36,9 +36,11 @@ function webform_help($section = 'admin/help#webform', $arg = NULL) {
}
$output = '
' . $output . '
';
break;
+
case 'admin/content/webform':
$output = '
' . t('This page lists all of the content on the site that may have a webform attached to it.') . '
Your form is now ready for viewing. After receiving submissions, you can check the results users have submitted by visiting the Results tab on the piece of content.
Help on adding and configuring the components will be shown after you add your first component.
' . t('Conditionals may be used to hide or show certain components (or entire pages!) based on the value of other components.') . '
';
break;
+
case 'node/%/submission/%/resend':
$output .= '
' . t('This form may be used to resend e-mails configured for this webform. Check the e-mails that need to be sent and click Resend e-mails to send these e-mails again.') . '
';
break;
@@ -455,10 +464,11 @@ function webform_menu_load($nid) {
* @param string $arg
* The argument supplied by the caller.
* @param array $map
- * Array of path fragments (e.g. e.g. array('node','123','edit') for
+ * Array of path fragments (for example, array('node','123','edit') for
* 'node/123/edit').
- * @param integer $index
+ * @param int $index
* Which element of $map corresponds to $arg.
+ *
* @return string
* The $arg, modified as desired.
*/
@@ -484,7 +494,14 @@ function webform_menu_component_load($cid, $nid, $type) {
module_load_include('inc', 'webform', 'includes/webform.components');
if ($cid == 'new') {
$components = webform_components();
- $component = in_array($type, array_keys($components)) ? array('type' => $type, 'nid' => $nid, 'name' => $_GET['name'], 'required' => $_GET['required'], 'pid' => $_GET['pid'], 'weight' => $_GET['weight']) : FALSE;
+ $component = in_array($type, array_keys($components)) ? array(
+ 'type' => $type,
+ 'nid' => $nid,
+ 'name' => $_GET['name'],
+ 'required' => $_GET['required'],
+ 'pid' => $_GET['pid'],
+ 'weight' => $_GET['weight'],
+ ) : FALSE;
}
else {
$node = node_load($nid);
@@ -496,7 +513,6 @@ function webform_menu_component_load($cid, $nid, $type) {
return $component;
}
-
/**
* Menu loader callback. Load a webform e-mail if the given eid is a valid.
*/
@@ -538,11 +554,11 @@ function webform_get_submission_access_token($submission) {
/**
* Access function for confirmation pages.
*
- * @param $node
+ * @param stdClass $node
* The webform node object.
*
- * @return
- * Boolean whether the user has access to the confirmation page.
+ * @return bool
+ * Boolean whether the user has access to the confirmation page.
*/
function webform_confirmation_page_access($node) {
global $user;
@@ -582,7 +598,8 @@ function webform_confirmation_page_access($node) {
}
else {
// No submission exists (such as auto-deleted by another module, such as
- // webform_clear), just ensure that the user has access to view the node page.
+ // webform_clear), just ensure that the user has access to view the node
+ // page.
if (node_access('view', $node)) {
return TRUE;
}
@@ -594,16 +611,16 @@ function webform_confirmation_page_access($node) {
/**
* Access function for Webform submissions.
*
- * @param $node
+ * @param stdClass $node
* The webform node object.
- * @param $submission
+ * @param stdClass $submission
* The webform submission object.
- * @param $op
+ * @param stdClass $op
* The operation to perform. Must be one of view, edit, delete, list.
- * @param $account
+ * @param array $account
* Optional. A user object or NULL to use the currently logged-in user.
*
- * @return
+ * @return bool
* Boolean whether the user has access to a webform submission.
*/
function webform_submission_access($node, $submission, $op = 'view', $account = NULL) {
@@ -635,10 +652,13 @@ function webform_submission_access($node, $submission, $op = 'view', $account =
switch ($op) {
case 'view':
return $module_access || $general_access;
+
case 'edit':
return $module_access || ($general_access && (user_access('edit all webform submissions', $account) || (user_access('edit own webform submissions', $account) && $account->uid == $submission->uid)));
+
case 'delete':
return $module_access || ($general_access && (user_access('delete all webform submissions', $account) || (user_access('delete own webform submissions', $account) && $account->uid == $submission->uid)));
+
case 'list':
return $module_access || user_access('access all webform results', $account) || (user_access('access own webform submissions', $account) && ($account->uid || isset($_SESSION['webform_submission']))) || (user_access('access own webform results', $account) && $account->uid == $node->uid);
}
@@ -685,7 +705,7 @@ function webform_results_clear_access($node, $account = NULL) {
* be granted, FALSE if it should absolutely be denied, or NULL if node_access
* and 'edit webform components' permission should determine access.
*
- * @see hook_webform_update_access().
+ * @see hook_webform_update_access()
*/
function webform_node_update_access($node, $account = NULL) {
global $user;
@@ -758,7 +778,16 @@ function webform_theme() {
'render element' => 'webform',
),
'webform_view_messages' => array(
- 'variables' => array('node' => NULL, 'page' => NULL, 'submission_count' => NULL, 'user_limit_exceeded' => NULL, 'total_limit_exceeded' => NULL, 'allowed_roles' => NULL, 'closed' => NULL, 'cached' => NULL),
+ 'variables' => array(
+ 'node' => NULL,
+ 'page' => NULL,
+ 'submission_count' => NULL,
+ 'user_limit_exceeded' => NULL,
+ 'total_limit_exceeded' => NULL,
+ 'allowed_roles' => NULL,
+ 'closed' => NULL,
+ 'cached' => NULL,
+ ),
),
'webform_form' => array(
'render element' => 'form',
@@ -783,16 +812,29 @@ function webform_theme() {
'render element' => 'element',
),
'webform_progressbar' => array(
- 'variables' => array('node' => NULL, 'page_num' => NULL, 'page_count' => NULL, 'page_labels' => array()),
+ 'variables' => array(
+ 'node' => NULL,
+ 'page_num' => NULL,
+ 'page_count' => NULL,
+ 'page_labels' => array(),
+ ),
'template' => 'templates/webform-progressbar',
),
'webform_mail_message' => array(
- 'variables' => array('node' => NULL, 'submission' => NULL, 'email' => NULL),
+ 'variables' => array(
+ 'node' => NULL,
+ 'submission' => NULL,
+ 'email' => NULL,
+ ),
'template' => 'templates/webform-mail',
'pattern' => 'webform_mail(_[0-9]+)?',
),
'webform_mail_headers' => array(
- 'variables' => array('node' => NULL, 'submission' => NULL, 'email' => NULL),
+ 'variables' => array(
+ 'node' => NULL,
+ 'submission' => NULL,
+ 'email' => NULL,
+ ),
'pattern' => 'webform_mail_headers_[0-9]+',
),
'webform_token_help' => array(
@@ -882,7 +924,13 @@ function webform_theme() {
'file' => 'includes/webform.report.inc',
),
'webform_results_table' => array(
- 'variables' => array('node' => NULL, 'components' => NULL, 'submissions' => NULL, 'total_count' => NULL, 'pager_count' => NULL),
+ 'variables' => array(
+ 'node' => NULL,
+ 'components' => NULL,
+ 'submissions' => NULL,
+ 'total_count' => NULL,
+ 'pager_count' => NULL,
+ ),
'file' => 'includes/webform.report.inc',
),
'webform_results_download_range' => array(
@@ -907,7 +955,7 @@ function webform_theme() {
'variables' => array('component' => NULL, 'data' => NULL),
'file' => 'includes/webform.report.inc',
),
- // webform.submissions.inc
+ // webform.submissions.inc.
'webform_submission' => array(
'render element' => 'renderable',
'template' => 'templates/webform-submission',
@@ -915,12 +963,24 @@ function webform_theme() {
'file' => 'includes/webform.submissions.inc',
),
'webform_submission_page' => array(
- 'variables' => array('node' => NULL, 'submission' => NULL, 'submission_content' => NULL, 'submission_navigation' => NULL, 'submission_information' => NULL, 'submission_actions' => NULL, 'mode' => NULL),
+ 'variables' => array(
+ 'node' => NULL,
+ 'submission' => NULL,
+ 'submission_content' => NULL,
+ 'submission_navigation' => NULL,
+ 'submission_information' => NULL,
+ 'submission_actions' => NULL,
+ 'mode' => NULL,
+ ),
'template' => 'templates/webform-submission-page',
'file' => 'includes/webform.submissions.inc',
),
'webform_submission_information' => array(
- 'variables' => array('node' => NULL, 'submission' => NULL, 'mode' => 'display'),
+ 'variables' => array(
+ 'node' => NULL,
+ 'submission' => NULL,
+ 'mode' => 'display',
+ ),
'template' => 'templates/webform-submission-information',
'file' => 'includes/webform.submissions.inc',
),
@@ -1187,7 +1247,7 @@ function webform_webform_conditional_operator_info() {
/**
* Implements hook_forms().
*
- * All webform_client_form forms share the same form handler
+ * All webform_client_form forms share the same form handler.
*/
function webform_forms($form_id) {
$forms = array();
@@ -1285,7 +1345,8 @@ function webform_webform_submission_presave($node, &$submission) {
}
}
- // Only rename files if this is the first time the submission is being saved as finished.
+ // Only rename files if this is the first time the submission is being saved
+ // as finished.
if ($submission->is_draft || (isset($old_submission) && !$old_submission->is_draft)) {
$renameable = array();
}
@@ -1460,7 +1521,8 @@ function webform_node_insert($node) {
// Insert the components into the database. Used with clone.module.
if (isset($node->webform['components']) && !empty($node->webform['components'])) {
foreach ($node->webform['components'] as $cid => $component) {
- $component['nid'] = $node->nid; // Required for clone.module.
+ // Required for clone.module.
+ $component['nid'] = $node->nid;
webform_component_insert($component);
}
}
@@ -1571,7 +1633,7 @@ function webform_node_update($node) {
$conditional['nid'] = $node->nid;
$conditional['rgid'] = $rgid;
if (!isset($original->webform['conditionals'][$rgid]) || $original->webform['conditionals'][$rgid] != $conditional) {
- webform_conditional_insert($conditional);
+ webform_conditional_insert($conditional);
}
}
}
@@ -1696,7 +1758,6 @@ function webform_node_prepare($node) {
}
}
-
/**
* Implements hook_node_load().
*/
@@ -1811,14 +1872,13 @@ function webform_node_load($nodes, $types) {
}
}
}
-
}
/**
-* Implements hook_user_role_delete().
-*
-* Removes references to deleted role from existing webforms.
-*/
+ * Implements hook_user_role_delete().
+ *
+ * Removes references to deleted role from existing webforms.
+ */
function webform_user_role_delete($role) {
db_delete('webform_roles')->condition('rid', $role->rid)->execute();
}
@@ -1934,7 +1994,8 @@ function webform_node_view($node, $view_mode) {
$allowed_roles = array();
}
else {
- $allowed_roles = _webform_allowed_roles($node, $enabled); // $enabled set by reference.
+ // $enabled set by reference.
+ $allowed_roles = _webform_allowed_roles($node, $enabled);
}
// Get a count of previous submissions by this user. Note that the
@@ -1948,13 +2009,16 @@ function webform_node_view($node, $view_mode) {
// Check if this page is cached or not.
$cached = drupal_page_is_cacheable();
- // Check if the user can add another submission based on the individual submission limit.
- if ($node->webform['submit_limit'] != -1) { // -1: Submissions are never throttled.
+ // Check if the user can add another submission based on the individual
+ // submission limit.
+ // -1: Submissions are never throttled.
+ if ($node->webform['submit_limit'] != -1) {
module_load_include('inc', 'webform', 'includes/webform.submissions');
- // Disable the form if the limit is exceeded and page cache is not active. This prevent
- // One anonymous user from generated a disabled webform page for the cache, which would
- // be shown to other anonymous users who have not exceeded the limit.
+ // Disable the form if the limit is exceeded and page cache is not active.
+ // This prevents one anonymous user from generated a disabled webform page
+ // for the cache, which would be shown to other anonymous users who have not
+ // exceeded the limit.
if (($user_limit_exceeded = webform_submission_user_limit_check($node)) && !$cached) {
$enabled = FALSE;
}
@@ -1962,12 +2026,13 @@ function webform_node_view($node, $view_mode) {
// Check if the user can add another submission if there is a limit on total
// submissions.
- if ($node->webform['total_submit_limit'] != -1) { // -1: Submissions are never throttled.
+ // -1: Submissions are never throttled.
+ if ($node->webform['total_submit_limit'] != -1) {
module_load_include('inc', 'webform', 'includes/webform.submissions');
- // Disable the form if the limit is exceeded. The cache is irrelevant for the total
- // submission limit; when it is exceeded for one user, it is exceeded for any other
- // user.
+ // Disable the form if the limit is exceeded. The cache is irrelevant for
+ // the total submission limit; when it is exceeded for one user, it is
+ // exceeded for any other user.
if (($total_limit_exceeded = webform_submission_total_limit_check($node))) {
$enabled = FALSE;
}
@@ -2005,7 +2070,17 @@ function webform_node_view($node, $view_mode) {
// Print out messages for the webform.
if (empty($node->in_preview) && !isset($node->webform_block) && !$logging_in) {
- theme('webform_view_messages', array('node' => $node, 'page' => $page, 'submission_count' => $submission_count, 'user_limit_exceeded' => $user_limit_exceeded, 'total_limit_exceeded' => $total_limit_exceeded, 'allowed_roles' => $allowed_roles, 'closed' => $closed, 'cached' => $cached));
+ theme('webform_view_messages', array(
+ 'node' => $node,
+ 'page' => $page,
+ 'submission_count' => $submission_count,
+ 'user_limit_exceeded' => $user_limit_exceeded,
+ 'total_limit_exceeded' => $total_limit_exceeded,
+ 'allowed_roles' => $allowed_roles,
+ 'closed' => $closed,
+ 'cached' => $cached,
+ )
+ );
}
// Add the output to the node.
@@ -2023,10 +2098,11 @@ function webform_node_view($node, $view_mode) {
/**
* Helper. Generates an array of allowed roles.
*
- * @param object $node
+ * @param stdClass $node
* The loaded node object containing a webform.
- * @param boolean $user_is_allowed
+ * @param bool $user_is_allowed
* Reference to boolean to be set to whether the current user is allowed.
+ *
* @return array
* Associative array of allowed roles indexed by the role id with a boolean
* value indicating if the current user has this role.
@@ -2057,14 +2133,16 @@ function _webform_allowed_roles($node, &$user_is_allowed) {
/**
* Output the Webform into the node content.
*
- * @param $node
+ * @param stdClass $node
* The webform node object.
- * @param $page
+ * @param stdClass $page
* If this webform node is being viewed as the main content of the page.
- * @param $form
+ * @param array $form
* The rendered form.
* @param $enabled
* If the form allowed to be completed by the current user.
+ *
+ * @return string
*/
function theme_webform_view($variables) {
// Only show the form if this user is allowed access.
@@ -2076,7 +2154,7 @@ function theme_webform_view($variables) {
/**
* Display a message to a user if they are not allowed to fill out a form.
*
- * @param $node
+ * @param stdClass $node
* The webform node object.
* @param $page
* If this webform node is being viewed as the main content of the page.
@@ -2110,8 +2188,7 @@ function theme_webform_view_messages($variables) {
$message = t('Submissions for this form are closed.');
}
elseif ($node->webform['confidential'] && user_is_logged_in()) {
- $message = t('This form is confidential. You must Log out to submit it.',
- array('!url' => url('/user/logout', array('query' => array('destination' => request_uri())))));
+ $message = t('This form is confidential. You must Log out to submit it.', array('!url' => url('/user/logout', array('query' => array('destination' => request_uri())))));
}
// If open and not allowed to submit the form, give an explanation.
elseif (array_search(TRUE, $allowed_roles) === FALSE && $user->uid != 1) {
@@ -2276,7 +2353,7 @@ function webform_block_view($delta = '') {
'#node' => $node,
'#sid' => $_SESSION['webform_confirmation'][$nid]['sid'],
);
- }
+ }
elseif (strlen(trim(strip_tags($node->webform['confirmation'])))) {
// Display confirmation link drupal status messages, but in the block.
$message = webform_replace_tokens($node->webform['confirmation'],
@@ -2287,14 +2364,13 @@ function webform_block_view($delta = '') {
$content = array(
'confirmation_message' => array(
'#markup' => "
\n" .
- '
' . t('Status message') . "
\n" .
- $message .
- "
\n",
+ '
' . t('Status message') . "
\n" .
+ $message .
+ "
\n",
'#weight' => -1,
),
'webform_view' => $content,
);
-
}
unset($_SESSION['webform_confirmation'][$nid]);
if (empty($_SESSION['webform_confirmation'])) {
@@ -2401,7 +2477,7 @@ function webform_block_save($delta = '', $edit = array()) {
* The current form array (always empty).
* @param $form_state
* The current form values of a submission, used in multipage webforms.
- * @param $node
+ * @param stdClass $node
* The current webform node.
* @param $submission
* An object containing information about the form submission if we're
@@ -2463,13 +2539,13 @@ function webform_client_form($form, &$form_state, $node, $submission = FALSE, $r
$form['#submit'] = array('webform_client_form_pages', 'webform_client_form_submit');
$form['#validate'] = array('webform_client_form_validate');
- // Add includes for used component types and pre/post validation handlers
+ // Add includes for used component types and pre/post validation handlers.
$form['#process'] = array('webform_client_form_process');
if (is_array($node->webform['components']) && !empty($node->webform['components'])) {
// Prepare a new form array.
$form['submitted'] = array(
- '#tree' => TRUE
+ '#tree' => TRUE,
);
$form['details'] = array(
'#tree' => TRUE,
@@ -2528,7 +2604,7 @@ function webform_client_form($form, &$form_state, $node, $submission = FALSE, $r
$sorter = webform_get_conditional_sorter($node);
$sorter->reportErrors();
- // Excecute the condtionals on the current input values
+ // Excecute the condtionals on the current input values.
$input_values = $sorter->executeConditionals($input_values);
// Allow values from other pages to be sent to browser for conditionals.
@@ -2544,12 +2620,12 @@ function webform_client_form($form, &$form_state, $node, $submission = FALSE, $r
// 1) previous/next non-empty page, or
// 2) the preview page, or
// 3) the preview page, forcing its display if the form would unexpectedly submit, or
- // 4) page 1 even if empty, if no other previous page would be shown
+ // 4) page 1 even if empty, if no other previous page would be shown.
$form_state['webform']['page_num'] = $submission->highest_valid_page;
do {
$form_state['webform']['page_num']++;
} while (!webform_get_conditional_sorter($node)->pageVisibility($form_state['webform']['page_num']));
- if (!$form_state['webform']['preview'] && $form_state['webform']['page_num'] == $form_state['webform']['page_count'] + (int)!$form_state['webform']['preview']) {
+ if (!$form_state['webform']['preview'] && $form_state['webform']['page_num'] == $form_state['webform']['page_count'] + (int) !$form_state['webform']['preview']) {
// Force a preview to avert an unintended submission via Next.
$form_state['webform']['preview'] = TRUE;
$form_state['webform']['page_count']++;
@@ -2575,7 +2651,7 @@ function webform_client_form($form, &$form_state, $node, $submission = FALSE, $r
'#page_num' => $page_num,
'#page_count' => count($page_labels),
'#page_labels' => $page_labels,
- '#weight' => -100
+ '#weight' => -100,
);
}
@@ -2631,11 +2707,11 @@ function webform_client_form($form, &$form_state, $node, $submission = FALSE, $r
'#value' => isset($submission->uid) ? $submission->uid : $user->uid,
);
$form['details']['page_num'] = array(
- '#type' => 'hidden',
+ '#type' => 'hidden',
'#value' => $page_num,
);
$form['details']['page_count'] = array(
- '#type' => 'hidden',
+ '#type' => 'hidden',
'#value' => $page_count,
);
$form['details']['finished'] = array(
@@ -2660,7 +2736,8 @@ function webform_client_form($form, &$form_state, $node, $submission = FALSE, $r
'#type' => 'submit',
'#value' => t('Save Draft'),
'#weight' => -2,
- '#validate' => array('webform_client_form_prevalidate'), // Prevalidation only; no element validation for Save Draft
+ // Prevalidation only; no element validation for Save Draft.
+ '#validate' => array('webform_client_form_prevalidate'),
'#attributes' => array(
'formnovalidate' => 'formnovalidate',
'class' => array('webform-draft'),
@@ -2726,20 +2803,19 @@ function webform_client_form_process($form, $form_state) {
// Add the post validation to end of validators. Do this first on the off
// chance that an _alter function has unset form['#validate'].
$form['#validate'][] = 'webform_client_form_postvalidate';
- // Add the pre-validator to the front of the list to run first
+ // Add the pre-validator to the front of the list to run first.
array_unshift($form['#validate'], 'webform_client_form_prevalidate');
return $form;
}
-
/**
* Add a component to a renderable array. Called recursively for fieldsets.
*
* This function assists in the building of the client form, as well as the
* display of results, and the text of e-mails.
*
- * @param $node
+ * @param stdClass $node
* The current webform node.
* @param $component
* The component to be added to the form.
@@ -2808,7 +2884,8 @@ function _webform_client_form_add_component($node, $component, $component_value,
// Show the component only on its form page, or if building an unfiltered
// version of the form (such as for Form Builder).
elseif ($component['page_num'] == $page_num || $filter == FALSE) {
- // Add this user-defined field to the form (with all the values that are always available).
+ // Add this user-defined field to the form (with all the values that are
+ // always available).
if ($element = webform_component_invoke($component['type'], 'render', $component, $component_value, $filter, $form['#submission'])) {
// Set access based on the private property.
$element += array('#access' => TRUE);
@@ -2832,7 +2909,8 @@ function _webform_client_form_add_component($node, $component, $component_value,
// Add custom CSS classes to the field and wrapper.
_webform_component_classes($element, $component);
- // Allow modules to modify a webform component that is going to be render in a form.
+ // Allow modules to modify a webform component that is going to be render
+ // in a form.
drupal_alter('webform_component_render', $element, $component);
// Add the element into the proper parent in the form.
@@ -2854,7 +2932,8 @@ function _webform_client_form_add_component($node, $component, $component_value,
$sorter = webform_get_conditional_sorter($node);
foreach ($component['children'] as $scid => $subcomponent) {
$subcomponent_value = isset($input_values[$scid]) ? $input_values[$scid] : NULL;
- // Include if always shown, or for forms, also if currently hidden but might be shown due to conditionals.
+ // Include if always shown, or for forms, also if currently hidden but
+ // might be shown due to conditionals.
$visibility = $sorter->componentVisibility($scid, $subcomponent['page_num']);
if ($visibility == WebformConditionals::componentShown || ($format == 'form' && $visibility) || !$filter) {
_webform_client_form_add_component($node, $subcomponent, $subcomponent_value, $parent_fieldset[$component['form_key']], $form, $input_values, $format, $page_num, $filter);
@@ -2880,7 +2959,8 @@ function webform_client_form_prevalidate($form, &$form_state) {
// Check if the user is allowed to submit based on role. This check is
// repeated here to ensure the user is still logged in at the time of
// submission, otherwise a stale form in another window may be allowed.
- $allowed_roles = _webform_allowed_roles($node, $allowed_role); // $allowed_role set by reference.
+ // $allowed_role set by reference.
+ $allowed_roles = _webform_allowed_roles($node, $allowed_role);
// Check that the submissions have not exceeded the total submission limit.
$total_limit_exceeded = FALSE;
@@ -2902,8 +2982,7 @@ function webform_client_form_prevalidate($form, &$form_state) {
// is no submission yet (hence isn't being edited) or the user isn't an admin.
// Another way to consider this is that the form is open when its status is
// open OR there is a submission and the user is an admin.
- $closed = empty($node->webform['status']) &&
- (empty($form['#submission']) || !user_access('edit all webform submissions'));
+ $closed = empty($node->webform['status']) && (empty($form['#submission']) || !user_access('edit all webform submissions'));
// Prevent submission by throwing an error.
if ((!$allowed_role || $total_limit_exceeded || $user_limit_exceeded || $closed)) {
@@ -2916,8 +2995,9 @@ function webform_client_form_prevalidate($form, &$form_state) {
* Form API #validate handler for the webform_client_form() form.
*/
function webform_client_form_validate($form, &$form_state) {
- if (($errors = form_get_errors()) && key_exists('', $errors)) {
- // Prevalidation failed. The form cannot be submitted. Do not attemp futher validation.
+ if (($errors = form_get_errors()) && array_key_exists('', $errors)) {
+ // Prevalidation failed. The form cannot be submitted. Do not attemp futher
+ // validation.
return;
}
if ($form_state['webform']['preview'] && $form_state['webform']['page_count'] === $form_state['webform']['page_num']) {
@@ -2943,7 +3023,6 @@ function webform_client_form_validate($form, &$form_state) {
$input_values = NULL;
}
-
// Run all #element_validate and #required checks. These are skipped initially
// by setting #validated = TRUE on all components when they are added.
_webform_client_form_validate($form, $form_state, 'webform_client_form', $input_values);
@@ -2982,8 +3061,10 @@ function _webform_client_form_validate(&$elements, &$form_state, $form_id = NULL
$component = $elements['#webform_component'];
$value = $input_values[$cid];
$value = is_array($value) ? $value[0] : $value;
- // webform_component_invoke cannot be called with reference arguments. Call directly.
- // webform_component_invoke($component['type'], 'action_set', $component, $elements, $form_state, $value);
+ // webform_component_invoke cannot be called with reference arguments.
+ // Call directly.
+ // webform_component_invoke($component['type'], 'action_set', $component,
+ // $elements, $form_state, $value);.
$function = '_webform_action_set_' . $component['type'];
$function($component, $elements, $form_state, $value);
}
@@ -2993,8 +3074,8 @@ function _webform_client_form_validate(&$elements, &$form_state, $form_id = NULL
if (isset($required)) {
$elements['#required'] = $required;
- // Some components, e.g. grids, have nested sub-elements. Extend required
- // to any sub-components.
+ // Some components, for example, grids, have nested sub-elements. Extend
+ // required to any sub-components.
foreach (element_children($elements) as $key) {
if (isset($elements[$key]) && $elements[$key] && !isset($elements[$key]['#webform_component'])) {
// Child is *not* a component.
@@ -3027,6 +3108,15 @@ function _webform_client_form_validate(&$elements, &$form_state, $form_id = NULL
form_error($elements, t('!name cannot be longer than %max characters but is currently %length characters long.', array('!name' => empty($elements['#title']) ? $elements['#parents'][0] : $elements['#title'], '%max' => $elements['#maxlength'], '%length' => drupal_strlen($elements['#value']))));
}
+ // Verify that the value is not shorter than #minlength. The value may
+ // still be empty (required is a separate validation option).
+ if (isset($elements['#minlength'])) {
+ $length = drupal_strlen($elements['#value']);
+ if ($length > 0 && $length < $elements['#minlength']) {
+ form_error($elements, t('!name cannot be shorter than %min characters but is currently %length characters long.', array('!name' => empty($elements['#title']) ? $elements['#parents'][0] : $elements['#title'], '%min' => $elements['#minlength'], '%length' => drupal_strlen($elements['#value']))));
+ }
+ }
+
if (isset($elements['#options']) && isset($elements['#value'])) {
if ($elements['#type'] == 'select') {
$options = form_options_flatten($elements['#options']);
@@ -3058,7 +3148,7 @@ function _webform_client_form_validate(&$elements, &$form_state, $form_id = NULL
// #value data.
elseif (isset($elements['#element_validate'])) {
foreach ($elements['#element_validate'] as $function) {
- if (is_callable($function)) {
+ if (is_callable($function)) {
$function($elements, $form_state, $form_state['complete form']);
}
}
@@ -3113,10 +3203,10 @@ function webform_client_form_postvalidate(&$form, &$form_state) {
$node->webform['auto_save'] &&
!$form_state['values']['details']['finished'] &&
!empty($form_state['values']['op'])) {
- // Validation errors are present, prevalidation succeeded (e.g. submission
- // limits are ok), auto-save is enabled, this form isn't finished (i.e. is
- // or soon will be a draft) and a button was pushed (not ajax).
-
+ // Validation errors are present, prevalidation succeeded (for example
+ // submission limits are ok), auto-save is enabled, this form isn't finished
+ // (this is, is or soon will be a draft) and a button was pushed (not ajax).
+ //
// Process submission on a copy of the form and form_state to prevent the
// submission handlers from making unintended changes. Use a button that
// isn't Save Draft, Next Page, Submit, etc to avoid triggering any
@@ -3208,8 +3298,8 @@ function webform_client_form_pages($form, &$form_state) {
// 1) previous/next non-empty page, or
// 2) the preview page, or
// 3) the preview page, forcing its display if the form would unexpectedly submit, or
- // 4) page 1 even if empty, if no other previous page would be shown
- $preview_page_num = $form_state['storage']['page_count'] + (int)!$form_state['webform']['preview'];
+ // 4) page 1 even if empty, if no other previous page would be shown.
+ $preview_page_num = $form_state['storage']['page_count'] + (int) !$form_state['webform']['preview'];
$page_num = $current_page;
do {
$page_num += $forward;
@@ -3228,8 +3318,7 @@ function webform_client_form_pages($form, &$form_state) {
}
// Inform the submit handlers that a draft will be saved.
- $form_state['save_draft'] = in_array($form_state['values']['op'], array($draft_op, '__AUTOSAVE__')) ||
- ($node->webform['auto_save'] && !$form_state['values']['details']['finished'] && !$form_state['webform_completed'] && user_is_logged_in());
+ $form_state['save_draft'] = in_array($form_state['values']['op'], array($draft_op, '__AUTOSAVE__')) || ($node->webform['auto_save'] && !$form_state['values']['details']['finished'] && !$form_state['webform_completed'] && user_is_logged_in());
// Determine what we need to do on the next page.
if (!empty($form_state['save_draft']) || !$form_state['webform_completed']) {
@@ -3271,9 +3360,9 @@ function webform_client_form_submit($form, &$form_state) {
// Merge with new submission data. The + operator maintains numeric keys.
// This maintains existing data with just-submitted data when a user resumes
- // a submission previously saved as a draft.
- // Remove any existing data on this and previous pages. If components are hidden, they may
- // be in the $submission->data but absent entirely from $new_data;
+ // a submission previously saved as a draft. Remove any existing data on
+ // this and previous pages. If components are hidden, they may be in the
+ // $submission->data but absent entirely from $new_data.
$page_map = webform_get_conditional_sorter($node)->getPageMap();
for ($page_nr = 1; $page_nr <= $form_state['webform']['page_num']; $page_nr++) {
$submission->data = array_diff_key($submission->data, $page_map[$page_nr]);
@@ -3292,9 +3381,9 @@ function webform_client_form_submit($form, &$form_state) {
$submission->is_draft = $is_draft;
$submission->highest_valid_page = 0;
if ($is_draft) {
- $submission->highest_valid_page = end($form_state['clicked_button']['#parents']) == 'next' && $form_state['values']['op'] != '__AUTOSAVE__'
- ? $form_state['webform']['page_num']
- : $form_state['webform']['page_num'] - 1;
+ $submission->highest_valid_page = end($form_state['clicked_button']['#parents']) == 'next' && $form_state['values']['op'] != '__AUTOSAVE__'
+ ? $form_state['webform']['page_num']
+ : $form_state['webform']['page_num'] - 1;
}
// If there is no data to be saved (such as on a multipage form with no fields
@@ -3409,7 +3498,7 @@ function webform_client_form_submit($form, &$form_state) {
/**
* Post processes the submission tree with any updates from components.
*
- * @param $node
+ * @param stdClass $node
* The full webform node.
* @param $form_values
* The form values for the form.
@@ -3481,11 +3570,10 @@ function template_preprocess_webform_form(&$vars) {
module_load_include('inc', 'webform', 'includes/webform.conditionals');
$submission_data = isset($vars['form']['#conditional_values']) ? $vars['form']['#conditional_values'] : array();
$settings = webform_conditional_prepare_javascript($vars['form']['#node'],
- $submission_data,
- $vars['form']['details']['page_num']['#value']);
+ $submission_data,
+ $vars['form']['details']['page_num']['#value']);
drupal_add_js(array('webform' => array('conditionals' => array('webform-client-form-' . $vars['nid'] => $settings))), 'setting');
}
-
}
/**
@@ -3654,6 +3742,12 @@ function theme_webform_element($variables) {
TRUE => !empty($element['#description']) ? '
' . $element['#description'] . "
\n" : '',
);
+ // If #children does not contain an element with a matching @id, do not
+ // include @for in the label.
+ if (strpos($element['#children'], ' id="' . $variables['element']['#id'] . '"') === FALSE) {
+ $variables['element']['#id'] = NULL;
+ }
+
switch ($element['#title_display']) {
case 'inline':
$output .= $description[$above];
@@ -3813,10 +3907,10 @@ function theme_webform_inline_radio_label($variables) {
$attributes['class'][] = 'element-invisible';
}
- $attributes['class'][] = 'webform-inline-radio';
- if (!empty($element['#id'])) {
- $attributes['for'] = $element['#id'];
- }
+ $attributes['class'][] = 'webform-inline-radio';
+ if (!empty($element['#id'])) {
+ $attributes['for'] = $element['#id'];
+ }
// The leading whitespace helps visually separate fields from inline labels.
return ' \n";
@@ -3825,7 +3919,7 @@ function theme_webform_inline_radio_label($variables) {
/**
* Theme the headers when sending an email from webform.
*
- * @param $node
+ * @param stdClass $node
* The complete node object for the webform.
* @param $submission
* The webform submission of the user.
@@ -3834,6 +3928,7 @@ function theme_webform_inline_radio_label($variables) {
* you can check the $email['email'] property to output different content.
* This will be the ID of the component that is a conditional e-mail
* recipient. For the normal e-mails, it will have the value of 'default'.
+ *
* @return
* An array of headers to be used when sending a webform email. If headers
* for "From", "To", or "Subject" are set, they will take precedence over
@@ -3854,7 +3949,7 @@ function _webform_fetch_draft_sid($nid, $uid) {
// should be returned.
if (isset($_POST['form_id']) && stripos($_POST['form_id'], 'webform_client_form_') === 0 &&
!empty($_POST['details']['sid']) && empty($_POST['details']['finished'])) {
- // A draft is already being edited
+ // A draft is already being edited.
$sid = $_POST['details']['sid'];
}
else {
@@ -3881,8 +3976,9 @@ function _webform_fetch_draft_sid($nid, $uid) {
/**
* Returns a new or cached WebformConditionals object for the specified node.
*
- * @param object $node
+ * @param stdClass $node
* The loaded webform node.
+ *
* @returns object
* Object of type WebformConditionals, possibly with the conditionals already
* analyzed for dependencies.
@@ -3901,12 +3997,12 @@ function _webform_filter_values($string, $node = NULL, $submission = NULL, $emai
return $strict ? webform_filter_xss($output) : $output;
}
-/*
+/**
* Replace tokens with Webform contexts populated.
*
* @param $string
* The string to have its tokens replaced.
- * @param $node
+ * @param stdClass $node
* If replacing node-level tokens, the node for which tokens will be created.
* @param $submission
* If replacing submission-level tokens, the submission for which tokens will
@@ -3957,14 +4053,18 @@ function webform_replace_tokens($string, $node = NULL, $submission = NULL, $emai
* to be called with the option 'clear' => FALSE, to not remove input filters.
* For security reasons webform_replace_tokens() is called before
* check_markup(), where input filters get replaced. Tokens won't be replaced if
- * there is no value provided. These tokens i.e. [current-page:query:*] needs to
- * be removed to not show up in the output.
+ * there is no value provided. These tokens, that is, [current-page:query:*]
+ * needs to be removed to not show up in the output.
*
* Note: This function was previously named webform_clear_tokens, which
* conflicted with the webform_clear module, being called as hook_tokens.
*
* @param string $text
* The text to have its tokens removed.
+ *
+ * @return mixed|string
+ * Replace tokens with actual value.
+ *
* @see token_replace()
*/
function webform_replace_tokens_clear($text) {
@@ -3993,11 +4093,12 @@ function webform_replace_tokens_clear($text) {
*
* @param string $redirect_url
* The redirect URL, with everything other than tokens already URL encoded.
- * @param $node
+ * @param stdClass $node
* If replacing node-level tokens, the node for which tokens will be created.
* @param $submission
* If replacing submission-level tokens, the submission for which tokens will
* be created.
+ *
* @return array
* An array of path and url() options, suitable for a redirect or drupal_goto.
*/
@@ -4061,8 +4162,9 @@ function _webform_filter_xss($string) {
/**
* Utility function to ensure that a webform record exists in the database.
*
- * @param $node
+ * @param stdClass $node
* The node object to check if a database entry exists.
+ *
* @return
* This function should always return TRUE if no errors were encountered,
* ensuring that a webform table row has been created. Will return FALSE if
@@ -4086,8 +4188,9 @@ function webform_ensure_record(&$node) {
* delete rows from the webform table if the node-type is exclusively used for
* webforms (per the "webform_node_types_primary" variable).
*
- * @param $node
+ * @param stdClass $node
* The node object to check if a database entry is still required.
+ *
* @return
* Returns TRUE if the webform still has a record in the database. Returns
* FALSE if the webform does not have a record or if the previously existing
@@ -4110,19 +4213,33 @@ function webform_check_record(&$node) {
}
/**
- * Given a form_key and a list of form_key parents, determine the cid.
+ * Given a component's form_key and optionally its parent's cid, get its cid(s).
*
- * @param $node
- * A fully loaded node object.
- * @param $form_key
- * The form key for which we're finding a cid.
- * @param $parent
+ * @param stdClass $node
+ * A fully loaded webform node object.
+ * @param string $form_key
+ * The form key for which to find the cid(s).
+ * @param int|null $pid
* The cid of the parent component.
+ *
+ * @return int|int[]
+ * The cid of the component or an array of component ids.
*/
-function webform_get_cid(&$node, $form_key, $pid) {
- foreach ($node->webform['components'] as $cid => $component) {
- if ($component['form_key'] == $form_key && $component['pid'] == $pid) {
- return $cid;
+function webform_get_cid(&$node, $form_key, $pid = NULL) {
+ if ($pid === NULL) {
+ $cids = array();
+ foreach ($node->webform['components'] as $cid => $component) {
+ if ((string) $component['form_key'] === (string) $form_key) {
+ $cids[] = $cid;
+ }
+ }
+ return $cids;
+ }
+ else {
+ foreach ($node->webform['components'] as $cid => $component) {
+ if ((string) $component['form_key'] === (string) $form_key && $component['pid'] == $pid) {
+ return $cid;
+ }
}
}
}
@@ -4130,10 +4247,11 @@ function webform_get_cid(&$node, $form_key, $pid) {
/**
* Find the label of a given page based on page breaks.
*
- * @param $node
+ * @param stdClass $node
* The webform node.
* @param $form_state
* The form's state, if available
+ *
* @return array
* An array of all page labels, indexed by page number.
*/
@@ -4164,90 +4282,118 @@ function webform_variable_get($variable) {
case 'webform_blocks':
$result = variable_get('webform_blocks', array());
break;
+
case 'webform_tracking_mode':
$result = variable_get('webform_tracking_mode', 'cookie');
break;
+
case 'webform_allowed_tags':
$result = variable_get('webform_allowed_tags', array('a', 'em', 'strong', 'code', 'img'));
break;
+
case 'webform_email_address_format':
$result = variable_get('webform_email_address_format', 'long');
break;
+
case 'webform_email_address_individual':
$result = variable_get('webform_email_address_individual', 0);
break;
+
case 'webform_default_from_name':
$result = variable_get('webform_default_from_name', variable_get('site_name', ''));
break;
+
case 'webform_default_from_address':
$result = variable_get('webform_default_from_address', variable_get('site_mail', ini_get('sendmail_from')));
break;
+
case 'webform_default_subject':
$result = variable_get('webform_default_subject', t('Form submission from: [node:title]'));
break;
+
case 'webform_email_replyto':
$result = variable_get('webform_email_replyto', TRUE);
break;
+
case 'webform_email_html_capable':
$result = variable_get('webform_email_html_capable', FALSE);
break;
+
case 'webform_default_format':
$result = variable_get('webform_default_format', 0);
break;
+
case 'webform_format_override':
$result = variable_get('webform_format_override', 0);
break;
+
case 'webform_email_select_max':
$result = variable_get('webform_email_select_max', 50);
break;
+
case 'webform_node_types':
$result = webform_node_types();
break;
+
case 'webform_node_types_primary':
$result = variable_get('webform_node_types_primary', array('webform'));
break;
+
case 'webform_date_type':
$result = variable_get('webform_date_type', 'medium');
break;
+
case 'webform_export_format':
module_load_include('inc', 'webform', 'includes/webform.export');
$options = webform_export_list();
$result = variable_get('webform_export_format', 'excel');
$result = isset($options[$result]) ? $result : key($options);
break;
+
case 'webform_csv_delimiter':
$result = variable_get('webform_csv_delimiter', '\t');
break;
+
case 'webform_csv_line_ending':
$result = variable_get('webform_csv_line_ending', "\n");
break;
+
case 'webform_export_wordwrap':
$result = variable_get('webform_export_wordwrap', 0);
break;
+
case 'webform_excel_legacy_exporter':
$result = variable_get('webform_excel_legacy_exporter', 0);
break;
+
case 'webform_progressbar_style':
$result = variable_get('webform_progressbar_style', array('progressbar_bar', 'progressbar_pagebreak_labels', 'progressbar_include_confirmation'));
break;
+
case 'webform_progressbar_label_first':
$result = variable_get('webform_progressbar_label_first', t('Start'));
break;
+
case 'webform_progressbar_label_confirmation':
$result = variable_get('webform_progressbar_label_confirmation', t('Complete'));
break;
+
case 'webform_table':
$result = variable_get('webform_table', FALSE);
break;
+
case 'webform_submission_access_control':
$result = variable_get('webform_submission_access_control', 1);
break;
+
case 'webform_token_access':
$result = variable_get('webform_token_access', 1);
break;
+
case 'webform_update_batch_size':
$result = variable_get('webform_update_batch_size', 100);
break;
+
case 'webform_disabled_components':
$result = variable_get('webform_disabled_components', array());
break;
@@ -4340,7 +4486,7 @@ function _webform_transliterate($name) {
* @param $name
* The name to be used in the formatted address. If the address contains a
* name in 'Some Name ' format, $name is ignored.
- * @param $node
+ * @param stdClass $node
* The webform node if replacements will be done.
* @param $submission
* The webform submission values if replacements will be done.
@@ -4355,6 +4501,7 @@ function _webform_transliterate($name) {
* "long", or NULL for the system default.
* @param $mapping
* A mapping array to be applied to the address values.
+ *
* @return string|array
* The formatted e-mail address -- or addresses (if not $single)
*/
@@ -4377,7 +4524,8 @@ function webform_format_email_address($address, $name, $node = NULL, $submission
foreach ($name as &$one_name) {
$one_name = isset($options[$one_name]) ? $options[$one_name] : $one_name;
}
- unset($one_name); // Drop PHP reference.
+ // Drop PHP reference.
+ unset($one_name);
}
}
else {
@@ -4431,7 +4579,6 @@ function webform_format_email_address($address, $name, $node = NULL, $submission
}
return $single ? reset($address) : $address;
-
}
/**
@@ -4443,16 +4590,17 @@ function webform_format_email_address($address, $name, $node = NULL, $submission
* with a comma and space.
* @param string $form_name
* The name of the form element to receive an error, in form_set_error format.
- * @param boolean $allow_empty
+ * @param bool $allow_empty
* TRUE if optional. FALSE if required.
- * @param boolean $allow_multiple
+ * @param bool $allow_multiple
* TRUE if a list of emails is allowed. FALSE if only one.
- * @param boolean $allow_tokens
+ * @param bool $allow_tokens
* TRUE if any token should be assumed to contain a valid e-mail address.
* @param string $format
* 'short', 'long', or NULL (for default) format. Long format has a name and
* the address in angle brackets.
- * @return integer|boolean
+ *
+ * @return int|bool
* The number of valid addresses found, or FALSE for an invalid email found.
*/
function webform_email_validate(&$emails, $form_name, $allow_empty, $allow_multiple, $allow_tokens, $format = NULL) {
@@ -4476,12 +4624,13 @@ function webform_email_validate(&$emails, $form_name, $allow_empty, $allow_multi
* An email address, a list of comma-separated email addresses. If all the
* addresses are valid, the list of trimmed, non-empty emails is returned by
* reference.
- * @param boolean $allow_tokens
+ * @param bool $allow_tokens
* TRUE if any token should be assumed to contain a valid e-mail address.
* @param string $format
* 'short', 'long', or NULL (for default) format. Long format has a name and
* the address in angle brackets.
- * @return boolean|integer
+ *
+ * @return bool|int
* Returns FALSE if an invalid e-mail address was found, 0 if no email
* address(es) were found, or the number of valid e-mail addresses found.
*/
@@ -4514,6 +4663,7 @@ function webform_valid_email_address(&$emails, $allow_tokens = FALSE, $format =
* @param string $format
* 'short', 'long', or NULL (for default) format. Long format has a name and
* the address in angle brackets.
+ *
* @return array
* Associative array indexed by 'name' and 'address'.
*/
@@ -4522,14 +4672,7 @@ function webform_parse_email_address($email, $format = NULL) {
$format = webform_variable_get('webform_email_address_format');
}
if ($format == 'long') {
- // Match e-mails of the form 'My Name ' as follows:
- // ^ = beginning of string
- // "? = optional quote
- // ([^<]*?) = match optional characters that aren't a < (non-greedy)
- // "? = optional quote
- // SPACE* = optional spaces
- // (?:<(.*)>) = < matching stuff > (without the angle brakets)
- // $ = end of string
+ // Match e-mails of the form 'My Name '.
preg_match('/^"?([^<]*?)"? *(?:<(.*)>)?$/', $email, $matches);
if (isset($matches[2]) && strlen($matches[2])) {
return array(
@@ -4582,7 +4725,7 @@ function webform_format_email_subject($subject, $node = NULL, $submission = NULL
}
/**
- * Convert an array of components into a tree
+ * Convert an array of components into a tree.
*/
function _webform_components_tree_build($src, &$tree, $parent, &$page_count) {
foreach ($src as $cid => $component) {
@@ -4631,7 +4774,7 @@ function _webform_components_sort($a, $b) {
}
/**
- * Sort each level of a component tree by weight and name
+ * Sort each level of a component tree by weight and name.
*/
function _webform_components_tree_sort($tree) {
if (isset($tree['children']) && is_array($tree['children'])) {
@@ -4663,7 +4806,7 @@ function webform_components($include_disabled = FALSE, $reset = FALSE) {
$components += $module_components;
}
drupal_alter('webform_component_info', $components);
- uasort($components, function($a, $b) {
+ uasort($components, function ($a, $b) {
return strnatcasecmp($a['label'], $b['label']);
});
$enabled = array_diff_key($components, $disabled);
@@ -4716,6 +4859,9 @@ function webform_component_include($component_type) {
* The callback to execute.
* @param ...
* Any additional parameters required by the $callback.
+ *
+ * @return mixed
+ * Return value of the callback on success and FALSE on failure.
*/
function webform_component_invoke($type, $callback) {
$args = func_get_args();
@@ -4735,6 +4881,8 @@ function webform_component_invoke($type, $callback) {
* The component type as a string.
* @param $callback
* The callback to check.
+ *
+ * @return bool
*/
function webform_component_implements($type, $callback) {
$function = '_webform_' . $callback . '_' . $type;
@@ -4756,11 +4904,11 @@ function webform_conditional_expand($element) {
function _webform_component_classes(&$element, $component) {
if (isset($component['extra']['css_classes']) && drupal_strlen($component['extra']['css_classes'])) {
$element['#attributes']['class'] = isset($element['#attributes']['class']) ? $element['#attributes']['class'] : array();
- $element['#attributes']['class'] = array_merge($element['#attributes']['class'], explode(' ' , $component['extra']['css_classes']));
+ $element['#attributes']['class'] = array_merge($element['#attributes']['class'], explode(' ', $component['extra']['css_classes']));
}
if (isset($component['extra']['wrapper_classes']) && drupal_strlen($component['extra']['wrapper_classes'])) {
$element['#wrapper_attributes']['class'] = isset($element['#wrapper_attributes']['class']) ? $element['#wrapper_attributes']['class'] : array();
- $element['#wrapper_attributes']['class'] = array_merge($element['#wrapper_attributes']['class'], explode(' ' , $component['extra']['wrapper_classes']));
+ $element['#wrapper_attributes']['class'] = array_merge($element['#wrapper_attributes']['class'], explode(' ', $component['extra']['wrapper_classes']));
}
}
@@ -4774,13 +4922,13 @@ function webform_disable_page_cache() {
/**
* Set the necessary breadcrumb for the page we are on.
*
- * @param object $node
+ * @param stdClass $node
* The loaded webform node.
- * @param boolean|object $submission
+ * @param bool|object $submission
* The submission if the current page is viewing or dealing with a submission,
* or TRUE to just include the webform node in the breadcrumbs (used for
* the submission completion confirmation page), or NULL for no extra
- * processing
+ * processing.
*/
function webform_set_breadcrumb($node, $submission = NULL) {
$node_path = "node/{$node->nid}";
@@ -4807,7 +4955,7 @@ function webform_set_breadcrumb($node, $submission = NULL) {
// Setting the current menu href will cause the submission title and current
// tab (if not the default tab) to be added to the active path when the
// webform is in the default location in the menu (node/NID). The title
- // is desirable, but the tab name (e.g. Edit or Delete) isn't.
+ // is desirable, but the tab name (for example Edit or Delete) isn't.
if (preg_match('/href=".*"/', end($breadcrumb), $matches)) {
foreach ($breadcrumb as $index => $link) {
if (stripos($link, $matches[0]) !== FALSE) {
@@ -4815,7 +4963,7 @@ function webform_set_breadcrumb($node, $submission = NULL) {
break;
}
}
- }
+ }
// If the user is dealing with a submission, then the breadcrumb should
// be fudged to allow them to return to a likely list of webforms.
@@ -4858,6 +5006,9 @@ function webform_set_breadcrumb($node, $submission = NULL) {
* - hour (in 24hr notation)
* - minute
* - second
+ *
+ * @return array
+ * Date in array formate.
*/
function webform_date_array($string, $type = NULL) {
$pattern = '/((\d{4}?)-(\d{2}?)-(\d{2}?))?(T?(\d{2}?):(\d{2}?):(\d{2}?))?/';
@@ -4892,6 +5043,9 @@ function webform_date_array($string, $type = NULL) {
* @param $type
* If wanting a specific string format back specify either "date" or "time".
* Otherwise a full ISO 8601 date and time string will be returned.
+ *
+ * @return string
+ * Date in string format
*/
function webform_date_string($array, $type = NULL) {
$string = '';
@@ -4909,11 +5063,11 @@ function webform_date_string($array, $type = NULL) {
}
if ($type == 'time' || !isset($type)) {
- $string .= empty($array['hour']) ? '00' : sprintf('%02d', $array['hour']);
+ $string .= empty($array['hour']) ? '00' : sprintf('%02d', $array['hour']);
$string .= ':';
- $string .= empty($array['minute']) ? '00' : sprintf('%02d', $array['minute']);
+ $string .= empty($array['minute']) ? '00' : sprintf('%02d', $array['minute']);
$string .= ':';
- $string .= empty($array['second']) ? '00' : sprintf('%02d', $array['second']);
+ $string .= empty($array['second']) ? '00' : sprintf('%02d', $array['second']);
}
return $string;
@@ -4929,6 +5083,7 @@ function webform_date_string($array, $type = NULL) {
* @param array $exclude
* An array containing 'day', 'month', and/or 'year' if they should be
* removed from the format.
+ *
* @return string
* A date/time format string.
*/
@@ -4953,7 +5108,7 @@ function webform_date_format($type = NULL, $exclude = array()) {
// --------------------------------------------------------------------------
// Time aABgGhHisueIOPTZ
// Special /.,-:
-
+ //
// Strip Time and Special characters from the beginning and end of format.
$date_format = trim($format, 'aABgGhHisueIOPTZ/.,-: ');
@@ -5013,11 +5168,10 @@ function webform_strtodate($format, $string, $timezone_name = NULL, $reference_t
// 3) Set the time to midnight because when a non-referenced relative
// date is created without a time, it is created at midnight (0:00).
// 4) Adjust to the specified relative (or absolute) time.
-
@$datetime = new DateTime('@' . $reference_timestamp);
@$datetime->setTimezone($timezone)
- ->setTime(0, 0, 0)
- ->modify($string);
+ ->setTime(0, 0, 0)
+ ->modify($string);
}
else {
@$datetime = new DateTime($string, $timezone);
@@ -5084,7 +5238,7 @@ function webform_views_default_views() {
$path = './' . drupal_get_path('module', 'webform') . '/views/default_views/*.inc';
$views = array();
foreach (glob($path) as $views_filename) {
- require_once($views_filename);
+ require_once $views_filename;
}
return $views;
}
@@ -5248,7 +5402,7 @@ function _webform_submission_serial_next_value($nid) {
* @param int $nid
* The Node ID of the Webform.
*
- * $return int
+ * @return int
* The largest serial number used by a submission plus 1 for the specified
* node or 1 when there are no submissions.
*/
@@ -5266,7 +5420,7 @@ function _webform_submission_serial_next_value_used($nid) {
/**
* Alter the node before saving a clone.
*
- * @param $node
+ * @param stdClass $node
* Reference to the fully loaded node object being saved (the clone) that
* can be altered as needed.
* @param array $context
@@ -5310,16 +5464,16 @@ function webform_input_vars_check(&$form, $form_state, $detect_key, $parent_key
// is that the POST was truncated because PHP exceeded its max_input_vars limit.
$subs = array(
'@count' => webform_count_terminals($_POST),
- '@limit' => (int)ini_get('max_input_vars'),
+ '@limit' => (int) ini_get('max_input_vars'),
);
drupal_set_message(user_access('administer site configuration')
? t('This form could not be submitted because $_POST was truncated to @count input vars. PHP max_input_vars is @limit and needs to be increased.', $subs)
: t('This form could not be submitted because it exceeds the server configuration. Contact the administrator.'),
'error');
watchdog('webform',
- 'POST truncated to @count input vars. PHP max_input_vars is @limit. Increase max_input_vars.',
- $subs,
- WATCHDOG_ERROR);
+ 'POST truncated to @count input vars. PHP max_input_vars is @limit. Increase max_input_vars.',
+ $subs,
+ WATCHDOG_ERROR);
}
}
@@ -5334,7 +5488,8 @@ function webform_pre_render_input_vars($element) {
$limit = ini_get('max_input_vars');
if ($limit) {
// Estimate the number of input vars needed to see if the PHP limit has been exceeded.
- $count = 1 + webform_count_input_vars($element); // Additional input_vars: op
+ // Additional input_vars: op.
+ $count = 1 + webform_count_input_vars($element);
if ($count > $limit * 0.95) {
$subs = array(
'@count' => $count,
@@ -5342,10 +5497,10 @@ function webform_pre_render_input_vars($element) {
);
$warning = array(
'#markup' => '
' .
- (user_access('administer site configuration')
- ? t('This form contains @count input elements. PHP max_input_vars is @limit and should be increased.', $subs)
- : t('This form may be too long to work properly. Contact the administrator.'))
- . '
',
+ (user_access('administer site configuration')
+ ? t('This form contains @count input elements. PHP max_input_vars is @limit and should be increased.', $subs)
+ : t('This form may be too long to work properly. Contact the administrator.'))
+ . '
',
'#weight' => -1,
);
if ($element['#input_var_waring_parent']) {
@@ -5355,9 +5510,9 @@ function webform_pre_render_input_vars($element) {
$element['input_vars_warning'] = $warning;
}
watchdog('webform',
- 'Page contains @count input elements but PHP max_input_vars is only @limit. Increase max_input_vars.',
- $subs,
- WATCHDOG_ERROR);
+ 'Page contains @count input elements but PHP max_input_vars is only @limit. Increase max_input_vars.',
+ $subs,
+ WATCHDOG_ERROR);
}
}
return $element;
@@ -5378,7 +5533,8 @@ function webform_pre_render_input_vars($element) {
*
* @param array $element
* The form whose elements should be counted.
- * @return integer
+ *
+ * @return int
* The number of elements in the form that will result in $_POST entries.
*/
function webform_count_input_vars($element) {
@@ -5412,7 +5568,8 @@ function webform_count_input_vars($element) {
*
* @param $a
* Array or array element to be counted
- * @return integer
+ *
+ * @return int
* Number of non-array elements within $a.
*/
function webform_count_terminals($a) {
diff --git a/sites/all/modules/contrib/webform/webform.tokens.inc b/sites/all/modules/contrib/webform/webform.tokens.inc
index 9104ce83e..3c39fbfab 100644
--- a/sites/all/modules/contrib/webform/webform.tokens.inc
+++ b/sites/all/modules/contrib/webform/webform.tokens.inc
@@ -109,7 +109,7 @@ function webform_tokens($type, $tokens, array $data = array(), array $options =
// from the rendered submission if recursion has been detected.
if ($recursion_level) {
$markup_components = array_keys(array_filter($node->webform['components'],
- function ($component) { return $component['type'] == 'markup'; }));
+ function ($component) { return $component['type'] == 'markup'; }));
}
$recursion_level++;
diff --git a/sites/all/modules/contrib/wysiwyg/editors/ckeditor.inc b/sites/all/modules/contrib/wysiwyg/editors/ckeditor.inc
index b2c20f3ea..0a1ff6824 100644
--- a/sites/all/modules/contrib/wysiwyg/editors/ckeditor.inc
+++ b/sites/all/modules/contrib/wysiwyg/editors/ckeditor.inc
@@ -32,7 +32,7 @@ function wysiwyg_ckeditor_editor() {
),
),
'install note callback' => 'wysiwyg_ckeditor_install_note',
- 'verified version range' => array('3.0', '4.6.1.580bcaf'),
+ 'verified version range' => array('3.0', '4.6.2.20af917'),
'migrate settings callback' => 'wysiwyg_ckeditor_migrate_settings',
'version callback' => 'wysiwyg_ckeditor_version',
'themes callback' => 'wysiwyg_ckeditor_themes',
diff --git a/sites/all/modules/contrib/wysiwyg/editors/css/wymeditor.css b/sites/all/modules/contrib/wysiwyg/editors/css/wymeditor.css
new file mode 100644
index 000000000..ea86604b6
--- /dev/null
+++ b/sites/all/modules/contrib/wysiwyg/editors/css/wymeditor.css
@@ -0,0 +1,6 @@
+.wym_skin_compact .wym_dropdown ul {
+ margin-top: 0;
+}
+.wym_skin_compact .wym_iframe iframe {
+ height: 400px !important;
+}
diff --git a/sites/all/modules/contrib/wysiwyg/editors/js/ckeditor-3.0.js b/sites/all/modules/contrib/wysiwyg/editors/js/ckeditor-3.0.js
index d8c7185ac..70eebe462 100644
--- a/sites/all/modules/contrib/wysiwyg/editors/js/ckeditor-3.0.js
+++ b/sites/all/modules/contrib/wysiwyg/editors/js/ckeditor-3.0.js
@@ -12,7 +12,7 @@ var instanceMap;
* Initialize the editor library.
*
* This method is called once the first time a library is needed. If new
- * WYSIWYG fieldsare added later, update() will be called instead.
+ * WYSIWYG fields are added later, update() will be called instead.
*
* @param settings
* An object containing editor settings for each input format.
@@ -202,7 +202,7 @@ Drupal.wysiwyg.editor.detach.ckeditor = function (context, params, trigger) {
Drupal.wysiwyg.editor.instance.ckeditor = {
addPlugin: function (pluginName, pluginSettings) {
CKEDITOR.plugins.add(pluginName, {
- // Wrap Drupal plugin in a proxy pluygin.
+ // Wrap Drupal plugin in a proxy plugin.
init: function(editor) {
if (pluginSettings.css) {
editor.on('mode', function(ev) {
@@ -224,7 +224,18 @@ Drupal.wysiwyg.editor.instance.ckeditor = {
data.node = data.node.$;
}
if (selection.getType() == CKEDITOR.SELECTION_TEXT) {
- data.content = selection.getSelectedText();
+ if (selection.getSelectedText) {
+ data.content = selection.getSelectedText();
+ }
+ else {
+ // Pre v3.6.1.
+ if (CKEDITOR.env.ie) {
+ data.content = selection.getNative().createRange().text;
+ }
+ else {
+ data.content = selection.getNative().toString();
+ }
+ }
}
else if (data.node) {
// content is supposed to contain the "outerHTML".
@@ -253,7 +264,7 @@ Drupal.wysiwyg.editor.instance.ckeditor = {
insert: function(content) {
content = this.prepareContent(content);
- if (CKEDITOR.env.webkit || CKEDITOR.env.chrome || CKEDITOR.env.opera || CKEDITOR.env.safari) {
+ if (CKEDITOR.version.split('.')[0] === '3' && (CKEDITOR.env.webkit || CKEDITOR.env.chrome || CKEDITOR.env.opera || CKEDITOR.env.safari)) {
// Works around a WebKit bug which removes wrapper elements.
// @see https://drupal.org/node/1927968
var tmp = new CKEDITOR.dom.element('div'), children, skip = 0, item;
diff --git a/sites/all/modules/contrib/wysiwyg/editors/js/epiceditor.js b/sites/all/modules/contrib/wysiwyg/editors/js/epiceditor.js
index 0d983ff2e..f6e2db07a 100644
--- a/sites/all/modules/contrib/wysiwyg/editors/js/epiceditor.js
+++ b/sites/all/modules/contrib/wysiwyg/editors/js/epiceditor.js
@@ -27,7 +27,7 @@ Drupal.wysiwyg.editor.attach.epiceditor = function (context, params, settings) {
};
/**
- * Detach a single edtor instance.
+ * Detach a single editor instance.
*/
Drupal.wysiwyg.editor.detach.epiceditor = function (context, params, trigger) {
var $target = $('#' + params.field, context);
diff --git a/sites/all/modules/contrib/wysiwyg/editors/js/tinymce-3.js b/sites/all/modules/contrib/wysiwyg/editors/js/tinymce-3.js
index 929b3f878..40a5632e0 100644
--- a/sites/all/modules/contrib/wysiwyg/editors/js/tinymce-3.js
+++ b/sites/all/modules/contrib/wysiwyg/editors/js/tinymce-3.js
@@ -50,7 +50,7 @@ Drupal.wysiwyg.editor.update.tinymce = function(settings, pluginInfo) {
/**
* Attach this editor to a target element.
*
- * See Drupal.wysiwyg.editor.attach.none() for a full desciption of this hook.
+ * See Drupal.wysiwyg.editor.attach.none() for a full description of this hook.
*/
Drupal.wysiwyg.editor.attach.tinymce = function(context, params, settings) {
// Configure editor settings for this input format.
@@ -96,7 +96,7 @@ Drupal.wysiwyg.editor.attach.tinymce = function(context, params, settings) {
/**
* Detach a single editor instance.
*
- * See Drupal.wysiwyg.editor.detach.none() for a full desciption of this hook.
+ * See Drupal.wysiwyg.editor.detach.none() for a full description of this hook.
*/
Drupal.wysiwyg.editor.detach.tinymce = function (context, params, trigger) {
var instance = tinyMCE.get(params.field);
diff --git a/sites/all/modules/contrib/wysiwyg/editors/js/tinymce-4.js b/sites/all/modules/contrib/wysiwyg/editors/js/tinymce-4.js
index 448e1b942..ff6980ac3 100644
--- a/sites/all/modules/contrib/wysiwyg/editors/js/tinymce-4.js
+++ b/sites/all/modules/contrib/wysiwyg/editors/js/tinymce-4.js
@@ -47,7 +47,7 @@ Drupal.wysiwyg.editor.update.tinymce = function (settings, pluginInfo) {
/**
* Attach this editor to a target element.
*
- * See Drupal.wysiwyg.editor.attach.none() for a full desciption of this hook.
+ * See Drupal.wysiwyg.editor.attach.none() for a full description of this hook.
*/
Drupal.wysiwyg.editor.attach.tinymce = function (context, params, settings) {
// Remove TinyMCE's internal mceItem class, which was incorrectly added to
@@ -77,7 +77,7 @@ Drupal.wysiwyg.editor.attach.tinymce = function (context, params, settings) {
/**
* Detach a single or all editors.
*
- * See Drupal.wysiwyg.editor.detach.none() for a full desciption of this hook.
+ * See Drupal.wysiwyg.editor.detach.none() for a full description of this hook.
*/
Drupal.wysiwyg.editor.detach.tinymce = function (context, params, trigger) {
var instance;
diff --git a/sites/all/modules/contrib/wysiwyg/editors/js/wymeditor-1.js b/sites/all/modules/contrib/wysiwyg/editors/js/wymeditor-1.js
new file mode 100644
index 000000000..369e41564
--- /dev/null
+++ b/sites/all/modules/contrib/wysiwyg/editors/js/wymeditor-1.js
@@ -0,0 +1,63 @@
+(function($) {
+
+/**
+ * Attach this editor to a target element.
+ */
+Drupal.wysiwyg.editor.attach.wymeditor = function (context, params, settings) {
+ // Prepend basePath to wymPath.
+ settings.wymPath = settings.basePath + settings.wymPath;
+ settings.postInit = function (instance) {
+ var $doc = $(instance._doc);
+ // Inject stylesheet for backwards compatibility.
+ if (settings.stylesheet) {
+ $doc.find('head').append('');
+ }
+ // Update activeId on focus.
+ $doc.find('body').focus(function () {
+ Drupal.wysiwyg.activeId = params.field;
+ });
+ };
+ // Attach editor.
+ $('#' + params.field).wymeditor(settings);
+};
+
+/**
+ * Detach a single editor instance.
+ */
+Drupal.wysiwyg.editor.detach.wymeditor = function (context, params, trigger) {
+ var $field = $('#' + params.field, context);
+ var index = $field.data(WYMeditor.WYM_INDEX);
+ if (typeof index == 'undefined' || !WYMeditor.INSTANCES[index]) {
+ return;
+ }
+ var instance = WYMeditor.INSTANCES[index];
+ instance.update();
+ if (trigger != 'serialize') {
+ instance.vanish();
+ }
+};
+
+Drupal.wysiwyg.editor.instance.wymeditor = {
+ insert: function (content) {
+ this.getInstance().insert(content);
+ },
+
+ setContent: function (content) {
+ this.getInstance().html(content);
+ },
+
+ getContent: function () {
+ return this.getInstance().html();
+ },
+
+ getInstance: function () {
+ var $field = $('#' + this.field);
+ var index = $field.data(WYMeditor.WYM_INDEX);
+ if (typeof index != 'undefined') {
+ return WYMeditor.INSTANCES[index];
+ }
+ return null;
+ }
+};
+
+})(jQuery);
diff --git a/sites/all/modules/contrib/wysiwyg/editors/js/wymeditor.js b/sites/all/modules/contrib/wysiwyg/editors/js/wymeditor.js
index db4f570e6..6c195dddc 100644
--- a/sites/all/modules/contrib/wysiwyg/editors/js/wymeditor.js
+++ b/sites/all/modules/contrib/wysiwyg/editors/js/wymeditor.js
@@ -8,7 +8,7 @@ Drupal.wysiwyg.editor.attach.wymeditor = function (context, params, settings) {
settings.wymPath = settings.basePath + settings.wymPath;
// Update activeId on focus.
settings.postInit = function (instance) {
- $(instance._doc).focus(function () {
+ $(instance._doc).find('body').focus(function () {
Drupal.wysiwyg.activeId = params.field;
});
};
@@ -26,11 +26,17 @@ Drupal.wysiwyg.editor.detach.wymeditor = function (context, params, trigger) {
return;
}
var instance = WYMeditor.INSTANCES[index];
+ var i;
instance.update();
if (trigger != 'serialize') {
$(instance._box).remove();
$(instance._element).show();
- delete WYMeditor.INSTANCES[index];
+ $field.removeData(WYMeditor.WYM_INDEX);
+ WYMeditor.INSTANCES.splice(index, 1);
+ // Reindex the editors to maintain internal state..
+ for (i = 0; i < WYMeditor.INSTANCES.length; i++) {
+ WYMeditor.INSTANCES[i]._index = i;
+ }
$field.show();
}
};
diff --git a/sites/all/modules/contrib/wysiwyg/editors/tinymce.inc b/sites/all/modules/contrib/wysiwyg/editors/tinymce.inc
index 56b8aff34..2fbec94ec 100644
--- a/sites/all/modules/contrib/wysiwyg/editors/tinymce.inc
+++ b/sites/all/modules/contrib/wysiwyg/editors/tinymce.inc
@@ -27,7 +27,7 @@ function wysiwyg_tinymce_editor() {
),
),
'version callback' => 'wysiwyg_tinymce_version',
- 'verified version range' => array('3.3.9.2', '4.5.1'),
+ 'verified version range' => array('3.3.9.2', '4.5.7'),
'themes callback' => 'wysiwyg_tinymce_themes',
'settings form callback' => 'wysiwyg_tinymce_settings_form',
'init callback' => 'wysiwyg_tinymce_init',
@@ -887,7 +887,7 @@ function wysiwyg_tinymce_settings($editor, $config, $theme) {
$settings['toolbar'][] = $settings['buttons'][$i];
}
}
- // TinyMCE 3 allowed the callback to be the name of a funciton. Convert it
+ // TinyMCE 3 allowed the callback to be the name of a function. Convert it
// to a reference to keep compatibility with IMCE Wysiwyg bridge module.
// Both isset() and is_string() needed, generates a notice if undefined.
if (isset($settings['file_browser_callback']) && is_string($settings['file_browser_callback'])) {
@@ -995,11 +995,29 @@ function _wysiwyg_tinymce_migrate_settings(&$settings, $editor, $profile_version
$settings['buttons'] = $fixed_buttons;
$migrated_version = '4.0.0';
}
+ if (version_compare($profile_version, '4.5.0', '<') && version_compare($installed_version, '4.5.0', '>=')) {
+ // The list buttons now require the lists plugin.
+ if (!empty($settings['buttons']['default']['bullist'])) {
+ $settings['buttons']['lists']['bullist'] = 1;
+ }
+ if (!empty($settings['buttons']['default']['numlist'])) {
+ $settings['buttons']['lists']['numlist'] = 1;
+ }
+ unset($settings['buttons']['default']['bullist'], $settings['buttons']['default']['numlist']);
+ $migrated_version = '4.5.0';
+ }
}
else {
// Downgrading, starting at the profile version going down.
if (version_compare($profile_version, '4.5.0', '>=') && version_compare($installed_version, '4.5.0', '<')) {
unset($settings['buttons']['toc']);
+ if (!empty($settings['buttons']['lists']['bullist'])) {
+ $settings['buttons']['default']['bullist'] = 1;
+ }
+ if (!empty($settings['buttons']['lists']['numlist'])) {
+ $settings['buttons']['default']['numlist'] = 1;
+ }
+ unset($settings['buttons']['lists']);
$migrated_version = '4.5.0';
}
if (version_compare($profile_version, '4.3.0', '>=') && version_compare($installed_version, '4.3.0', '<')) {
@@ -1371,6 +1389,9 @@ function _wysiwyg_tinymce_plugins($editor) {
'buttons' => array('toc' => t('Table of Contents')),
'url' => _wysiwyg_tinymce_get_plugin_url('toc'),
);
+ // The list buttons now require the lists plugin.
+ $plugins['lists']['buttons'] = array('bullist' => t('Unordered list'), 'numlist' => t('Ordered list'));
+ unset($plugins['default']['buttons']['bullist'], $plugins['default']['buttons']['numlist']);
}
}
diff --git a/sites/all/modules/contrib/wysiwyg/editors/wymeditor.inc b/sites/all/modules/contrib/wysiwyg/editors/wymeditor.inc
index af1917fae..0e180cb31 100644
--- a/sites/all/modules/contrib/wysiwyg/editors/wymeditor.inc
+++ b/sites/all/modules/contrib/wysiwyg/editors/wymeditor.inc
@@ -11,24 +11,20 @@
function wysiwyg_wymeditor_editor() {
$editor['wymeditor'] = array(
'title' => 'WYMeditor',
- 'vendor url' => 'http://www.wymeditor.org/',
- 'download url' => 'http://www.wymeditor.org/download/',
- 'library path' => wysiwyg_get_path('wymeditor') . '/wymeditor',
+ 'vendor url' => 'http://wymeditor.github.io/wymeditor/',
+ 'download url' => 'https://github.com/wymeditor/wymeditor/releases',
+ 'library path' => wysiwyg_get_path('wymeditor'),
'libraries' => array(
'min' => array(
'title' => 'Minified',
'files' => array('jquery.wymeditor.min.js'),
),
- 'pack' => array(
- 'title' => 'Packed',
- 'files' => array('jquery.wymeditor.pack.js'),
- ),
'src' => array(
'title' => 'Source',
'files' => array('jquery.wymeditor.js'),
),
),
- 'verified version range' => array('0.5', '1.0.0b5'),
+ 'verified version range' => array('0.5', '1.1.1'),
'version callback' => 'wysiwyg_wymeditor_version',
'themes callback' => 'wysiwyg_wymeditor_themes',
'settings form callback' => 'wysiwyg_wymeditor_settings_form',
@@ -36,8 +32,18 @@ function wysiwyg_wymeditor_editor() {
'plugin callback' => '_wysiwyg_wymeditor_plugins',
'versions' => array(
'0.5-rc1' => array(
+ 'library path' => wysiwyg_get_path('wymeditor') . '/wymeditor',
'js files' => array('wymeditor.js'),
),
+ '1.0.0a1' => array(
+ 'library path' => wysiwyg_get_path('wymeditor') . '/wymeditor',
+ 'js files' => array('wymeditor-1.js'),
+ 'css files' => array('wymeditor.css'),
+ ),
+ '1.0.0b5' => array(
+ 'js files' => array('wymeditor-1.js'),
+ 'css files' => array('wymeditor.css'),
+ ),
),
);
return $editor;
@@ -53,16 +59,23 @@ function wysiwyg_wymeditor_editor() {
* The installed editor version.
*/
function wysiwyg_wymeditor_version($editor) {
- $script = $editor['library path'] . '/jquery.wymeditor.js';
+ $script = $editor['library path'] . '/wymeditor/jquery.wymeditor.js';
+ if (!file_exists($script)) {
+ $script = $editor['library path'] . '/jquery.wymeditor.js';
+ if (!file_exists($script)) {
+ return;
+ }
+ }
if (!file_exists($script)) {
return;
}
$script = fopen($script, 'r');
- fgets($script);
- $line = fgets($script);
- if (preg_match('@version\s+([0-9a-z\.-]+)@', $line, $version)) {
- fclose($script);
- return $version[1];
+ for ($i = 0; $i < 189; $i++) {
+ $line = fgets($script);
+ if (preg_match('@version\s+([0-9\.]+(?:-?[a-z0-9\.]+)?[^\.])@', $line, $version)) {
+ fclose($script);
+ return $version[1];
+ }
}
fclose($script);
}
@@ -127,8 +140,6 @@ function wysiwyg_wymeditor_settings($editor, $config, $theme) {
$settings = array(
'basePath' => base_path() . $editor['library path'] . '/',
'wymPath' => $editor['libraries'][$library]['files'][0],
- // @todo Does not work in Drupal; jQuery can live anywhere.
- 'jQueryPath' => base_path() . 'misc/jquery.js',
// WYMeditor's update event handler will revert the field contents if
// changes were made after it was detached. Wysiwyg takes care of submit
// events anyway so make sure WYMeditor does not bind it anywhere.
@@ -136,6 +147,13 @@ function wysiwyg_wymeditor_settings($editor, $config, $theme) {
'updateEvent' => 'wysiwyg-no-event',
'skin' => $theme,
);
+ if (version_compare($editor['installed version'], '1.0.0-b5', '>=')) {
+ drupal_add_css(wysiwyg_get_path('wymeditor') . '/skins/' . $settings['skin'] . '/skin.css');
+ }
+ else {
+ // @todo Does not work in Drupal; jQuery can live anywhere.
+ $settings['jQueryPath'] = base_path() . 'misc/jquery.js';
+ }
if (isset($config['language'])) {
$settings['lang'] = $config['language'];
@@ -144,7 +162,7 @@ function wysiwyg_wymeditor_settings($editor, $config, $theme) {
// Add configured buttons.
$settings['toolsItems'] = array();
if (!empty($config['buttons'])) {
- $buttoninfo = _wysiwyg_wymeditor_button_info();
+ $buttoninfo = _wysiwyg_wymeditor_button_info($editor['installed version']);
$plugins = wysiwyg_get_plugins($editor['name']);
foreach ($config['buttons'] as $plugin => $buttons) {
foreach ($buttons as $button => $enabled) {
@@ -246,8 +264,8 @@ function _wysiwyg_wymeditor_plugins($editor) {
/**
* Helper function to provide additional meta-data for internal default buttons.
*/
-function _wysiwyg_wymeditor_button_info() {
- return array(
+function _wysiwyg_wymeditor_button_info($version) {
+ $info = array(
'Bold' => array('title' => 'Strong', 'css' => 'wym_tools_strong'),
'Italic' => array('title' => 'Emphasis', 'css' => 'wym_tools_emphasis'),
'Superscript' => array('title' => 'Superscript', 'css' => 'wym_tools_superscript'),
@@ -266,4 +284,10 @@ function _wysiwyg_wymeditor_button_info() {
'ToggleHtml' => array('title' => 'HTML', 'css' => 'wym_tools_html'),
'Preview' => array('title' => 'Preview', 'css' => 'wym_tools_preview'),
);
+ if (version_compare($version, '1.0.0-rc2', '>=')) {
+ foreach (array('CreateLink', 'InsertImage', 'InsertTable', 'Paste', 'Preview') as $button) {
+ $info[$button]['css'] .= ' wym_opens_dialog';
+ }
+ }
+ return $info;
}
diff --git a/sites/all/modules/contrib/wysiwyg/includes/styling.inc b/sites/all/modules/contrib/wysiwyg/includes/styling.inc
index 3c0100734..ce2547d13 100644
--- a/sites/all/modules/contrib/wysiwyg/includes/styling.inc
+++ b/sites/all/modules/contrib/wysiwyg/includes/styling.inc
@@ -58,7 +58,7 @@ function _wysiwyg_delivery_dummy($page_callback_result) {
}
/**
- * Theme callback to simply suggest a theme based on the page arugment.
+ * Theme callback to simply suggest a theme based on the page argument.
*/
function _wysiwyg_theme_callback($theme) {
return $theme;
@@ -102,7 +102,7 @@ function _wysiwyg_pre_render_styles($elements) {
}
$cached = cache_get('wysiwyg_css');
foreach (element_children($elements) as $child) {
- if ($elements['#groups'][$child]['group'] != CSS_THEME) {
+ if (isset($elements['#groups'][$child]['group']) && $elements['#groups'][$child]['group'] != CSS_THEME) {
continue;
}
switch ($elements[$child]['#tag']) {
diff --git a/sites/all/modules/contrib/wysiwyg/tests/wysiwyg_test.info b/sites/all/modules/contrib/wysiwyg/tests/wysiwyg_test.info
index 7cdf8ba5c..5291db602 100644
--- a/sites/all/modules/contrib/wysiwyg/tests/wysiwyg_test.info
+++ b/sites/all/modules/contrib/wysiwyg/tests/wysiwyg_test.info
@@ -6,9 +6,9 @@ hidden = TRUE
dependencies[] = wysiwyg
files[] = wysiwyg_test.module
-; Information added by Drupal.org packaging script on 2016-12-31
-version = "7.x-2.3"
+; Information added by Drupal.org packaging script on 2017-05-01
+version = "7.x-2.4"
core = "7.x"
project = "wysiwyg"
-datestamp = "1483223295"
+datestamp = "1493674446"
diff --git a/sites/all/modules/contrib/wysiwyg/wysiwyg.admin.inc b/sites/all/modules/contrib/wysiwyg/wysiwyg.admin.inc
index 5ee0bca91..49e9af0c5 100644
--- a/sites/all/modules/contrib/wysiwyg/wysiwyg.admin.inc
+++ b/sites/all/modules/contrib/wysiwyg/wysiwyg.admin.inc
@@ -89,10 +89,10 @@ function wysiwyg_profile_form($form, &$form_state, $profile) {
// If the editor integration supports migration between versions, attempt
// it before widgets for settings are rendered.
if (isset($editor['migrate settings callback']) && function_exists($editor['migrate settings callback'])) {
- // Get the version migrated to. MUST be in the verified version range or
- // FALSE if no migration was possible.
+ // Get the version migrated to. MUST be in the verified version range,
+ // FALSE if no migration was possible, or TRUE if no change needed.
$migrated_version = $editor['migrate settings callback']($settings, $editor, $profile_version, $installed_version);
- $profile->changed = ($migrated_version !== TRUE && $migrated_version != $installed_version);
+ $profile->changed = ($migrated_version !== TRUE && $migrated_version != $profile_version);
if ($migrated_version === FALSE) {
$migrate_message .= ' ' . t('Wysiwyg is not able to automatically adapt the profile to the installed editor version. It is recommended to start over with a new profile.');
$migrate_status = 'error';
@@ -590,7 +590,10 @@ function wysiwyg_profile_overview($form, &$form_state) {
'#title' => t('Installation instructions'),
'#collapsible' => TRUE,
'#collapsed' => !isset($show_instructions),
- '#description' => t('A complete list of supported editor versions for all Wysiwyg module versions can be found on drupal.org.', array('@url' => url('https://www.drupal.org/node/596966'))) . (!$count ? ' ' . t('There are no editor libraries installed currently. The following list contains a list of currently supported editors:') : ''),
+ '#description' => t('A complete list of supported editor versions for all Wysiwyg module versions can be found on drupal.org.', array('@url' => url('https://www.drupal.org/node/596966')))
+ . (!$count ? ' ' . t('There are no editor libraries installed currently. The following list contains a list of currently supported editors:') : '')
+ . ' ' . t('The instructions apply to the latest supported editor version. Paths for previous versions may differ.')
+ . ' ' . t('In general: Unpack the downloaded library archive directly into the libraries folder. You may need to rename the top folder to exactly match the plain library name.'),
'#weight' => 10,
);
$form['status']['report'] = array('#markup' => theme('status_report', array('requirements' => $status)));
diff --git a/sites/all/modules/contrib/wysiwyg/wysiwyg.api.php b/sites/all/modules/contrib/wysiwyg/wysiwyg.api.php
index 5c156dc2a..7bc7ac4e4 100644
--- a/sites/all/modules/contrib/wysiwyg/wysiwyg.api.php
+++ b/sites/all/modules/contrib/wysiwyg/wysiwyg.api.php
@@ -206,7 +206,7 @@ function hook_INCLUDE_editor() {
// (optional) A callback to invoke to return additional notes for installing
// the editor library in the administrative list/overview.
'install note callback' => 'wysiwyg_ckeditor_install_note',
- // The minimum and maximum versions the implemetation has been tested with.
+ // The minimum and maximum versions the implementation has been tested with.
// Users will be notified if installing a version not within this range.
'verified version range' => array('1.2.3', '3.4.5'),
// (optional) A callback to perform migrations of the settings stored in a
@@ -320,7 +320,7 @@ function hook_wysiwyg_editor_settings_alter(&$settings, $context) {
*
* This hook acts like a pre-render callback to the style element normally
* output in the document header. It is invoked before Core has
- * sorted/grouped/aggregated stylehsheets and changes made here will only have
+ * sorted/grouped/aggregated stylesheets and changes made here will only have
* an effect on the stylesheets used in an editor's WYSIWYG mode.
* Wysiwyg will only keep items if their type is 'file' or 'inline' and only if
* they are in the group CSS_THEME.
diff --git a/sites/all/modules/contrib/wysiwyg/wysiwyg.features.inc b/sites/all/modules/contrib/wysiwyg/wysiwyg.features.inc
index 02742a6f3..00e638e92 100644
--- a/sites/all/modules/contrib/wysiwyg/wysiwyg.features.inc
+++ b/sites/all/modules/contrib/wysiwyg/wysiwyg.features.inc
@@ -52,9 +52,10 @@ function wysiwyg_features_export_render($module, $data, $export = NULL) {
foreach ($data as $name) {
if ($profile = wysiwyg_get_profile($name)) {
+ $profile = (array) $profile;
$profile_export = features_var_export($profile, ' ');
- $profile_identifier = features_var_export($profile->format);
- $code[] = " // Exported profile: {$profile->format}";
+ $profile_identifier = features_var_export($profile['format']);
+ $code[] = " // Exported profile: {$profile['format']}.";
$code[] = " \$profiles[{$profile_identifier}] = {$profile_export};";
$code[] = "";
}
@@ -78,27 +79,44 @@ function wysiwyg_features_revert($module) {
function wysiwyg_features_rebuild($module) {
if ($defaults = features_get_default('wysiwyg', $module)) {
foreach ($defaults as $profile) {
+ $profile = is_object($profile) ? (array) $profile : $profile;
if (empty($profile['settings']['_profile_preferences'])) {
- $settings = &$profile['settings'];
- // Importing an older profile, move state to its own section.
+ if (!empty($profile['preferences'])) {
+ $settings = &$profile['preferences'];
+ }
+ else {
+ // Importing an older profile, move state to its own section.
+ $settings = &$profile['settings'];
+ }
+
$preferences = array(
- 'add_to_summaries' => $settings['add_to_summaries'],
+ 'add_to_summaries' => (!empty($settings['add_to_summaries']) ? $settings['add_to_summaries'] : FALSE),
'default' => $settings['default'],
'show_toggle' => $settings['show_toggle'],
'user_choose' => $settings['user_choose'],
- 'version' => NULL,
+ 'version' => (!empty($settings['version']) ? $settings['version'] : NULL),
);
- unset($settings['add_to_summaries'], $settings['default'], $settings['show_toggle'], $settings['user_choose']);
+ unset($settings['add_to_summaries'],
+ $settings['default'],
+ $settings['show_toggle'],
+ $settings['user_choose'],
+ $settings['version'],
+ $profile['preferences']
+ );
+
if (!empty($settings['library'])) {
- $prefereces['library'] = $settings['library'];
+ $preferences['library'] = $settings['library'];
unset($settings['library']);
}
- $editor = wysiwyg_get_editor($profile->editor);
- if ($editor['installed']) {
+
+ $editor = wysiwyg_get_editor($profile['editor']);
+ if (empty($preferences['version']) && !empty($editor['installed'])) {
$preferences['version'] = $editor['installed version'];
}
- $settings['_profile_preferences'] = $preferences;
+
+ $profile['settings']['_profile_preferences'] = $preferences;
}
+
db_merge('wysiwyg')
->key(array('format' => $profile['format']))
->fields(array(
@@ -116,4 +134,3 @@ function wysiwyg_features_rebuild($module) {
wysiwyg_profile_cache_clear();
}
}
-
diff --git a/sites/all/modules/contrib/wysiwyg/wysiwyg.info b/sites/all/modules/contrib/wysiwyg/wysiwyg.info
index 1bc5c2865..2f8f9fc72 100644
--- a/sites/all/modules/contrib/wysiwyg/wysiwyg.info
+++ b/sites/all/modules/contrib/wysiwyg/wysiwyg.info
@@ -9,9 +9,9 @@ configure = admin/config/content/wysiwyg
files[] = wysiwyg.module
files[] = tests/wysiwyg.test
-; Information added by Drupal.org packaging script on 2016-12-31
-version = "7.x-2.3"
+; Information added by Drupal.org packaging script on 2017-05-01
+version = "7.x-2.4"
core = "7.x"
project = "wysiwyg"
-datestamp = "1483223295"
+datestamp = "1493674446"
diff --git a/sites/all/modules/contrib/wysiwyg/wysiwyg.install b/sites/all/modules/contrib/wysiwyg/wysiwyg.install
index 99227cee5..1874e5b1d 100644
--- a/sites/all/modules/contrib/wysiwyg/wysiwyg.install
+++ b/sites/all/modules/contrib/wysiwyg/wysiwyg.install
@@ -384,6 +384,10 @@ function wysiwyg_update_7204() {
->execute();
$query = db_select('wysiwyg', 'w')
->fields('w', array('format', 'editor', 'settings'));
+ drupal_load('module', 'wysiwyg');
+ if (module_exists('ctools')) {
+ drupal_load('module', 'ctools');
+ }
foreach ($query->execute() as $profile) {
// Clear the editing caches.
if (module_exists('ctools')) {
@@ -398,7 +402,7 @@ function wysiwyg_update_7204() {
continue;
}
$preferences = array(
- 'add_to_summaries' => $settings['add_to_summaries'],
+ 'add_to_summaries' => !empty($settings['add_to_summaries']),
'default' => $settings['default'],
'show_toggle' => $settings['show_toggle'],
'user_choose' => $settings['user_choose'],
@@ -423,3 +427,25 @@ function wysiwyg_update_7204() {
}
wysiwyg_profile_cache_clear();
}
+
+/**
+ * Check for profiles without add_to_summaries settings.
+ */
+function wysiwyg_update_7205() {
+ $query = db_select('wysiwyg', 'w');
+ $query->join('filter_format', 'f', 'w.format = f.format');
+ $query->fields('w', array('format', 'editor', 'settings'));
+ $query->fields('f', array('name'));
+
+ foreach ($query->execute() as $profile) {
+ $settings = unserialize($profile->settings);
+
+ if (!isset($settings['_profile_preferences']['add_to_summaries'])) {
+ $values = array(
+ '@format' => $profile->name,
+ '!url' => 'https://www.drupal.org/node/2851313',
+ );
+ drupal_set_message(t('You may need to manually resave the Wysiwyg profile configuration tied to the @format text format. See !url', $values), 'warning');
+ }
+ }
+}
diff --git a/sites/all/modules/contrib/wysiwyg/wysiwyg.js b/sites/all/modules/contrib/wysiwyg/wysiwyg.js
index 131a4be05..0cd842382 100644
--- a/sites/all/modules/contrib/wysiwyg/wysiwyg.js
+++ b/sites/all/modules/contrib/wysiwyg/wysiwyg.js
@@ -213,6 +213,12 @@ Drupal.behaviors.attachWysiwyg = {
}
wysiwygs.each(function () {
Drupal.wysiwygDetach(context, this.id, trigger);
+ if (trigger === 'unload') {
+ // Delete the instance in case the field is removed. This is safe since
+ // detaching with the unload trigger is reverts to the 'none' "editor".
+ delete _internalInstances[this.id];
+ delete Drupal.wysiwyg.instances[this.id];
+ }
});
}
};
@@ -235,25 +241,12 @@ Drupal.behaviors.attachWysiwyg = {
*/
Drupal.wysiwygAttach = function(context, fieldId) {
var fieldInfo = getFieldInfo(fieldId),
- formatInfo = fieldInfo.getFormatInfo(),
- editorSettings = formatInfo.editorSettings,
- editor = formatInfo.editor,
- previousStatus = false,
- previousEditor = 'none',
- doSummary = (fieldInfo.summary && (!fieldInfo.formats[fieldInfo.activeFormat] || !fieldInfo.formats[fieldInfo.activeFormat].skip_summary));
- if (_internalInstances[fieldId]) {
- previousStatus = _internalInstances[fieldId]['status'];
- previousEditor = _internalInstances[fieldId].editor;
- }
+ doSummary = (fieldInfo.summary && (!fieldInfo.formats[fieldInfo.activeFormat] || !fieldInfo.formats[fieldInfo.activeFormat].skip_summary));
// Detach any previous editor instance if enabled, else remove the grippie.
- detachFromField(context, {'editor': previousEditor, 'status': previousStatus, 'field': fieldId, 'resizable': fieldInfo.resizable}, 'unload');
- if (doSummary) {
- // Summary instances may have a different status if no real editor was
- // attached yet because the field was hidden.
- if (_internalInstances[fieldInfo.summary]) {
- previousStatus = _internalInstances[fieldInfo.summary]['status'];
- }
- detachFromField(context, {'editor': previousEditor, 'status': previousStatus, 'field': fieldInfo.summary, 'resizable': fieldInfo.resizable}, 'unload');
+ detachFromField(fieldId, context, 'unload');
+ var wasSummary = !!_internalInstances[fieldInfo.summary];
+ if (doSummary || wasSummary) {
+ detachFromField(fieldId, context, 'unload', {summary: true});
}
// Store this field id, so (external) plugins can use it.
// @todo Wrong point in time. Probably can only supported by editors which
@@ -262,21 +255,21 @@ Drupal.wysiwygAttach = function(context, fieldId) {
// Attach or update toggle link, if enabled.
Drupal.wysiwygAttachToggleLink(context, fieldId);
// Attach to main field.
- attachToField(context, {'status': fieldInfo.enabled, 'editor': editor, 'field': fieldId, 'format': fieldInfo.activeFormat, 'resizable': fieldInfo.resizable}, editorSettings);
+ attachToField(fieldId, context);
// Attach to summary field.
- if (doSummary) {
+ if (doSummary || wasSummary) {
// If the summary wrapper is visible, attach immediately.
if ($('#' + fieldInfo.summary).parents('.text-summary-wrapper').is(':visible')) {
- attachToField(context, {'status': fieldInfo.enabled, 'editor': editor, 'field': fieldInfo.summary, 'format': fieldInfo.activeFormat, 'resizable': fieldInfo.resizable}, editorSettings);
+ attachToField(fieldId, context, {summary: true, forceDisabled: !doSummary});
}
else {
// Attach an instance of the 'none' editor to have consistency while the
// summary is hidden, then switch to a real editor instance when shown.
- attachToField(context, {'status': false, 'editor': editor, 'field': fieldInfo.summary, 'format': fieldInfo.activeFormat, 'resizable': fieldInfo.resizable}, editorSettings);
+ attachToField(fieldId, context, {summary: true, forceDisabled: true});
// Unbind any existing click handler to avoid double toggling.
- $('#' + fieldId).parents('.text-format-wrapper').find('.link-edit-summary').unbind('click.wysiwyg').bind('click.wysiwyg', function () {
- detachFromField(context, {'status': false, 'editor': editor, 'field': fieldInfo.summary, 'format': fieldInfo.activeFormat, 'resizable': fieldInfo.resizable}, editorSettings);
- attachToField(context, {'status': fieldInfo.enabled, 'editor': editor, 'field': fieldInfo.summary, 'format': fieldInfo.activeFormat, 'resizable': fieldInfo.resizable}, editorSettings);
+ $('#' + fieldId).parents('.text-format-wrapper').find('.link-edit-summary').closest('.field-edit-link').unbind('click.wysiwyg').bind('click.wysiwyg', function () {
+ detachFromField(fieldId, context, 'unload', {summary: true});
+ attachToField(fieldId, context, {summary: true, forceDisabled: !doSummary});
$(this).unbind('click.wysiwyg');
});
}
@@ -355,7 +348,7 @@ function WysiwygInstance(internalInstance) {
/**
* Open a native editor dialog.
*
- * Use of this method i not recomended due to limited editor support.
+ * Use of this method i not recommended due to limited editor support.
*
* @param dialog
* An object with dialog settings. Keys used:
@@ -482,6 +475,10 @@ function updateInternalState(settings, context) {
var fieldId = trigger.field;
var baseFieldId = (fieldId.indexOf('--') === -1 ? fieldId : fieldId.substr(0, fieldId.indexOf('--')));
var fieldInfo = null;
+ if ($('#' + triggerId, context).length === 0) {
+ // Skip fields which may have been removed or are not in this context.
+ continue;
+ }
if (!(fieldInfo = _fieldInfoStorage[baseFieldId])) {
fieldInfo = _fieldInfoStorage[baseFieldId] = {
formats: {},
@@ -495,15 +492,15 @@ function updateInternalState(settings, context) {
return getFormatInfo(this.activeFormat);
}
// 'activeFormat' and 'enabled' added below.
- }
- };
+ };
+ }
for (var format in trigger) {
if (format.indexOf('format') != 0 || fieldInfo.formats[format]) {
continue;
}
fieldInfo.formats[format] = {
'enabled': trigger[format].status
- }
+ };
if (!_formatInfoStorage[format]) {
_formatInfoStorage[format] = {
editor: trigger[format].editor,
@@ -544,38 +541,44 @@ function updateInternalState(settings, context) {
*
* Creates the 'instance' object under Drupal.wysiwyg.instances[fieldId].
*
+ * @param mainFieldId
+ * The id of the field's main element, for fetching field info.
* @param context
* A DOM element, supplied by Drupal.attachBehaviors().
* @param params
- * An object containing state information for the editor with the following
- * properties:
- * - 'status': A boolean stating whether the editor is currently active. If
- * false, the default textarea behaviors will be attached instead (aka the
- * 'none' editor implementation).
- * - 'editor': The internal name of the editor to attach when active.
- * - 'field': The field id to use as an output target for the editor.
- * - 'format': The name of the active text format (prefixed 'format').
- * - 'resizable': A boolean indicating whether the original textarea was
- * resizable.
- * Note: This parameter is passed directly to the editor implementation and
- * needs to have been reconstructed or cloned before attaching.
- * @param editorSettings
- * An object containing all the settings the editor needs for this field.
- * Settings are automatically cloned to prevent editors from modifying them.
+ * An optional object for overriding state information for the editor with the
+ * following properties:
+ * - 'summary': Set to true to indicate to attach to the summary instead of
+ * the main element. Defaults to false.
+ * - 'forceDisabled': Set to true to override the current state of the field
+ * and assume it is disabled. Useful for hidden summary instances.
+ *
+ * @see Drupal.wysiwygAttach()
*/
-function attachToField(context, params, editorSettings) {
+function attachToField(mainFieldId, context, params) {
+ params = params || {};
+ var fieldInfo = getFieldInfo(mainFieldId);
+ var fieldId = (params.summary ? fieldInfo.summary : mainFieldId);
+ var formatInfo = fieldInfo.getFormatInfo();
// If the editor isn't active, attach default behaviors instead.
- var editor = (params.status ? params.editor : 'none');
+ var enabled = (fieldInfo.enabled && !params.forceDisabled);
+ var editor = (enabled ? formatInfo.editor : 'none');
// Settings are deep merged (cloned) to prevent editor implementations from
// permanently modifying them while attaching.
- var clonedSettings = jQuery.extend(true, {}, editorSettings);
+ var clonedSettings = (enabled ? jQuery.extend(true, {}, formatInfo.editorSettings) : {});
// (Re-)initialize field instance.
- var internalInstance = new WysiwygInternalInstance(params);
- _internalInstances[params.field] = internalInstance;
- Drupal.wysiwyg.instances[params.field] = internalInstance.publicInstance;
- if ($.isFunction(Drupal.wysiwyg.editor.attach[editor])) {
- Drupal.wysiwyg.editor.attach[editor].call(internalInstance, context, params, params.status ? clonedSettings : {});
- }
+ var stateParams = {
+ field: fieldId,
+ editor: formatInfo.editor,
+ 'status': enabled,
+ format: fieldInfo.activeFormat,
+ resizable: fieldInfo.resizable
+ };
+ var internalInstance = new WysiwygInternalInstance(stateParams);
+ _internalInstances[fieldId] = internalInstance;
+ Drupal.wysiwyg.instances[fieldId] = internalInstance.publicInstance;
+ // Attach editor, if enabled by default or last state was enabled.
+ Drupal.wysiwyg.editor.attach[editor].call(internalInstance, context, stateParams, clonedSettings);
}
/**
@@ -601,29 +604,22 @@ function attachToField(context, params, editorSettings) {
*/
Drupal.wysiwygDetach = function (context, fieldId, trigger) {
var fieldInfo = getFieldInfo(fieldId),
- editor = fieldInfo.getFormatInfo().editor,
- trigger = trigger || 'unload',
- previousStatus = (_internalInstances[fieldId] && _internalInstances[fieldId]['status']);
+ trigger = trigger || 'unload';
// Detach from main field.
- detachFromField(context, {'editor': editor, 'status': previousStatus, 'field': fieldId, 'resizable': fieldInfo.resizable}, trigger);
+ detachFromField(fieldId, context, trigger);
if (trigger == 'unload') {
// Attach the resize behavior by forcing status to false. Other values are
// intentionally kept the same to show which editor is normally attached.
- attachToField(context, {'editor': editor, 'status': false, 'format': fieldInfo.activeFormat, 'field': fieldId, 'resizable': fieldInfo.resizable});
+ attachToField(fieldId, context, {forceDisabled: true});
Drupal.wysiwygAttachToggleLink(context, fieldId);
}
// Detach from summary field.
if (fieldInfo.summary && _internalInstances[fieldInfo.summary]) {
// The "Edit summary" click handler could re-enable the editor by mistake.
$('#' + fieldId).parents('.text-format-wrapper').find('.link-edit-summary').unbind('click.wysiwyg');
- // Summary instances may have a different status if no real editor was
- // attached yet because the field was hidden.
- if (_internalInstances[fieldInfo.summary]) {
- previousStatus = _internalInstances[fieldInfo.summary]['status'];
- }
- detachFromField(context, {'editor': editor, 'status': previousStatus, 'field': fieldInfo.summary, 'resizable': fieldInfo.resizable}, trigger);
+ detachFromField(fieldId, context, trigger, {summary: true});
if (trigger == 'unload') {
- attachToField(context, {'editor': editor, 'status': false, 'format': fieldInfo.activeFormat, 'field': fieldInfo.summary, 'resizable': fieldInfo.resizable});
+ attachToField(fieldId, context, {summary: true});
}
}
};
@@ -633,38 +629,47 @@ Drupal.wysiwygDetach = function (context, fieldId, trigger) {
*
* Removes the 'instance' object under Drupal.wysiwyg.instances[fieldId].
*
+ * @param mainFieldId
+ * The id of the field's main element, for fetching field info.
* @param context
* A DOM element, supplied by Drupal.detachBehaviors().
- * @param params
- * An object containing state information for the editor with the following
- * properties:
- * - 'status': A boolean stating whether the editor is currently active. If
- * false, the default textarea behaviors will be attached instead (aka the
- * 'none' editor implementation).
- * - 'editor': The internal name of the editor to attach when active.
- * - 'field': The field id to use as an output target for the editor.
- * - 'format': The name of the active text format (prefixed 'format').
- * - 'resizable': A boolean indicating whether the original textarea was
- * resizable.
- * Note: This parameter is passed directly to the editor implementation and
- * needs to have been reconstructed or cloned before detaching.
* @param trigger
* A string describing what is causing the editor to be detached.
* - 'serialize': The editor normally just syncs its contents to the original
* textarea for value serialization before an AJAX request.
* - 'unload': The editor is to be removed completely and the original
* textarea restored.
+ * @param params
+ * An optional object for overriding state information for the editor with the
+ * following properties:
+ * - 'summary': Set to true to indicate to detach from the summary instead of
+ * the main element. Defaults to false.
*
* @see Drupal.wysiwygDetach()
*/
-function detachFromField(context, params, trigger) {
- var editor = (params.status ? params.editor : 'none');
+function detachFromField(mainFieldId, context, trigger, params) {
+ params = params || {};
+ var fieldInfo = getFieldInfo(mainFieldId);
+ var fieldId = (params.summary ? fieldInfo.summary : mainFieldId);
+ var enabled = false;
+ var editor = 'none';
+ if (_internalInstances[fieldId]) {
+ enabled = _internalInstances[fieldId]['status'];
+ editor = (enabled ? _internalInstances[fieldId].editor : 'none');
+ }
+ var stateParams = {
+ field: fieldId,
+ 'status': enabled,
+ editor: fieldInfo.editor,
+ format: fieldInfo.activeFormat,
+ resizable: fieldInfo.resizable
+ };
if (jQuery.isFunction(Drupal.wysiwyg.editor.detach[editor])) {
- Drupal.wysiwyg.editor.detach[editor].call(_internalInstances[params.field], context, params, trigger);
+ Drupal.wysiwyg.editor.detach[editor].call(_internalInstances[fieldId], context, stateParams, trigger);
}
if (trigger == 'unload') {
- delete Drupal.wysiwyg.instances[params.field];
- delete _internalInstances[params.field];
+ delete Drupal.wysiwyg.instances[fieldId];
+ delete _internalInstances[fieldId];
}
}
@@ -730,16 +735,21 @@ Drupal.wysiwyg.toggleWysiwyg = function (event) {
* Event handler for when the selected format is changed.
*/
function formatChanged(event) {
- var fieldId = _selectToField[this.id.replace(/--\d+$/,'')];
+ var fieldId = _selectToField[this.id.replace(/--\d+$/, '')];
var context = $(this).closest('form');
+ var newFormat = 'format' + $(this).val();
// Field state is fetched by reference.
var currentField = getFieldInfo(fieldId);
+ // Prevent double-attaching if change event is triggered manually.
+ if (newFormat === currentField.activeFormat) {
+ return;
+ }
// Save the state of the current format.
if (currentField.formats[currentField.activeFormat]) {
currentField.formats[currentField.activeFormat].enabled = currentField.enabled;
}
// Switch format/profile.
- currentField.activeFormat = 'format' + this.value;
+ currentField.activeFormat = newFormat;
// Load the state from the new format.
if (currentField.formats[currentField.activeFormat]) {
currentField.enabled = currentField.formats[currentField.activeFormat].enabled;
diff --git a/sites/all/modules/contrib/wysiwyg/wysiwyg.module b/sites/all/modules/contrib/wysiwyg/wysiwyg.module
index c925ca5ea..c966294c6 100644
--- a/sites/all/modules/contrib/wysiwyg/wysiwyg.module
+++ b/sites/all/modules/contrib/wysiwyg/wysiwyg.module
@@ -148,11 +148,11 @@ function wysiwyg_admin_menu_map() {
}
$profiles = wysiwyg_profile_load_all();
- $map['admin/config/content/wysiwyg/profile/%wysiwyg_profile'] = array(
+ $map['admin/config/content/wysiwyg/profile/%wysiwyg_ui_profile_cache'] = array(
'parent' => 'admin/config/content/wysiwyg',
'hide' => 'admin/config/content/wysiwyg/list',
'arguments' => array(
- array('%wysiwyg_profile' => array_keys($profiles)),
+ array('%wysiwyg_ui_profile_cache' => array_keys($profiles)),
),
);
return $map;
@@ -275,7 +275,7 @@ function wysiwyg_pre_render_text_format($element) {
'toggle' => 1,
);
$loaded = TRUE;
- if (isset($profile->settings['add_to_summaries']) && !$profile->settings['add_to_summaries']) {
+ if (isset($profile->preferences['add_to_summaries']) && !$profile->preferences['add_to_summaries']) {
$settings[$format]['skip_summary'] = 1;
}
$settings[$format]['editor'] = $profile->editor;
@@ -771,13 +771,13 @@ function wysiwyg_get_css($theme = NULL) {
*/
function wysiwyg_themes_enabled($theme_list) {
$cached = cache_get('wysiwyg_css');
- foreach ($theme_list as $theme) {
- if ($cached && !empty($cached->data)) {
- $css = $cached->data;
+ if ($cached && !empty($cached->data)) {
+ $css = $cached->data;
+ foreach ($theme_list as $theme) {
unset($css[$theme]);
}
+ cache_set('wysiwyg_css', $css);
}
- cache_set('wysiwyg_css', $css);
}
/**
@@ -1099,6 +1099,17 @@ function wysiwyg_get_all_editors() {
);
// Check whether library is present.
if (!($editors[$editor]['installed'] = file_exists($editors[$editor]['library path']))) {
+ // Find the latest supported version.
+ ksort($editors[$editor]['versions']);
+ $version = key($editors[$editor]['versions']);
+ foreach ($editors[$editor]['versions'] as $supported_version => $version_properties) {
+ if (version_compare($version, $supported_version, '<')) {
+ $version = $supported_version;
+ }
+ }
+ // Apply library version specific definitions and overrides.
+ // This is to show the newest installation instructions.
+ $editors[$editor] = array_merge($editors[$editor], $editors[$editor]['versions'][$version]);
continue;
}
$installed_version = NULL;
diff --git a/sites/all/modules/contrib/yoast_seo/includes/yoast_seo.forms.inc b/sites/all/modules/contrib/yoast_seo/includes/yoast_seo.forms.inc
index 9db2faf6f..dfafdac6c 100644
--- a/sites/all/modules/contrib/yoast_seo/includes/yoast_seo.forms.inc
+++ b/sites/all/modules/contrib/yoast_seo/includes/yoast_seo.forms.inc
@@ -100,10 +100,10 @@ function _yoast_seo_process_node_settings_form(&$form) {
* '#multiple' => TRUE,
*/
if (empty($body_fields)) {
- $description = t('There is no filed that can be used as additional field.');
+ $description = t('There are no other text fields that could be used instead of the Body field.');
}
else {
- $description = t('Select fields to use instead or in addition to body for Real-time SEO. Access to all fields must be allowed.');
+ $description = t('Select fields to use instead, or in addition to body for Real-time SEO. Access to all fields must be allowed.');
}
$form['yoast_seo']['yoast_seo_body']['yoast_seo_body_fields'] = array(
diff --git a/sites/all/modules/contrib/yoast_seo/js/yoast_seo.js b/sites/all/modules/contrib/yoast_seo/js/yoast_seo.js
index 7ac2341e6..f1b020fde 100644
--- a/sites/all/modules/contrib/yoast_seo/js/yoast_seo.js
+++ b/sites/all/modules/contrib/yoast_seo/js/yoast_seo.js
@@ -151,7 +151,9 @@ YoastSEO_DrupalSource.prototype.parseSnippetData = function(source, target) {
document.getElementById(target).value = (ev.target.value || "");
this.triggerEvent(target);
}.bind(this);
- document.getElementById(source).addEventListener("blur", listener);
+ if (document.getElementById(source) !== null) {
+ document.getElementById(source).addEventListener('blur', listener);
+ }
};
diff --git a/sites/all/modules/contrib/yoast_seo/yoast_seo.info b/sites/all/modules/contrib/yoast_seo/yoast_seo.info
index 450178d8d..f9209e634 100644
--- a/sites/all/modules/contrib/yoast_seo/yoast_seo.info
+++ b/sites/all/modules/contrib/yoast_seo/yoast_seo.info
@@ -16,9 +16,9 @@ configure = admin/config/search/yoast
; Views Handlers.
files[] = views/yoast_seo_handler_rating.inc
-; Information added by Drupal.org packaging script on 2016-12-05
-version = "7.x-1.1"
+; Information added by Drupal.org packaging script on 2017-04-05
+version = "7.x-1.2"
core = "7.x"
project = "yoast_seo"
-datestamp = "1480952305"
+datestamp = "1491409085"
diff --git a/sites/all/modules/contrib/yoast_seo/yoast_seo.module b/sites/all/modules/contrib/yoast_seo/yoast_seo.module
index 7ec21818b..7f7b98151 100644
--- a/sites/all/modules/contrib/yoast_seo/yoast_seo.module
+++ b/sites/all/modules/contrib/yoast_seo/yoast_seo.module
@@ -338,11 +338,11 @@ function yoast_seo_configuration_form_after_build($form, &$form_state) {
'fields' => array(
'focusKeyword' => $form['yoast_seo'][$langcode]['focus_keyword']['#id'],
'seoStatus' => $form['yoast_seo'][$langcode]['seo_status']['#attributes']['id'],
- 'pageTitle' => $form['metatags'][$langcode]['basic']['title']['value']['#id'],
+ 'pageTitle' => (module_exists('seo_ui')) ? $form['seo_vtab']['metatags_title']['title']['value']['#id'] : $form['metatags'][$langcode]['basic']['title']['value']['#id'],
'nodeTitle' => $form['title']['#id'],
- 'description' => $form['metatags'][$langcode]['basic']['description']['value']['#id'],
+ 'description' => (module_exists('seo_ui')) ? $form['seo_vtab']['metatags'][$langcode]['basic']['description']['value']['#id'] : $form['metatags'][$langcode]['basic']['description']['value']['#id'],
'bodyText' => array_keys($text_content),
- 'url' => $form['path']['alias']['#id'],
+ 'url' => (module_exists('seo_ui')) ? $form['seo_vtab']['path']['alias']['#id'] : $form['path']['alias']['#id'],
),
'placeholderText' => array(
'title' => t('Please click here to alter your page meta title'),