diff --git a/PATCH_LIST.txt b/PATCH_LIST.txt index 40ea7a6d..5ec3a180 100644 --- a/PATCH_LIST.txt +++ b/PATCH_LIST.txt @@ -9,7 +9,7 @@ https://www.drupal.org/node/1754162 # Modules : -link : allow any tld (https://www.drupal.org/node/2299657#comment-11414075) +// link : allow any tld (https://www.drupal.org/node/2299657#comment-11414075) commited in dev cer contentadminrelink // entity_translation_search_api @@ -23,7 +23,7 @@ filter_path_alias // search_api_page // search_api_solr termreferencetree -views +?? views wysiwyg views_rss_media node_export : diff --git a/sites/all/modules/contrib/admin/context/context.core.inc b/sites/all/modules/contrib/admin/context/context.core.inc index 41ed93a5..9e198314 100644 --- a/sites/all/modules/contrib/admin/context/context.core.inc +++ b/sites/all/modules/contrib/admin/context/context.core.inc @@ -94,11 +94,27 @@ function context_theme_registry_alter(&$theme_registry) { */ function context_ctools_render_alter($info, $page, $data) { extract($data); - if ($page && in_array($task['name'], array('node_view', 'node_edit'), TRUE)) { - foreach ($contexts as $ctools_context) { - if (in_array('node', $ctools_context->type) && !empty($ctools_context->data)) { - context_node_condition($ctools_context->data, $task['name'] === 'node_view' ? 'view' : 'form'); - break; + + // Check for page handlers. + if ($page) { + // Check for node page handler. + if (in_array($task['name'], array('node_view', 'node_edit'), TRUE)) { + foreach ($contexts as $ctools_context) { + if (in_array('node', $ctools_context->type) && !empty($ctools_context->data)) { + context_node_condition($ctools_context->data, $task['name'] === 'node_view' ? 'view' : 'form'); + break; + } + } + } + // Check for taxonomy term page handler. + elseif (in_array($task['name'], array('term_view', 'term_edit'), TRUE)) { + foreach ($contexts as $ctools_context) { + if (in_array('taxonomy_term', $ctools_context->type) && !empty($ctools_context->data)) { + if ($plugin = context_get_plugin('condition', 'taxonomy_term')) { + $plugin->execute($ctools_context->data, $task['name'] === 'term_view' ? 'view' : 'form'); + } + break; + } } } } diff --git a/sites/all/modules/contrib/admin/context/context.info b/sites/all/modules/contrib/admin/context/context.info index 159f142a..eef3a9c1 100644 --- a/sites/all/modules/contrib/admin/context/context.info +++ b/sites/all/modules/contrib/admin/context/context.info @@ -8,9 +8,8 @@ files[] = tests/context.test files[] = tests/context.conditions.test files[] = tests/context.reactions.test -; Information added by Drupal.org packaging script on 2016-05-18 -version = "7.x-3.7" +; Information added by Drupal.org packaging script on 2019-02-26 +version = "7.x-3.10" core = "7.x" project = "context" -datestamp = "1463605446" - +datestamp = "1551220089" diff --git a/sites/all/modules/contrib/admin/context/context.module b/sites/all/modules/contrib/admin/context/context.module index 5c0bd5c8..c83b15ef 100644 --- a/sites/all/modules/contrib/admin/context/context.module +++ b/sites/all/modules/contrib/admin/context/context.module @@ -243,6 +243,11 @@ function context_preprocess_menu_link(&$variables) { // css class to the link of this menu. // - Do not add class twice on current page. if (in_array($variables['element']['#href'], $reaction_menu_paths) && $variables['element']['#href'] != $_GET['q']) { + // Initialize classes array if not set. + if (!isset($variables['element']['#localized_options']['attributes']['class'])) { + $variables['element']['#localized_options']['attributes']['class'] = array(); + } + // Do not add the 'active' class twice in views tabs. if (!in_array('active', $variables['element']['#localized_options']['attributes']['class'])) { $variables['element']['#localized_options']['attributes']['class'][] = 'active'; diff --git a/sites/all/modules/contrib/admin/context/context_layouts/context_layouts.info b/sites/all/modules/contrib/admin/context/context_layouts/context_layouts.info index 129c4cdb..65880e38 100644 --- a/sites/all/modules/contrib/admin/context/context_layouts/context_layouts.info +++ b/sites/all/modules/contrib/admin/context/context_layouts/context_layouts.info @@ -6,9 +6,8 @@ core = 7.x files[] = plugins/context_layouts_reaction_block.inc -; Information added by Drupal.org packaging script on 2016-05-18 -version = "7.x-3.7" +; Information added by Drupal.org packaging script on 2019-02-26 +version = "7.x-3.10" core = "7.x" project = "context" -datestamp = "1463605446" - +datestamp = "1551220089" diff --git a/sites/all/modules/contrib/admin/context/context_ui/context_ui.info b/sites/all/modules/contrib/admin/context/context_ui/context_ui.info index e6c51051..e5d17f8f 100644 --- a/sites/all/modules/contrib/admin/context/context_ui/context_ui.info +++ b/sites/all/modules/contrib/admin/context/context_ui/context_ui.info @@ -8,9 +8,8 @@ configure = admin/structure/context files[] = context.module files[] = tests/context_ui.test -; Information added by Drupal.org packaging script on 2016-05-18 -version = "7.x-3.7" +; Information added by Drupal.org packaging script on 2019-02-26 +version = "7.x-3.10" core = "7.x" project = "context" -datestamp = "1463605446" - +datestamp = "1551220089" diff --git a/sites/all/modules/contrib/admin/context/plugins/context_condition_query_string.inc b/sites/all/modules/contrib/admin/context/plugins/context_condition_query_string.inc index 781d4cbb..b7bf5d51 100644 --- a/sites/all/modules/contrib/admin/context/plugins/context_condition_query_string.inc +++ b/sites/all/modules/contrib/admin/context/plugins/context_condition_query_string.inc @@ -16,7 +16,7 @@ class context_condition_query_string extends context_condition_path { */ function execute() { if ($this->condition_used()) { - $current_query_string = $_SERVER["QUERY_STRING"]; + $current_query_string = empty($_SERVER["QUERY_STRING"]) ? '' : $_SERVER["QUERY_STRING"]; foreach ($this->get_contexts() as $context) { $query_strings = $this->fetch_from_context($context, 'values'); if ($this->match($current_query_string, $query_strings, TRUE)) { diff --git a/sites/all/modules/contrib/admin/context/plugins/context_reaction_block.inc b/sites/all/modules/contrib/admin/context/plugins/context_reaction_block.inc index abcafd87..90c005c6 100644 --- a/sites/all/modules/contrib/admin/context/plugins/context_reaction_block.inc +++ b/sites/all/modules/contrib/admin/context/plugins/context_reaction_block.inc @@ -400,13 +400,17 @@ class context_reaction_block extends context_reaction { unset($_context_blocks); foreach ($context_blocks as $r => $blocks) { - //only render blocks in an active region + // Only render blocks in an active region. if (array_key_exists($r, $active_regions)) { $context_blocks[$r] = _block_render_blocks($blocks); - // Make blocks editable if allowed. - if ($this->is_editable_region($r)) { - foreach ($context_blocks[$r] as $key => $block) { + $editable = $this->is_editable_region($r); + foreach ($context_blocks[$r] as $key => $block) { + // Add the region property to each block. + $context_blocks[$r][$key]->region = $r; + + // Make blocks editable if allowed. + if ($editable) { $context_blocks[$r][$key] = $this->editable_block($block); } } @@ -450,12 +454,9 @@ class context_reaction_block extends context_reaction { */ protected function max_block_weight() { $blocks = $this->get_blocks(); - $block_count = 0; - foreach ($blocks as $region => $block_list) { - $block_count += count($block_list); - } - // Add 2 to make sure there's space at either end of the block list - return round(($block_count + 2) / 2); + + // Add 2 to make sure there's space at either end of the block list. + return round((count($blocks) + 2) / 2); } /** diff --git a/sites/all/modules/contrib/admin/context/plugins/context_reaction_block.js b/sites/all/modules/contrib/admin/context/plugins/context_reaction_block.js index fb0f3f16..192b956f 100644 --- a/sites/all/modules/contrib/admin/context/plugins/context_reaction_block.js +++ b/sites/all/modules/contrib/admin/context/plugins/context_reaction_block.js @@ -68,7 +68,7 @@ DrupalContextBlockForm = function(blockForm) { // Hide enabled blocks from selector that are used $('table.context-blockform-region tr').each(function() { - var bid = $(this).attr('id'); + var bid = Drupal.checkPlain($(this).attr('id')); $('div.context-blockform-selector input[value="'+bid+'"]').parents('div.form-item').eq(0).hide(); }); // Show blocks in selector that are unused diff --git a/sites/all/modules/contrib/admin/context/plugins/context_reaction_region.inc b/sites/all/modules/contrib/admin/context/plugins/context_reaction_region.inc index c4f0fd7c..d9c0a8ed 100644 --- a/sites/all/modules/contrib/admin/context/plugins/context_reaction_region.inc +++ b/sites/all/modules/contrib/admin/context/plugins/context_reaction_region.inc @@ -17,7 +17,7 @@ class context_reaction_region extends context_reaction { '#type' => 'fieldset', '#title' => "Disable Regions in {$theme->name} Theme", '#collapsible' => TRUE, - '#collapsed' => !array_reduce($default, create_function('$a, $b', 'return $a || $b;')), + '#collapsed' => !array_reduce($default, 'context_reaction_region::collapseRegion'), ); $form[$theme->name]['disable'] = array( '#type' => 'checkboxes', @@ -29,6 +29,10 @@ class context_reaction_region extends context_reaction { } return $form; } + + function collapseRegion($a, $b) { + return $a || $b; + } function execute(&$page) { global $theme; diff --git a/sites/all/modules/contrib/admin/module_filter/CHANGELOG.txt b/sites/all/modules/contrib/admin/module_filter/CHANGELOG.txt index c5c66703..5513831c 100644 --- a/sites/all/modules/contrib/admin/module_filter/CHANGELOG.txt +++ b/sites/all/modules/contrib/admin/module_filter/CHANGELOG.txt @@ -1,27 +1,38 @@ -Module Filter 7.x-2.x, 2015-02-20 +Module Filter 7.x-2.1, 2017-06-09 +--------------------------------- +Issue #2437439 by mikhail.krainiuk, greenSkin, jayhawkfan75: Module Filter does + not care about anchors in permission links. +Issue #2866236 by Munavijayalakshmi, dhruveshdtripathi: Typo error in + README.TXT file. +Issue #2452067 by Madis: Option to show description expanded as default + not working. +Issue #2580791 by makbul_khan8: Coding standards and few function without + help comments. +Issue #2153697 by annya: Disabling option "Number of enabled modules" breaks + tabs functionality. +Issue #1710230 by willvincent: On | Off buttons does not change state with + jquery_update module active. +Added option to show description as expanded by default. +Improved description field so when it is open, interacting with it's contents + does not make it collapse. +Placed collapsed/expanded images inside of module for easier, more reliable + access. +Added option to place version in own column. +Issue #2113191 by joelpittet: Category tabs not working. + + +Module Filter 7.x-2.0, 2015-02-22 --------------------------------- Simplifying the table rows by hiding version and requirements until a particular description is clicked. - - -Module Filter 7.x-2.x, 2014-09-01 ---------------------------------- #2235553 by greenSkin: Fixed latest jquery_update breaks module filter. #2304687 by mpdonadio: Fixed Remove hardcoded operations. #2293029 by topsitemakers: Fixed Take header offset into account when selecting a tab. #2290213 by topsitemakers: Minor typo in description - "has no affect" -> "has no effect". - - -Module Filter 7.x-2.0-alpha2, 2013-12-06 ----------------------------------------- #2141743, #2141743 by greenSkin: Fixed issues related to the new dynamically positioned tabs and using the dynamically positioned save button. - - -Module Filter 7.x-2.0-alpha1, 2013-11-18 ----------------------------------------- by greenSkin: Tabs now should always be visible while scrolling large lists of modules. #1854348 by alexweber, greenSkin: Make filter textfield wider on modules page diff --git a/sites/all/modules/contrib/admin/module_filter/README.txt b/sites/all/modules/contrib/admin/module_filter/README.txt index 0bc967ab..b03d9702 100644 --- a/sites/all/modules/contrib/admin/module_filter/README.txt +++ b/sites/all/modules/contrib/admin/module_filter/README.txt @@ -17,8 +17,8 @@ visibility of modules that are disabled and depend on module(s) that are missing. The update status report filter also contains four checkboxes: Up-to-Date, -Update availabe, Security update, and Unknown. These directly affect the -visibilty of each project; whether it is up-to-date, there is an update +Update available, Security update, and Unknown. These directly affect the +visibility of each project; whether it is up-to-date, there is an update available, a security update is available, or the status is unknown. Installation diff --git a/sites/all/modules/contrib/admin/module_filter/css/module_filter.css b/sites/all/modules/contrib/admin/module_filter/css/module_filter.css index 19d113fb..b03bbb75 100644 --- a/sites/all/modules/contrib/admin/module_filter/css/module_filter.css +++ b/sites/all/modules/contrib/admin/module_filter/css/module_filter.css @@ -18,3 +18,9 @@ text-transform: uppercase; color: #888; } +#module-filter-modules { + position: relative; +} +#module-filter-modules table { + position: absolute; +} diff --git a/sites/all/modules/contrib/admin/module_filter/css/module_filter_tab.css b/sites/all/modules/contrib/admin/module_filter/css/module_filter_tab.css index 2607a617..fd7d0f0c 100644 --- a/sites/all/modules/contrib/admin/module_filter/css/module_filter_tab.css +++ b/sites/all/modules/contrib/admin/module_filter/css/module_filter_tab.css @@ -167,9 +167,6 @@ html.js #module-filter-modules table td { .admin-version { white-space: nowrap; } -.admin-operations { - float: right; -} .admin-operations a.module-link { display: inline; } diff --git a/sites/all/modules/contrib/admin/module_filter/css/modules.css b/sites/all/modules/contrib/admin/module_filter/css/modules.css index 91fa7418..06598257 100644 --- a/sites/all/modules/contrib/admin/module_filter/css/modules.css +++ b/sites/all/modules/contrib/admin/module_filter/css/modules.css @@ -7,6 +7,9 @@ #system-modules th.name { width: 25%; } +#system-modules th.version { + width: 10%; +} #system-modules th.links { width: 15%; } @@ -14,12 +17,12 @@ vertical-align: top; } #system-modules .expand.inner { - background: transparent url(/misc/menu-collapsed.png) left 0.6em no-repeat; + background: transparent url(../images/collapsed.png) left 0.6em no-repeat; margin-left: -12px; padding-left: 12px; } #system-modules .expanded.expand.inner { - background: transparent url(/misc/menu-expanded.png) left 0.6em no-repeat; + background: transparent url(../images/expanded.png) left 0.6em no-repeat; } #system-modules .description { cursor: pointer; @@ -29,6 +32,9 @@ text-overflow: ellipsis; white-space: nowrap; } +#system-modules .description .inner.expanded > * { + cursor: auto; +} #system-modules .description .requirements, #system-modules .description .links { display: none; diff --git a/sites/all/modules/contrib/admin/module_filter/images/collapsed.png b/sites/all/modules/contrib/admin/module_filter/images/collapsed.png new file mode 100644 index 00000000..91f3fd40 Binary files /dev/null and b/sites/all/modules/contrib/admin/module_filter/images/collapsed.png differ diff --git a/sites/all/modules/contrib/admin/module_filter/images/expanded.png b/sites/all/modules/contrib/admin/module_filter/images/expanded.png new file mode 100644 index 00000000..46f39ecb Binary files /dev/null and b/sites/all/modules/contrib/admin/module_filter/images/expanded.png differ diff --git a/sites/all/modules/contrib/admin/module_filter/js/module_filter.js b/sites/all/modules/contrib/admin/module_filter/js/module_filter.js index d5f53287..4fcf6e65 100644 --- a/sites/all/modules/contrib/admin/module_filter/js/module_filter.js +++ b/sites/all/modules/contrib/admin/module_filter/js/module_filter.js @@ -265,6 +265,9 @@ $.fn.moduleFilter = function(selector, options) { if (Drupal.settings.moduleFilter.setFocus) { filterInput.focus(); } + if (Drupal.settings.moduleFilter.expandedDescription) { + $('#system-modules td.description .inner.expand').addClass('expanded'); + } filterInput.data('moduleFilter', new Drupal.ModuleFilter.Filter(this, selector, options)); }; diff --git a/sites/all/modules/contrib/admin/module_filter/js/module_filter_tab.js b/sites/all/modules/contrib/admin/module_filter/js/module_filter_tab.js index aa54b983..c62b9ef6 100644 --- a/sites/all/modules/contrib/admin/module_filter/js/module_filter_tab.js +++ b/sites/all/modules/contrib/admin/module_filter/js/module_filter_tab.js @@ -57,7 +57,7 @@ Drupal.behaviors.moduleFilterTabs = { // Build tabs from package title rows. var tabs = '
' . variable_get('uc_credit_policy', t('Your billing information must match the billing address for the credit card entered below or we will be unable to process your payment.')) . '
' + '#prefix' => '', + '#markup' => variable_get('uc_credit_policy', t('Your billing information must match the billing address for the credit card entered below or we will be unable to process your payment.')), + '#suffix' => '
', ); $types = variable_get('uc_credit_accepted_types', implode("\r\n", array(t('Visa'), t('Mastercard'), t('Discover'), t('American Express')))); @@ -714,12 +733,12 @@ function uc_credit_display_number($number) { /** * Caches CC details on a pageload for use in various functions. * - * @param $op + * @param string $op * The cache operation to perform; either 'save', 'load', or 'clear'. - * @param $data + * @param string $data * The encrypted, serialized string containing the CC data. * - * @return + * @return array * An array of credit card details. */ function uc_credit_cache($op, $data = NULL, $encrypted = TRUE) { @@ -809,7 +828,13 @@ function _uc_credit_valid_cvv($cvv) { /** * Validates a credit card number during checkout. * - * Luhn algorithm. See: http://www.merriampark.com/anatomycc.htm + * @param string $number + * Credit card number as a string. + * + * @return bool + * TRUE if card number is valid according to the Luhn algorithm. + * + * @see https://en.wikipedia.org/wiki/Luhn_algorithm */ function _uc_credit_valid_card_number($number) { $id = substr($number, 0, 1); @@ -843,12 +868,12 @@ function _uc_credit_valid_card_number($number) { /** * Validates a start date on a card. * - * @param $month + * @param int $month * The 1 or 2-digit numeric representation of the month, i.e. 1, 6, 12. - * @param $year + * @param int $year * The 4-digit numeric representation of the year, i.e. 2008. * - * @return + * @return bool * TRUE for cards whose start date is blank (both month and year) or in the * past, FALSE otherwise. */ @@ -876,12 +901,12 @@ function _uc_credit_valid_card_start($month, $year) { /** * Validates an expiration date on a card. * - * @param $month + * @param int $month * The 1 or 2-digit numeric representation of the month, i.e. 1, 6, 12. - * @param $year + * @param int $year * The 4-digit numeric representation of the year, i.e. 2008. * - * @return + * @return bool * TRUE for non-expired cards, FALSE for expired. */ function _uc_credit_valid_card_expiration($month, $year) { @@ -899,6 +924,12 @@ function _uc_credit_valid_card_expiration($month, $year) { /** * Validates an issue number on a card; returns TRUE or FALSE. + * + * @param string $issue + * The issue number. + * + * @return bool + * TRUE if the issue number if valid, FALSE otherwise. */ function _uc_credit_valid_card_issue($issue) { if (empty($issue) || (is_numeric($issue) && $issue > 0)) { @@ -914,8 +945,8 @@ function _uc_credit_valid_card_issue($issue) { * Path to key file is stored in system variable 'uc_credit_encryption_path'. * Key file name is stored in constant UC_CREDIT_KEYFILE_NAME. * - * @return - * FALSE if no encryption key is found. + * @return string|false + * Key, or FALSE if no encryption key is found. */ function uc_credit_encryption_key() { static $key = FALSE; @@ -957,6 +988,9 @@ function _uc_credit_save_cc_data_to_order($cc_data, $order_id) { /** * Returns an array of default credit card transaction types. + * + * @return array + * Associative array of transaction types, keyed by defined constant value. */ function uc_credit_transaction_types() { $types = array( @@ -972,7 +1006,7 @@ function uc_credit_transaction_types() { /** * Retrieves the ID of the default credit card gateway. * - * @return + * @return string|false * A string containing the ID of the default gateway or FALSE if none exists * or none have valid credit callbacks. */ @@ -996,14 +1030,14 @@ function uc_credit_default_gateway() { /** * Stores a credit card authorization to an order's data array. * - * @param $order_id + * @param int $order_id * The order associated with the credit card authorization. - * @param $auth_id + * @param string $auth_id * The payment service's ID for the authorization. - * @param $amount + * @param float $amount * The amount that was authorized on the card. * - * @return + * @return array * The entire updated data array for the order. */ function uc_credit_log_authorization($order_id, $auth_id, $amount) { @@ -1029,12 +1063,12 @@ function uc_credit_log_authorization($order_id, $auth_id, $amount) { /** * Logs the capture of a prior authorization to an order's data array. * - * @param $order_id + * @param int $order_id * The order associated with the credit card capture. - * @param $auth_id + * @param string $auth_id * The payment service's ID for the authorization that was captured. * - * @return + * @return array|false * The entire updated data array for the order or FALSE to indicate the * specified authorization was not found. */ @@ -1063,16 +1097,16 @@ function uc_credit_log_prior_auth_capture($order_id, $auth_id) { /** * Logs a credit card reference to an order's data array. * - * @param $order_id + * @param int $order_id * The order associated with the credit card details. - * @param $ref_id + * @param string $ref_id * The payment service's ID for the reference that may be used to charge the * same credit card at a later date. - * @param $cc_number + * @param string $cc_number * The credit card number associated with this reference. Only the last 4 * digits will be stored. * - * @return + * @return array * The entire updated data array for the order. */ function uc_credit_log_reference($order_id, $ref_id, $cc_number) { diff --git a/sites/all/modules/contrib/ecommerce/ubercart/payment/uc_cybersource/uc_cybersource.info b/sites/all/modules/contrib/ecommerce/ubercart/payment/uc_cybersource/uc_cybersource.info index c696e486..2e9297b2 100644 --- a/sites/all/modules/contrib/ecommerce/ubercart/payment/uc_cybersource/uc_cybersource.info +++ b/sites/all/modules/contrib/ecommerce/ubercart/payment/uc_cybersource/uc_cybersource.info @@ -7,9 +7,8 @@ core = 7.x ; Class definitions files[] = uc_cybersource.soap.inc -; Information added by Drupal.org packaging script on 2016-07-16 -version = "7.x-3.10" +; Information added by Drupal.org packaging script on 2019-03-06 +version = "7.x-3.12" core = "7.x" project = "ubercart" -datestamp = "1468644909" - +datestamp = "1551862392" diff --git a/sites/all/modules/contrib/ecommerce/ubercart/payment/uc_cybersource/uc_cybersource.module b/sites/all/modules/contrib/ecommerce/ubercart/payment/uc_cybersource/uc_cybersource.module index 36c546f3..cbf61fc2 100644 --- a/sites/all/modules/contrib/ecommerce/ubercart/payment/uc_cybersource/uc_cybersource.module +++ b/sites/all/modules/contrib/ecommerce/ubercart/payment/uc_cybersource/uc_cybersource.module @@ -13,7 +13,6 @@ * http://growingventuresolutions.com */ - /** * Implements hook_menu(). */ @@ -179,12 +178,15 @@ function uc_cybersource_hop_post() { uc_cart_complete_sale($order); uc_order_comment_save($order_id, 0, t('Payment of @amount @currency submitted through CyberSource with request ID @rid.', array('@amount' => $payment_amount, '@currency' => $payment_currency, '@rid' => $request_id)), 'order', 'payment_received'); break; + case 'ERROR': uc_order_comment_save($order_id, 0, t("Payment error:@reason with request ID @rid", array('@reason' => $reason, '@rid' => '@request_id')), 'admin'); break; + case 'REJECT': uc_order_comment_save($order_id, 0, t("Payment is rejected:@reason with request ID @rid", array('@reason' => $reason, '@rid' => '@request_id')), 'admin'); break; + case 'REVIEW': uc_order_update_status($order_id, 'review'); uc_order_comment_save($order_id, 0, t('Payment is in review & not complete: @reason. Request ID @rid', array('@reason' => $reason, '@rid' => '@request_id')), 'admin'); @@ -533,13 +535,16 @@ function uc_cybersource_charge($order_id, $amount, $data) { case 'american express': $cc_type = '003'; break; + case 'visa': $cc_type = '001'; break; + case 'mastercard': case 'master card': $cc_type = '002'; break; + case 'discover': $cc_type = '004'; break; @@ -1170,7 +1175,7 @@ function uc_cybersource_uc_calculate_tax($order) { if ($reply->reasonCode == '100') { // Add a city tax if applicable. if (floatval($reply->taxReply->totalCityTaxAmount) > 0) { - $result['city'] = (object)array( + $result['city'] = (object) array( 'id' => 'city', 'name' => t('@city city tax', array('@city' => floatval($reply->taxReply->city))), 'amount' => floatval($reply->taxReply->totalCityTaxAmount), @@ -1179,7 +1184,7 @@ function uc_cybersource_uc_calculate_tax($order) { // Add a county tax if applicable. if (floatval($reply->taxReply->totalCountyTaxAmount) > 0) { - $result['county'] = (object)array( + $result['county'] = (object) array( 'id' => 'county', 'name' => t('County tax'), 'amount' => floatval($reply->taxReply->totalCountryTaxAmount), @@ -1188,7 +1193,7 @@ function uc_cybersource_uc_calculate_tax($order) { // Add a district tax if applicable. if (floatval($reply->taxReply->totalDistrictTaxAmount) > 0) { - $result['district'] = (object)array( + $result['district'] = (object) array( 'id' => 'district', 'name' => t('District tax'), 'amount' => floatval($reply->taxReply->totalDistrictTaxAmount), @@ -1197,7 +1202,7 @@ function uc_cybersource_uc_calculate_tax($order) { // Add a state tax if applicable. if (floatval($reply->taxReply->totalStateTaxAmount) > 0) { - $result['state'] = (object)array( + $result['state'] = (object) array( 'id' => 'state', 'name' => t('@state state tax', array('@state' => $reply->taxReply->state)), 'amount' => floatval($reply->taxReply->totalStateTaxAmount), @@ -1215,7 +1220,7 @@ function uc_cybersource_uc_calculate_tax($order) { watchdog('uc_cybersource', 'Tax calculation produced uneven results. Expected a total of @total, received the following: @dump', array('@total' => uc_currency_format($reply->taxReply->totalTaxAmount), '@dump' => '' . print_r($result, TRUE) . ''), WATCHDOG_ERROR); $result = array( - 'total' => (object)array( + 'total' => (object) array( 'id' => 'total', 'name' => t('Tax'), 'amount' => floatval($reply->taxReply->totalTaxAmount), @@ -1310,10 +1315,13 @@ function _uc_cybersource_card_type($cc_number) { else { return '007'; // JCB } + case '4': return '001'; // Visa + case '5': return '002'; // MasterCard + case '6': return '004'; // Discover } @@ -1328,58 +1336,85 @@ function _uc_cybersource_parse_reason_code($code) { switch ($code) { case '100': return t('Successful transaction.'); + case '102': return t('One or more fields in the request are missing or invalid.
' . t('Organize products into packages. Package numbers in multiple shipping types are of the first shipping type they appear in. All packages are given a unique ID when they are saved. Choose the default package "Sep." to automatically create a package for each of the selected quantity of products in that row.') . '
'; - break; } } @@ -445,7 +443,7 @@ function uc_shipping_package_load($package_id) { * Saves a package. */ function uc_shipping_package_save($package) { - $package = (object)$package; + $package = (object) $package; if (!isset($package->package_id)) { $package->package_id = db_insert('uc_packages') @@ -853,9 +851,7 @@ function uc_shipping_uc_order($op, $order, $arg2) { if ($package_count > 0) { return FALSE; } - return TRUE; - break; case 'delete': // Find and delete the shipments. diff --git a/sites/all/modules/contrib/ecommerce/ubercart/shipping/uc_shipping/uc_shipping.rules.inc b/sites/all/modules/contrib/ecommerce/ubercart/shipping/uc_shipping/uc_shipping.rules.inc index 830dfd65..02a23d75 100644 --- a/sites/all/modules/contrib/ecommerce/ubercart/shipping/uc_shipping/uc_shipping.rules.inc +++ b/sites/all/modules/contrib/ecommerce/ubercart/shipping/uc_shipping/uc_shipping.rules.inc @@ -55,7 +55,7 @@ function uc_shipping_rules_data_info() { 'carrier' => array( 'type' => 'text', 'label' => t('Carrier'), - 'description' > t('The company making the delivery.'), + 'description' => t('The company making the delivery.'), ), 'transaction_id' => array( 'type' => 'text', diff --git a/sites/all/modules/contrib/ecommerce/ubercart/shipping/uc_shipping/uc_shipping.tokens.inc b/sites/all/modules/contrib/ecommerce/ubercart/shipping/uc_shipping/uc_shipping.tokens.inc index eaeec562..01cf7b8d 100644 --- a/sites/all/modules/contrib/ecommerce/ubercart/shipping/uc_shipping/uc_shipping.tokens.inc +++ b/sites/all/modules/contrib/ecommerce/ubercart/shipping/uc_shipping/uc_shipping.tokens.inc @@ -5,7 +5,6 @@ * Token hooks for the uc_shipping module. */ - /** * Implements hook_token_info(). */ diff --git a/sites/all/modules/contrib/ecommerce/ubercart/shipping/uc_shipping/views/uc_shipping_handler_field_package_weight.inc b/sites/all/modules/contrib/ecommerce/ubercart/shipping/uc_shipping/views/uc_shipping_handler_field_package_weight.inc index f414cd08..ac73bc7e 100644 --- a/sites/all/modules/contrib/ecommerce/ubercart/shipping/uc_shipping/views/uc_shipping_handler_field_package_weight.inc +++ b/sites/all/modules/contrib/ecommerce/ubercart/shipping/uc_shipping/views/uc_shipping_handler_field_package_weight.inc @@ -12,6 +12,7 @@ * in packages have the same weight unit. */ class uc_shipping_handler_field_package_weight extends uc_product_handler_field_weight { + /** * Overrides views_handler::use_group_by(). * @@ -43,4 +44,5 @@ class uc_shipping_handler_field_package_weight extends uc_product_handler_field_ return uc_weight_format($package->weight, $package->weight_units); } } + } diff --git a/sites/all/modules/contrib/ecommerce/ubercart/shipping/uc_ups/uc_ups.admin.inc b/sites/all/modules/contrib/ecommerce/ubercart/shipping/uc_ups/uc_ups.admin.inc index 20878772..12596f19 100644 --- a/sites/all/modules/contrib/ecommerce/ubercart/shipping/uc_ups/uc_ups.admin.inc +++ b/sites/all/modules/contrib/ecommerce/ubercart/shipping/uc_ups/uc_ups.admin.inc @@ -88,7 +88,7 @@ function uc_ups_admin_settings($form, &$form_state) { '#description' => t('Select the UPS services that are available to customers.'), ); - // Container for quote options + // Container for quote options. $form['uc_ups_quote_options'] = array( '#type' => 'fieldset', '#title' => t('Quote options'), @@ -109,7 +109,7 @@ function uc_ups_admin_settings($form, &$form_state) { '#description' => t('Indicate whether each product is quoted as shipping separately or all in one package. Orders with one kind of product will still use the package quantity to determine the number of packages needed, however.'), ); - // Form to select package types + // Form to select package types. $form['uc_ups_quote_options']['uc_ups_pkg_type'] = array( '#type' => 'select', '#title' => t('Default Package Type'), @@ -137,7 +137,7 @@ function uc_ups_admin_settings($form, &$form_state) { '#description' => t('Is your UPS account receiving negotiated rates on shipments?'), ); - // Form to select pickup type + // Form to select pickup type. $form['uc_ups_quote_options']['uc_ups_pickup_type'] = array( '#type' => 'select', '#title' => t('Pickup type'), @@ -181,7 +181,7 @@ function uc_ups_admin_settings($form, &$form_state) { '#description' => t('When enabled, the quotes presented to the customer will include the cost of insurance for the full sales price of all products in the order.'), ); - // Container for markup forms + // Container for markup forms. $form['uc_ups_markups'] = array( '#type' => 'fieldset', '#title' => t('Markups'), @@ -191,7 +191,7 @@ function uc_ups_admin_settings($form, &$form_state) { '#group' => 'ups-settings', ); - // Form to select type of rate markup + // Form to select type of rate markup. $form['uc_ups_markups']['uc_ups_rate_markup_type'] = array( '#type' => 'select', '#title' => t('Rate markup type'), @@ -203,7 +203,7 @@ function uc_ups_admin_settings($form, &$form_state) { ), ); - // Form to select rate markup amount + // Form to select rate markup amount. $form['uc_ups_markups']['uc_ups_rate_markup'] = array( '#type' => 'textfield', '#title' => t('Shipping rate markup'), @@ -211,7 +211,7 @@ function uc_ups_admin_settings($form, &$form_state) { '#description' => t('Markup shipping rate quote by currency amount, percentage, or multiplier.'), ); - // Form to select type of weight markup + // Form to select type of weight markup. $form['uc_ups_markups']['uc_ups_weight_markup_type'] = array( '#type' => 'select', '#title' => t('Weight markup type'), @@ -224,7 +224,7 @@ function uc_ups_admin_settings($form, &$form_state) { '#disabled' => TRUE, ); - // Form to select weight markup amount + // Form to select weight markup amount. $form['uc_ups_markups']['uc_ups_weight_markup'] = array( '#type' => 'textfield', '#title' => t('Shipping weight markup'), @@ -233,7 +233,7 @@ function uc_ups_admin_settings($form, &$form_state) { '#disabled' => TRUE, ); - // Container for label printing + // Container for label printing. $form['uc_ups_labels'] = array( '#type' => 'fieldset', '#title' => t('Label Printing'), @@ -246,7 +246,7 @@ function uc_ups_admin_settings($form, &$form_state) { $period = drupal_map_assoc(array(86400, 302400, 604800, 1209600, 2419200, 0), 'format_interval'); $period[0] = t('Forever'); - // Form to select how long labels stay on server + // Form to select how long labels stay on server. $form['uc_ups_labels']['uc_ups_label_lifetime'] = array( '#type' => 'select', '#title' => t('Label lifetime'), diff --git a/sites/all/modules/contrib/ecommerce/ubercart/shipping/uc_ups/uc_ups.info b/sites/all/modules/contrib/ecommerce/ubercart/shipping/uc_ups/uc_ups.info index fbf7c10c..0d205a06 100644 --- a/sites/all/modules/contrib/ecommerce/ubercart/shipping/uc_ups/uc_ups.info +++ b/sites/all/modules/contrib/ecommerce/ubercart/shipping/uc_ups/uc_ups.info @@ -6,9 +6,8 @@ core = 7.x configure = admin/store/settings/quotes/settings/ups -; Information added by Drupal.org packaging script on 2016-07-16 -version = "7.x-3.10" +; Information added by Drupal.org packaging script on 2019-03-06 +version = "7.x-3.12" core = "7.x" project = "ubercart" -datestamp = "1468644909" - +datestamp = "1551862392" diff --git a/sites/all/modules/contrib/ecommerce/ubercart/shipping/uc_ups/uc_ups.module b/sites/all/modules/contrib/ecommerce/ubercart/shipping/uc_ups/uc_ups.module index 9d39bbda..b694a953 100644 --- a/sites/all/modules/contrib/ecommerce/ubercart/shipping/uc_ups/uc_ups.module +++ b/sites/all/modules/contrib/ecommerce/ubercart/shipping/uc_ups/uc_ups.module @@ -387,6 +387,7 @@ function uc_ups_shipping_quote($packages, $origin, $destination, $ups_service) { $units = 'LBS'; $unit_name = 'Pounds'; break; + case 'cm': $units = 'KGS'; $unit_name = 'Kilograms'; @@ -404,6 +405,7 @@ function uc_ups_shipping_quote($packages, $origin, $destination, $ups_service) { case 'in': $weight_factor = uc_weight_conversion($package->weight_units, 'lb'); break; + case 'cm': $weight_factor = uc_weight_conversion($package->weight_units, 'kg'); break; @@ -663,7 +665,7 @@ function uc_ups_quote($products, $details, $method) { if (!isset($product->pkg_qty) || !$product->pkg_qty) { $product->pkg_qty = 1; } - $num_of_pkgs = (int)($product->qty / $product->pkg_qty); + $num_of_pkgs = (int) ($product->qty / $product->pkg_qty); // Grab some product properties directly from the (cached) product // data. They are not normally available here because the $product @@ -706,7 +708,7 @@ function uc_ups_quote($products, $details, $method) { return array(); } - $dest = (object)$details; + $dest = (object) $details; foreach ($packages as $key => $ship_packages) { $orig = $addresses[$key]; @@ -727,9 +729,9 @@ function uc_ups_quote($products, $details, $method) { if (isset($response->Response->Error)) { foreach ($response->Response->Error as $error) { if (user_access('configure quotes') && variable_get('uc_quote_display_debug', FALSE)) { - $debug_data[$ups_service]['error'][] = (string)$error->ErrorSeverity . ' ' . (string)$error->ErrorCode . ': ' . (string)$error->ErrorDescription; + $debug_data[$ups_service]['error'][] = (string) $error->ErrorSeverity . ' ' . (string) $error->ErrorCode . ': ' . (string) $error->ErrorDescription; } - if (strpos((string)$error->ErrorSeverity, 'Hard') !== FALSE) { + if (strpos((string) $error->ErrorSeverity, 'Hard') !== FALSE) { // All or nothing quote. If some products can't be shipped by // a certain service, no quote is given for that service. If // that means no quotes are given at all, they'd better call in. @@ -744,12 +746,12 @@ function uc_ups_quote($products, $details, $method) { if (isset($response->RatedShipment->NegotiatedRates)) { $charge = $response->RatedShipment->NegotiatedRates->NetSummaryCharges->GrandTotal; } - if (!isset($charge->CurrencyCode) || (string)$charge->CurrencyCode == variable_get('uc_currency_code', "USD")) { + if (!isset($charge->CurrencyCode) || (string) $charge->CurrencyCode == variable_get('uc_currency_code', "USD")) { // Markup rate before customer sees it. if (!isset($quotes[$ups_service]['rate'])) { $quotes[$ups_service]['rate'] = 0; } - $rate = uc_ups_rate_markup((string)$charge->MonetaryValue); + $rate = uc_ups_rate_markup((string) $charge->MonetaryValue); $quotes[$ups_service]['rate'] += $rate; } } @@ -847,20 +849,20 @@ function uc_ups_void_shipment($shipment_number, $tracking_numbers = array()) { $response = new SimpleXMLElement($resp->data); if (isset($response->Response)) { if (isset($response->Response->ResponseStatusCode)) { - $success = (string)$response->Response->ResponseStatusCode; + $success = (string) $response->Response->ResponseStatusCode; } if (isset($response->Response->Error)) { foreach ($response->Response->Error as $error) { - drupal_set_message((string)$error->ErrorSeverity . ' ' . (string)$error->ErrorCode . ': ' . (string)$error->ErrorDescription, 'error'); + drupal_set_message((string) $error->ErrorSeverity . ' ' . (string) $error->ErrorCode . ': ' . (string) $error->ErrorDescription, 'error'); } } } if (isset($response->Status)) { if (isset($response->Status->StatusType)) { - $success = (string)$response->Status->StatusType->Code; + $success = (string) $response->Status->StatusType->Code; } } - return (bool)$success; + return (bool) $success; } /** @@ -880,8 +882,10 @@ function uc_ups_rate_markup($rate) { switch ($type) { case 'percentage': return $rate + $rate * floatval($markup) / 100; + case 'multiplier': return $rate * floatval($markup); + case 'currency': return $rate + floatval($markup); } diff --git a/sites/all/modules/contrib/ecommerce/ubercart/shipping/uc_ups/uc_ups.ship.inc b/sites/all/modules/contrib/ecommerce/ubercart/shipping/uc_ups/uc_ups.ship.inc index 06a4bece..fd1f6f2c 100644 --- a/sites/all/modules/contrib/ecommerce/ubercart/shipping/uc_ups/uc_ups.ship.inc +++ b/sites/all/modules/contrib/ecommerce/ubercart/shipping/uc_ups/uc_ups.ship.inc @@ -5,7 +5,6 @@ * UPS functions for label generation. */ - /** * Shipment creation callback. * @@ -31,7 +30,7 @@ function uc_ups_fulfill_order($form, &$form_state, $order, $package_ids) { '#type' => 'fieldset', '#title' => t('Packages'), '#collapsible' => TRUE, - '#tree' => TRUE + '#tree' => TRUE, ); foreach ($package_ids as $id) { $package = uc_shipping_package_load($id); @@ -42,14 +41,14 @@ function uc_ups_fulfill_order($form, &$form_state, $order, $package_ids) { } } // Create list of products and get a representative product (last one in - // the loop) to use for some default values + // the loop) to use for some default values. $product_list = array(); $declared_value = 0; foreach ($package->products as $product) { $product_list[] = $product->qty . ' x ' . $product->model; $declared_value += $product->qty * $product->price; } - // Use last product in package to determine package type + // Use last product in package to determine package type. $ups_data = db_query("SELECT pkg_type FROM {uc_ups_products} WHERE nid = :nid", array(':nid' => $product->nid))->fetchAssoc(); $product->ups = $ups_data; $pkg_form = array( @@ -151,7 +150,7 @@ function uc_ups_fulfill_order($form, &$form_state, $order, $package_ids) { $form['destination'][$field]['#required'] = TRUE; } - // Determine shipping option chosen by the customer + // Determine shipping option chosen by the customer. $method = $order->quote['method']; $methods = module_invoke_all('uc_shipping_method'); if (isset($methods[$method])) { @@ -159,14 +158,14 @@ function uc_ups_fulfill_order($form, &$form_state, $order, $package_ids) { $method = $services[$order->quote['accessorials']]; } - // Container for shipment data + // Container for shipment data. $form['shipment'] = array( '#type' => 'fieldset', '#title' => t('Shipment data'), '#collapsible' => TRUE, ); - // Inform user of customer's shipping choice + // Inform user of customer's shipping choice. $form['shipment']['shipping_choice'] = array( '#type' => 'markup', '#prefix' => '' . print_r($var, TRUE) . ''); } + } diff --git a/sites/all/modules/contrib/ecommerce/ubercart/uc_attribute/tests/uc_attribute_checkout.test b/sites/all/modules/contrib/ecommerce/ubercart/uc_attribute/tests/uc_attribute_checkout.test index 6efdcb3a..5ee1d3d7 100644 --- a/sites/all/modules/contrib/ecommerce/ubercart/uc_attribute/tests/uc_attribute_checkout.test +++ b/sites/all/modules/contrib/ecommerce/ubercart/uc_attribute/tests/uc_attribute_checkout.test @@ -5,6 +5,9 @@ * Ubercart attribute checkout tests. */ +/** + * Tests the product attribute API. + */ class UbercartAttributeCheckoutTestCase extends UbercartTestHelper { public static function getInfo() { @@ -26,7 +29,7 @@ class UbercartAttributeCheckoutTestCase extends UbercartTestHelper { /** * Tests that product in cart has the selected attribute option. */ - function testAttributeAddToCart() { + public function testAttributeAddToCart() { for ($display = 0; $display <= 3; ++$display) { // Set up an attribute. $data = array( diff --git a/sites/all/modules/contrib/ecommerce/ubercart/uc_attribute/uc_attribute.admin.inc b/sites/all/modules/contrib/ecommerce/ubercart/uc_attribute/uc_attribute.admin.inc index f5b8ce69..8c60466a 100644 --- a/sites/all/modules/contrib/ecommerce/ubercart/uc_attribute/uc_attribute.admin.inc +++ b/sites/all/modules/contrib/ecommerce/ubercart/uc_attribute/uc_attribute.admin.inc @@ -64,6 +64,7 @@ function uc_attribute_admin() { * Form builder for product attributes. * * @see uc_attribute_form_submit() + * * @ingroup forms */ function uc_attribute_form($form, &$form_state, $attribute = NULL) { @@ -234,6 +235,7 @@ function uc_attribute_delete_confirm_submit($form, &$form_state) { * * @see uc_attribute_options_form_validate() * @see uc_attribute_options_form_submit() + * * @ingroup forms */ function uc_attribute_options_form($form, &$form_state, $attribute) { @@ -263,7 +265,7 @@ function uc_attribute_options_form($form, &$form_state, $attribute) { '#price' => $data->price, ), 'weight' => array( - '#markup' => (string)$data->weight, + '#markup' => (string) $data->weight, ), 'ordering' => array( '#type' => 'weight', @@ -358,6 +360,7 @@ function theme_uc_attribute_options_form($variables) { * * @see uc_attribute_option_form_validate() * @see uc_attribute_option_form_submit() + * * @ingroup forms */ function uc_attribute_option_form($form, &$form_state, $attribute, $option = NULL) { @@ -538,6 +541,7 @@ function uc_attribute_option_delete_confirm_submit($form, &$form_state) { * * @see uc_object_attributes_form_submit() * @see theme_uc_object_attributes_form() + * * @ingroup forms */ function uc_object_attributes_form($form, &$form_state, $object, $type, $view = 'overview') { @@ -551,6 +555,7 @@ function uc_object_attributes_form($form, &$form_state, $object, $type, $view = drupal_set_title($class->name); $attributes = uc_class_get_attributes($id); break; + case 'product': default: $product = $object; @@ -595,7 +600,7 @@ function uc_object_attributes_form($form, &$form_state, $object, $type, $view = '#maxlength' => 255, ), 'option' => array( - '#markup' => $option ? (check_plain($option->name) . ' (' . theme('uc_price', array('price' => $option->price)) . ')' ) : t('n/a'), + '#markup' => $option ? (check_plain($option->name) . ' (' . theme('uc_price', array('price' => $option->price)) . ')') : t('n/a'), ), 'required' => array( '#type' => 'checkbox', @@ -644,7 +649,7 @@ function uc_object_attributes_form($form, &$form_state, $object, $type, $view = '#title' => t('Attributes'), '#options' => count($unused_attributes) > 0 ? $unused_attributes : array(t('No attributes left to add.')), '#disabled' => count($unused_attributes) == 0 ? TRUE : FALSE, - '#weight' => -1 + '#weight' => -1, ); $form['actions'] = array('#type' => 'actions'); $form['actions']['add'] = array( @@ -679,6 +684,7 @@ function uc_object_attributes_form($form, &$form_state, $object, $type, $view = * - form: A render element representing the form. * * @see uc_object_attributes_form() + * * @ingroup themeable */ function theme_uc_object_attributes_form($variables) { @@ -852,6 +858,7 @@ function uc_object_attributes_form_submit($form, &$form_state) { * @see uc_object_options_form_validate() * @see uc_object_options_form_submit() * @see theme_uc_object_options_form() + * * @ingroup forms */ function uc_object_options_form($form, &$form_state, $object, $type) { @@ -1003,6 +1010,7 @@ function uc_object_options_form($form, &$form_state, $object, $type) { * - form: A render element representing the form. * * @see uc_object_options_form() + * * @ingroup themeable */ function theme_uc_object_options_form($variables) { @@ -1084,7 +1092,7 @@ function theme_uc_product_attributes($variables) { foreach (element_children($attributes) as $key) { $optionstr = ''; - foreach ((array)$attributes[$key]['#options'] as $option) { + foreach ((array) $attributes[$key]['#options'] as $option) { // We only need to allow translation from the second option onward if (empty($optionstr)) { $optionstr .= $option; @@ -1203,6 +1211,7 @@ function uc_object_options_form_submit($form, &$form_state) { * Form builder: associate option combinations with a product variant's SKU. * * @see uc_product_adjustments_form_submit() + * * @ingroup forms */ function uc_product_adjustments_form($form, &$form_state, $node) { @@ -1260,7 +1269,7 @@ function uc_product_adjustments_form($form, &$form_state, $node) { $num_prod_attr = count($attribute_ids); if ($num_prod_attr) { - // Get previous values + // Get previous values. $old_vals = db_query("SELECT * FROM {uc_product_adjustments} WHERE nid = :nid", array(':nid' => $nid))->fetchAll(); $result = $query->execute(); diff --git a/sites/all/modules/contrib/ecommerce/ubercart/uc_attribute/uc_attribute.info b/sites/all/modules/contrib/ecommerce/ubercart/uc_attribute/uc_attribute.info index f69b2ad6..4fb83d12 100644 --- a/sites/all/modules/contrib/ecommerce/ubercart/uc_attribute/uc_attribute.info +++ b/sites/all/modules/contrib/ecommerce/ubercart/uc_attribute/uc_attribute.info @@ -8,9 +8,8 @@ core = 7.x files[] = tests/uc_attribute.test files[] = tests/uc_attribute_checkout.test -; Information added by Drupal.org packaging script on 2016-07-16 -version = "7.x-3.10" +; Information added by Drupal.org packaging script on 2019-03-06 +version = "7.x-3.12" core = "7.x" project = "ubercart" -datestamp = "1468644909" - +datestamp = "1551862392" diff --git a/sites/all/modules/contrib/ecommerce/ubercart/uc_attribute/uc_attribute.module b/sites/all/modules/contrib/ecommerce/ubercart/uc_attribute/uc_attribute.module index fd63d644..00cd2071 100644 --- a/sites/all/modules/contrib/ecommerce/ubercart/uc_attribute/uc_attribute.module +++ b/sites/all/modules/contrib/ecommerce/ubercart/uc_attribute/uc_attribute.module @@ -11,7 +11,6 @@ * instead of listing each combination separately. */ - /** * Implements hook_help(). */ @@ -20,6 +19,7 @@ function uc_attribute_help($path, $arg) { // Help messages for the attributes overview on products and classes. case 'node/%/edit/attributes': return '
' . t('Add attributes to this product using the add attributes form. You may then adjust the settings for these attributes on this page and go on to configure their options in the Options tab.', array('!url' => url('node/' . $arg[1] . '/edit/attributes/add'))) . '
'; + case 'admin/store/products/classes/%/attributes': return '' . t('Add attributes to the product class using the add attributes form. You may then adjust the settings for these attributes on this page and go on to configure their options in the Options tab.', array('!url' => url('admin/store/products/classes/' . $arg[4] . '/attributes/add'))) . '
'; @@ -287,7 +287,8 @@ function uc_attribute_form_uc_product_settings_form_alter(&$form, &$form_state) '#type' => 'radios', '#title' => t('Option price format'), '#default_value' => variable_get('uc_attribute_option_price_format', 'adjustment'), - '#options' => array('none' => t('Do not display'), + '#options' => array( + 'none' => t('Do not display'), 'adjustment' => t('Display price adjustment'), 'total' => t('Display total price'), ), @@ -385,7 +386,7 @@ function uc_attribute_node_insert($node) { 'default_option', )) ->condition('pcid', $node->type); - // SELECT $node->nid AS nid + // SELECT $node->nid AS nid. $select->addExpression(':nid', 'nid', array(':nid' => $node->nid)); db_insert('uc_product_attributes') @@ -453,6 +454,12 @@ function uc_attribute_node_update_index($node) { /** * Implements hook_uc_product_models(). + * + * @param int $nid + * Node number for product type node. + * + * @return array + * Array of SKUs (model numbers) for this $nid. */ function uc_attribute_uc_product_models($nid) { // Get all the SKUs for all the attributes on this node. @@ -594,18 +601,18 @@ function uc_attribute_uc_product_description($product) { * logic; that is, we could make uc_attribute load call this function and allow * this function to minimize the number of queries necessary. -cha0s * - * @param $aids + * @param array $aids * Attribute IDs to load. - * @param $type + * @param string $type * The type of attribute. 'product', or 'class'. Any other type will fetch * a base attribute. - * @param $id + * @param int $id * The ID of the product/class this attribute belongs to. * - * @return + * @return array * An array of loaded attributes. */ -function uc_attribute_load_multiple($aids = array(), $type = '', $id = NULL) { +function uc_attribute_load_multiple(array $aids = array(), $type = '', $id = NULL) { $sql = uc_attribute_type_info($type); // Product/class attributes. @@ -652,15 +659,15 @@ function uc_attribute_load_multiple($aids = array(), $type = '', $id = NULL) { /** * Loads an attribute from the database. * - * @param $aid + * @param int $aid * The ID of the attribute. - * @param $type + * @param int $id + * The ID of the product/class this attribute belongs to. + * @param string $type * The type of attribute. 'product', or 'class'. Any other type will fetch * a base attribute. - * @param $id - * The ID of the product/class this attribute belongs to. * - * @return + * @return object|false * The attribute object, or FALSE if it doesn't exist. */ function uc_attribute_load($aid, $id = NULL, $type = '') { @@ -669,7 +676,6 @@ function uc_attribute_load($aid, $id = NULL, $type = '') { switch ($type) { case 'product': case 'class': - // Read attribute data. $query = db_select('uc_attributes', 'a') ->fields('a', array('aid', 'name', 'description')) @@ -685,7 +691,9 @@ function uc_attribute_load($aid, $id = NULL, $type = '') { $attribute = $query->execute()->fetchObject(); // Don't try to build it further if it failed already. - if (!$attribute) return FALSE; + if (!$attribute) { + return FALSE; + } // Set any missing defaults. foreach (array('ordering', 'required', 'display', 'label') as $field) { @@ -707,10 +715,9 @@ function uc_attribute_load($aid, $id = NULL, $type = '') { ->orderBy('ao.name'); $result = $query->execute(); - break; + break; default: - // Read attribute and option data. $attribute = db_query("SELECT * FROM {uc_attributes} WHERE aid = :aid", array(':aid' => $aid))->fetchObject(); $result = db_query("SELECT * FROM {uc_attribute_options} WHERE aid = :aid ORDER BY ordering, name", array(':aid' => $aid)); @@ -719,8 +726,7 @@ function uc_attribute_load($aid, $id = NULL, $type = '') { if (!$attribute) { return FALSE; } - - break; + break; } // Got an attribute? @@ -739,10 +745,10 @@ function uc_attribute_load($aid, $id = NULL, $type = '') { /** * Fetches an array of attribute objects that belong to a product. * - * @param $nid + * @param int $nid * Product whose attributes to load. * - * @return + * @return object[] * The array of attribute objects. */ function uc_attribute_load_product_attributes($nid) { @@ -752,10 +758,10 @@ function uc_attribute_load_product_attributes($nid) { /** * Saves an attribute object to the database. * - * @param $attribute + * @param object $attribute * The attribute object to save. * - * @return + * @return int * The integer result from drupal_write_record(). */ function uc_attribute_save(&$attribute) { @@ -767,10 +773,10 @@ function uc_attribute_save(&$attribute) { /** * Deletes an attribute from the database. * - * @param $aid + * @param int $aid * Attribute ID to delete. * - * @return + * @return int * The Drupal SAVED_DELETED flag. */ function uc_attribute_delete($aid) { @@ -794,10 +800,10 @@ function uc_attribute_delete($aid) { /** * Loads an attribute option from the database. * - * @param $oid + * @param int $oid * Option ID to load. * - * @return + * @return object * The attribute option object. */ function uc_attribute_option_load($oid) { @@ -807,10 +813,10 @@ function uc_attribute_option_load($oid) { /** * Saves an attribute object to the database. * - * @param $option + * @param object $option * The attribute option object to save. * - * @return + * @return int * The integer result from drupal_write_record(). */ function uc_attribute_option_save(&$option) { @@ -822,10 +828,10 @@ function uc_attribute_option_save(&$option) { /** * Deletes an attribute option from the database. * - * @param $oid + * @param int $oid * Option ID to delete. * - * @return + * @return int * The Drupal SAVED_DELETED flag. */ function uc_attribute_option_delete($oid) { @@ -848,14 +854,14 @@ function uc_attribute_option_delete($oid) { * * @param &$attribute * The product/class attribute. - * @param $type + * @param string $type * Is this a product or a class? - * @param $id + * @param string $id * The product/class ID. - * @param $save_options + * @param bool $save_options * Save the product/class attribute's options, too? * - * @return + * @return int * The integer result from drupal_write_record(). */ function uc_attribute_subject_save(&$attribute, $type, $id, $save_options = FALSE) { @@ -895,14 +901,14 @@ function uc_attribute_subject_save(&$attribute, $type, $id, $save_options = FALS /** * Deletes an attribute and all options associated with it. * - * @param $aid + * @param int $aid * The base attribute ID. - * @param $type + * @param string $type * Is this a product or a class? * @param $id * The product/class ID. * - * @return + * @return int * The Drupal SAVED_DELETED flag. */ function uc_attribute_subject_delete($aid, $type, $id = NULL) { @@ -944,14 +950,14 @@ function uc_attribute_subject_delete($aid, $type, $id = NULL) { /** * Loads a product/class attribute option. * - * @param $oid + * @param int $oid * The product/class attribute option ID. - * @param $type + * @param string $type * Is this a product or a class? - * @param $id + * @param int $id * The product/class ID. * - * @return + * @return object * An object containing the product/class attribute option. */ function uc_attribute_subject_option_load($oid, $type, $id) { @@ -974,12 +980,12 @@ function uc_attribute_subject_option_load($oid, $type, $id) { * * @param &$option * The product/class attribute option. - * @param $type + * @param string $type * Is this a product or a class? - * @param $id + * @param int $id * The product/class ID. * - * @return + * @return int * The integer result from drupal_write_record(). */ function uc_attribute_subject_option_save(&$option, $type, $id) { @@ -1000,12 +1006,12 @@ function uc_attribute_subject_option_save(&$option, $type, $id) { * * @param $oid * The base attribute's option ID. - * @param $type + * @param string $type * Is this a product or a class? - * @param $id + * @param int $id * The product/class ID. * - * @return + * @return int * The Drupal SAVED_DELETED flag. */ function uc_attribute_subject_option_delete($oid, $type, $id = NULL, $adjustments = TRUE) { @@ -1037,14 +1043,14 @@ function uc_attribute_subject_option_delete($oid, $type, $id = NULL, $adjustment /** * Deletes an attribute adjustment. * - * @param $fields + * @param array $fields * Fields used to build a condition to delete adjustments against. Fields * currently handled are 'aid', 'oid', and 'nid'. * - * @return + * @return int * The Drupal SAVED_DELETED flag. */ -function uc_attribute_adjustments_delete($fields) { +function uc_attribute_adjustments_delete(array $fields) { // Build the serialized string to match against adjustments. $match = ''; if (!empty($fields['aid'])) { @@ -1067,7 +1073,7 @@ function uc_attribute_adjustments_delete($fields) { $query->condition('nid', $fields['nid']); } - // Delete what's necessary, + // Delete what's necessary. if ($query->conditions()) { $query->execute(); } @@ -1078,14 +1084,14 @@ function uc_attribute_adjustments_delete($fields) { /** * Checks if a product/class attribute exists. * - * @param $aid + * @param int $aid * The base attribute ID. - * @param $id - * The product/class attribute's ID. - * @param $type + * @param string $type * Is this a product or a class? + * @param int $id + * The product/class attribute's ID. * - * @return + * @return bool * TRUE if the attribute exists. */ function uc_attribute_subject_exists($aid, $type, $id) { @@ -1100,14 +1106,14 @@ function uc_attribute_subject_exists($aid, $type, $id) { /** * Checks if a product/class attribute option exists. * - * @param $oid + * @param int $oid * The base attribute option ID. - * @param $id + * @param int $id * The product/class attribute option's ID. - * @param $type + * @param string $type * Is this a product or a class? * - * @return + * @return bool * TRUE if the attribute option exists. */ function uc_attribute_subject_option_exists($oid, $type, $id) { @@ -1122,10 +1128,10 @@ function uc_attribute_subject_option_exists($oid, $type, $id) { /** * Returns a list of names to abstract queries between products and classes. * - * @param $type + * @param string $type * Is this a product or a class? * - * @return + * @return array * Array of information helpful for creating SQL queries dealing * with attributes. */ @@ -1137,7 +1143,6 @@ function uc_attribute_type_info($type) { 'opt_table' => 'uc_product_options', 'id' => 'nid', ); - break; case 'class': return array( @@ -1145,12 +1150,17 @@ function uc_attribute_type_info($type) { 'opt_table' => 'uc_class_attribute_options', 'id' => 'pcid', ); - break; } } /** * Loads all attributes associated with a product node. + * + * @param int $nid + * The product node id. + * + * @return array + * The attributes. */ function uc_product_get_attributes($nid) { $attributes = array(); @@ -1165,6 +1175,12 @@ function uc_product_get_attributes($nid) { /** * Loads all attributes associated with a product class. + * + * @param int $pcid + * The product class id. + * + * @return array + * The attributes. */ function uc_class_get_attributes($pcid) { $attributes = array(); @@ -1180,10 +1196,10 @@ function uc_class_get_attributes($pcid) { /** * Gets the options chosen for a product that is in the cart. * - * @param $item + * @param mixed $item * An element of the array returned by uc_cart_get_contents. * - * @return + * @return array * Array of options chosen by a customer, indexed by attribute ids. Each * element stores the attribute name and the option object chosen. */ @@ -1204,9 +1220,9 @@ function _uc_cart_product_get_options($item) { // Only discrete options can affect the price of an item. if ($attribute->display && count($attribute->options)) { // There may be many selected options, or just one. - foreach ((array)$selected as $oid) { + foreach ((array) $selected as $oid) { if ($oid > 0) { - $options[$index] = (array)$attribute->options[$oid]; + $options[$index] = (array) $attribute->options[$oid]; $options[$index]['attribute'] = $name; $index++; } @@ -1262,18 +1278,21 @@ function uc_attribute_option_ajax($form, $form_state) { * The unique id to use to wrap these form elements. * @param &$product * The product node for which the attribute form elements are to be attached. - * @param $use_ajax + * @param bool $use_ajax * TRUE to add ajax to the form. Note that ajax may be added even if this is * FALSE, if there are multiple attributes and one or more of them is set to * display total price. * + * @return array + * Form API array with attribute elements to add to the product form. + * * @see theme_uc_attribute_add_to_cart() * @see uc_attribute_option_ajax() */ function _uc_attribute_alter_form($id, &$product, $use_ajax) { // If the product doesn't have attributes, return the form as it is. if (empty($product->attributes) || !is_array($product->attributes)) { - return NULL; + return array(); } $nid = $product->nid; @@ -1286,7 +1305,8 @@ function _uc_attribute_alter_form($id, &$product, $use_ajax) { $product->data = array(); } - // If the form is being built for the first time, populate attributes with their default values. + // If the form is being built for the first time, populate attributes + // with their default values. if (!isset($product->data['attributes'])) { $values = array(); foreach ($priced_attributes as $aid) { @@ -1386,9 +1406,11 @@ function _uc_attribute_alter_form($id, &$product, $use_ajax) { case 1: $attr_type = 'select'; break; + case 2: $attr_type = 'radios'; break; + case 3: $attr_type = 'checkboxes'; $attribute->default_option = array(); @@ -1436,6 +1458,9 @@ function _uc_attribute_alter_form($id, &$product, $use_ajax) { /** * Returns an array of display types used as options when creating attributes. + * + * @return array + * Array of display types used as options when creating attributes. */ function _uc_attribute_display_types() { return array( @@ -1449,10 +1474,10 @@ function _uc_attribute_display_types() { /** * Gets the price affecting attributes for a product. * - * @param $nid + * @param int $nid * The nid of a product. * - * @return + * @return array * Array of attribute ids that have price affecting options. */ function uc_attribute_priced_attributes($nid) { @@ -1472,13 +1497,13 @@ function uc_attribute_priced_attributes($nid) { * The NULL return value is typically used by forms so they know to hide the * #title property of the element. * - * @param $attribute + * @param object $attribute * Attribute object. - * @param $title + * @param bool $title * TRUE indicates the function is to return the attribute name when its label * is set to '' . t('To keep track of stock for a particular product SKU, make sure it is marked as active and enter a stock value. When the stock level drops below the threshold value, you can be notified based on your stock settings.') . '
'; + case 'admin/store/reports/stock': case 'admin/store/reports/stock/threshold': return '' . t('This is the list of product SKUs that are currently active. Stock levels below their threshold have highlighted rows. Toggle the checkbox below to alter which stock levels are shown.') . '
'; @@ -92,7 +90,7 @@ function uc_stock_permission() { return array( 'administer product stock' => array( 'title' => t('Administer product stock'), - ) + ), ); } diff --git a/sites/all/modules/contrib/ecommerce/ubercart/uc_stock/uc_stock.variable.inc b/sites/all/modules/contrib/ecommerce/ubercart/uc_stock/uc_stock.variable.inc index 3692bdd4..bc997aba 100644 --- a/sites/all/modules/contrib/ecommerce/ubercart/uc_stock/uc_stock.variable.inc +++ b/sites/all/modules/contrib/ecommerce/ubercart/uc_stock/uc_stock.variable.inc @@ -5,7 +5,6 @@ * Variable module hook implementations. */ - /** * Implements hook_variable_group_info(). */ diff --git a/sites/all/modules/contrib/ecommerce/ubercart/uc_stock/views/uc_stock_handler_filter_below_threshold.inc b/sites/all/modules/contrib/ecommerce/ubercart/uc_stock/views/uc_stock_handler_filter_below_threshold.inc index 9e75178b..82510375 100644 --- a/sites/all/modules/contrib/ecommerce/ubercart/uc_stock/views/uc_stock_handler_filter_below_threshold.inc +++ b/sites/all/modules/contrib/ecommerce/ubercart/uc_stock/views/uc_stock_handler_filter_below_threshold.inc @@ -17,4 +17,5 @@ class uc_stock_handler_filter_below_threshold extends views_handler_filter_boole $this->ensure_my_table(); $this->query->add_where_expression($this->options['group'], "$this->table_alias.stock " . (empty($this->value) ? '>=' : '<') . " $this->table_alias.threshold"); } + } diff --git a/sites/all/modules/contrib/ecommerce/ubercart/uc_store/classes/address.inc b/sites/all/modules/contrib/ecommerce/ubercart/uc_store/classes/address.inc index 09bb42ab..d5c651b8 100644 --- a/sites/all/modules/contrib/ecommerce/ubercart/uc_store/classes/address.inc +++ b/sites/all/modules/contrib/ecommerce/ubercart/uc_store/classes/address.inc @@ -43,7 +43,6 @@ class UcAddress { /** Email address. */ public $email = ''; - /** * Constructor. * diff --git a/sites/all/modules/contrib/ecommerce/ubercart/uc_store/classes/encrypt.inc b/sites/all/modules/contrib/ecommerce/ubercart/uc_store/classes/encrypt.inc index 54c0dde0..88a4522f 100644 --- a/sites/all/modules/contrib/ecommerce/ubercart/uc_store/classes/encrypt.inc +++ b/sites/all/modules/contrib/ecommerce/ubercart/uc_store/classes/encrypt.inc @@ -30,7 +30,6 @@ class UbercartEncryption { protected $adj = 1.75; protected $mod = 3; - /** * Decrypts cyphertext. * @@ -269,4 +268,5 @@ class UbercartEncryption { return $array; } + } diff --git a/sites/all/modules/contrib/ecommerce/ubercart/uc_store/countries/afghanistan_4_1.cif b/sites/all/modules/contrib/ecommerce/ubercart/uc_store/countries/afghanistan_4_1.cif index f3a51dc4..9e25d30b 100644 --- a/sites/all/modules/contrib/ecommerce/ubercart/uc_store/countries/afghanistan_4_1.cif +++ b/sites/all/modules/contrib/ecommerce/ubercart/uc_store/countries/afghanistan_4_1.cif @@ -63,11 +63,11 @@ function afghanistan_install() { // Set address format uc_set_address_format( 4, - "!company\r\n". - "!first_name !last_name\r\n". - "!street1\r\n". - "!street2\r\n". - "!city, !zone_code !postal_code\r\n". + "!company\r\n" . + "!first_name !last_name\r\n" . + "!street1\r\n" . + "!street2\r\n" . + "!city, !zone_code !postal_code\r\n" . "!country_name_if" ); } diff --git a/sites/all/modules/contrib/ecommerce/ubercart/uc_store/countries/aland_islands_248_1.cif b/sites/all/modules/contrib/ecommerce/ubercart/uc_store/countries/aland_islands_248_1.cif index 936c0d82..de6d6736 100644 --- a/sites/all/modules/contrib/ecommerce/ubercart/uc_store/countries/aland_islands_248_1.cif +++ b/sites/all/modules/contrib/ecommerce/ubercart/uc_store/countries/aland_islands_248_1.cif @@ -1,5 +1,9 @@ fields(array( - 'country_id' => 100, - 'country_name' => 'Bulgaria', - 'country_iso_code_2' => 'BG', - 'country_iso_code_3' => 'BGR', - 'version' => 1, - )) - ->execute(); - - // BG has no postal zones in the Ubercart sense - - // Set address format - uc_set_address_format( - 100, - "!first_name !last_name\r\n". - "!company\r\n". - "!street1\r\n". - "!street2\r\n". - "!zone_name\r\n". - "!postal_code !city !country_name_if" - ); -} diff --git a/sites/all/modules/contrib/ecommerce/ubercart/uc_store/countries/bulgaria_100_2.cif b/sites/all/modules/contrib/ecommerce/ubercart/uc_store/countries/bulgaria_100_2.cif new file mode 100644 index 00000000..9e98a65a --- /dev/null +++ b/sites/all/modules/contrib/ecommerce/ubercart/uc_store/countries/bulgaria_100_2.cif @@ -0,0 +1,118 @@ +fields(array( + 'country_id' => 100, + 'country_name' => 'Bulgaria', + 'country_iso_code_2' => 'BG', + 'country_iso_code_3' => 'BGR', + 'version' => 2, + )) + ->execute(); + + // Insert zone codes and names. + $zones = array( + array(100, 'BL', 'Blagoevgrad'), + array(100, 'BR', 'Burgas'), + array(100, 'VN', 'Varna'), + array(100, 'VT', 'Veliko Tarnovo'), + array(100, 'VD', 'Vidin'), + array(100, 'VR', 'Vratsa'), + array(100, 'GB', 'Gabrovo'), + array(100, 'DO', 'Dobrich'), + array(100, 'KZ', 'Kardzhali'), + array(100, 'KY', 'Kyustendil'), + array(100, 'LV', 'Lovech'), + array(100, 'MT', 'Montana'), + array(100, 'PZ', 'Pazardzhik'), + array(100, 'PN', 'Pernik'), + array(100, 'PV', 'Pleven'), + array(100, 'PD', 'Plovdiv'), + array(100, 'RG', 'Razgrad'), + array(100, 'RS', 'Ruse'), + array(100, 'SI', 'Silistra'), + array(100, 'SL', 'Sliven'), + array(100, 'SM', 'Smolyan'), + array(100, 'SG', 'Sofia (stolitsa)'), + array(100, 'SF', 'Sofia'), + array(100, 'SZ', 'Stara Zagora'), + array(100, 'TU', 'Targovishte'), + array(100, 'KK', 'Haskovo'), + array(100, 'SH', 'Shumen'), + array(100, 'YA', 'Yambol'), + ); + + $query = db_insert('uc_zones')->fields(array('zone_country_id', 'zone_code', 'zone_name')); + foreach ($zones as $zone) { + $query->values($zone); + } + $query->execute(); + + // Set address format + uc_set_address_format( + 100, + "!first_name !last_name\r\n" . + "!company\r\n" . + "!street1\r\n" . + "!street2\r\n" . + "!zone_name\r\n" . + "!postal_code !city !country_name_if" + ); +} + +/** + * Implements hook_update() with $version being the only argument. + * Add a new case for each version update, and be sure to always include the + * latest changes in the install function. + */ +function bulgaria_update($version) { + switch ($version) { + case '2': + // Update zone codes and names. + $zones = array( + array(100, 'BL', 'Blagoevgrad'), + array(100, 'BR', 'Burgas'), + array(100, 'VN', 'Varna'), + array(100, 'VT', 'Veliko Tarnovo'), + array(100, 'VD', 'Vidin'), + array(100, 'VR', 'Vratsa'), + array(100, 'GB', 'Gabrovo'), + array(100, 'DO', 'Dobrich'), + array(100, 'KZ', 'Kardzhali'), + array(100, 'KY', 'Kyustendil'), + array(100, 'LV', 'Lovech'), + array(100, 'MT', 'Montana'), + array(100, 'PZ', 'Pazardzhik'), + array(100, 'PN', 'Pernik'), + array(100, 'PV', 'Pleven'), + array(100, 'PD', 'Plovdiv'), + array(100, 'RG', 'Razgrad'), + array(100, 'RS', 'Ruse'), + array(100, 'SI', 'Silistra'), + array(100, 'SL', 'Sliven'), + array(100, 'SM', 'Smolyan'), + array(100, 'SG', 'Sofia (stolitsa)'), + array(100, 'SF', 'Sofia'), + array(100, 'SZ', 'Stara Zagora'), + array(100, 'TU', 'Targovishte'), + array(100, 'KK', 'Haskovo'), + array(100, 'SH', 'Shumen'), + array(100, 'YA', 'Yambol'), + ); + + $query = db_insert('uc_zones')->fields(array('zone_country_id', 'zone_code', 'zone_name')); + foreach ($zones as $zone) { + $query->values($zone); + } + $query->execute(); + + break; + } +} diff --git a/sites/all/modules/contrib/ecommerce/ubercart/uc_store/countries/burkina_faso_854_1.cif b/sites/all/modules/contrib/ecommerce/ubercart/uc_store/countries/burkina_faso_854_1.cif index e9cc306d..2b754273 100644 --- a/sites/all/modules/contrib/ecommerce/ubercart/uc_store/countries/burkina_faso_854_1.cif +++ b/sites/all/modules/contrib/ecommerce/ubercart/uc_store/countries/burkina_faso_854_1.cif @@ -1,5 +1,9 @@ fields(array( - 'country_id' => 170, - 'country_name' => 'Colombia', - 'country_iso_code_2' => 'CO', - 'country_iso_code_3' => 'COL', - 'version' => 1, - )) - ->execute(); - - // Make the entries in the zones table. - $zones = array( - array(170, 'AMA', 'Amazonas'), - array(170, 'ANT', 'Antioquia'), - array(170, 'ARA', 'Arauca'), - array(170, 'ATL', 'Atlantico'), - array(170, 'BOL', 'Bolivar'), - array(170, 'CAL', 'Caldas'), - array(170, 'CAQ', 'Caqueta'), - array(170, 'CAS', 'Casanare'), - array(170, 'CAU', 'Cauca'), - array(170, 'CES', 'Cesar'), - array(170, 'CHO', 'Choco'), - array(170, 'COR', 'Cordoba'), - array(170, 'CUN', 'Cundinamarca'), - array(170, 'DC', 'Distrito Capital de Bogota'), - array(170, 'GUA', 'Guainia'), - array(170, 'GUV', 'Guaviare'), - array(170, 'HUI', 'Huila'), - array(170, 'LAG', 'La Guajira'), - array(170, 'MAG', 'Magdalena'), - array(170, 'MET', 'Meta'), - array(170, 'NAR', 'Narino'), - array(170, 'NSA', 'Norte de Santander'), - array(170, 'PUT', 'Putumayo'), - array(170, 'QUI', 'Quindio'), - array(170, 'RIS', 'Risaralda'), - array(170, 'SAP', 'San Andres, Providencia y Santa Catalina'), - array(170, 'SAN', 'Santander'), - array(170, 'SUC', 'Sucre'), - array(170, 'TOL', 'Tolima'), - array(170, 'VAC', 'Valle del Cauca'), - array(170, 'VAU', 'Vaupes'), - array(170, 'VID', 'Vichada'), - ); - - $query = db_insert('uc_zones')->fields(array('zone_country_id', 'zone_code', 'zone_name')); - foreach ($zones as $zone) { - $query->values($zone); - } - $query->execute(); - - // Set address format - uc_set_address_format( - 170, - "!company\r\n". - "!first_name !last_name\r\n". - "!street1\r\n". - "!street2\r\n". - "!city !zone_code !postal_code\r\n". - "!country_name_if" - ); -} diff --git a/sites/all/modules/contrib/ecommerce/ubercart/uc_store/countries/colombia_170_2.cif b/sites/all/modules/contrib/ecommerce/ubercart/uc_store/countries/colombia_170_2.cif new file mode 100644 index 00000000..42a38186 --- /dev/null +++ b/sites/all/modules/contrib/ecommerce/ubercart/uc_store/countries/colombia_170_2.cif @@ -0,0 +1,164 @@ +fields(array( + 'country_id' => 170, + 'country_name' => 'Colombia', + 'country_iso_code_2' => 'CO', + 'country_iso_code_3' => 'COL', + 'version' => 2, + )) + ->execute(); + + // Make the entries in the zones table. + $zones = array( + array(170, 'DC', 'Distrito Capital de Bogotá'), + array(170, 'AMA', 'Amazonas'), + array(170, 'ANT', 'Antioquia'), + array(170, 'ARA', 'Arauca'), + array(170, 'ATL', 'Atlántico'), + array(170, 'BOL', 'Bolívar'), + array(170, 'BOY', 'Boyacá'), + array(170, 'CAL', 'Caldas'), + array(170, 'CAQ', 'Caquetá'), + array(170, 'CAS', 'Casanare'), + array(170, 'CAU', 'Cauca'), + array(170, 'CES', 'Cesar'), + array(170, 'COR', 'Córdoba'), + array(170, 'CUN', 'Cundinamarca'), + array(170, 'CHO', 'Chocó'), + array(170, 'GUA', 'Guainía'), + array(170, 'GUV', 'Guaviare'), + array(170, 'HUI', 'Huila'), + array(170, 'LAG', 'La Guajira'), + array(170, 'MAG', 'Magdalena'), + array(170, 'MET', 'Meta'), + array(170, 'NAR', 'Nariño'), + array(170, 'NSA', 'Norte de Santander'), + array(170, 'PUT', 'Putumayo'), + array(170, 'QUI', 'Quindío'), + array(170, 'RIS', 'Risaralda'), + array(170, 'SAP', 'San Andrés, Providencia y Santa Catalina'), + array(170, 'SAN', 'Santander'), + array(170, 'SUC', 'Sucre'), + array(170, 'TOL', 'Tolima'), + array(170, 'VAC', 'Valle del Cauca'), + array(170, 'VAU', 'Vaupés'), + array(170, 'VID', 'Vichada'), + ); + + $query = db_insert('uc_zones')->fields(array('zone_country_id', 'zone_code', 'zone_name')); + foreach ($zones as $zone) { + $query->values($zone); + } + $query->execute(); + + // Set address format. + uc_set_address_format( + 170, + "!company\r\n" . + "!first_name !last_name\r\n" . + "!street1\r\n" . + "!street2\r\n" . + "!city !zone_code !postal_code\r\n" . + "!country_name_if" + ); +} + +/** + * Implements hook_update() with $version being the only argument. + * Add a new case for each version update, and be sure to always include the + * latest changes in the install function. + */ +function colombia_update($version) { + switch ($version) { + case 2: + // Add missing zone. + $zones = array( + array(170, 'BOY', 'Boyacá'), + ); + + $query = db_insert('uc_zones')->fields(array('zone_country_id', 'zone_code', 'zone_name')); + foreach ($zones as $zone) { + $query->values($zone); + } + $query->execute(); + + // Rename zones. + db_update('uc_zones') + ->fields(array('zone_name' => 'Distrito Capital de Bogotá')) + ->condition('zone_country_id', 170) + ->condition('zone_code', 'DC') + ->execute(); + + db_update('uc_zones') + ->fields(array('zone_name' => 'Atlántico')) + ->condition('zone_country_id', 170) + ->condition('zone_code', 'ATL') + ->execute(); + + db_update('uc_zones') + ->fields(array('zone_name' => 'Bolívar')) + ->condition('zone_country_id', 170) + ->condition('zone_code', 'BOL') + ->execute(); + + db_update('uc_zones') + ->fields(array('zone_name' => 'Caquetá')) + ->condition('zone_country_id', 170) + ->condition('zone_code', 'CAQ') + ->execute(); + + db_update('uc_zones') + ->fields(array('zone_name' => 'Córdoba')) + ->condition('zone_country_id', 170) + ->condition('zone_code', 'COR') + ->execute(); + + db_update('uc_zones') + ->fields(array('zone_name' => 'Chocó')) + ->condition('zone_country_id', 170) + ->condition('zone_code', 'CHO') + ->execute(); + + db_update('uc_zones') + ->fields(array('zone_name' => 'Guainía')) + ->condition('zone_country_id', 170) + ->condition('zone_code', 'GUA') + ->execute(); + + db_update('uc_zones') + ->fields(array('zone_name' => 'Nariño')) + ->condition('zone_country_id', 170) + ->condition('zone_code', 'NAR') + ->execute(); + + db_update('uc_zones') + ->fields(array('zone_name' => 'Quindío')) + ->condition('zone_country_id', 170) + ->condition('zone_code', 'QUI') + ->execute(); + + db_update('uc_zones') + ->fields(array('zone_name' => 'San Andrés, Providencia y Santa Catalina')) + ->condition('zone_country_id', 170) + ->condition('zone_code', 'SAP') + ->execute(); + + db_update('uc_zones') + ->fields(array('zone_name' => 'Vaupés')) + ->condition('zone_country_id', 170) + ->condition('zone_code', 'VAU') + ->execute(); + + break; + } + +} diff --git a/sites/all/modules/contrib/ecommerce/ubercart/uc_store/countries/comoros_174_1.cif b/sites/all/modules/contrib/ecommerce/ubercart/uc_store/countries/comoros_174_1.cif index e8a22d0b..b563f354 100644 --- a/sites/all/modules/contrib/ecommerce/ubercart/uc_store/countries/comoros_174_1.cif +++ b/sites/all/modules/contrib/ecommerce/ubercart/uc_store/countries/comoros_174_1.cif @@ -1,5 +1,9 @@ fields(array( diff --git a/sites/all/modules/contrib/ecommerce/ubercart/uc_store/countries/czech_203_1.cif b/sites/all/modules/contrib/ecommerce/ubercart/uc_store/countries/czech_203_1.cif index 786de789..5d5a8c17 100644 --- a/sites/all/modules/contrib/ecommerce/ubercart/uc_store/countries/czech_203_1.cif +++ b/sites/all/modules/contrib/ecommerce/ubercart/uc_store/countries/czech_203_1.cif @@ -1,5 +1,9 @@ fields(array( @@ -107,15 +111,20 @@ function russia_install() { // Set address format uc_set_address_format( 643, - "!company\r\n". - "!first_name !last_name\r\n". - "!street1\r\n". - "!street2\r\n". - "!postal_code !city\r\n". + "!company\r\n" . + "!first_name !last_name\r\n" . + "!street1\r\n" . + "!street2\r\n" . + "!postal_code !city\r\n" . "!country_name_if" ); } +/** + * Implements hook_update() with $version being the only argument. + * Add a new case for each version update, and be sure to always include the + * latest changes in the install function. + */ function russia_update($version) { switch ($version) { case 2: diff --git a/sites/all/modules/contrib/ecommerce/ubercart/uc_store/countries/rwanda_646_1.cif b/sites/all/modules/contrib/ecommerce/ubercart/uc_store/countries/rwanda_646_1.cif index 646e9b6d..b6e984fe 100644 --- a/sites/all/modules/contrib/ecommerce/ubercart/uc_store/countries/rwanda_646_1.cif +++ b/sites/all/modules/contrib/ecommerce/ubercart/uc_store/countries/rwanda_646_1.cif @@ -1,5 +1,9 @@ 'Thailand', 'country_iso_code_2' => 'TH', 'country_iso_code_3' => 'THA', - 'version' => 2, + 'version' => 3, )) ->execute(); @@ -108,15 +108,20 @@ function thailand_install() { // Set address format uc_set_address_format( 764, - "!first_name !last_name\r\n". - "!company\r\n". - "!street1\r\n". - "!street2\r\n". - "!city, !zone_name !postal_code\r\n". + "!first_name !last_name\r\n" . + "!company\r\n" . + "!street1\r\n" . + "!street2\r\n" . + "!city, !zone_name !postal_code\r\n" . "!country_name" ); } +/** + * Implements hook_update() with $version being the only argument. + * Add a new case for each version update, and be sure to always include the + * latest changes in the install function. + */ function thailand_update($version) { switch ($version) { case 3: diff --git a/sites/all/modules/contrib/ecommerce/ubercart/uc_store/countries/timor_leste_626_1.cif b/sites/all/modules/contrib/ecommerce/ubercart/uc_store/countries/timor_leste_626_1.cif index 0c5f864d..2afdf37c 100644 --- a/sites/all/modules/contrib/ecommerce/ubercart/uc_store/countries/timor_leste_626_1.cif +++ b/sites/all/modules/contrib/ecommerce/ubercart/uc_store/countries/timor_leste_626_1.cif @@ -1,5 +1,9 @@ '; break; + case 'greater_equal': $ops = array('>', '=='); break; + case 'begins': case 'contains': case 'ends': $settings['operator'] = 'contains'; break; + case 'yes': $settings['operator'] = '=='; $settings['value'] = TRUE; break; + case 'no': $settings['operator'] = '=='; $settings['value'] = FALSE; @@ -191,10 +200,12 @@ function ca_add_conditions(&$component, $conditions) { case 'uid': $type = 'integer'; break; + case 'type': case 'title': $type = 'text'; break; + case 'status': case 'promote': case 'sticky': @@ -283,10 +294,12 @@ function ca_add_actions(&$rule, $actions) { 'error' => $settings['message_type'] == 'error', ); break; + case 'ca_action_custom_php': $name = 'php_eval'; $settings = array('code' => $settings['php']); break; + default: $name = $action['#name']; break; diff --git a/sites/all/modules/contrib/ecommerce/ubercart/uc_store/includes/tapir.inc b/sites/all/modules/contrib/ecommerce/ubercart/uc_store/includes/tapir.inc index 2f74cccd..517d201d 100644 --- a/sites/all/modules/contrib/ecommerce/ubercart/uc_store/includes/tapir.inc +++ b/sites/all/modules/contrib/ecommerce/ubercart/uc_store/includes/tapir.inc @@ -64,7 +64,7 @@ function tapir_gather_rows($element) { * @param $form * The array of form information needing to be rendered into the table. * - * @return + * @return string * The table output rendered in HTML. * * @ingroup themeable @@ -117,7 +117,7 @@ function theme_tapir_table($variables) { // Merge the row data into a single row array along with the attributes. if (isset($data['#attributes'])) { - $row = array_merge(array('data' => $row), (array)$data['#attributes']); + $row = array_merge(array('data' => $row), (array) $data['#attributes']); } // Add the current row to the table rows array. @@ -130,7 +130,7 @@ function theme_tapir_table($variables) { 'rows' => $rows, ); if (isset($element['#attributes'])) { - $options['attributes'] = (array)$element['#attributes']; + $options['attributes'] = (array) $element['#attributes']; } if (isset($element['#title'])) { $options['caption'] = $element['#title']; diff --git a/sites/all/modules/contrib/ecommerce/ubercart/uc_store/includes/uc_ajax_attach.inc b/sites/all/modules/contrib/ecommerce/ubercart/uc_store/includes/uc_ajax_attach.inc index 973721a1..84906add 100644 --- a/sites/all/modules/contrib/ecommerce/ubercart/uc_store/includes/uc_ajax_attach.inc +++ b/sites/all/modules/contrib/ecommerce/ubercart/uc_store/includes/uc_ajax_attach.inc @@ -1,4 +1,5 @@ $quotes_defaults, 'panes][billing][address][billing_country' => array('payment-pane' => 'payment-pane'), ); + default: return array(); } diff --git a/sites/all/modules/contrib/ecommerce/ubercart/uc_store/tests/uc_address.test b/sites/all/modules/contrib/ecommerce/ubercart/uc_store/tests/uc_address.test index 2cbc110c..551f4b70 100644 --- a/sites/all/modules/contrib/ecommerce/ubercart/uc_store/tests/uc_address.test +++ b/sites/all/modules/contrib/ecommerce/ubercart/uc_store/tests/uc_address.test @@ -21,7 +21,6 @@ class UbercartAddressTestCase extends UbercartTestHelper { ); } - /** * Overrides DrupalWebTestCase::setUp(). */ @@ -50,7 +49,7 @@ class UbercartAddressTestCase extends UbercartTestHelper { /** * Tests comparison of address objects. */ - function testAddressComparison() { + public function testAddressComparison() { $address1 = $this->test_address[0]; $address2 = $this->test_address[1]; diff --git a/sites/all/modules/contrib/ecommerce/ubercart/uc_store/tests/uc_ajax.test b/sites/all/modules/contrib/ecommerce/ubercart/uc_store/tests/uc_ajax.test index 208b7fc2..72467df9 100644 --- a/sites/all/modules/contrib/ecommerce/ubercart/uc_store/tests/uc_ajax.test +++ b/sites/all/modules/contrib/ecommerce/ubercart/uc_store/tests/uc_ajax.test @@ -4,10 +4,12 @@ * @file * Tests for the UcAddress class. */ + /** * Tests for the Ubercart Ajax Attach. */ class UbercartAjaxTestCase extends UbercartTestHelper { + public static function getInfo() { return array( 'name' => 'Ajax functionality', @@ -37,7 +39,7 @@ class UbercartAjaxTestCase extends UbercartTestHelper { * @param $negate * TRUE to negate the condition. */ - function addPaymentZoneCondition($method, $zone, $negate = FALSE) { + protected function addPaymentZoneCondition($method, $zone, $negate = FALSE) { $not = $negate ? 'NOT ' : ''; $name = 'uc_payment_method_' . $method; $label = ucfirst($method) . ' conditions'; @@ -72,7 +74,7 @@ class UbercartAjaxTestCase extends UbercartTestHelper { //$this->drupalGet('admin/config/workflow/rules/components/manage/' . $newconfig->id); } - function testCheckoutAjax() { + public function testCheckoutAjax() { // Enable two payment methods and set a condition on one. variable_set('uc_payment_method_check_checkout', TRUE); variable_set('uc_payment_method_other_checkout', TRUE); @@ -100,4 +102,5 @@ class UbercartAjaxTestCase extends UbercartTestHelper { // Not in Kansas any more... $this->assertNoText("Other"); } + } diff --git a/sites/all/modules/contrib/ecommerce/ubercart/uc_store/tests/uc_store.test b/sites/all/modules/contrib/ecommerce/ubercart/uc_store/tests/uc_store.test index 709974bf..91031513 100644 --- a/sites/all/modules/contrib/ecommerce/ubercart/uc_store/tests/uc_store.test +++ b/sites/all/modules/contrib/ecommerce/ubercart/uc_store/tests/uc_store.test @@ -19,7 +19,6 @@ class UbercartTestHelper extends DrupalWebTestCase { /** Test product. */ protected $product; - /** * Overrides DrupalWebTestCase::setUp(). * @@ -62,7 +61,7 @@ class UbercartTestHelper extends DrupalWebTestCase { /** * Creates a new product. */ - function createProduct($product = array()) { + protected function createProduct($product = array()) { // Set the default required fields. $weight_units = array('lb', 'kg', 'oz', 'g'); $length_units = array('in', 'ft', 'cm', 'mm'); @@ -92,7 +91,7 @@ class UbercartTestHelper extends DrupalWebTestCase { * * Fix this after adding a proper API call for saving a product class. */ - function createProductClass($data = array()) { + protected function createProductClass($data = array()) { $product_class = $data + array( 'pcid' => $this->randomName(8), 'name' => $this->randomName(8), @@ -111,10 +110,10 @@ class UbercartTestHelper extends DrupalWebTestCase { * @param $edit * The form-values array to which to add required fields. */ - function populateCheckoutForm($edit = array()) { + protected function populateCheckoutForm($edit = array()) { foreach (array('billing', 'delivery') as $pane) { $prefix = 'panes[' . $pane . '][' . $pane; - $key = $prefix . '_country]'; + $key = $prefix . '_country]'; $country = empty($edit[$key]) ? variable_get('uc_store_country', 840) : $edit[$key]; $zone_id = db_query_range('SELECT zone_id FROM {uc_zones} WHERE zone_country_id = :country ORDER BY rand()', 0, 1, array('country' => $country))->fetchField(); $edit += array( @@ -139,7 +138,7 @@ class UbercartTestHelper extends DrupalWebTestCase { /** * Executes the checkout process. */ - function checkout($edit = array()) { + protected function checkout($edit = array()) { $this->drupalPost('cart', array(), 'Checkout'); $this->assertText( t('Enter your billing address and information here.'), @@ -180,7 +179,7 @@ class UbercartTestHelper extends DrupalWebTestCase { * An array containing the most recently sent matching email, * or FALSE if the subject line did not match anything. */ - function findMail($pattern) { + protected function findMail($pattern) { foreach (array_reverse($this->drupalGetMails()) as $mail) { if (preg_match($pattern, $mail['subject'])) { $this->pass(t('E-mail found with subject matching %pattern.', array('%pattern' => $pattern))); @@ -207,7 +206,7 @@ class UbercartTestHelper extends DrupalWebTestCase { * TRUE to check only the plain-text contents of the 'data' keys of each 'insert' command (i.e. what would * be inserted into the page). FALSE to check the complete, json-encoded ajax response. */ - function assertAjaxHelper($ajax, $text, $message = FALSE, $not_exists = FALSE, $plain = TRUE) { + protected function assertAjaxHelper($ajax, $text, $message = FALSE, $not_exists = FALSE, $plain = TRUE) { $content = ''; if ($plain) { foreach ($ajax as $command) { @@ -237,7 +236,7 @@ class UbercartTestHelper extends DrupalWebTestCase { * @param $message * The assertion message. */ - function assertAjaxText($ajax, $text, $message = FALSE) { + protected function assertAjaxText($ajax, $text, $message = FALSE) { $this->assertAjaxHelper($ajax, $text, $message, FALSE, TRUE); } @@ -252,7 +251,7 @@ class UbercartTestHelper extends DrupalWebTestCase { * @param $message * The assertion message. */ - function assertNoAjaxText($ajax, $text, $message = FALSE) { + protected function assertNoAjaxText($ajax, $text, $message = FALSE) { $this->assertAjaxHelper($ajax, $text, $message, TRUE, TRUE); } @@ -266,7 +265,7 @@ class UbercartTestHelper extends DrupalWebTestCase { * @param $message * The assertion message. */ - function assertAjaxRaw($ajax, $text, $message = FALSE) { + protected function assertAjaxRaw($ajax, $text, $message = FALSE) { $this>assertAjaxHelper($ajax, $text, $message, FALSE, FALSE); } @@ -280,7 +279,7 @@ class UbercartTestHelper extends DrupalWebTestCase { * @param $message * The assertion message. */ - function assertNoAjaxRaw($ajax, $text, $message = FALSE) { + protected function assertNoAjaxRaw($ajax, $text, $message = FALSE) { $this>assertAjaxHelper($ajax, $text, $message, TRUE, FALSE); } @@ -314,22 +313,27 @@ class UbercartTestHelper extends DrupalWebTestCase { case 'replaceWith': $wrapperNode->parentNode->replaceChild($newNode, $wrapperNode); break; + case 'append': $wrapperNode->appendChild($newNode); break; + case 'prepend': // If no firstChild, insertBefore() falls back to // appendChild(). $wrapperNode->insertBefore($newNode, $wrapperNode->firstChild); break; + case 'before': $wrapperNode->parentNode->insertBefore($newNode, $wrapperNode); break; + case 'after': // If no nextSibling, insertBefore() falls back to // appendChild(). $wrapperNode->parentNode->insertBefore($newNode, $wrapperNode->nextSibling); break; + case 'html': foreach ($wrapperNode->childNodes as $childNode) { $wrapperNode->removeChild($childNode); @@ -345,6 +349,7 @@ class UbercartTestHelper extends DrupalWebTestCase { $this->verbose('Page content after ajax submission:' . t('About') . '
'; + $output .= '' . t('The link provides a standard custom content field for links. Links can be easily added to any content types and profiles and include advanced validating and different ways of storing internal or external links and URLs. It also supports additional link text title, site wide tokens for titles and title attributes, target attributes, css class attribution, static repeating values, input conversion, and many more.') . '
'; + $output .= '' . t('Requirements / Dependencies') . '
'; + $output .= '' . 'Fields API is provided already by core [no dependencies].' . '
'; + $output .= 'Configuration
'; + $output .= '' . 'Configuration is only slightly more complicated than a text field. Link text titles for URLs can be made required, set as instead of URL, optional (default), or left out entirely. If no link text title is provided, the trimmed version of the complete URL will be displayed. The target attribute should be set to "_blank", "top", or left out completely (checkboxes provide info). The rel=nofollow attribute prevents the link from being followed by certain search engines.' . '
'; + return $output; + } +} + /** * Implements hook_field_info(). */ @@ -97,6 +116,7 @@ function link_field_instance_settings_form($field, $instance) { 'optional' => t('Optional Title'), 'required' => t('Required Title'), 'value' => t('Static Title'), + 'select' => t('Selected Title'), 'none' => t('No Title'), ); @@ -110,9 +130,26 @@ function link_field_instance_settings_form($field, $instance) { $form['title_value'] = array( '#type' => 'textfield', - '#title' => t('Static title'), + '#title' => t('Static or default title'), '#default_value' => isset($instance['settings']['title_value']) ? $instance['settings']['title_value'] : '', - '#description' => t('This title will always be used if “Static Title” is selected above.'), + '#description' => t('This title will 1) always be used if "Static Title" is selected above, or 2) used if "Optional title" is selected above and no title is entered when creating content.'), + '#states' => array( + 'visible' => array( + ':input[name="instance[settings][title]"]' => array('value' => 'value'), + ), + ), + ); + + $form['title_allowed_values'] = array( + '#type' => 'textarea', + '#title' => t('Title allowed values'), + '#default_value' => isset($instance['settings']['title_allowed_values']) ? $instance['settings']['title_allowed_values'] : '', + '#description' => t('When using "Selected Title", you can allow users to select the title from a limited set of values (eg. Home, Office, Other). Enter here all possible values that title can take, one value per line.'), + '#states' => array( + 'visible' => array( + ':input[name="instance[settings][title]"]' => array('value' => 'select'), + ), + ), ); $form['title_label_use_field_label'] = array( @@ -162,15 +199,18 @@ function link_field_instance_settings_form($field, $instance) { '#size' => 3, ); + // Target options. E.g. New window = target="_blank". $target_options = array( LINK_TARGET_DEFAULT => t('Default (no target attribute)'), LINK_TARGET_TOP => t('Open link in window root'), LINK_TARGET_NEW_WINDOW => t('Open link in new window'), LINK_TARGET_USER => t('Allow the user to choose'), ); + $form['attributes'] = array( '#tree' => TRUE, ); + $form['attributes']['target'] = array( '#type' => 'radios', '#title' => t('Link Target'), @@ -180,7 +220,7 @@ function link_field_instance_settings_form($field, $instance) { $form['attributes']['rel'] = array( '#type' => 'textfield', '#title' => t('Rel Attribute'), - '#description' => t('When output, this link will have this rel attribute. The most common usage is rel="nofollow" which prevents some search engines from spidering entered links.'), + '#description' => t('When output, this link will have this rel attribute. The most common usage is rel="nofollow" which prevents some search engines from spidering entered links.'), '#default_value' => empty($instance['settings']['attributes']['rel']) ? '' : $instance['settings']['attributes']['rel'], '#field_prefix' => 'rel = "', '#field_suffix' => '"', @@ -217,7 +257,7 @@ function link_field_instance_settings_form($field, $instance) { $form['attributes']['title'] = array( '#title' => t("Default link 'title' Attribute"), '#type' => 'textfield', - '#description' => t('When output, links will use this "title" attribute if the user does not provide one and when different from the link text. Read WCAG 1.0 Guidelines for links comformances. Tokens values will be evaluated.'), + '#description' => t('When output, links will use this "title" attribute if the user does not provide one and when different from the link text. Read WCAG 1.0 Guidelines for links comformances. Tokens values will be evaluated.'), '#default_value' => empty($instance['settings']['attributes']['title']) ? '' : $instance['settings']['attributes']['title'], '#field_prefix' => 'title = "', '#field_suffix' => '"', @@ -227,11 +267,17 @@ function link_field_instance_settings_form($field, $instance) { } /** + * Form validate. + * * #element_validate handler for link_field_instance_settings_form(). */ function link_field_settings_form_validate($element, &$form_state, $complete_form) { if ($form_state['values']['instance']['settings']['title'] === 'value' && empty($form_state['values']['instance']['settings']['title_value'])) { - form_set_error('title_value', t('A default title must be provided if the title is a static value.')); + form_set_error('instance][settings][title_value', t('A default title must be provided if the title is a static value.')); + } + if ($form_state['values']['instance']['settings']['title'] === 'select' + && empty($form_state['values']['instance']['settings']['title_allowed_values'])) { + form_set_error('instance][settings][title_allowed_values', t('You must enter one or more allowed values for link Title, the title is a selected value.')); } if (!empty($form_state['values']['instance']['settings']['display']['url_cutoff']) && !is_numeric($form_state['values']['instance']['settings']['display']['url_cutoff'])) { form_set_error('display', t('URL Display Cutoff value must be numeric.')); @@ -261,6 +307,8 @@ function link_field_load($entity_type, $entities, $field, $instances, $langcode, foreach ($entities as $id => $entity) { foreach ($items[$id] as $delta => $item) { $items[$id][$delta]['attributes'] = _link_load($field, $item, $instances[$id]); + $items[$id][$delta]['original_title'] = $item['title']; + $items[$id][$delta]['original_url'] = $item['url']; } } } @@ -276,6 +324,16 @@ function link_field_validate($entity_type, $entity, $field, $instance, $langcode } } + foreach ($items as $delta => $value) { + if (isset($value['attributes']) && is_string($value['attributes'])) { + $errors[$field['field_name']][$langcode][$delta][] = array( + 'error' => 'link_required', + 'message' => t('String values are not acceptable for attributes.'), + 'error_element' => array('url' => TRUE, 'title' => FALSE), + ); + } + } + if ($instance['settings']['url'] === 'optional' && $instance['settings']['title'] === 'optional' && $instance['required'] && !$optional_field_found) { $errors[$field['field_name']][$langcode][0][] = array( 'error' => 'link_required', @@ -308,8 +366,19 @@ function link_field_update($entity_type, $entity, $field, $instance, $langcode, */ function link_field_prepare_view($entity_type, $entities, $field, $instances, $langcode, &$items) { foreach ($items as $entity_id => $entity_items) { - foreach ($entity_items as $delta => $value) { - _link_sanitize($items[$entity_id][$delta], $delta, $field, $instances[$entity_id], $entities[$entity_id]); + $settings = $instances[$entity_id]['settings']; + $trimTitle = trim($settings['title_value']); + if (empty($entity_items) && !empty($trimTitle) && $settings['title'] == 'value' && $settings['url'] === 'optional') { + $token_value = token_replace($settings['title_value'], array($entity_type => $entities[$entity_id])); + $display_title = htmlspecialchars_decode($token_value, ENT_QUOTES); + $items[$entity_id][0]['url'] = NULL; + $items[$entity_id][0]['title'] = $display_title; + $items[$entity_id][0]['attributes'] = array(); + } + else { + foreach ($entity_items as $delta => $value) { + _link_sanitize($items[$entity_id][$delta], $delta, $field, $instances[$entity_id], $entities[$entity_id]); + } } } } @@ -342,10 +411,10 @@ function link_field_widget_form(&$form, &$form_state, $field, $instance, $langco * Implements hook_field_widget_error(). */ function link_field_widget_error($element, $error, $form, &$form_state) { - if ($error['error_element']['title']) { + if (!empty($error['error_element']['title'])) { form_error($element['title'], $error['message']); } - elseif ($error['error_element']['url']) { + elseif (!empty($error['error_element']['url'])) { form_error($element['url'], $error['message']); } } @@ -371,23 +440,21 @@ function _link_load($field, $item, $instance) { /** * Prepares the item attributes and url for storage. * - * @param $item - * Link field values. - * - * @param $delta - * The sequence number for current values. - * - * @param $field - * The field structure array. - * - * @param $entity - * Entity object. - * - * @param $instance - * The instance structure for $field on $entity's bundle. + * @param array $item + * Link field values. + * @param array $delta + * The sequence number for current values. + * @param array $field + * The field structure array. + * @param object $entity + * Entity object. + * @param array $instance + * The instance structure for $field on $entity's bundle. * + * @codingStandardsIgnoreStart */ function _link_process(&$item, $delta, $field, $entity, $instance) { + // @codingStandardsIgnoreEnd // Trim whitespace from URL. if (!empty($item['url'])) { $item['url'] = trim($item['url']); @@ -446,9 +513,10 @@ function _link_validate(&$item, $delta, $field, $entity, $instance, $langcode, & 'error_element' => array('url' => TRUE, 'title' => FALSE), ); } - // In a totally bizzaro case, where URLs and titles are optional but the field is required, ensure there is at least one link. + // In a totally bizzaro case, where URLs and titles are optional but the field + // is required, ensure there is at least one link. if ($instance['settings']['url'] === 'optional' && $instance['settings']['title'] === 'optional' - && (strlen(trim($item['url'])) !== 0 || strlen(trim($item['title'])) !== 0)) { + && (strlen(trim($item['url'])) !== 0 || strlen(trim($item['title'])) !== 0)) { $optional_field_found = TRUE; } // Require entire field. @@ -464,16 +532,30 @@ function _link_validate(&$item, $delta, $field, $entity, $instance, $langcode, & /** * Clean up user-entered values for a link field according to field settings. * - * @param array $item + * @param array $item * A single link item, usually containing url, title, and attributes. - * @param int $delta + * @param int $delta * The delta value if this field is one of multiple fields. - * @param array $field + * @param array $field * The CCK field definition. - * @param object $entity + * @param object $entity * The entity containing this link. + * + * @codingStandardsIgnoreStart */ function _link_sanitize(&$item, $delta, &$field, $instance, &$entity) { + // @codingStandardsIgnoreEnd + // As this function can be called multiple times and the item is changed by + // reference we need to ensure that there's always the original data to + // process otherwise processed data are processed again which might leads to + // unexpected results. + if (isset($item['_link_sanitized'])) { + return; + } + + // Store a flag to check in case of a second call. + $item['_link_sanitized'] = TRUE; + // Don't try to process empty links. if (empty($item['url']) && empty($item['title'])) { return; @@ -487,7 +569,7 @@ function _link_sanitize(&$item, $delta, &$field, $instance, &$entity) { $entity_info = entity_get_info($entity_type); $property_id = $entity_info['entity keys']['id']; $entity_token_type = isset($entity_info['token type']) ? $entity_info['token type'] : ( - $entity_type == 'taxonomy_term' || $entity_type == 'taxonomy_vocabulary' ? str_replace('taxonomy_', '', $entity_type) : $entity_type + $entity_type == 'taxonomy_term' || $entity_type == 'taxonomy_vocabulary' ? str_replace('taxonomy_', '', $entity_type) : $entity_type ); if (isset($instance['settings']['enable_tokens']) && $instance['settings']['enable_tokens']) { $text_tokens = token_scan($item['url']); @@ -510,23 +592,33 @@ function _link_sanitize(&$item, $delta, &$field, $instance, &$entity) { if ($type == FALSE && $instance['settings']['validate_url'] === 0) { $type = LINK_EXTERNAL; } + elseif ($type == LINK_FRAGMENT || $type == LINK_QUERY) { + // If type is a fragment or query, then use the current URL. + $item['url'] = $_GET['q'] . $item['url']; + } $url = link_cleanup_url($item['url']); $url_parts = _link_parse_url($url); if (!empty($url_parts['url'])) { - $item['url'] = url($url_parts['url'], - array('query' => isset($url_parts['query']) ? $url_parts['query'] : NULL, + $item = array( + 'url' => $url_parts['url'], + 'query' => isset($url_parts['query']) ? $url_parts['query'] : NULL, 'fragment' => isset($url_parts['fragment']) ? $url_parts['fragment'] : NULL, 'absolute' => !empty($instance['settings']['absolute_url']), 'html' => TRUE, - ) - ); + ) + $item; } // Create a shortened URL for display. if ($type == LINK_EMAIL) { $display_url = str_replace('mailto:', '', $url); } + elseif ($type === LINK_EXTERNAL) { + $display_url = $item['url']; + } + elseif ($type == LINK_TEL) { + $display_url = str_replace('tel:', '', $url); + } else { $display_url = url($url_parts['url'], array( @@ -537,7 +629,7 @@ function _link_sanitize(&$item, $delta, &$field, $instance, &$entity) { ); } if ($instance['settings']['display']['url_cutoff'] && strlen($display_url) > $instance['settings']['display']['url_cutoff']) { - $display_url = substr($display_url, 0, $instance['settings']['display']['url_cutoff']) . "..."; + $display_url = substr($display_url, 0, $instance['settings']['display']['url_cutoff']) . "…"; } $item['display_url'] = $display_url; @@ -550,15 +642,20 @@ function _link_sanitize(&$item, $delta, &$field, $instance, &$entity) { } } // Use the title defined by the user at the widget level. - elseif (isset($item['title'])) { + elseif (isset($item['title']) && drupal_strlen(trim($item['title']))) { $title = $item['title']; } + // Use the static title if a user-defined title is optional and a static title + // has been defined. + elseif ($instance['settings']['title'] == 'optional' && drupal_strlen(trim($instance['settings']['title_value']))) { + $title = $instance['settings']['title_value']; + } else { $title = ''; } // Replace title tokens. - if ($title && ($instance['settings']['title'] == 'value' || $instance['settings']['enable_tokens'])) { + if ($title && $instance['settings']['enable_tokens']) { $text_tokens = token_scan($title); if (!empty($text_tokens)) { // Load the entity if necessary for entities in views. @@ -571,10 +668,25 @@ function _link_sanitize(&$item, $delta, &$field, $instance, &$entity) { } $title = token_replace($title, array($entity_token_type => $entity_loaded)); } - $title = filter_xss($title, array('b', 'br', 'code', 'em', 'i', 'img', 'span', 'strong', 'sub', 'sup', 'tt', 'u')); + } + if ($title && ($instance['settings']['title'] == 'value' || $instance['settings']['enable_tokens'])) { + $title = filter_xss($title, array( + 'b', + 'br', + 'code', + 'em', + 'i', + 'img', + 'span', + 'strong', + 'sub', + 'sup', + 'tt', + 'u', + )); $item['html'] = TRUE; } - $item['title'] = empty($title) ? $item['display_url'] : $title; + $item['title'] = empty($title) && $title !== '0' ? $item['display_url'] : $title; if (!isset($item['attributes'])) { $item['attributes'] = array(); @@ -621,7 +733,7 @@ function _link_sanitize(&$item, $delta, &$field, $instance, &$entity) { // Handle "title" link attribute. if (!empty($item['attributes']['title']) && module_exists('token')) { $text_tokens = token_scan($item['attributes']['title']); - if (!empty($text_tokens)) { + if (!empty($text_tokens)) { // Load the entity (necessary for entities in views). if (isset($entity->{$property_id})) { $entity_loaded = entity_load($entity_type, array($entity->{$property_id})); @@ -630,9 +742,22 @@ function _link_sanitize(&$item, $delta, &$field, $instance, &$entity) { else { $entity_loaded = $entity; } - $item['attributes']['title'] = token_replace($item['attributes']['title'], array($entity_token_type => $entity_loaded)); + $item['attributes']['title'] = token_replace($item['attributes']['title'], array($entity_token_type => $entity_loaded), array('clear' => TRUE)); } - $item['attributes']['title'] = filter_xss($item['attributes']['title'], array('b', 'br', 'code', 'em', 'i', 'img', 'span', 'strong', 'sub', 'sup', 'tt', 'u')); + $item['attributes']['title'] = filter_xss($item['attributes']['title'], array( + 'b', + 'br', + 'code', + 'em', + 'i', + 'img', + 'span', + 'strong', + 'sub', + 'sup', + 'tt', + 'u', + )); } // Handle attribute classes. if (!empty($item['attributes']['class'])) { @@ -684,7 +809,8 @@ function _link_parse_url($url) { * Replaces the PHP parse_str() function. * * Because parse_str replaces the following characters in query parameters name - * in order to maintain compatibility with deprecated register_globals directive: + * in order to maintain compatibility with deprecated register_globals + * directive: * * - chr(32) ( ) (space) * - chr(46) (.) (dot) @@ -731,7 +857,14 @@ function link_theme() { 'variables' => array('element' => NULL, 'field' => NULL), ), 'link_formatter_link_domain' => array( - 'variables' => array('element' => NULL, 'display' => NULL, 'field' => NULL), + 'variables' => array( + 'element' => NULL, + 'display' => NULL, + 'field' => NULL, + ), + ), + 'link_formatter_link_no_protocol' => array( + 'variables' => array('element' => NULL, 'field' => NULL), ), 'link_formatter_link_title_plain' => array( 'variables' => array('element' => NULL, 'field' => NULL), @@ -758,7 +891,7 @@ function link_theme() { * Formats a link field widget. */ function theme_link_field($vars) { - drupal_add_css(drupal_get_path('module', 'link') . '/link.css'); + drupal_add_css(drupal_get_path('module', 'link') . '/css/link.css'); $element = $vars['element']; // Prefix single value link fields with the name of the field. if (empty($element['#field']['multiple'])) { @@ -818,10 +951,24 @@ function _link_default_attributes() { * Build the form element. When creating a form using FAPI #process, * note that $element['#value'] is already set. * - * The $fields array is in $complete_form['#field_info'][$element['#field_name']]. + * The $fields array is in + * $complete_form['#field_info'][$element['#field_name']]. */ function link_field_process($element, $form_state, $complete_form) { $instance = field_widget_instance($element, $form_state); + if (!$instance) { + // The element comes from a custom form, we have to manually create the + // $instance settings. + $instance['settings'] = array ( + 'title_maxlength' => isset($element['#title_maxlength']) ? $element['#title_maxlength'] : 128, + 'title' => isset($element['#title_mode']) ? $element['#title_mode'] : 'optional', + 'title_label_use_field_label' => isset($element['#title_label_use_field_label']) ? $element['#title_label_use_field_label'] : FALSE, + 'url' => isset($element['#url']) ? $element['#url'] : 'optional', + ); + if (isset($element['#attributes'])) { + $instance['settings']['attributes'] = $element['#attributes']; + } + } $settings = $instance['settings']; $element['url'] = array( '#type' => 'textfield', @@ -830,7 +977,7 @@ function link_field_process($element, $form_state, $complete_form) { '#required' => ($element['#delta'] == 0 && $settings['url'] !== 'optional') ? $element['#required'] : FALSE, '#default_value' => isset($element['#value']['url']) ? $element['#value']['url'] : NULL, ); - if ($settings['title'] !== 'none' && $settings['title'] !== 'value') { + if (in_array($settings['title'], array('optional', 'required'))) { // Figure out the label of the title field. if (!empty($settings['title_label_use_field_label'])) { // Use the element label as the title field label. @@ -842,15 +989,31 @@ function link_field_process($element, $form_state, $complete_form) { $title_label = t('Title'); } + // Default value. + $title_maxlength = 128; + if (!empty($settings['title_maxlength'])) { + $title_maxlength = $settings['title_maxlength']; + } + $element['title'] = array( '#type' => 'textfield', - '#maxlength' => $settings['title_maxlength'], + '#maxlength' => $title_maxlength, '#title' => $title_label, - '#description' => t('The link title is limited to @maxlength characters maximum.', array('@maxlength' => $settings['title_maxlength'])), + '#description' => t('The link title is limited to @maxlength characters maximum.', array('@maxlength' => $title_maxlength)), '#required' => ($settings['title'] == 'required' && (($element['#delta'] == 0 && $element['#required']) || !empty($element['#value']['url']))) ? TRUE : FALSE, '#default_value' => isset($element['#value']['title']) ? $element['#value']['title'] : NULL, ); } + elseif ($settings['title'] == 'select') { + $options = drupal_map_assoc(array_filter(explode("\n", str_replace("\r", "\n", trim($settings['title_allowed_values']))))); + $element['title'] = array( + '#type' => 'select', + '#title' => t('Title'), + '#description' => t('Select the a title for this link.'), + '#default_value' => isset($element['#value']['title']) ? $element['#value']['title'] : NULL, + '#options' => $options, + ); + } // Initialize field attributes as an array if it is not an array yet. if (!is_array($settings['attributes'])) { @@ -887,7 +1050,8 @@ function link_field_process($element, $form_state, $complete_form) { } // If the title field is available or there are field accepts multiple values - // then allow the individual field items display the required asterisk if needed. + // then allow the individual field items display the required asterisk if + // needed. if (isset($element['title']) || isset($element['_weight'])) { // To prevent an extra required indicator, disable the required flag on the // base element since all the sub-fields are already required if desired. @@ -906,6 +1070,9 @@ function link_field_formatter_info() { 'label' => t('Title, as link (default)'), 'field types' => array('link_field'), 'multiple values' => FIELD_BEHAVIOR_DEFAULT, + 'settings' => array( + 'custom_title' => '', + ), ), 'link_title_plain' => array( 'label' => t('Title, as plain text'), @@ -940,6 +1107,11 @@ function link_field_formatter_info() { 'strip_www' => FALSE, ), ), + 'link_no_protocol' => array( + 'label' => t('URL with the protocol removed'), + 'field types' => array('link_field'), + 'multiple values' => FIELD_BEHAVIOR_DEFAULT, + ), 'link_short' => array( 'label' => t('Short, as link with title "Link"'), 'field types' => array('link_field'), @@ -972,6 +1144,14 @@ function link_field_formatter_settings_form($field, $instance, $view_mode, $form '#default_value' => $settings['strip_www'], ); } + if ($display['type'] == 'link_default') { + $element['custom_title'] = array( + '#title' => t('Override title'), + '#description' => t('Optionally override the title for the link(s).'), + '#type' => 'textfield', + '#default_value' => $settings['custom_title'], + ); + } return $element; } @@ -979,8 +1159,9 @@ function link_field_formatter_settings_form($field, $instance, $view_mode, $form * Implements hook_field_formatter_settings_summary(). */ function link_field_formatter_settings_summary($field, $instance, $view_mode) { + $display = $instance['display'][$view_mode]; - $settings = $display['settings']; + if ($display['type'] == 'link_domain') { if ($display['settings']['strip_www']) { return t('Strip www. from domain'); @@ -989,6 +1170,11 @@ function link_field_formatter_settings_summary($field, $instance, $view_mode) { return t('Leave www. in domain'); } } + if ($display['type'] == 'link_default') { + if ($display['settings']['custom_title']) { + return t('Title: %title', array('%title' => $display['settings']['custom_title'])); + } + } return ''; } @@ -998,11 +1184,16 @@ function link_field_formatter_settings_summary($field, $instance, $view_mode) { function link_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) { $elements = array(); foreach ($items as $delta => $item) { + if (!empty($display['settings']['custom_title'])) { + $item['title'] = $display['settings']['custom_title']; + } $elements[$delta] = array( '#theme' => 'link_formatter_' . $display['type'], '#element' => $item, '#field' => $instance, - '#display' => $display, + '#display' => array( + 'settings' => $display['settings'], + ), ); } return $elements; @@ -1021,14 +1212,14 @@ function theme_link_formatter_link_default($vars) { } // Display a normal link if both title and URL are available. if (!empty($vars['element']['title']) && !empty($vars['element']['url'])) { - return l($vars['element']['title'], $vars['element']['url'], $link_options); + return l($vars['element']['title'], rawurldecode($vars['element']['url']), $link_options); } // If only a title, display the title. elseif (!empty($vars['element']['title'])) { - return $link_options['html'] ? $vars['element']['title'] : check_plain($vars['element']['title']); + return !empty($link_options['html']) ? $vars['element']['title'] : check_plain($vars['element']['title']); } elseif (!empty($vars['element']['url'])) { - return l($vars['element']['title'], $vars['element']['url'], $link_options); + return l($vars['element']['title'], rawurldecode($vars['element']['url']), $link_options); } } @@ -1077,11 +1268,27 @@ function theme_link_formatter_link_domain($vars) { return $vars['element']['url'] ? l($domain, $vars['element']['url'], $link_options) : ''; } +/** + * Formats a link without the http:// or https://. + */ +function theme_link_formatter_link_no_protocol($vars) { + $link_options = $vars['element']; + unset($link_options['title']); + unset($link_options['url']); + // We drop any scheme of the url. + $scheme = parse_url($vars['element']['url']); + $search = '/' . preg_quote($scheme['scheme'] . '://', '/') . '/'; + $replace = ''; + $display_url = preg_replace($search, $replace, $vars['element']['url'], 1); + + return $vars['element']['url'] ? l($display_url, $vars['element']['url'], $link_options) : ''; +} + /** * Formats a link's title as plain text. */ function theme_link_formatter_link_title_plain($vars) { - return empty($vars['element']['title']) ? '' : check_plain($vars['element']['title']); + return empty($vars['element']['title']) ? '' : check_plain(decode_entities($vars['element']['title'])); } /** @@ -1089,6 +1296,9 @@ function theme_link_formatter_link_title_plain($vars) { */ function theme_link_formatter_link_url($vars) { $link_options = $vars['element']; + if (isset($link_options['attributes']['class'])) { + $link_options['attributes']['class'] = array($link_options['attributes']['class']); + } unset($link_options['title']); unset($link_options['url']); return $vars['element']['url'] ? l($vars['element']['display_url'], $vars['element']['url'], $link_options) : ''; @@ -1111,7 +1321,12 @@ function theme_link_formatter_link_label($vars) { $link_options = $vars['element']; unset($link_options['title']); unset($link_options['url']); - return $vars['element']['url'] ? l($vars['field']['label'], $vars['element']['url'], $link_options) : ''; + $label = $vars['field']['label']; + if (function_exists('i18n_string_translate')) { + $i18n_string_name = "field:{$vars['field']['field_name']}:{$vars['field']['bundle']}:label"; + $label = i18n_string_translate($i18n_string_name, $label); + } + return $vars['element']['url'] ? l($label, $vars['element']['url'], $link_options) : ''; } /** @@ -1141,7 +1356,8 @@ function theme_link_formatter_link_separate($vars) { /** * Implements hook_token_list(). * - * @TODO: hook_token_list no longer exists - this should change to hook_token_info(). + * @TODO: hook_token_list no longer exists - this should change to + * hook_token_info(). */ function link_token_list($type = 'all') { if ($type === 'field' || $type === 'all') { @@ -1156,7 +1372,8 @@ function link_token_list($type = 'all') { /** * Implements hook_token_values(). * - * @TODO: hook_token_values no longer exists - this should change to hook_tokens(). + * @TODO: hook_token_values no longer exists - this should change to + * hook_tokens(). */ function link_token_values($type, $object = NULL) { if ($type === 'field') { @@ -1184,12 +1401,12 @@ function link_views_api() { * Forms a valid URL if possible from an entered address. * * Trims whitespace and automatically adds an http:// to addresses without a - * protocol specified + * protocol specified. * * @param string $url * The url entered by the user. * @param string $protocol - * The protocol to be prepended to the url if one is not specified + * The protocol to be prepended to the url if one is not specified. */ function link_cleanup_url($url, $protocol = 'http') { $url = trim($url); @@ -1199,9 +1416,10 @@ function link_cleanup_url($url, $protocol = 'http') { // Check if there is no protocol specified. $protocol_match = preg_match("/^([a-z0-9][a-z0-9\.\-_]*:\/\/)/i", $url); if (empty($protocol_match)) { - // But should there be? Add an automatic http:// if it starts with a domain name. - $LINK_DOMAINS = _link_domains(); - $domain_match = preg_match('/^(([a-z0-9]([a-z0-9\-_]*\.)+)(' . $LINK_DOMAINS . '|[a-z]{2}))/i', $url); + // But should there be? Add an automatic http:// if it starts with a + // domain name. + $link_domains = _link_domains(); + $domain_match = preg_match('/^(([a-z0-9]([a-z0-9\-_]*\.)+)(' . $link_domains . '|[a-z]{2}))/i', $url); if (!empty($domain_match)) { $url = $protocol . "://" . $url; } @@ -1214,16 +1432,17 @@ function link_cleanup_url($url, $protocol = 'http') { /** * Validates a URL. * - * @param $text + * @param string $text * Url to be validated. - * - * @param $langcode + * @param string $langcode * An optional language code to look up the path in. * - * @return boolean + * @return bool * True if a valid link, FALSE otherwise. */ function link_validate_url($text, $langcode = NULL) { + + $text = _link_clean_relative($text); $text = link_cleanup_url($text); $type = link_url_type($text); @@ -1252,6 +1471,31 @@ function link_validate_url($text, $langcode = NULL) { return $flag; } +/** + * Cleaner of relatives urls. + * + * @param string $url + * The url to clean up the relative protocol. + */ +function _link_clean_relative($url) { + $check = substr($url, 0, 2); + if (isset($_SERVER['HTTPS']) && + ($_SERVER['HTTPS'] == 'on' || $_SERVER['HTTPS'] == 1) || + isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && + $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https') { + $protocol = 'https://'; + } + else { + $protocol = 'http://'; + } + + if ($check == '//') { + $url = str_replace('//', $protocol, $url); + } + + return $url; +} + /** * Type check a URL. * @@ -1267,97 +1511,133 @@ function link_validate_url($text, $langcode = NULL) { */ function link_url_type($text) { // @TODO Complete letters. - $LINK_ICHARS_DOMAIN = (string) html_entity_decode(implode("", array( - "æ", // æ - "Æ", // Æ + // @codingStandardsIgnoreStart + $link_ichars_domain = (string) html_entity_decode(implode("", array( + "¿", // ¿ "À", // À - "à", // à "Á", // Á - "á", // á "Â", //  - "â", // â - "å", // å - "Å", // Å - "ä", // ä + "Ã", // à "Ä", // Ä + "Å", // Å + "Æ", // Æ "Ç", // Ç - "ç", // ç - "Ð", // Ð - "ð", // ð "È", // È - "è", // è "É", // É - "é", // é "Ê", // Ê - "ê", // ê "Ë", // Ë - "ë", // ë + "Ì", // Ì + "Í", // Í "Î", // Î - "î", // î "Ï", // Ï - "ï", // ï - "ø", // ø - "Ø", // Ø - "ö", // ö - "Ö", // Ö + "Ð", // Ð + "Ñ", // Ñ + "Ò", // Ò + "Ó", // Ó "Ô", // Ô - "ô", // ô "Õ", // Õ + "Ö", // Ö + // × + "Ø", // Ø + "Ù", // Ù + "Ú", // Ú + "Û", // Û + "Ü", // Ü + "Ý", // Ý + "Þ", // Þ + // ß (see LINK_ICHARS) + "à", // à + "á", // á + "â", // â + "ã", // ã + "ä", // ä + "å", // å + "æ", // æ + "ç", // ç + "è", // è + "é", // é + "ê", // ê + "ë", // ë + "ì", // ì + "í", // í + "î", // î + "ï", // ï + "ð", // ð + "ñ", // ñ + "ò", // ò + "ó", // ó + "ô", // ô "õ", // õ + "ö", // ö + // ÷ + "ø", // ø + "ù", // ù + "ú", // ú + "û", // û + "ü", // ü + "ý", // ý + "þ", // þ + "ÿ", // ÿ "Œ", // Œ "œ", // œ - "ü", // ü - "Ü", // Ü - "Ù", // Ù - "ù", // ù - "Û", // Û - "û", // û "Ÿ", // Ÿ - "ÿ", // ÿ - "Ñ", // Ñ - "ñ", // ñ - "þ", // þ - "Þ", // Þ - "ý", // ý - "Ý", // Ý - "¿", // ¿ )), ENT_QUOTES, 'UTF-8'); + // @codingStandardsIgnoreEnd - $LINK_ICHARS = $LINK_ICHARS_DOMAIN . (string) html_entity_decode(implode("", array( - "ß", // ß + $link_ichars = $link_ichars_domain . (string) html_entity_decode(implode("", array( + // ß. + "ß", )), ENT_QUOTES, 'UTF-8'); - $allowed_protocols = variable_get('filter_allowed_protocols', array('http', 'https', 'ftp', 'news', 'nntp', 'telnet', 'mailto', 'irc', 'ssh', 'sftp', 'webcal')); - $LINK_DOMAINS = _link_domains(); + $allowed_protocols = variable_get('filter_allowed_protocols', array( + 'http', + 'https', + 'ftp', + 'file', + 'news', + 'nntp', + 'telnet', + 'mailto', + 'irc', + 'ssh', + 'sftp', + 'webcal', + 'tel', + )); + $link_domains = _link_domains(); - // Starting a parenthesis group with (?: means that it is grouped, but is not captured. + // Starting a parenthesis group with (?: means that it is grouped, but is not + // captured. $protocol = '((?:' . implode("|", $allowed_protocols) . '):\/\/)'; - $authentication = "(?:(?:(?:[\w\.\-\+!$&'\(\)*\+,;=" . $LINK_ICHARS . "]|%[0-9a-f]{2})+(?::(?:[\w" . $LINK_ICHARS . "\.\-\+%!$&'\(\)*\+,;=]|%[0-9a-f]{2})*)?)?@)"; - $domain = '(?:(?:[a-z0-9' . $LINK_ICHARS_DOMAIN . ']([a-z0-9' . $LINK_ICHARS_DOMAIN . '\-_\[\]])*)(\.(([a-z0-9' . $LINK_ICHARS_DOMAIN . '\-_\[\]])+\.)*(' . $LINK_DOMAINS . '|[a-z]{2}))?)'; + $authentication = "(?:(?:(?:[\w\.\-\+!$&'\(\)*\+,;=" . $link_ichars . "]|%[0-9a-f]{2})+(?::(?:[\w" . $link_ichars . "\.\-\+%!$&'\(\)*\+,;=]|%[0-9a-f]{2})*)?)?@)"; + $domain = '(?:(?:[a-z0-9' . $link_ichars_domain . ']([a-z0-9' . $link_ichars_domain . '\-_\[\]])*)(\.(([a-z0-9' . $link_ichars_domain . '\-_\[\]])+\.)*(' . $link_domains . '|[a-z]{2}))?)'; $ipv4 = '(?:[0-9]{1,3}(\.[0-9]{1,3}){3})'; $ipv6 = '(?:[0-9a-fA-F]{1,4}(\:[0-9a-fA-F]{1,4}){7})'; $port = '(?::([0-9]{1,5}))'; - // Pattern specific to external links. $external_pattern = '/^' . $protocol . '?' . $authentication . '?(' . $domain . '|' . $ipv4 . '|' . $ipv6 . ' |localhost)' . $port . '?'; // Pattern specific to internal links. - $internal_pattern = "/^(?:[a-z0-9" . $LINK_ICHARS . "_\-+\[\] ]+)"; - $internal_pattern_file = "/^(?:[a-z0-9" . $LINK_ICHARS . "_\-+\[\]\. \/\(\)][a-z0-9" . $LINK_ICHARS . "_\-+\[\]\. \(\)][a-z0-9" . $LINK_ICHARS . "_\-+\[\]\. \/\(\)]+)$/i"; + $internal_pattern = "/^(?:[a-z0-9" . $link_ichars . "_\-+\[\] ]+)"; + $internal_pattern_file = "/^(?:[a-z0-9" . $link_ichars . "_\-+\[\]\. \/\(\)][a-z0-9" . $link_ichars . "_\-+\[\]\. \(\)][a-z0-9" . $link_ichars . "_\-+\[\]\. \/\(\)]+)$/i"; - $directories = "(?:\/[a-z0-9" . $LINK_ICHARS . "_\-\.~+%=&,$'#!():;*@\[\]]*)*"; + $directories = "(?:\/[a-z0-9" . $link_ichars . "_\-\.~+%=&,$'#!():;*@\[\]]*)*"; // Yes, four backslashes == a single backslash. - $query = "(?:\/?\?([?a-z0-9" . $LINK_ICHARS . "+_|\-\.~\/\\\\%=&,$'!():;*@\[\]{} ]*))"; - $anchor = "(?:#[a-z0-9" . $LINK_ICHARS . "_\-\.~+%=&,$'():;*@\[\]\/\?]*)"; + $query = "(?:\/?\?([?a-zA-Z0-9" . $link_ichars . "+_|\-\.~\/\\\\%=&,$'!():;*@\[\]{} ]*))"; + $anchor = "(?:#[a-zA-Z0-9" . $link_ichars . "_\-\.~+%=&,$'():;*@\[\]\/\?]*)"; // The rest of the path for a standard URL. + // @codingStandardsIgnoreLine $end = $directories . '?' . $query . '?' . $anchor . '?' . '$/i'; $message_id = '[^@].*@' . $domain; $newsgroup_name = '(?:[0-9a-z+-]*\.)*[0-9a-z+-]*'; $news_pattern = '/^news:(' . $newsgroup_name . '|' . $message_id . ')$/i'; - $user = '[a-zA-Z0-9' . $LINK_ICHARS . '_\-\.\+\^!#\$%&*+\/\=\?\`\|\{\}~\'\[\]]+'; + $user = '[a-zA-Z0-9' . $link_ichars . '_\-\.\+\^!#\$%&*+\/\=\?\`\|\{\}~\'\[\]]+'; $email_pattern = '/^mailto:' . $user . '@' . '(?:' . $domain . '|' . $ipv4 . '|' . $ipv6 . '|localhost)' . $query . '?$/'; + $tel_pattern = '/^tel:(?:\+[1-9]\d{1,14}|\d{2,15})$/'; + + $file_pattern = "/^(?:file:\/\/)" . "(?:\/?[a-z0-9" . $link_ichars . "_\-\.\\\~+%=&,$'#!():;*@\[\]]*)*" . '$/i'; if (strpos($text, '' . print_r($token_url_tests, TRUE) . '');
-
+ // @codingStandardsIgnoreLine
+ // $this->assert('pass', '' . print_r($token_url_tests, TRUE) . '');.
foreach ($token_url_tests as &$input) {
$this->drupalGet('node/add/page');
-
+
$edit = array(
'title' => $input['label'],
$field_name . '[und][0][title]' => $input['label'],
@@ -73,34 +79,37 @@ class LinkEntityTokenTest extends LinkBaseTestClass {
$input['url'] = $url;
}
- // change to anonymous user
+ // Change to anonymous user.
$this->drupalLogout();
-
+
foreach ($token_url_tests as $index => $input2) {
$node = node_load($index);
$this->assertNotEqual(NULL, $node, "Do we have a node?");
$this->assertEqual($node->nid, $index, "Test that we have a node.");
$token_name = '[node:' . str_replace('_', '-', $field_name) . ':url]';
$assert_data = token_replace($token_name,
- array('node' => $node));
+ array('node' => $node));
$this->assertEqual($input2['href'], $assert_data, "Test that the url token has been set to " . $input2['href'] . ' - ' . $assert_data);
}
}
-
+
/**
- * Creates a link field, fills it, then uses a loaded and node_view'd node to test tokens.
+ * Field Token Node Viewed.
+ *
+ * Creates a link field, fills it, then uses a loaded and node_view'd node to
+ * test tokens.
*/
- function testFieldTokenNodeViewed() {
- // create field
+ public function testFieldTokenNodeViewed() {
+ // Create field.
$settings = array(
'instance[settings][enable_tokens]' => 0,
);
$field_name = $this->createLinkField('page',
- $settings);
+ $settings);
- // create page form
+ // Create page form.
$this->drupalGet('node/add/page');
- //$field_name = 'field_' . $name;
+ // $field_name = 'field_' . $name;.
$this->assertField($field_name . '[und][0][title]', 'Title found');
$this->assertField($field_name . '[und][0][url]', 'URL found');
@@ -122,11 +131,12 @@ class LinkEntityTokenTest extends LinkBaseTestClass {
'label' => $this->randomName(),
),
);
- //$this->assert('pass', '' . print_r($token_url_tests, TRUE) . '');
+ //@codingStandardsIgnoreLine
+ // $this->assert('pass', '' . print_r($token_url_tests, TRUE) . '');.
foreach ($token_url_tests as &$input) {
$this->drupalGet('node/add/page');
-
+
$edit = array(
'title' => $input['label'],
$field_name . '[und][0][title]' => $input['label'],
@@ -137,19 +147,18 @@ class LinkEntityTokenTest extends LinkBaseTestClass {
$input['url'] = $url;
}
- // change to anonymous user
+ // Change to anonymous user.
$this->drupalLogout();
-
+
foreach ($token_url_tests as $index => $input2) {
$node = node_load($index);
- $node_array = node_view($node, 'full');
$this->assertNotEqual(NULL, $node, "Do we have a node?");
$this->assertEqual($node->nid, $index, "Test that we have a node.");
$token_name = '[node:' . str_replace('_', '-', $field_name) . ':url]';
$assert_data = token_replace($token_name,
- array('node' => $node));
+ array('node' => $node));
$this->assertEqual($input2['href'], $assert_data, "Test that the url token has been set to " . $input2['href'] . ' - ' . $assert_data);
}
}
-
-}
\ No newline at end of file
+
+}
diff --git a/sites/all/modules/contrib/fields/link/tests/link.multilingual.test b/sites/all/modules/contrib/fields/link/tests/link.multilingual.test
new file mode 100644
index 00000000..75350722
--- /dev/null
+++ b/sites/all/modules/contrib/fields/link/tests/link.multilingual.test
@@ -0,0 +1,191 @@
+permissions = array_merge($this->permissions, array(
+ 'administer site configuration',
+ 'administer languages',
+ ));
+ parent::setUp($modules);
+ }
+
+ /**
+ * Enables and configured language related stuff.
+ */
+ public function setUpLanguage() {
+ global $language_url;
+ $this->drupalGet('admin/config/regional/language');
+ // Enable the path prefix for the default language: this way any un-prefixed
+ // URL must have a valid fallback value.
+ $edit = array('prefix' => 'en');
+ $this->drupalPost('admin/config/regional/language/edit/en', $edit, t('Save language'));
+ $language_url->prefix = $language_url->language;
+
+ // Add custom language - as we need more than 1 language to be multilingual.
+ // Code for the language.
+ $langcode = 'xx';
+ // The English name for the language.
+ $name = $this->randomName(16);
+ // The native name for the language.
+ $native = $this->randomName(16);
+ $edit = array(
+ 'langcode' => $langcode,
+ 'name' => $name,
+ 'native' => $native,
+ 'prefix' => $langcode,
+ 'direction' => '0',
+ );
+ $this->drupalPost('admin/config/regional/language/add', $edit, t('Add custom language'));
+ variable_set('locale_language_negotiation_url_part', LOCALE_LANGUAGE_NEGOTIATION_URL_PREFIX);
+
+ // Enable URL language detection and selection.
+ $edit = array('language[enabled][locale-url]' => 1);
+ $this->drupalPost('admin/config/regional/language/configure', $edit, t('Save settings'));
+ language_negotiation_set(LANGUAGE_TYPE_INTERFACE, array(LOCALE_LANGUAGE_NEGOTIATION_URL));
+
+ // Reset static caching.
+ drupal_static_reset('language_list');
+ drupal_static_reset('locale_url_outbound_alter');
+ drupal_static_reset('locale_language_url_rewrite_url');
+ }
+}
+
+class LinkMultilingualPathTest extends LinkMultilingualTestCase {
+
+ public static function getInfo() {
+ return array(
+ 'name' => 'Link language path prefix',
+ 'description' => 'Tests that path properly work with language path prefixes.',
+ 'group' => 'Link',
+ );
+ }
+
+ /**
+ * Creates a link field, fills it, then uses a loaded node to test paths.
+ */
+ public function testLanguagePrefixedPaths() {
+ $this->setUpLanguage();
+
+ // Create fields.
+ // Field for absolute urls.
+ $field_name_absolute = $this->createLinkField('page');
+
+ // Field for relative urls.
+ $settings = array(
+ 'instance[settings][absolute_url]' => FALSE,
+ );
+ $field_name_relative = $this->createLinkField('page', $settings);
+
+ // Check the node edit form.
+ $this->drupalGet('node/add/page');
+ $this->assertField($field_name_absolute . '[und][0][title]', 'Title absolute found');
+ $this->assertField($field_name_absolute . '[und][0][url]', 'URL absolute found');
+ $this->assertField($field_name_relative . '[und][0][title]', 'Title relative found');
+ $this->assertField($field_name_relative . '[und][0][url]', 'URL relative found');
+
+ // Create test content.
+ $url_tests = array(
+ 1 => array(
+ 'href' => 'http://dummy.com/' . $this->randomName(),
+ 'label' => $this->randomName(),
+ ),
+ 2 => array(
+ 'href' => 'node/1',
+ 'label' => $this->randomName(),
+ ),
+ 3 => array(
+ 'href' => 'node/1?property=value',
+ 'label' => $this->randomName(),
+ 'query' => array('property' => 'value'),
+ ),
+ 4 => array(
+ 'href' => 'node/1#position',
+ 'label' => $this->randomName(),
+ 'fragment' => 'position',
+ ),
+ 5 => array(
+ 'href' => 'node/1?property=value2#lower',
+ 'label' => $this->randomName(),
+ 'fragment' => 'lower',
+ 'query' => array('property' => 'value2'),
+ ),
+ );
+ foreach ($url_tests as $index => &$input) {
+ $this->drupalGet('node/add/page');
+
+ $edit = array(
+ 'title' => $input['label'],
+ $field_name_absolute . '[und][0][title]' => $input['label'],
+ $field_name_absolute . '[und][0][url]' => $input['href'],
+ $field_name_relative . '[und][0][title]' => $input['label'],
+ $field_name_relative . '[und][0][url]' => $input['href'],
+ );
+ $this->drupalPost(NULL, $edit, t('Save'));
+ $url = $this->getUrl();
+ $input['url'] = $url;
+ }
+
+ // Change to anonymous user.
+ $this->drupalLogout();
+
+ foreach (array_slice($url_tests, 1, NULL, TRUE) as $index => $input2) {
+ $node = node_load($index);
+ $this->assertNotEqual(NULL, $node, "Do we have a node?");
+ $this->assertEqual($node->nid, $index, "Test that we have a node.");
+ $this->drupalGet('node/' . $index);
+
+ $relative_expected = url('node/1', array('absolute' => FALSE) + $input2);
+ $absolute_expected = url('node/1', array('absolute' => TRUE) + $input2);
+
+ $absolute_result = $this->xpath('//*[contains(@class, "field-name-' . drupal_clean_css_identifier($field_name_absolute) . '")]/div/div/a/@href');
+ $absolute_result = (string) reset($absolute_result);
+ $this->assertEqual($absolute_result, $absolute_expected, "Absolute url output ('" . $absolute_result . "') looks as expected ('" . $absolute_expected . "')");
+
+ $relative_result = $this->xpath('//*[contains(@class, "field-name-' . drupal_clean_css_identifier($field_name_relative) . '")]/div/div/a/@href');
+ $relative_result = (string) reset($relative_result);
+ $this->assertEqual($relative_result, $relative_expected, "Relative url output ('" . $relative_result . "') looks as expected ('" . $relative_expected . "')");
+ }
+
+ // Check if this works with the alias too.
+ // Add a path alias for node 1.
+ $path = array(
+ 'source' => 'node/1',
+ 'alias' => $url_tests[1]['label'],
+ );
+ path_save($path);
+ // Another iteration over the same nodes - this time they should use the
+ // path alias.
+ foreach (array_slice($url_tests, 1, NULL, TRUE) as $index => $input2) {
+ $node = node_load($index);
+ $this->assertNotEqual(NULL, $node, "Do we have a node?");
+ $this->assertEqual($node->nid, $index, "Test that we have a node.");
+ $this->drupalGet('node/' . $index);
+
+ $relative_expected = url('node/1', array('absolute' => FALSE) + $input2);
+ $absolute_expected = url('node/1', array('absolute' => TRUE) + $input2);
+
+ $absolute_result = $this->xpath('//*[contains(@class, "field-name-' . drupal_clean_css_identifier($field_name_absolute) . '")]/div/div/a/@href');
+ $absolute_result = (string) reset($absolute_result);
+ $this->assertEqual($absolute_result, $absolute_expected, "Absolute alias-url output ('" . $absolute_result . "') looks as expected ('" . $absolute_expected . "')");
+
+ $relative_result = $this->xpath('//*[contains(@class, "field-name-' . drupal_clean_css_identifier($field_name_relative) . '")]/div/div/a/@href');
+ $relative_result = (string) reset($relative_result);
+ $this->assertEqual($relative_result, $relative_expected, "Relative alias-url output ('" . $relative_result . "') looks as expected ('" . $relative_expected . "')");
+ }
+ }
+}
diff --git a/sites/all/modules/contrib/fields/link/tests/link.test b/sites/all/modules/contrib/fields/link/tests/link.test
index b0301530..dd9adb49 100644
--- a/sites/all/modules/contrib/fields/link/tests/link.test
+++ b/sites/all/modules/contrib/fields/link/tests/link.test
@@ -5,10 +5,15 @@
* Link base test file - contains common functions for testing links.
*/
+/**
+ * Base Test Class.
+ */
class LinkBaseTestClass extends DrupalWebTestCase {
+
protected $permissions = array(
'access content',
'administer content types',
+ 'administer fields',
'administer nodes',
'administer filters',
'access comments',
@@ -17,19 +22,23 @@ class LinkBaseTestClass extends DrupalWebTestCase {
'create page content',
);
- function setUp() {
+ /**
+ * Setup.
+ */
+ public function setUp() {
$modules = func_get_args();
$modules = (isset($modules[0]) && is_array($modules[0]) ? $modules[0] : $modules);
$modules[] = 'field_ui';
$modules[] = 'link';
parent::setUp($modules);
- $perms = user_role_permissions(array(array_search('administrator', user_roles()) => 'administrator'));
- $perms = array_keys($perms[array_search('administrator', user_roles())]);
- $admin = $this->drupalCreateUser($perms);
- $this->drupalLogin($admin);
+ $this->web_user = $this->drupalCreateUser($this->permissions);
+ $this->drupalLogin($this->web_user);
}
+ /**
+ * Create Link Field.
+ */
protected function createLinkField($node_type = 'page', $settings = array()) {
$name = strtolower($this->randomName());
$edit = array(
@@ -50,4 +59,5 @@ class LinkBaseTestClass extends DrupalWebTestCase {
return $field_name;
}
+
}
diff --git a/sites/all/modules/contrib/fields/link/tests/link.token.test b/sites/all/modules/contrib/fields/link/tests/link.token.test
index 617260e6..edbb1df5 100644
--- a/sites/all/modules/contrib/fields/link/tests/link.token.test
+++ b/sites/all/modules/contrib/fields/link/tests/link.token.test
@@ -6,10 +6,13 @@
*/
/**
- * Testing that tokens can be used in link titles
+ * Testing that tokens can be used in link titles.
*/
class LinkTokenTest extends LinkBaseTestClass {
+ /**
+ * Get Info.
+ */
public static function getInfo() {
return array(
'name' => 'Link tokens - browser test',
@@ -19,34 +22,38 @@ class LinkTokenTest extends LinkBaseTestClass {
);
}
- function setUp($modules = array()) {
+ /**
+ * Setup.
+ */
+ public function setUp($modules = array()) {
parent::setUp(array('token'));
}
/**
* Creates a link field with a required title enabled for user-entered tokens.
+ *
* Creates a node with a token in the link title and checks the value.
*/
- function testUserTokenLinkCreate() {
- // create field
+ public function testUserTokenLinkCreate() {
+ // Create field.
$settings = array(
'instance[settings][enable_tokens]' => 1,
);
$field_name = $this->createLinkField('page',
- $settings);
+ $settings);
- // create page form
+ // Create page form.
$this->drupalGet('node/add/page');
- //$field_name = 'field_' . $name;
+ // $field_name = 'field_' . $name;.
$this->assertField($field_name . '[und][0][title]', 'Title found');
$this->assertField($field_name . '[und][0][url]', 'URL found');
$input = array(
- 'href' => 'http://example.com/' . $this->randomName(),
- 'label' => $this->randomName(),
+ 'href' => 'http://example.com/' . $this->randomName(),
+ 'label' => $this->randomName(),
);
- //$this->drupalLogin($this->web_user);
+ // $this->drupalLogin($this->web_user);.
$this->drupalGet('node/add/page');
$edit = array(
@@ -57,36 +64,37 @@ class LinkTokenTest extends LinkBaseTestClass {
$this->drupalPost(NULL, $edit, t('Save'));
$url = $this->getUrl();
- // change to anonymous user
+ // Change to anonymous user.
$this->drupalLogout();
$this->drupalGet($url);
$this->assertRaw(l($input['label'] . ' page', $input['href']));
}
-
/**
* Creates a link field with a static title and an admin-entered token.
+ *
* Creates a node with a link and checks the title value.
*/
- function testStaticTokenLinkCreate() {
+ public function testStaticTokenLinkCreate() {
- // create field
+ // Create field.
$name = $this->randomName();
$settings = array(
'instance[settings][title]' => 'value',
- 'instance[settings][title_value]' => $name . ' [node:content-type:machine-name]');
+ 'instance[settings][title_value]' => $name . ' [node:content-type:machine-name]',
+ );
$field_name = $this->createLinkField('page', $settings);
- // create page form
+ // Create page form.
$this->drupalGet('node/add/page');
$this->assertField($field_name . '[und][0][url]', 'URL found');
$input = array(
- 'href' => 'http://example.com/' . $this->randomName()
+ 'href' => 'http://example.com/' . $this->randomName(),
);
- //$this->drupalLogin($this->web_user);
+ // $this->drupalLogin($this->web_user);.
$this->drupalGet('node/add/page');
$edit = array(
@@ -97,7 +105,7 @@ class LinkTokenTest extends LinkBaseTestClass {
$url = $this->getUrl();
- // change to anonymous user
+ // Change to anonymous user.
$this->drupalLogout();
$this->drupalGet($url);
@@ -106,30 +114,32 @@ class LinkTokenTest extends LinkBaseTestClass {
/**
* Creates a link field with a static title and an admin-entered token.
+ *
* Creates a node with a link and checks the title value.
*
* Basically, I want to make sure the [title-raw] token works, because it's a
* token that changes from node to node, where [type]'s always going to be the
* same.
*/
- function testStaticTokenLinkCreate2() {
+ public function testStaticTokenLinkCreate2() {
- // create field
+ // Create field.
$name = $this->randomName();
$settings = array(
'instance[settings][title]' => 'value',
- 'instance[settings][title_value]' => $name . ' [node:title]');
+ 'instance[settings][title_value]' => $name . ' [node:title]',
+ );
$field_name = $this->createLinkField('page', $settings);
- // create page form
+ // Create page form.
$this->drupalGet('node/add/page');
$this->assertField($field_name . '[und][0][url]', 'URL found');
$input = array(
- 'href' => 'http://example.com/' . $this->randomName()
+ 'href' => 'http://example.com/' . $this->randomName(),
);
- //$this->drupalLogin($this->web_user);
+ // $this->drupalLogin($this->web_user);.
$this->drupalGet('node/add/page');
$edit = array(
@@ -140,27 +150,32 @@ class LinkTokenTest extends LinkBaseTestClass {
$url = $this->getUrl();
- // change to anonymous user
+ // Change to anonymous user.
$this->drupalLogout();
$this->drupalGet($url);
$this->assertRaw(l($name . ' ' . $name, $input['href']));
}
- // This test doesn't seem to actually work, due to lack of 'title' in url.
- function _test_Link_With_Title_Attribute_token_url_form() {
- /* $this->loginWithPermissions($this->permissions);
+ /**
+ * This test doesn't seem to actually work, due to lack of 'title' in url.
+ *
+ * @codingStandardsIgnoreStart
+ */
+ public function _test_Link_With_Title_Attribute_token_url_form() {
+ // @codingStandardsIgnoreEnd
+ /* $this->loginWithPermissions($this->permissions);
$this->acquireContentTypes(1);
$field_settings = array(
- 'type' => 'link',
- 'widget_type' => 'link',
- 'type_name' => $this->content_types[0]->name,
- 'attributes' => array(
- 'class' => '',
- 'target' => 'default',
- 'rel' => 'nofollow',
- 'title' => '',
- ),
+ 'type' => 'link',
+ 'widget_type' => 'link',
+ 'type_name' => $this->content_types[0]->name,
+ 'attributes' => array(
+ 'class' => '',
+ 'target' => 'default',
+ 'rel' => 'nofollow',
+ 'title' => '',
+ ),
);
$field = $this->createField($field_settings, 0);
@@ -170,10 +185,10 @@ class LinkTokenTest extends LinkBaseTestClass {
$url_type = str_replace('_', '-', $this->content_types[0]->type);
$edit = array('attributes[title]' => '['. $field_name .'-url]',
- 'enable_tokens' => TRUE);
-
+ 'enable_tokens' => TRUE);
+ // @codingStandardsIgnoreLine
$this->drupalPost('admin/content/node-type/'. $url_type .'/fields/'. $field['field_name'],
- $edit, t('Save field settings'));
+ $edit, t('Save field settings'));
$this->assertText(t('Saved field @field_name', array('@field_name' => $field['field_name'])));*/
$name = $this->randomName();
$settings = array(
@@ -183,12 +198,9 @@ class LinkTokenTest extends LinkBaseTestClass {
$field_name = $this->createLinkField('page', $settings);
// So, having saved this field_name, let's see if it works...
- //$this->acquireNodes(1);
-
- //$node = node_load($this->nodes[0]->nid);
-
- //$this->drupalGet('node/'. $this->nodes[0]->nid);
-
+ // $this->acquireNodes(1);
+ // $node = node_load($this->nodes[0]->nid);
+ // $this->drupalGet('node/'. $this->nodes[0]->nid);.
$edit = array();
$test_link_url = 'http://www.example.com/test';
$edit[$field_name . '[und][0][url]'] = $test_link_url;
@@ -200,23 +212,28 @@ class LinkTokenTest extends LinkBaseTestClass {
$this->drupalPost(NULL, $edit, t('Save'));
// Make sure we get a new version!
- //$node = node_load($this->nodes[0]->nid, NULL, TRUE);
+ // $node = node_load($this->nodes[0]->nid, NULL, TRUE);.
$this->assertText(t('Basic page @title has been updated.',
- array('@title' => $name)));
+ array('@title' => $name)));
- //$this->drupalGet('node/'. $node->nid);
+ // $this->drupalGet('node/'. $node->nid);.
$this->assertText($title, 'Make sure the link title/text shows');
$this->assertRaw(' title="' . $test_link_url . '"', "Do we show the link url as the title attribute?");
$this->assertNoRaw(' title="[' . $field_name . '-url]"');
$this->assertTrue(module_exists('token'), t('Assure that Token Module is enabled.'));
- //$this->fail($this->content);
+ // $this->fail($this->content);.
}
/**
+ * Link With Title Attribute token title form.
+ *
* If the title of the link is set to the title attribute, then the title
* attribute isn't supposed to show.
+ *
+ * @codingStandardsIgnoreStart
*/
- function _test_Link_With_Title_Attribute_token_title_form() {
+ public function _test_Link_With_Title_Attribute_token_title_form() {
+ // @codingStandardsIgnoreEnd
$this->loginWithPermissions($this->permissions);
$this->acquireContentTypes(1);
$field_settings = array(
@@ -233,21 +250,20 @@ class LinkTokenTest extends LinkBaseTestClass {
$field = $this->createField($field_settings, 0);
$field_name = $field['field_name'];
- $field_db_info = content_database_info($field);
$url_type = str_replace('_', '-', $this->content_types[0]->type);
- $edit = array('attributes[title]' => '[' . $field_name . '-title]',
- 'enable_tokens' => TRUE);
+ $edit = array(
+ 'attributes[title]' => '[' . $field_name . '-title]',
+ 'enable_tokens' => TRUE,
+ );
$this->drupalPost('admin/content/node-type/' . $url_type . '/fields/' . $field['field_name'],
- $edit, t('Save field settings'));
+ $edit, t('Save field settings'));
$this->assertText(t('Saved field @field_name', array('@field_name' => $field['field_name'])));
// So, having saved this field_name, let's see if it works...
$this->acquireNodes(1);
- $node = node_load($this->nodes[0]->nid);
-
$this->drupalGet('node/' . $this->nodes[0]->nid);
$edit = array();
@@ -260,24 +276,35 @@ class LinkTokenTest extends LinkBaseTestClass {
// Make sure we get a new version!
$node = node_load($this->nodes[0]->nid, NULL, TRUE);
$this->assertText(t('@type @title has been updated.',
- array('@title' => $node->title,
- '@type' => $this->content_types[0]->name)));
+ array(
+ '@title' => $node->title,
+ '@type' => $this->content_types[0]->name,
+ )));
$this->drupalGet('node/' . $node->nid);
$this->assertText($title, 'Make sure the link title/text shows');
$this->assertNoRaw(' title="' . $title . '"', "We should not show the link title as the title attribute?");
$this->assertNoRaw(' title="[' . $field_name . '-title]"');
- //$this->fail($this->content);
+ // $this->fail($this->content);.
}
/**
- * Trying to set the url to contain a token.
+ * Trying to set the url to contain a token.
+ *
+ * @codingStandardsIgnoreStart
*/
- function _testUserTokenLinkCreateInURL() {
- $this->web_user = $this->drupalCreateUser(array('administer content types', 'access content', 'create page content'));
+ public function _testUserTokenLinkCreateInURL() {
+ //@codingStandardsIgnoreEnd
+
+ $this->web_user = $this->drupalCreateUser(array(
+ 'administer content types',
+ 'administer fields',
+ 'access content',
+ 'create page content',
+ ));
$this->drupalLogin($this->web_user);
- // create field
+ // Create field.
$name = strtolower($this->randomName());
$edit = array(
'_add_new_field[label]' => $name,
@@ -288,20 +315,21 @@ class LinkTokenTest extends LinkBaseTestClass {
$this->drupalPost('admin/content/node-type/page/fields', $edit, t('Save'));
$this->drupalPost(NULL, array(
'title' => 'required',
- 'enable_tokens' => 1), t('Save field settings'));
+ 'enable_tokens' => 1,
+ ), t('Save field settings'));
// Is field created?
$this->assertRaw(t('Added field %label.', array('%label' => $name)), 'Field added');
- // create page form
+ // Create page form.
$this->drupalGet('node/add/page');
$field_name = 'field_' . $name;
$this->assertField($field_name . '[0][title]', 'Title found');
$this->assertField($field_name . '[0][url]', 'URL found');
$input = array(
- 'href' => 'http://example.com/' . $this->randomName(),
- 'label' => $this->randomName(),
+ 'href' => 'http://example.com/' . $this->randomName(),
+ 'label' => $this->randomName(),
);
$this->drupalLogin($this->web_user);
@@ -315,22 +343,31 @@ class LinkTokenTest extends LinkBaseTestClass {
$this->drupalPost(NULL, $edit, t('Save'));
$url = $this->getUrl();
- // change to anonymous user
+ // Change to anonymous user.
$this->drupalLogout();
$this->drupalGet($url);
$this->assertRaw(l($input['label'], $input['href'] . '/page'));
- //$this->fail($this->content);
+ // $this->fail($this->content);.
}
/**
- * Trying to set the url to contain a token.
+ * Trying to set the url to contain a token.
+ *
+ * @codingStandardsIgnoreStart
*/
- function _testUserTokenLinkCreateInURL2() {
- $this->web_user = $this->drupalCreateUser(array('administer content types', 'access content', 'create page content'));
+ public function _testUserTokenLinkCreateInURL2() {
+ // @codingStandardsIgnoreEnd
+
+ $this->web_user = $this->drupalCreateUser(array(
+ 'administer content types',
+ 'administer fields',
+ 'access content',
+ 'create page content',
+ ));
$this->drupalLogin($this->web_user);
- // create field
+ // Create field.
$name = strtolower($this->randomName());
$edit = array(
'_add_new_field[label]' => $name,
@@ -341,20 +378,21 @@ class LinkTokenTest extends LinkBaseTestClass {
$this->drupalPost('admin/content/node-type/page/fields', $edit, t('Save'));
$this->drupalPost(NULL, array(
'title' => 'required',
- 'enable_tokens' => 1), t('Save field settings'));
+ 'enable_tokens' => 1,
+ ), t('Save field settings'));
// Is field created?
$this->assertRaw(t('Added field %label.', array('%label' => $name)), 'Field added');
- // create page form
+ // Create page form.
$this->drupalGet('node/add/page');
$field_name = 'field_' . $name;
$this->assertField($field_name . '[0][title]', 'Title found');
$this->assertField($field_name . '[0][url]', 'URL found');
$input = array(
- 'href' => 'http://example.com/' . $this->randomName(),
- 'label' => $this->randomName(),
+ 'href' => 'http://example.com/' . $this->randomName(),
+ 'label' => $this->randomName(),
);
$this->drupalLogin($this->web_user);
@@ -368,22 +406,34 @@ class LinkTokenTest extends LinkBaseTestClass {
$this->drupalPost(NULL, $edit, t('Save'));
$url = $this->getUrl();
- // change to anonymous user
+ // Change to anonymous user.
$this->drupalLogout();
$this->drupalGet($url);
$this->assertRaw(l($input['label'], $input['href'] . '/' . $this->web_user->uid));
}
-
+
/**
- * Test that if you have a title and no url on a field which does not have tokens enabled,
- * that the title is sanitized once.
+ * CRUD Title Only Title No Link.
+ *
+ * Test that if you have a title and no url on a field which does not have
+ * tokens enabled, that the title is sanitized once.
+ *
+ * @codingStandardsIgnoreStart
*/
- function testCRUDTitleOnlyTitleNoLink2() {
- $this->web_user = $this->drupalCreateUser(array('administer content types', 'access content', 'create page content'));
+ public function testCRUDTitleOnlyTitleNoLink2() {
+ //@codingStandardsIgnoreEnd
+
+ $this->web_user = $this->drupalCreateUser(array(
+ 'administer content types',
+ 'administer fields',
+ 'access content',
+ 'create page content',
+ ));
+
$this->drupalLogin($this->web_user);
- // create field
+ // Create field.
$name = strtolower($this->randomName());
$field_name = 'field_' . $name;
$edit = array(
@@ -401,8 +451,8 @@ class LinkTokenTest extends LinkBaseTestClass {
// Is field created?
$this->assertRaw(t('Saved %label configuration', array('%label' => $name)), 'Field added');
-
- // create page form
+
+ // Create page form.
$this->drupalGet('node/add/page');
$this->assertField($field_name . '[und][0][url]', 'URL found');
@@ -419,13 +469,12 @@ class LinkTokenTest extends LinkBaseTestClass {
$this->drupalPost(NULL, $edit, t('Save'));
$url = $this->getUrl();
-
- // change to anonymous user
+
+ // Change to anonymous user.
$this->drupalLogout();
$this->drupalGet($url);
$this->assertRaw('This & That');
}
-
-
+
}
diff --git a/sites/all/modules/contrib/fields/link/tests/link.validate.test b/sites/all/modules/contrib/fields/link/tests/link.validate.test
index f03a64cc..6338840f 100644
--- a/sites/all/modules/contrib/fields/link/tests/link.validate.test
+++ b/sites/all/modules/contrib/fields/link/tests/link.validate.test
@@ -5,8 +5,14 @@
* Tests that exercise the validation functions in the link module.
*/
+/**
+ * Validate Test Case.
+ */
class LinkValidateTestCase extends LinkBaseTestClass {
+ /**
+ * Create Link.
+ */
protected function createLink($url, $title, $attributes = array()) {
return array(
'url' => $url,
@@ -17,8 +23,11 @@ class LinkValidateTestCase extends LinkBaseTestClass {
/**
* Takes a url, and sees if it can validate that the url is valid.
+ *
+ * @codingStandardsIgnoreStart
*/
protected function link_test_validate_url($url) {
+ // @codingStandardsIgnoreEnd
$field_name = $this->createLinkField();
@@ -26,11 +35,11 @@ class LinkValidateTestCase extends LinkBaseTestClass {
$settings = array(
'title' => $label,
$field_name => array(
- LANGUAGE_NONE=> array(
+ LANGUAGE_NONE => array(
array(
'title' => $label,
'url' => $url,
- )
+ ),
),
),
);
@@ -41,10 +50,17 @@ class LinkValidateTestCase extends LinkBaseTestClass {
$this->assertEqual($url, $node->{$field_name}[LANGUAGE_NONE][0]['url']);
}
+
}
+/**
+ * Class for Validate Test.
+ */
class LinkValidateTest extends LinkValidateTestCase {
+ /**
+ * Get Info.
+ */
public static function getInfo() {
return array(
'name' => 'Link Validation Tests',
@@ -53,20 +69,35 @@ class LinkValidateTest extends LinkValidateTestCase {
);
}
- function test_link_validate_basic_url() {
+ /**
+ * Validate basic URL.
+ *
+ * @codingStandardsIgnoreStart
+ */
+ public function test_link_validate_basic_url() {
+ // @codingStandardsIgnoreEnd
$this->link_test_validate_url('http://www.example.com');
}
/**
* Test if we're stopped from posting a bad url on default validation.
+ *
+ * @codingStandardsIgnoreStart
*/
- function test_link_validate_bad_url_validate_default() {
- $perms = user_role_permissions(array(array_search('administrator', user_roles()) => 'administrator'));
- $perms = array_keys($perms[array_search('administrator', user_roles())]);
- $admin = $this->drupalCreateUser($perms);
- $this->drupalLogin($admin);
+ public function test_link_validate_bad_url_validate_default() {
+ // @codingStandardsIgnoreEnd
+ $this->web_user = $this->drupalCreateUser(array(
+ 'administer content types',
+ 'administer fields',
+ 'administer nodes',
+ 'administer filters',
+ 'access content',
+ 'create page content',
+ 'access administration pages',
+ ));
+ $this->drupalLogin($this->web_user);
- // create field
+ // Create field.
$name = strtolower($this->randomName());
$edit = array(
'fields[_add_new_field][label]' => $name,
@@ -83,32 +114,43 @@ class LinkValidateTest extends LinkValidateTestCase {
node_types_rebuild();
menu_rebuild();
- // create page form
+ // Create page form.
$this->drupalGet('node/add/page');
$field_name = 'field_' . $name;
$this->assertField('edit-field-' . $name . '-und-0-title', 'Title found');
$this->assertField('edit-field-' . $name . '-und-0-url', 'URL found');
-
$edit = array(
'title' => 'Simple Title',
$field_name . '[und][0][url]' => 'edik:naw',
);
$this->drupalPost(NULL, $edit, t('Save'));
- $this->assertText(t('The value @value provided for @field is not a valid URL.', array('@value' => 'edik:naw', '@field' => $name)));
+ $this->assertText(t('The value @value provided for @field is not a valid URL.', array(
+ '@value' => 'edik:naw',
+ '@field' => $name,
+ )));
}
/**
* Test if we're stopped from posting a bad url with validation on.
+ *
+ * @codingStandardsIgnoreStart
*/
- function test_link_validate_bad_url_validate_on() {
- $perms = user_role_permissions(array(array_search('administrator', user_roles()) => 'administrator'));
- $perms = array_keys($perms[array_search('administrator', user_roles())]);
- $admin = $this->drupalCreateUser($perms);
- $this->drupalLogin($admin);
+ public function test_link_validate_bad_url_validate_on() {
+ // @codingStandardsIgnoreEnd
+ $this->web_user = $this->drupalCreateUser(array(
+ 'administer content types',
+ 'administer fields',
+ 'administer nodes',
+ 'administer filters',
+ 'access content',
+ 'create page content',
+ 'access administration pages',
+ ));
+ $this->drupalLogin($this->web_user);
- // create field
+ // Create field.
$name = strtolower($this->randomName());
$edit = array(
'fields[_add_new_field][label]' => $name,
@@ -125,33 +167,44 @@ class LinkValidateTest extends LinkValidateTestCase {
node_types_rebuild();
menu_rebuild();
- // create page form
+ // Create page form.
$this->drupalGet('node/add/page');
$field_name = 'field_' . $name;
$this->assertField('edit-field-' . $name . '-und-0-title', 'Title found');
$this->assertField('edit-field-' . $name . '-und-0-url', 'URL found');
-
$edit = array(
'title' => 'Simple Title',
$field_name . '[und][0][url]' => 'edik:naw',
);
$this->drupalPost(NULL, $edit, t('Save'));
- $this->assertText(t('The value @value provided for @field is not a valid URL.', array('@field' => $name, '@value' => 'edik:naw')));
+ $this->assertText(t('The value @value provided for @field is not a valid URL.', array(
+ '@field' => $name,
+ '@value' => 'edik:naw',
+ )));
}
/**
* Test if we can post a bad url if the validation is expressly turned off.
+ *
+ * @codingStandardsIgnoreStart
*/
- function test_link_validate_bad_url_validate_off() {
- $perms = user_role_permissions(array(array_search('administrator', user_roles()) => 'administrator'));
- $perms = array_keys($perms[array_search('administrator', user_roles())]);
- $admin = $this->drupalCreateUser($perms);
- $this->drupalLogin($admin);
+ public function test_link_validate_bad_url_validate_off() {
+ // @codingStandardsIgnoreEnd
+ $this->web_user = $this->drupalCreateUser(array(
+ 'administer content types',
+ 'administer fields',
+ 'administer nodes',
+ 'administer filters',
+ 'access content',
+ 'create page content',
+ 'access administration pages',
+ ));
+ $this->drupalLogin($this->web_user);
- // create field
+ // Create field.
$name = strtolower($this->randomName());
$edit = array(
'fields[_add_new_field][label]' => $name,
@@ -163,6 +216,7 @@ class LinkValidateTest extends LinkValidateTestCase {
$this->drupalPost(NULL, array(), t('Save field settings'));
$this->drupalPost(NULL, array('instance[settings][validate_url]' => FALSE), t('Save settings'));
+ // @codingStandardsIgnoreLine
/*$instance_details = db_query("SELECT * FROM {field_config_instance} WHERE field_name = :field_name AND bundle = 'page'", array(':field_name' => 'field_'. $name))->fetchObject();
$this->fail(''. print_r($instance_details, TRUE) .'
');
$this->fail(''. print_r(unserialize($instance_details->data), TRUE) .'
');*/
@@ -172,48 +226,62 @@ class LinkValidateTest extends LinkValidateTestCase {
node_types_rebuild();
menu_rebuild();
- // create page form
+ // Create page form.
$this->drupalGet('node/add/page');
$field_name = 'field_' . $name;
$this->assertField('edit-field-' . $name . '-und-0-title', 'Title found');
$this->assertField('edit-field-' . $name . '-und-0-url', 'URL found');
-
$edit = array(
'title' => 'Simple Title',
$field_name . '[und][0][url]' => 'edik:naw',
);
$this->drupalPost(NULL, $edit, t('Save'));
- $this->assertNoText(t('The value %value provided for %field is not a valid URL.', array('%field' => $name, '%value' => 'edik:naw')));
+ $this->assertNoText(t('The value %value provided for %field is not a valid URL.', array(
+ '%field' => $name,
+ '%value' => 'edik:naw',
+ )));
}
/**
- * Test if a bad url can sneak through un-filtered if we play with the validation...
+ * Validate switching between validation status.
+ *
+ * Test if a bad url can sneak through un-filtered if we play with the
+ * validation...
+ *
+ * @codingStandardsIgnoreStart
*/
- function x_test_link_validate_switching_between_validation_status() {
+ public function x_test_link_validate_switching_between_validation_status() {
+ // @codingStandardsIgnoreEnd
$this->acquireContentTypes(1);
- $perms = user_role_permissions(array(array_search('administrator', user_roles()) => 'administrator'));
- $perms = array_keys($perms[array_search('administrator', user_roles())]);
- $admin = $this->drupalCreateUser($perms);
- $this->drupalLogin($admin);
- variable_set('node_options_' . $this->content_types[0]->name, array('status', 'promote'));
+ $this->web_user = $this->drupalCreateUser(array(
+ 'administer content types',
+ 'administer fields',
+ 'administer nodes',
+ 'access administration pages',
+ 'access content',
+ 'create ' . $this->content_types[0]->type . ' content',
+ 'edit any ' . $this->content_types[0]->type . ' content',
+ ));
+ $this->drupalLogin($this->web_user);
+ variable_set('node_options_' . $this->content_types[0]->name, array(
+ 'status',
+ 'promote',
+ ));
$field_settings = array(
'type' => 'link',
'widget_type' => 'link',
'type_name' => $this->content_types[0]->name,
- 'attributes' => array(), // <-- This is needed or we have an error
+ // <-- This is needed or we have an error.
+ 'attributes' => array(),
'validate_url' => 0,
);
$field = $this->createField($field_settings, 0);
- //$this->fail(''. print_r($field, TRUE) .'
');
- $field_db_info = content_database_info($field);
$this->acquireNodes(2);
- $node = node_load($this->nodes[0]->nid);
-
$this->drupalGet('node/' . $this->nodes[0]->nid);
$edit = array();
@@ -223,8 +291,13 @@ class LinkValidateTest extends LinkValidateTestCase {
$edit[$field['field_name'] . '[0][title]'] = $title;
$this->drupalPost('node/' . $this->nodes[0]->nid . '/edit', $edit, t('Save'));
- //$this->pass($this->content);
- $this->assertNoText(t('The value %value provided for %field is not a valid URL.', array('%field' => $name, '%value' => trim($url))));
+ // $this->pass($this->content);.
+ // @codingStandardsIgnoreLine
+ $this->assertNoText(t('The value %value provided for %field is not a valid URL.', array(
+ // @codingStandardsIgnoreLine
+ '%field' => $name,
+ '%value' => trim($url),
+ )));
// Make sure we get a new version!
$node = node_load($this->nodes[0]->nid, NULL, TRUE);
@@ -236,8 +309,9 @@ class LinkValidateTest extends LinkValidateTestCase {
// Turn the array validation back _on_.
$edit = array('validate_url' => TRUE);
$node_type_link = str_replace('_', '-', $node->type);
- //$this->drupalGet('admin/content/node-type/'. $node_type_link .'/fields'); ///'. $field['field_name']);
- //$this->fail($this->content);
+ // @codingStandardsIgnoreLine
+ // $this->drupalGet('admin/content/node-type/'. $node_type_link .'/fields'); ///'. $field['field_name']);
+ // $this->fail($this->content);.
$this->drupalPost('admin/content/node-type/' . $node_type_link . '/fields/' . $field['field_name'], $edit, t('Save field settings'));
$this->drupalGet('node/' . $node->nid);
@@ -245,17 +319,26 @@ class LinkValidateTest extends LinkValidateTestCase {
// url() function. But we should have a test that makes sure it continues
// to work.
$this->assertNoRaw($url, 'Make sure Javascript does not display.');
- //$this->fail($this->content);
-
+ // $this->fail($this->content);.
}
- // Validate that '' is a valid url.
- function test_link_front_url() {
+ /**
+ * Validate that '' is a valid url.
+ *
+ * @codingStandardsIgnoreStart
+ */
+ public function test_link_front_url() {
+ // @codingStandardsIgnoreEnd
$this->link_test_validate_url('');
}
- // Validate that an internal url would be accepted.
- function test_link_internal_url() {
+ /**
+ * Validate that an internal url would be accepted.
+ *
+ * @codingStandardsIgnoreStart
+ */
+ public function test_link_internal_url() {
+ // @codingStandardsIgnoreEnd
// Create the content first.
$node = $this->drupalCreateNode();
@@ -265,22 +348,46 @@ class LinkValidateTest extends LinkValidateTestCase {
$this->assertEqual(LINK_INTERNAL, $type, 'Test ' . $link . ' is an internal link.');
}
- // Validate a simple mailto.
- function test_link_mailto() {
+ /**
+ * Validate a simple mailto.
+ *
+ * @codingStandardsIgnoreStart
+ */
+ public function test_link_mailto() {
+ // @codingStandardsIgnoreEnd
$this->link_test_validate_url('mailto:jcfiala@gmail.com');
}
- function test_link_external_https() {
+ /**
+ * Check link external https.
+ *
+ * @codingStandardsIgnoreStart
+ */
+ public function test_link_external_https() {
+ // @codingStandardsIgnoreEnd
$this->link_test_validate_url('https://www.example.com/');
}
- function test_link_ftp() {
+ /**
+ * Check link FTP.
+ *
+ * @codingStandardsIgnoreStart
+ */
+ public function test_link_ftp() {
+ // @codingStandardsIgnoreEnd
$this->link_test_validate_url('ftp://www.example.com/');
}
+
}
+/**
+ * Validate Test News.
+ */
class LinkValidateTestNews extends LinkValidateTestCase {
+ /**
+ * Get Info.
+ */
public static function getInfo() {
return array(
'name' => 'Link News Validation Tests',
@@ -289,18 +396,36 @@ class LinkValidateTestNews extends LinkValidateTestCase {
);
}
- // Validate a news link to a message group
- function test_link_news() {
+ /**
+ * Validate a news link to a message group.
+ *
+ * @codingStandardsIgnoreStart
+ */
+ public function test_link_news() {
+ // @codingStandardsIgnoreEnd
$this->link_test_validate_url('news:comp.infosystems.www.misc');
}
- // Validate a news link to a message id. Said ID copied off of google groups.
- function test_link_news_message() {
+ /**
+ * Validate a news link to a message id. Said ID copied off of google groups.
+ *
+ * @codingStandardsIgnoreStart
+ */
+ public function test_link_news_message() {
+ // @codingStandardsIgnoreEnd
$this->link_test_validate_url('news:hj0db8$vrm$1@news.eternal-september.org');
}
+
}
+/**
+ * Validate Specific URL.
+ */
class LinkValidateSpecificURL extends LinkValidateTestCase {
+
+ /**
+ * Get Info.
+ */
public static function getInfo() {
return array(
'name' => 'Link Specific URL Validation Tests',
@@ -309,24 +434,53 @@ class LinkValidateSpecificURL extends LinkValidateTestCase {
);
}
- // Lets throw in a lot of umlouts for testing!
- function test_umlout_url() {
+ /**
+ * Lets throw in a lot of umlouts for testing!
+ *
+ * @codingStandardsIgnoreStart
+ */
+ public function test_umlout_url() {
+ // @codingStandardsIgnoreEnd
$this->link_test_validate_url('http://üÜü.exämple.com/nöde');
}
- function test_umlout_mailto() {
+ /**
+ * Check umlout mailto.
+ *
+ * @codingStandardsIgnoreStart
+ */
+ public function test_umlout_mailto() {
+ // @codingStandardsIgnoreEnd
$this->link_test_validate_url('mailto:Üser@exÅmple.com');
}
- function test_german_b_url() {
+ /**
+ * Check german b in url.
+ *
+ * @codingStandardsIgnoreStart
+ */
+ public function test_german_b_url() {
+ // @codingStandardsIgnoreEnd
$this->link_test_validate_url('http://www.test.com/ßstuff');
}
- function test_special_n_url() {
+ /**
+ * Check Special in url.
+ *
+ * @codingStandardsIgnoreStart
+ */
+ public function test_special_n_url() {
+ // @codingStandardsIgnoreEnd
$this->link_test_validate_url('http://www.testÑñ.com/');
}
- function test_curly_brackets_in_query() {
+ /**
+ * Curly Brackets in query.
+ *
+ * @codingStandardsIgnoreStart
+ */
+ public function test_curly_brackets_in_query() {
+ // @codingStandardsIgnoreEnd
$this->link_test_validate_url('http://www.healthyteennetwork.org/index.asp?Type=B_PR&SEC={2AE1D600-4FC6-4B4D-8822-F1D5F072ED7B}&DE={235FD1E7-208D-4363-9854-4E6775EB8A4C}');
}
@@ -334,8 +488,11 @@ class LinkValidateSpecificURL extends LinkValidateTestCase {
* Here, we're testing that a very long url is stored properly in the db.
*
* Basically, trying to test http://drupal.org/node/376818
+ *
+ * @codingStandardsIgnoreStart
*/
- function testLinkURLFieldIsBig() {
+ public function testLinkURLFieldIsBig() {
+ // @codingStandardsIgnoreEnd
$long_url = 'http://th.wikipedia.org/wiki/%E0%B9%82%E0%B8%A3%E0%B8%87%E0%B9%80%E0%B8%A3%E0%B8%B5%E0%B8%A2%E0%B8%99%E0%B9%80%E0%B8%9A%E0%B8%8D%E0%B8%88%E0%B8%A1%E0%B8%A3%E0%B8%B2%E0%B8%8A%E0%B8%B9%E0%B8%97%E0%B8%B4%E0%B8%A8_%E0%B8%99%E0%B8%84%E0%B8%A3%E0%B8%A8%E0%B8%A3%E0%B8%B5%E0%B8%98%E0%B8%A3%E0%B8%A3%E0%B8%A1%E0%B8%A3%E0%B8%B2%E0%B8%8A';
$this->link_test_validate_url($long_url);
}
@@ -343,12 +500,18 @@ class LinkValidateSpecificURL extends LinkValidateTestCase {
}
/**
- * A series of tests of links, only going against the link_validate_url function in link.module.
+ * Validate Url Light.
+ *
+ * A series of tests of links, only going against the link_validate_url function
+ * in link.module.
*
* Validation is guided by the rules in http://tools.ietf.org/html/rfc1738 !
*/
class LinkValidateUrlLight extends DrupalWebTestCase {
+ /**
+ * Get Info.
+ */
public static function getInfo() {
return array(
'name' => 'Link Light Validation Tests',
@@ -357,66 +520,136 @@ class LinkValidateUrlLight extends DrupalWebTestCase {
);
}
- function setUp() {
+ /**
+ * Setup.
+ */
+ public function setUp() {
parent::setUp('link');
}
/**
- * Translates the LINK type constants to english for display and debugging of tests
+ * Name Link Type.
+ *
+ * Translates the LINK type constants to english for display and debugging of
+ * tests.
+ *
+ * @codingStandardsIgnoreStart
*/
- function name_Link_Type($type) {
+ public function name_Link_Type($type) {
+ // @codingStandardsIgnoreEnd
switch ($type) {
case LINK_FRONT:
return "Front";
+
case LINK_EMAIL:
return "Email";
+
+ case LINK_TEL:
+ return "Telephone";
+
case LINK_NEWS:
return "Newsgroup";
+
case LINK_INTERNAL:
return "Internal Link";
+
case LINK_EXTERNAL:
return "External Link";
+
case FALSE:
return "Invalid Link";
+
default:
return "Bad Value:" . $type;
}
}
- // Make sure that a link labeled works.
- function testValidateFrontLink() {
+ /**
+ * Make sure that a link labeled works.
+ */
+ public function testValidateFrontLink() {
$valid = link_validate_url('');
$this->assertEqual(LINK_FRONT, $valid, 'Make sure that front link is verified and identified');
}
- function testValidateEmailLink() {
+ /**
+ * Validate Email Link.
+ */
+ public function testValidateEmailLink() {
$valid = link_validate_url('mailto:bob@example.com');
$this->assertEqual(LINK_EMAIL, $valid, "Make sure a basic mailto is verified and identified");
}
- function testValidateEmailLinkBad() {
+ /**
+ * Validate Email Link Bad.
+ */
+ public function testValidateEmailLinkBad() {
$valid = link_validate_url(':bob@example.com');
$this->assertEqual(FALSE, $valid, 'Make sure just a bad address is correctly failed');
}
- function testValidateNewsgroupLink() {
+ function testValidateTelLinks() {
+ $links = array(
+ 'tel:01',
+ 'tel:123456789012345',
+ 'tel:+123456789012345',
+ );
+ foreach ($links as $link) {
+ $type = link_url_type($link);
+ $this->assertEqual(LINK_TEL, $type, 'Test ' . $link . ' is a tel link.');
+ $valid = link_validate_url($link);
+ $this->assertTrue($valid, 'Test ' . $link . ' is valid tel link.');
+ }
+ }
+
+ function testValidateTelLinksBad() {
+ $links = array(
+ 'tel:0',
+ 'tel:1234567890123456',
+ 'tel:+1',
+ 'tel:+0123456789',
+ 'tel:+1234567890123456',
+ ':12345678',
+ );
+ foreach ($links as $link) {
+ $type = link_url_type($link);
+ $this->assertFalse($type, 'Test ' . $link . ' is not a tel link.');
+ $valid = link_validate_url($link);
+ $this->assertFalse($valid, 'Test ' . $link . ' is not a valid tel link.');
+ }
+ }
+
+ /**
+ * Validate Newsgroup Link.
+ */
+ public function testValidateNewsgroupLink() {
$valid = link_validate_url('news:comp.infosystems.www.misc');
$this->assertEqual(LINK_NEWS, $valid, 'Make sure link to newsgroup validates as news.');
}
- function testValidateNewsArticleLink() {
+ /**
+ * Validate News Article Link.
+ */
+ public function testValidateNewsArticleLink() {
$valid = link_validate_url('news:hj0db8$vrm$1@news.eternal-september.org');
$this->assertEqual(LINK_NEWS, $valid, 'Make sure link to specific article validates as news.');
}
- function testValidateBadNewsgroupLink() {
+ /**
+ * Validate Bad Newsgroup Link.
+ */
+ public function testValidateBadNewsgroupLink() {
$valid = link_validate_url('news:comp.bad_name.misc');
$this->assertEqual(FALSE, $valid, 'newsgroup names can\'t contain underscores, so it should come back as invalid.');
}
- function testValidateInternalLinks() {
+ /**
+ * Validate Internal Links.
+ */
+ public function testValidateInternalLinks() {
$tempfile = drupal_tempnam('public://files', 'test');
$links = array(
+ 'rss.xml',
file_uri_target($tempfile),
drupal_realpath($tempfile),
);
@@ -429,7 +662,10 @@ class LinkValidateUrlLight extends DrupalWebTestCase {
}
}
- function testValidateExternalLinks() {
+ /**
+ * Validate External Links.
+ */
+ public function testValidateExternalLinks() {
$links = array(
'http://localhost:8080/',
'www.example.com',
@@ -445,7 +681,7 @@ class LinkValidateUrlLight extends DrupalWebTestCase {
'www.test-site.com',
'http://example.com/index.php?q=node/123',
'http://example.com/?first_name=Joe Bob&last_name=Smith',
- // Anchors
+ // Anchors.
'http://www.example.com/index.php#test',
'http://www.example.com/index.php#this@that.',
'http://www.example.com/index.php#',
@@ -453,8 +689,22 @@ class LinkValidateUrlLight extends DrupalWebTestCase {
'http://www.archive.org/stream/aesopsfables00aesorich#page/n7/mode/2up',
'http://www.example.com/blah/#this@that?',
);
+
// Test all of the protocols.
- $allowed_protocols = variable_get('filter_allowed_protocols', array('http', 'https', 'ftp', 'news', 'nntp', 'telnet', 'mailto', 'irc', 'ssh', 'sftp', 'webcal'));
+ $allowed_protocols = variable_get('filter_allowed_protocols', array(
+ 'http',
+ 'https',
+ 'ftp',
+ 'news',
+ 'nntp',
+ 'telnet',
+ 'mailto',
+ 'irc',
+ 'ssh',
+ 'sftp',
+ 'webcal',
+ ));
+
foreach ($allowed_protocols as $protocol) {
if ($protocol !== 'news' && $protocol !== 'mailto') {
$links[] = $protocol . '://www.example.com';
@@ -465,24 +715,28 @@ class LinkValidateUrlLight extends DrupalWebTestCase {
$this->assertEqual(LINK_EXTERNAL, $type, 'Testing that ' . $link . ' is an external link.');
$valid = link_validate_url($link);
$this->assertTrue($valid, 'Test ' . $link . ' is valid external link.');
- // The following two lines are commented out and only used for comparisons.
- //$valid2 = valid_url($link, TRUE);
- //$this->assertEqual(TRUE, $valid2, "Using valid_url() on $link.");
+ // The following two lines are commented out and only used for
+ // comparisons.
+ // $valid2 = valid_url($link, TRUE);
+ // $this->assertEqual(TRUE, $valid2, "Using valid_url() on $link.");.
}
- // Test if we can make a tld allowable:
- variable_set('link_allowed_domains', array('frog'));
- $valid = link_validate_url('http://www.example.frog');
- $this->assertEqual(LINK_EXTERNAL, $valid, "Testing that http://www.example.frog is a valid external link if we've added 'frog' to the list of valid domains.");
}
- function testInvalidExternalLinks() {
+ /**
+ * Check Invalid External Links.
+ */
+ public function testInvalidExternalLinks() {
$links = array(
'http://www.ex ample.com/',
- 'http://25.0.0/', // bad ip!
+ // Bad ip!
+ 'http://25.0.0/',
'http://4827.0.0.2/',
- '//www.example.com/',
- 'http://www.testß.com/', // ß not allowed in domain names!
- //'http://www.-fudge.com/', // domains can't have sections starting with a dash.
+ // ß not allowed in domain names!
+ 'http://www.testß.com/',
+ // Bad TLD.
+ 'http://.www.foo.bar./',
+ // Domains can't have sections starting with a dash.
+ // 'http://www.-fudge.com/',
'http://example.com/index.php?page=this\that',
'example@example.com',
);
@@ -490,9 +744,6 @@ class LinkValidateUrlLight extends DrupalWebTestCase {
$valid = link_validate_url($link);
$this->assertEqual(FALSE, $valid, 'Testing that ' . $link . ' is not a valid link.');
}
- // Test if we can make a tld disallowed:
- variable_set('link_allowed_domains', array('toad'));
- $valid = link_validate_url('http://www.example.frog');
- $this->assertEqual(FALSE, $valid, "Testing that http://www.example.frog is an invalid external link if we've not added 'frog' to the list of valid domains.");
}
+
}
diff --git a/sites/all/modules/contrib/fields/link/views/link.views.inc b/sites/all/modules/contrib/fields/link/views/link.views.inc
deleted file mode 100644
index 27d5182f..00000000
--- a/sites/all/modules/contrib/fields/link/views/link.views.inc
+++ /dev/null
@@ -1,113 +0,0 @@
- array(
- 'path' => drupal_get_path('module', 'link') .'/views',
- ),
- 'handlers' => array(
- 'link_views_handler_argument_target' => array(
- 'parent' => 'views_handler_argument',
- ),
- 'link_views_handler_filter_protocol' => array(
- 'parent' => 'views_handler_filter_string',
- ),
- ),
- );
-}*/
-
-/**
- * Return CCK Views data for the link_field_settings($op == 'views data').
- *
- * @TODO: Is there some way to tell views I have formatters for it?
- */
-/*function link_views_content_field_data($field) {
- // Build the automatic views data provided for us by CCK.
- // This creates all the information necessary for the "url" field.
- $data = content_views_field_views_data($field);
-
- $db_info = content_database_info($field);
- $table_alias = content_views_tablename($field);
- $field_types = _content_field_types();
-
- // Tweak the automatic views data for the link "url" field.
- // Set the filter title to "@label URL"
- $data[$table_alias][$field['field_name'] .'_url']['filter']['title'] = t('@label URL', array('@label' => t($field_types[$field['type']]['label']))) .': '. t($field['widget']['label']);
- // Remove the argument handling for URLs.
- unset($data[$table_alias][$field['field_name'] .'_url']['argument']);
-
- // Build out additional views data for the link "title" field.
- $data[$table_alias][$field['field_name'] .'_title'] = array(
- 'group' => t('Content'),
- 'title' => t('@label title', array('@label' => t($field_types[$field['type']]['label']))) .': '. t($field['widget']['label']) .' ('. $field['field_name'] .')',
- 'help' => $data[$table_alias][$field['field_name'] .'_url']['help'],
- 'argument' => array(
- 'field' => $db_info['columns']['title']['column'],
- 'tablename' => $db_info['table'],
- 'handler' => 'content_handler_argument_string',
- 'click sortable' => TRUE,
- 'name field' => '', // TODO, mimic content.views.inc :)
- 'content_field_name' => $field['field_name'],
- 'allow_empty' => TRUE,
- ),
- 'filter' => array(
- 'field' => $db_info['columns']['title']['column'],
- 'title' => t('@label title', array('@label' => t($field_types[$field['type']]['label']))),
- 'tablename' => $db_info['table'],
- 'handler' => 'content_handler_filter_string',
- 'additional fields' => array(),
- 'content_field_name' => $field['field_name'],
- 'allow_empty' => TRUE,
- ),
- 'sort' => array(
- 'field' => $db_info['columns']['title']['column'],
- 'tablename' => $db_info['table'],
- 'handler' => 'content_handler_sort',
- 'content_field_name' => $field['field_name'],
- 'allow_empty' => TRUE,
- ),
- );
-
- // Build out additional Views filter for the link "protocol" pseudo field.
- // TODO: Add a protocol argument.
- $data[$table_alias][$field['field_name'] .'_protocol'] = array(
- 'group' => t('Content'),
- 'title' => t('@label protocol', array('@label' => t($field_types[$field['type']]['label']))) .': '. t($field['widget']['label']) .' ('. $field['field_name'] .')',
- 'help' => $data[$table_alias][$field['field_name'] .'_url']['help'],
- 'filter' => array(
- 'field' => $db_info['columns']['url']['column'],
- 'title' => t('@label protocol', array('@label' => t($field_types[$field['type']]['label']))),
- 'tablename' => $db_info['table'],
- 'handler' => 'link_views_handler_filter_protocol',
- 'additional fields' => array(),
- 'content_field_name' => $field['field_name'],
- 'allow_empty' => TRUE,
- ),
- );
-
- // Build out additional Views argument for the link "target" pseudo field.
- // TODO: Add a target filter.
- $data[$table_alias][$field['field_name'] .'_target'] = array(
- 'group' => t('Content'),
- 'title' => t('@label target', array('@label' => t($field_types[$field['type']]['label']))) .': '. t($field['widget']['label']) .' ('. $field['field_name'] .')',
- 'help' => $data[$table_alias][$field['field_name'] .'_url']['help'],
- 'argument' => array(
- 'field' => $db_info['columns']['attributes']['column'],
- 'title' => t('@label target', array('@label' => t($field_types[$field['type']]['label']))) .': '. t($field['widget']['label']) .' ('. $field['field_name'] .')',
- 'tablename' => $db_info['table'],
- 'handler' => 'link_views_handler_argument_target',
- 'additional fields' => array(),
- 'content_field_name' => $field['field_name'],
- 'allow_empty' => TRUE,
- ),
- );
-
- return $data;
-}*/
diff --git a/sites/all/modules/contrib/fields/link/views/link_views_handler_argument_target.inc b/sites/all/modules/contrib/fields/link/views/link_views_handler_argument_target.inc
index f0622d05..2fa1715a 100644
--- a/sites/all/modules/contrib/fields/link/views/link_views_handler_argument_target.inc
+++ b/sites/all/modules/contrib/fields/link/views/link_views_handler_argument_target.inc
@@ -7,20 +7,26 @@
/**
* Argument handler to filter results by target.
+ *
+ * @codingStandardsIgnoreStart
*/
class link_views_handler_argument_target extends views_handler_argument {
/**
* Provide defaults for the argument when a new one is created.
*/
- function options(&$options) {
- parent::options($options);
- }
+ function option_definition() {
+ $options = parent::option_definition();
+ return $options;
+ }
/**
* Provide a default options form for the argument.
+ *
+ * @codingStandardsIgnoreStart
*/
- function options_form(&$form, &$form_state) {
+ public function options_form(&$form, &$form_state) {
+ // @codingStandardsIgnoreEnd
$defaults = $this->default_actions();
$form['title'] = array(
@@ -52,7 +58,7 @@ class link_views_handler_argument_target extends views_handler_argument {
$form['wildcard'] = array(
'#prefix' => '',
- // prefix and no suffix means these two items will be grouped together.
+ // Prefix and no suffix means these two items will be grouped together.
'#type' => 'textfield',
'#title' => t('Wildcard'),
'#size' => 20,
@@ -125,8 +131,8 @@ class link_views_handler_argument_target extends views_handler_argument {
asort($validate_types);
$form['validate_type']['#options'] = $validate_types;
- // Show this gadget if *anything* but 'none' is selected
+ // Show this gadget if *anything* but 'none' is selected.
$form['validate_fail'] = array(
'#type' => 'select',
'#title' => t('Action to take if argument does not validate'),
@@ -140,10 +146,11 @@ class link_views_handler_argument_target extends views_handler_argument {
*
* The argument sent may be found at $this->argument.
*/
- function query($group_by = FALSE) {
+ public function query($group_by = FALSE) {
$this->ensure_my_table();
// Because attributes are stored serialized, our only option is to also
// serialize the data we're searching for and use LIKE to find similar data.
$this->query->add_where(0, $this->table_alias . ' . ' . $this->real_field . " LIKE '%%%s%'", serialize(array('target' => $this->argument)));
}
+
}
diff --git a/sites/all/modules/contrib/fields/link/views/link_views_handler_filter_protocol.inc b/sites/all/modules/contrib/fields/link/views/link_views_handler_filter_protocol.inc
index a020b4e0..677fee58 100644
--- a/sites/all/modules/contrib/fields/link/views/link_views_handler_filter_protocol.inc
+++ b/sites/all/modules/contrib/fields/link/views/link_views_handler_filter_protocol.inc
@@ -7,22 +7,29 @@
/**
* Filter handler for limiting a view to URLs of a certain protocol.
+ *
+ * @codingStandardsIgnoreStart
*/
class link_views_handler_filter_protocol extends views_handler_filter_string {
+
/**
* Set defaults for the filter options.
*/
- function options(&$options) {
- parent::options($options);
+ public function option_definition() {
+ // @codingStandardsIgnoreEnd
+ $options = parent::option_definition();
+
$options['operator'] = 'OR';
$options['value'] = 'http';
$options['case'] = 0;
+
+ return $options;
}
/**
* Define the operators supported for protocols.
*/
- function operators() {
+ public function operators() {
$operators = array(
'OR' => array(
'title' => t('Is one of'),
@@ -35,7 +42,13 @@ class link_views_handler_filter_protocol extends views_handler_filter_string {
return $operators;
}
- function options_form(&$form, &$form_state) {
+ /**
+ * Options form.
+ *
+ * @codingStandardsIgnoreStart
+ */
+ public function options_form(&$form, &$form_state) {
+ //@codingStandardsIgnoreEnd
parent::options_form($form, $form_state);
$form['case'] = array(
'#type' => 'value',
@@ -45,8 +58,11 @@ class link_views_handler_filter_protocol extends views_handler_filter_string {
/**
* Provide a select list to choose the desired protocols.
+ *
+ * @codingStandardsIgnoreStart
*/
- function value_form(&$form, &$form_state) {
+ public function value_form(&$form, &$form_state) {
+ // @codingStandardsIgnoreEnd
// We have to make some choices when creating this as an exposed
// filter form. For example, if the operator is locked and thus
// not rendered, we can't render dependencies; instead we only
@@ -61,7 +77,19 @@ class link_views_handler_filter_protocol extends views_handler_filter_string {
'#type' => 'select',
'#title' => t('Protocol'),
'#default_value' => $this->value,
- '#options' => drupal_map_assoc(variable_get('filter_allowed_protocols', array('http', 'https', 'ftp', 'news', 'nntp', 'telnet', 'mailto', 'irc', 'ssh', 'sftp', 'webcal'))),
+ '#options' => drupal_map_assoc(variable_get('filter_allowed_protocols', array(
+ 'http',
+ 'https',
+ 'ftp',
+ 'news',
+ 'nntp',
+ 'telnet',
+ 'mailto',
+ 'irc',
+ 'ssh',
+ 'sftp',
+ 'webcal',
+ ))),
'#multiple' => 1,
'#size' => 4,
'#description' => t('The protocols displayed here are those globally available. You may add more protocols by modifying the filter_allowed_protocols variable in your installation.'),
@@ -71,8 +99,11 @@ class link_views_handler_filter_protocol extends views_handler_filter_string {
/**
* Filter down the query to include only the selected protocols.
+ *
+ * @codingStandardsIgnoreStart
*/
- function op_protocol($field, $upper) {
+ public function op_protocol($field, $upper) {
+ // @codingStandardsIgnoreEnd
$db_type = db_driver();
$protocols = $this->value;
@@ -82,20 +113,25 @@ class link_views_handler_filter_protocol extends views_handler_filter_string {
// Simple case, the URL begins with the specified protocol.
$condition = $field . ' LIKE \'' . $protocol . '%\'';
- // More complex case, no protocol specified but is automatically cleaned up
- // by link_cleanup_url(). RegEx is required for this search operation.
+ // More complex case, no protocol specified but is automatically cleaned
+ // up by link_cleanup_url(). RegEx is required for this search operation.
if ($protocol == 'http') {
- $LINK_DOMAINS = _link_domains();
+ $link_domains = _link_domains();
if ($db_type == 'pgsql') {
- // PostGreSQL code has NOT been tested. Please report any problems to the link issue queue.
- // pgSQL requires all slashes to be double escaped in regular expressions.
+ // PostGreSQL code has NOT been tested. Please report any problems to
+ // the link issue queue.
+ // pgSQL requires all slashes to be double escaped in regular
+ // expressions.
+ // @codingStandardsIgnoreLine
// See http://www.postgresql.org/docs/8.1/static/functions-matching.html#FUNCTIONS-POSIX-REGEXP
- $condition .= ' OR ' . $field . ' ~* \'' . '^(([a-z0-9]([a-z0-9\\-_]*\\.)+)(' . $LINK_DOMAINS . '|[a-z][a-z]))' . '\'';
+ $condition .= ' OR ' . $field . ' ~* \'' . '^(([a-z0-9]([a-z0-9\\-_]*\\.)+)(' . $link_domains . '|[a-z][a-z]))' . '\'';
}
else {
- // mySQL requires backslashes to be double (triple?) escaped within character classes.
+ // mySQL requires backslashes to be double (triple?) escaped within
+ // character classes.
+ // @codingStandardsIgnoreLine
// See http://dev.mysql.com/doc/refman/5.0/en/string-comparison-functions.html#operator_regexp
- $condition .= ' OR ' . $field . ' REGEXP \'' . '^(([a-z0-9]([a-z0-9\\\-_]*\.)+)(' . $LINK_DOMAINS . '|[a-z][a-z]))' . '\'';
+ $condition .= ' OR ' . $field . ' REGEXP \'' . '^(([a-z0-9]([a-z0-9\\\-_]*\.)+)(' . $link_domains . '|[a-z][a-z]))' . '\'';
}
}
@@ -104,4 +140,5 @@ class link_views_handler_filter_protocol extends views_handler_filter_string {
$this->query->add_where($this->options['group'], implode(' ' . $this->operator . ' ', $where_conditions));
}
+
}
diff --git a/sites/all/modules/contrib/search/search_api_solr/CHANGELOG.txt b/sites/all/modules/contrib/search/search_api_solr/CHANGELOG.txt
index 68fe9882..a730632d 100644
--- a/sites/all/modules/contrib/search/search_api_solr/CHANGELOG.txt
+++ b/sites/all/modules/contrib/search/search_api_solr/CHANGELOG.txt
@@ -1,3 +1,23 @@
+Search API Solr Search 1.x, dev (xxxx-xx-xx):
+---------------------------------------------
+- #3003819 by mandclu, drunken monkey: Added support for indexing nested
+ documents.
+
+Search API Solr Search 1.13 (2018-09-17):
+-----------------------------------------
+- #2998931 by drunken monkey, mahipal46: Fixed warning during excerpt creation.
+- #2459457 by das-peter, drunken monkey, ruloweb, SpadXIII, mkalkbrenner: Added
+ support for the "(not) between" operator.
+- #2970829 by donquixote, drunken monkey: Fixed "missing" facet in PHP 7.
+- #2916951 by drunken monkey, mkalkbrenner, osopolar, jcnventura, arcadLemon,
+ Siridivi: Added support for Solr 7.x.
+- #2949293 by Novitsh: Fixed path to README.txt on multilingual sites.
+- #2900308 by cgoffin, drunken monkey: Fixed retrieval of multi-valued date
+ fields in results.
+- #2824956 by lex0r, drunken monkey: Added support for atomic updates on API
+ level.
+- #2867076 by Sardis: Fixed Solr config name for Solr 5.x.
+
Search API Solr Search 1.12 (2017-02-23):
-----------------------------------------
- #2612770 by Temoor, drunken monkey: Fixed conjunction in complex filter
diff --git a/sites/all/modules/contrib/search/search_api_solr/includes/document.inc b/sites/all/modules/contrib/search/search_api_solr/includes/document.inc
index 010744f5..735488e7 100644
--- a/sites/all/modules/contrib/search/search_api_solr/includes/document.inc
+++ b/sites/all/modules/contrib/search/search_api_solr/includes/document.inc
@@ -96,6 +96,20 @@ class SearchApiSolrDocument implements IteratorAggregate {
*/
protected $fieldBoosts = array();
+ /**
+ * Document field update values, indexed by name.
+ *
+ * @var array
+ */
+ protected $fieldUpdates = array();
+
+ /**
+ * Document nested objects.
+ *
+ * @var SearchApiSolrDocument[]
+ */
+ protected $nestedObjects = array();
+
/**
* Clears all boosts and fields from this document.
*/
@@ -104,6 +118,8 @@ class SearchApiSolrDocument implements IteratorAggregate {
$this->fields = array();
$this->fieldBoosts = array();
+ $this->fieldUpdates = array();
+ $this->nestedObjects = array();
}
/**
@@ -262,6 +278,42 @@ class SearchApiSolrDocument implements IteratorAggregate {
return $this->fieldBoosts;
}
+ /**
+ * Gets the currently set field's 'update' attribute for a document field.
+ *
+ * @param string $key
+ * The name of the field.
+ *
+ * @return string|false
+ * The currently set field's update attribute, or FALSE if none was set.
+ */
+ public function getFieldUpdate($key) {
+ return isset($this->fieldUpdates[$key]) ? $this->fieldUpdates[$key] : FALSE;
+ }
+
+ /**
+ * Sets the field's 'update' attribute for a document field.
+ *
+ * @param string $key
+ * The name of the field.
+ * @param string|false $update
+ * One of the allowed update values ('add', 'set', 'inc').
+ */
+ public function setFieldUpdate($key, $update) {
+ $this->fieldUpdates[$key] = $update;
+ }
+
+ /**
+ * Retrieves all currently set field updates.
+ *
+ * @return string[]
+ * Associative array of field's "update" attributes that were set, keyed by
+ * field name.
+ */
+ public function getFieldUpdates() {
+ return $this->fieldUpdates;
+ }
+
/**
* Gets the names of all fields in this document.
*
@@ -282,6 +334,29 @@ class SearchApiSolrDocument implements IteratorAggregate {
return array_values($this->fields);
}
+ /**
+ * Retrieves the nested documents set on this document.
+ *
+ * @return \SearchApiSolrDocument[]
+ * The nested documents.
+ */
+ public function getNestedObjects() {
+ return $this->nestedObjects;
+ }
+
+ /**
+ * Sets an array of nested documents.
+ *
+ * Populate nested documents for use with block join queries. Note that this
+ * will lead to errors when used with Solr versions older than 4.5.
+ *
+ * @param SearchApiSolrDocument[] $nested_documents
+ * An array of SearchApiSolrDocument objects.
+ */
+ public function setNestedDocuments(array $nested_documents) {
+ $this->nestedObjects = $nested_documents;
+ }
+
/**
* Implements IteratorAggregate::getIterator().
*
@@ -380,35 +455,45 @@ class SearchApiSolrDocument implements IteratorAggregate {
$xml .= '>';
- foreach ($this->fields as $key => $value) {
+ foreach ($this->fields as $key => $values) {
$fieldBoost = $this->getFieldBoost($key);
+ $fieldUpdate = $this->getFieldUpdate($key);
$key = htmlspecialchars($key, ENT_COMPAT, 'UTF-8');
- if (is_array($value)) {
- foreach ($value as $multivalue) {
- $xml .= '';
- }
+ if (!is_array($values)) {
+ $values = array($values);
}
- else {
+
+ foreach ($values as $value) {
$xml .= '';
}
}
+ // If nested objects have been added, include them in the XML to be indexed.
+ foreach ($this->nestedObjects as $object) {
+ // Skip any documents that aren't of the correct type.
+ if (!($object instanceof SearchApiSolrDocument)) {
+ $vars['@type'] = is_object($object) ? get_class($object) : gettype($object);
+ watchdog('search_api_solr', 'Attempt to add an invalid nested Solr document of type @type.', $vars, WATCHDOG_ERROR);
+ continue;
+ }
+ // Generate the markup for each nested document.
+ $xml .= $object->toXml();
+ }
+
$xml .= '';
// Remove any control characters to avoid Solr XML parser exception.
@@ -432,4 +517,5 @@ class SearchApiSolrDocument implements IteratorAggregate {
// Printable utf-8 does not include any of these chars below x7F
return preg_replace('@[\x00-\x08\x0B\x0C\x0E-\x1F]@', ' ', $string);
}
-}
\ No newline at end of file
+
+}
diff --git a/sites/all/modules/contrib/search/search_api_solr/includes/service.inc b/sites/all/modules/contrib/search/search_api_solr/includes/service.inc
index e80b35fa..6c9765b9 100644
--- a/sites/all/modules/contrib/search/search_api_solr/includes/service.inc
+++ b/sites/all/modules/contrib/search/search_api_solr/includes/service.inc
@@ -336,6 +336,7 @@ class SearchApiSolrService extends SearchApiAbstractService {
// First, check the features we always support.
$supported = drupal_map_assoc(array(
'search_api_autocomplete',
+ 'search_api_between',
'search_api_facets',
'search_api_facets_operator_or',
'search_api_grouping',
@@ -646,9 +647,17 @@ class SearchApiSolrService extends SearchApiAbstractService {
* This has to consist of both index and item ID. Optionally, the site hash is
* also included.
*
+ * @param string $index_id
+ * The search index's machine name.
+ * @param mixed $item_id
+ * The Search API item ID of the item.
+ *
+ * @return string
+ * The Solr ID to use for this item.
+ *
* @see search_api_solr_site_hash()
*/
- protected function createId($index_id, $item_id) {
+ public function createId($index_id, $item_id) {
$site_hash = !empty($this->options['site_hash']) ? search_api_solr_site_hash() . '-' : '';
return "$site_hash$index_id-$item_id";
}
@@ -1303,14 +1312,15 @@ class SearchApiSolrService extends SearchApiAbstractService {
// SearchApiSolrService::getFieldNames().
foreach ($fields as $search_api_property => $solr_property) {
if (isset($doc->{$solr_property})) {
- $result['fields'][$search_api_property] = $doc->{$solr_property};
+ $value = $doc->{$solr_property};
// Date fields need some special treatment to become valid date values
// (i.e., timestamps) again.
if (isset($field_options[$search_api_property]['type'])
- && $field_options[$search_api_property]['type'] == 'date'
- && preg_match('/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z$/', $result['fields'][$search_api_property])) {
- $result['fields'][$search_api_property] = strtotime($result['fields'][$search_api_property]);
+ && search_api_extract_inner_type($field_options[$search_api_property]['type']) === 'date'
+ && preg_match('/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z$/', $value)) {
+ $value = is_array($value) ? array_map('strtotime', $value) : strtotime($value);
}
+ $result['fields'][$search_api_property] = $value;
}
}
@@ -1338,7 +1348,7 @@ class SearchApiSolrService extends SearchApiAbstractService {
$index_id = $this->getIndexId($index->machine_name);
$solr_id = $this->createId($index_id, $result['id']);
- $excerpt = $this->getExcerpt($response, $solr_id, $result['fields'], $fields);
+ $excerpt = $this->getExcerpt($response, $solr_id, $result['fields'], $fields, $query->getFields());
if ($excerpt) {
$result['excerpt'] = $excerpt;
}
@@ -1364,53 +1374,87 @@ class SearchApiSolrService extends SearchApiAbstractService {
* Will also use highlighted fields to replace retrieved field data, if the
* corresponding option is set.
*/
- protected function getExcerpt($response, $id, array &$fields, array $field_mapping) {
+ protected function getExcerpt($response, $id, array &$fields, array $field_mapping, array $fulltext_fields) {
if (!isset($response->highlighting->$id)) {
return FALSE;
}
$output = '';
+ $highlighting = $response->highlighting->$id;
- if (!empty($this->options['excerpt']) && !empty($response->highlighting->$id->content)) {
- foreach ($response->highlighting->$id->content as $snippet) {
- $snippet = strip_tags($snippet);
- $snippet = preg_replace('/^.*>|<.*$/', '', $snippet);
- $snippet = check_plain($snippet);
- $snippet = $this->formatHighlighting($snippet);
- // The created fragments sometimes have leading or trailing punctuation.
- // We remove that here for all common cases, but take care not to remove
- // < or > (so HTML tags stay valid).
- $snippet = trim($snippet, "\00..\x2F:;=\x3F..\x40\x5B..\x60");
- $output .= $snippet . ' … ';
- }
+ $highlight_fields = !empty($this->options['highlight_data']);
+ $create_excerpt = !empty($this->options['excerpt']);
+ if (!$highlight_fields && !$create_excerpt) {
+ return FALSE;
}
- if (!empty($this->options['highlight_data'])) {
- $prefix = variable_get('search_api_solr_highlight_prefix', 'tm_');
- $prefix_length = strlen($prefix);
- foreach ($field_mapping as $search_api_property => $solr_property) {
- if (substr($solr_property, 0, $prefix_length) == $prefix && !empty($response->highlighting->$id->$solr_property)) {
- $value = $response->highlighting->$id->$solr_property;
- $value = $this->sanitizeHighlightValue($value, $search_api_property);
- // Remove highlight prefixes and suffixes so we could compare values
- // in order to replace the correspond items.
- $orig_value = preg_replace('#\[(/?)HIGHLIGHT\]#', '', $value);
- $field_values = $this->sanitizeHighlightValue($fields[$search_api_property]);
- foreach ($field_values as $delta => $field_value) {
- foreach ($orig_value as $num => $item) {
- if ($item === $field_value) {
- $field_values[$delta] = $this->formatHighlighting($value[$num]);
- $change = TRUE;
- continue 2;
- }
- }
- }
- if (!empty($change)) {
- $fields[$search_api_property] = array(
- '#value' => $field_values,
- '#sanitize_callback' => FALSE,
- );
+
+ // Collect highlighted field values for the excerpt and set them in the
+ // field values, if requested.
+ $excerpt_parts = array();
+ $field_mapping = array_flip($field_mapping);
+ $fulltext_fields = drupal_map_assoc($fulltext_fields);
+ foreach ($highlighting as $solr_property => $values) {
+ $values = (array) $values;
+ if (empty($field_mapping[$solr_property])) {
+ continue;
+ }
+ $search_api_property = $field_mapping[$solr_property];
+
+ // Only use fields that were actually searched for the excerpt.
+ if (isset($fulltext_fields[$search_api_property])) {
+ // Remember the highlighted value so we can use it for the excerpt, if
+ // requested.
+ $excerpt_parts = array_merge($excerpt_parts, $values);
+ }
+
+ if (!$highlight_fields) {
+ continue;
+ }
+
+ $values = $this->sanitizeHighlightValue($values, $search_api_property);
+ // Remove highlight prefixes and suffixes so we can compare values in
+ // order to replace the corresponding items.
+ $orig_values = preg_replace('#\[(/?)HIGHLIGHT\]#', '', $values);
+ $field_values = array();
+ if (!empty($fields[$search_api_property])) {
+ $field_values = $this->sanitizeHighlightValue($fields[$search_api_property]);
+ }
+ foreach ($field_values as $delta => $field_value) {
+ foreach ($orig_values as $num => $item) {
+ if ($item === $field_value) {
+ $field_values[$delta] = $this->formatHighlighting($values[$num]);
+ $change = TRUE;
+ continue 2;
}
}
}
+ if (!empty($change)) {
+ $fields[$search_api_property] = array(
+ '#value' => $field_values,
+ '#sanitize_callback' => FALSE,
+ );
+ }
+ }
+
+ // Create an excerpt, if requested.
+ if ($create_excerpt && $excerpt_parts) {
+ $excerpt = array();
+ $excerpt_length = 0;
+ foreach ($excerpt_parts as $value) {
+ // Excerpts don't have HTML (except for the highlighting tags, of
+ // course).
+ $value = strip_tags($value);
+ foreach ($this->extractHighlightingSnippets($value) as $snippet) {
+ $excerpt[] = $snippet;
+ $excerpt_length += drupal_strlen($snippet);
+ // Restrict ourselves to three snippets or 300 characters.
+ if (count($excerpt) >= 3 || $excerpt_length >= 300) {
+ break 2;
+ }
+ }
+ }
+ if ($excerpt) {
+ $output = implode(' … ', $excerpt) . ' …';
+ }
}
return $output;
@@ -1450,6 +1494,84 @@ class SearchApiSolrService extends SearchApiAbstractService {
return preg_replace('#\[(/?)HIGHLIGHT\]#', '<$1strong>', $snippet);
}
+ /**
+ * Extracts short snippets with highlighting from highlighted field values.
+ *
+ * @param string $value
+ * A highlighted field value.
+ *
+ * @return string[]
+ * An array of short, highlighted snippets extracted from the field value.
+ */
+ protected function extractHighlightingSnippets($value) {
+ $snippets = array();
+ $parts = preg_split('#\[/?HIGHLIGHT\]#', $value);
+ $i = 0;
+ $combined_length = 0;
+ while (isset($parts[$i + 2])) {
+ $prefix = $parts[$i];
+ $short_prefix = FALSE;
+ $key = $parts[++$i];
+ $suffix = $parts[++$i];
+
+ // Make sure prefix and suffix are not too long.
+ $length = drupal_strlen($prefix);
+ if ($length > 30) {
+ $space = strrpos(substr($prefix, 0, -25), ' ');
+ // Fall back to just cutting at an arbitrary position, space or no.
+ if ($space === FALSE) {
+ $space = $length - 30;
+ }
+ $prefix = substr($prefix, $space + 1);
+ }
+ else {
+ $short_prefix = TRUE;
+ }
+
+ $length = drupal_strlen($suffix);
+ if ($length > 30) {
+ $space = strpos($suffix, ' ', 25);
+ // Fall back to just cutting at an arbitrary position, space or no.
+ if ($space === FALSE) {
+ $space = 30;
+ }
+ $suffix = substr($suffix, 0, $space);
+ }
+
+ // Fuse two snippets if they are separated by less than 30 characters.
+ $previous = NULL;
+ if ($short_prefix) {
+ $previous = array_pop($snippets);
+ if ($previous) {
+ $prefix = '';
+ }
+ }
+ $snippet = $prefix . '[HIGHLIGHT]' . $key . '[/HIGHLIGHT]' . $suffix;
+
+ // Sanitize and format the snippet.
+ $snippet = check_plain($snippet);
+ $snippet = $this->formatHighlighting($snippet);
+ // The created fragments sometimes have leading or trailing punctuation.
+ // We remove that here for all common cases, but take care not to remove
+ // < or > (so HTML tags stay valid).
+ $snippet = trim($snippet, "\00..\x2F:;=\x3F..\x40\x5B..\x60");
+
+ // Prepend the previous snippet if we're fusing.
+ if ($previous) {
+ $snippet = $previous . $snippet;
+ }
+
+ $snippets[] = $snippet;
+ $combined_length += drupal_strlen($snippet);
+
+ // Restrict ourselves to three snippets or 300 characters.
+ if (count($snippets) >= 3 || $combined_length >= 300) {
+ break;
+ }
+ }
+ return $snippets;
+ }
+
/**
* Extract facets from a Solr response.
*
@@ -1474,18 +1596,21 @@ class SearchApiSolrService extends SearchApiAbstractService {
if (isset($response->facet_counts->facet_fields)) {
$facet_fields = $response->facet_counts->facet_fields;
+ // The key for the "missing" facet (empty string in the JSON). This will
+ // be either "" or "_empty_", depending on the PHP version.
+ $empty_key = key((array) json_decode('{"":5}'));
foreach ($extract_facets as $delta => $info) {
$field = $fields[$info['field']];
if (!empty($facet_fields->$field)) {
$min_count = $info['min_count'];
$terms = $facet_fields->$field;
if ($info['missing']) {
- // We have to correctly incorporate the "_empty_" term.
+ // We have to correctly incorporate the "missing" term ($empty_key).
// This will ensure that the term with the least results is dropped,
// if the limit would be exceeded.
- if (isset($terms->_empty_)) {
- if ($terms->_empty_ < $min_count) {
- unset($terms->_empty_);
+ if (isset($terms->$empty_key)) {
+ if ($terms->$empty_key < $min_count) {
+ unset($terms->$empty_key);
}
else {
$terms = (array) $terms;
@@ -1496,14 +1621,14 @@ class SearchApiSolrService extends SearchApiAbstractService {
}
}
}
- elseif (isset($terms->_empty_)) {
+ elseif (isset($terms->$empty_key)) {
$terms = clone $terms;
- unset($terms->_empty_);
+ unset($terms->$empty_key);
}
$type = isset($index->options['fields'][$info['field']]['type']) ? search_api_extract_inner_type($index->options['fields'][$info['field']]['type']) : 'string';
foreach ($terms as $term => $count) {
if ($count >= $min_count) {
- if ($term === '_empty_') {
+ if ($term === $empty_key) {
$term = '!';
}
elseif ($type == 'boolean') {
@@ -1691,8 +1816,19 @@ class SearchApiSolrService extends SearchApiAbstractService {
if ($value === NULL) {
return ($operator == '=' ? '*:* AND -' : '') . "$field:[* TO *]";
}
- $value = $this->formatFilterValue($value, search_api_extract_inner_type($field_info['type']));
- switch ($operator) {
+
+ $type = search_api_extract_inner_type($field_info['type']);
+ if (!is_array($value)) {
+ $value = $this->formatFilterValue($value, $type);
+ }
+ else {
+ foreach($value as &$val) {
+ $val = $this->formatFilterValue($val, $type);
+ }
+ unset($val);
+ }
+
+ switch (strtoupper($operator)) {
case '<>':
return "*:* AND -($field:$value)";
case '<':
@@ -1703,6 +1839,10 @@ class SearchApiSolrService extends SearchApiAbstractService {
return "$field:[$value TO *]";
case '>':
return "$field:{{$value} TO *}";
+ case 'BETWEEN':
+ return "$field:[{$value[0]} TO {$value[1]}]";
+ case 'NOT BETWEEN':
+ return "*:* AND -$field:[{$value[0]} TO {$value[1]}]";
default:
return "$field:$value";
@@ -1794,29 +1934,11 @@ class SearchApiSolrService extends SearchApiAbstractService {
if (!empty($this->options['excerpt']) || !empty($this->options['highlight_data'])) {
$highlight_params['hl'] = 'true';
- $highlight_params['hl.fl'] = 'content';
+ $highlight_params['hl.fl'] = variable_get('search_api_solr_highlight_prefix', 'tm_') . '*';
$highlight_params['hl.simple.pre'] = '[HIGHLIGHT]';
$highlight_params['hl.simple.post'] = '[/HIGHLIGHT]';
- $highlight_params['hl.snippets'] = 3;
- $highlight_params['hl.fragsize'] = 70;
- $highlight_params['hl.mergeContiguous'] = 'true';
- }
-
- if (!empty($this->options['highlight_data'])) {
- $highlight_params['hl.fl'] = variable_get('search_api_solr_highlight_prefix', 'tm_') . '*';
$highlight_params['hl.snippets'] = 1;
$highlight_params['hl.fragsize'] = 0;
- if (!empty($this->options['excerpt'])) {
- // If we also generate a "normal" excerpt, set the settings for the
- // "content" field (which we use to generate the excerpt) back to the
- // above values.
- $highlight_params['f.content.hl.snippets'] = 3;
- $highlight_params['f.content.hl.fragsize'] = 70;
- // It regrettably doesn't seem to be possible to set hl.fl to several
- // values, if one contains wild cards (i.e., "t_*,content" wouldn't
- // work).
- $highlight_params['hl.fl'] = '*';
- }
}
return $highlight_params;
@@ -2252,18 +2374,19 @@ class SearchApiSolrService extends SearchApiAbstractService {
$solr_id = $this->createId($doc->index_id, $doc->item_id);
foreach ($fields as $search_api_property => $solr_property) {
if (isset($doc->{$solr_property})) {
- $result['fields'][$search_api_property] = $doc->{$solr_property};
+ $value = $doc->{$solr_property};
// Date fields need some special treatment to become valid date values
// (i.e., timestamps) again.
if (isset($field_options[$search_api_property]['type'])
- && $field_options[$search_api_property]['type'] == 'date'
- && preg_match('/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z$/', $result['fields'][$search_api_property])) {
- $result['fields'][$search_api_property] = strtotime($result['fields'][$search_api_property]);
+ && search_api_extract_inner_type($field_options[$search_api_property]['type']) === 'date'
+ && preg_match('/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z$/', $value)) {
+ $value = is_array($value) ? array_map('strtotime', $value) : strtotime($value);
}
+ $result['fields'][$search_api_property] = $value;
}
}
- $excerpt = $this->getExcerpt($response, $solr_id, $result['fields'], $fields);
+ $excerpt = $this->getExcerpt($response, $solr_id, $result['fields'], $fields, $search_fields);
if ($excerpt) {
$result['excerpt'] = $excerpt;
}
@@ -2280,18 +2403,21 @@ class SearchApiSolrService extends SearchApiAbstractService {
if (isset($response->facet_counts->facet_fields)) {
$results['search_api_facets'] = array();
$facet_fields = $response->facet_counts->facet_fields;
+ // The key for the "missing" facet (empty string in the JSON). This will
+ // be either "" or "_empty_", depending on the PHP version.
+ $empty_key = key((array) json_decode('{"":5}'));
foreach ($facets as $delta => $info) {
$field = $solr_fields[$info['field']];
if (!empty($facet_fields->$field)) {
$min_count = $info['min_count'];
$terms = $facet_fields->$field;
if ($info['missing']) {
- // We have to correctly incorporate the "_empty_" term.
+ // We have to correctly incorporate the "missing" term ($empty_key).
// This will ensure that the term with the least results is dropped,
// if the limit would be exceeded.
- if (isset($terms->_empty_)) {
- if ($terms->_empty_ < $min_count) {
- unset($terms->_empty_);
+ if (isset($terms->$empty_key)) {
+ if ($terms->$empty_key < $min_count) {
+ unset($terms->$empty_key);
}
else {
$terms = (array) $terms;
@@ -2302,14 +2428,14 @@ class SearchApiSolrService extends SearchApiAbstractService {
}
}
}
- elseif (isset($terms->_empty_)) {
+ elseif (isset($terms->$empty_key)) {
$terms = clone $terms;
- unset($terms->_empty_);
+ unset($terms->$empty_key);
}
$type = isset($fields[$info['field']]['type']) ? search_api_extract_inner_type($fields[$info['field']]['type']) : 'string';
foreach ($terms as $term => $count) {
if ($count >= $min_count) {
- if ($term === '_empty_') {
+ if ($term === $empty_key) {
$term = '!';
}
elseif ($type == 'boolean') {
diff --git a/sites/all/modules/contrib/search/search_api_solr/search_api_solr.info b/sites/all/modules/contrib/search/search_api_solr/search_api_solr.info
index 0ea0d30c..102b9bf2 100644
--- a/sites/all/modules/contrib/search/search_api_solr/search_api_solr.info
+++ b/sites/all/modules/contrib/search/search_api_solr/search_api_solr.info
@@ -11,9 +11,8 @@ files[] = includes/solr_connection.interface.inc
files[] = includes/solr_field.inc
files[] = includes/spellcheck.inc
-; Information added by Drupal.org packaging script on 2017-02-23
-version = "7.x-1.12"
+; Information added by Drupal.org packaging script on 2018-10-10
+version = "7.x-1.14"
core = "7.x"
project = "search_api_solr"
-datestamp = "1487844794"
-
+datestamp = "1539161895"
diff --git a/sites/all/modules/contrib/search/search_api_solr/search_api_solr.module b/sites/all/modules/contrib/search/search_api_solr/search_api_solr.module
index f3d943f9..ba2a24e4 100644
--- a/sites/all/modules/contrib/search/search_api_solr/search_api_solr.module
+++ b/sites/all/modules/contrib/search/search_api_solr/search_api_solr.module
@@ -31,7 +31,7 @@ function search_api_solr_menu() {
function search_api_solr_search_api_service_info() {
$variables = array(
'@solr_wiki_url' => url('http://wiki.apache.org/solr/SolrQuerySyntax'),
- '@readme_url' => url(drupal_get_path('module', 'search_api_solr') . '/README.txt'),
+ '@readme_url' => file_create_url(drupal_get_path('module', 'search_api_solr') . '/README.txt'),
);
$services['search_api_solr_service'] = array(
'name' => t('Solr service'),
diff --git a/sites/all/modules/contrib/search/search_api_solr/solr-conf/5.x/solrconfig.xml b/sites/all/modules/contrib/search/search_api_solr/solr-conf/5.x/solrconfig.xml
index c378343a..61b898b3 100644
--- a/sites/all/modules/contrib/search/search_api_solr/solr-conf/5.x/solrconfig.xml
+++ b/sites/all/modules/contrib/search/search_api_solr/solr-conf/5.x/solrconfig.xml
@@ -20,7 +20,7 @@
For more details about configurations options that may appear in
this file, see http://wiki.apache.org/solr/SolrConfigXml.
-->
-
+
+
+
+
+
+
+
+
diff --git a/sites/all/modules/contrib/search/search_api_solr/solr-conf/7.x/mapping-ISOLatin1Accent.txt b/sites/all/modules/contrib/search/search_api_solr/solr-conf/7.x/mapping-ISOLatin1Accent.txt
new file mode 100644
index 00000000..b92d03c5
--- /dev/null
+++ b/sites/all/modules/contrib/search/search_api_solr/solr-conf/7.x/mapping-ISOLatin1Accent.txt
@@ -0,0 +1,14 @@
+# This file contains character mappings for the default fulltext field type.
+# The source characters (on the left) will be replaced by the respective target
+# characters before any other processing takes place.
+# Lines starting with a pound character # are ignored.
+#
+# For sensible defaults, use the mapping-ISOLatin1Accent.txt file distributed
+# with the example application of your Solr version.
+#
+# Examples:
+# "À" => "A"
+# "\u00c4" => "A"
+# "\u00c4" => "\u0041"
+# "æ" => "ae"
+# "\n" => " "
diff --git a/sites/all/modules/contrib/search/search_api_solr/solr-conf/7.x/protwords.txt b/sites/all/modules/contrib/search/search_api_solr/solr-conf/7.x/protwords.txt
new file mode 100644
index 00000000..cda85814
--- /dev/null
+++ b/sites/all/modules/contrib/search/search_api_solr/solr-conf/7.x/protwords.txt
@@ -0,0 +1,7 @@
+#-----------------------------------------------------------------------
+# This file blocks words from being operated on by the stemmer and word delimiter.
+&
+<
+>
+'
+"
diff --git a/sites/all/modules/contrib/search/search_api_solr/solr-conf/7.x/schema.xml b/sites/all/modules/contrib/search/search_api_solr/solr-conf/7.x/schema.xml
new file mode 100644
index 00000000..de61b0eb
--- /dev/null
+++ b/sites/all/modules/contrib/search/search_api_solr/solr-conf/7.x/schema.xml
@@ -0,0 +1,693 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ id
+
+
+
+
+
+
+
+
+
diff --git a/sites/all/modules/contrib/search/search_api_solr/solr-conf/7.x/schema_extra_fields.xml b/sites/all/modules/contrib/search/search_api_solr/solr-conf/7.x/schema_extra_fields.xml
new file mode 100644
index 00000000..02b36555
--- /dev/null
+++ b/sites/all/modules/contrib/search/search_api_solr/solr-conf/7.x/schema_extra_fields.xml
@@ -0,0 +1,23 @@
+
+
+
+
diff --git a/sites/all/modules/contrib/search/search_api_solr/solr-conf/7.x/schema_extra_types.xml b/sites/all/modules/contrib/search/search_api_solr/solr-conf/7.x/schema_extra_types.xml
new file mode 100644
index 00000000..bd716b82
--- /dev/null
+++ b/sites/all/modules/contrib/search/search_api_solr/solr-conf/7.x/schema_extra_types.xml
@@ -0,0 +1,34 @@
+
+
+
+
diff --git a/sites/all/modules/contrib/search/search_api_solr/solr-conf/7.x/solrconfig.xml b/sites/all/modules/contrib/search/search_api_solr/solr-conf/7.x/solrconfig.xml
new file mode 100644
index 00000000..36e6fa14
--- /dev/null
+++ b/sites/all/modules/contrib/search/search_api_solr/solr-conf/7.x/solrconfig.xml
@@ -0,0 +1,1793 @@
+
+
+
+
+
+
+
+
+ ${solr.abortOnConfigurationError:true}
+
+
+ ${solr.luceneMatchVersion:LUCENE_60}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ${solr.data.dir:}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 32
+
+
+
+
+
+
+ 4
+
+
+
+
+
+
+ ${solr.lock.type:native}
+
+
+
+
+
+ true
+
+
+
+
+ 1
+
+ 0
+
+
+
+
+
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ${solr.autoCommit.MaxDocs:10000}
+ ${solr.autoCommit.MaxTime:120000}
+
+
+
+
+ ${solr.autoSoftCommit.MaxDocs:2000}
+ ${solr.autoSoftCommit.MaxTime:10000}
+
+
+
+
+
+
+
+
+ ${solr.data.dir:}
+
+
+
+
+
+
+
+
+
+
+ 1024
+
+
+ -1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+
+
+
+
+
+ 20
+
+
+ 200
+
+
+
+
+
+
+
+
+
+
+
+ solr rocks 0 10
+
+
+
+
+
+ false
+
+
+ 2
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ explicit
+ json
+ true
+ text
+
+
+
+
+
+
+
+ {!xport}
+ xsort
+ false
+
+
+
+ query
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ edismax
+ content
+ explicit
+ true
+ 0.01
+
+ ${solr.pinkPony.timeAllowed:-1}
+ *:*
+
+
+ false
+
+ true
+ false
+
+ 1
+
+
+ spellcheck
+ elevator
+
+
+
+
+
+
+ content
+ 1
+ 1
+ 3
+ 15
+ 20
+ false
+
+ ${solr.mlt.timeAllowed:2000}
+
+
+
+
+
+
+ content
+ explicit
+ true
+
+
+
+
+
+
+
+ text
+
+
+
+
+
+
+ _src_
+
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text
+ true
+ ignored_
+
+
+ true
+ links
+ ignored_
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ explicit
+ true
+
+
+
+
+
+
+ ${solr.replication.master:false}
+ commit
+ startup
+ ${solr.replication.confFiles:schema.xml,mapping-ISOLatin1Accent.txt,protwords.txt,stopwords.txt,synonyms.txt,elevate.xml}
+
+
+ ${solr.replication.slave:false}
+ ${solr.replication.masterUrl:http://localhost:8983/solr}/replication
+ ${solr.replication.pollInterval:00:00:60}
+
+
+
+
+
+
+ true
+ json
+ true
+
+
+
+
+
+
+
+
+
+ default
+ wordbreak
+ false
+ false
+ 1
+ 5
+ 5
+ true
+ true
+ 10
+ 5
+
+
+ spellcheck
+
+
+
+
+
+
+ mySuggester
+ FuzzyLookupFactory
+ DocumentDictionaryFactory
+ cat
+ price
+ string
+
+
+
+
+
+ true
+ 10
+
+
+ suggest
+
+
+
+
+
+
+
+
+
+ true
+
+
+ tvComponent
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+
+
+ terms
+
+
+
+
+
+
+ string
+ elevate.xml
+
+
+
+
+
+ explicit
+
+
+ elevator
+
+
+
+
+
+
+
+
+
+
+ 100
+
+
+
+
+
+
+
+ 70
+
+ 0.5
+
+ [-\w ,/\n\"']{20,200}
+
+
+
+
+
+
+ ]]>
+ ]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ,,
+ ,,
+ ,,
+ ,,
+ ,]]>
+ ]]>
+
+
+
+
+
+ 10
+ .,!?
+
+
+
+
+
+
+ WORD
+
+
+ en
+ US
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/plain; charset=UTF-8
+
+
+
+
+
+
+
+
+ 5
+
+
+
+
+
+
+
+
+
+
+
+
+ *:*
+
+
+
+
+
+
+
+
+
+
+
+ textSpell
+
+
+
+ default
+ spell
+ spellchecker
+ true
+
+
+
+
+
+
diff --git a/sites/all/modules/contrib/search/search_api_solr/solr-conf/7.x/solrconfig_extra.xml b/sites/all/modules/contrib/search/search_api_solr/solr-conf/7.x/solrconfig_extra.xml
new file mode 100644
index 00000000..c5bc3acf
--- /dev/null
+++ b/sites/all/modules/contrib/search/search_api_solr/solr-conf/7.x/solrconfig_extra.xml
@@ -0,0 +1,80 @@
+
+
+
+textSpell
+
+
+
+
+
+ default
+ spell
+ spellchecker
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/sites/all/modules/contrib/search/search_api_solr/solr-conf/7.x/solrcore.properties b/sites/all/modules/contrib/search/search_api_solr/solr-conf/7.x/solrcore.properties
new file mode 100644
index 00000000..fb8d7d05
--- /dev/null
+++ b/sites/all/modules/contrib/search/search_api_solr/solr-conf/7.x/solrcore.properties
@@ -0,0 +1,20 @@
+# Defines Solr properties for this specific core.
+solr.replication.master=false
+solr.replication.slave=false
+solr.replication.pollInterval=00:00:60
+solr.replication.masterUrl=http://localhost:8983/solr
+solr.replication.confFiles=schema.xml,mapping-ISOLatin1Accent.txt,protwords.txt,stopwords.txt,synonyms.txt,elevate.xml
+solr.mlt.timeAllowed=2000
+# You should not set your luceneMatchVersion to anything lower than your Solr
+# Version.
+solr.luceneMatchVersion=6.0
+solr.pinkPony.timeAllowed=-1
+# autoCommit after 10000 docs
+solr.autoCommit.MaxDocs=10000
+# autoCommit after 2 minutes
+solr.autoCommit.MaxTime=120000
+# autoSoftCommit after 2000 docs
+solr.autoSoftCommit.MaxDocs=2000
+# autoSoftCommit after 10 seconds
+solr.autoSoftCommit.MaxTime=10000
+solr.contrib.dir=../../../contrib
diff --git a/sites/all/modules/contrib/search/search_api_solr/solr-conf/7.x/stopwords.txt b/sites/all/modules/contrib/search/search_api_solr/solr-conf/7.x/stopwords.txt
new file mode 100644
index 00000000..d7f243e4
--- /dev/null
+++ b/sites/all/modules/contrib/search/search_api_solr/solr-conf/7.x/stopwords.txt
@@ -0,0 +1,4 @@
+# Contains words which shouldn't be indexed for fulltext fields, e.g., because
+# they're too common. For documentation of the format, see
+# http://wiki.apache.org/solr/AnalyzersTokenizersTokenFilters#solr.StopFilterFactory
+# (Lines starting with a pound character # are ignored.)
diff --git a/sites/all/modules/contrib/search/search_api_solr/solr-conf/7.x/synonyms.txt b/sites/all/modules/contrib/search/search_api_solr/solr-conf/7.x/synonyms.txt
new file mode 100644
index 00000000..7d22eea6
--- /dev/null
+++ b/sites/all/modules/contrib/search/search_api_solr/solr-conf/7.x/synonyms.txt
@@ -0,0 +1,3 @@
+# Contains synonyms to use for your index. For the format used, see
+# http://wiki.apache.org/solr/AnalyzersTokenizersTokenFilters#solr.SynonymFilterFactory
+# (Lines starting with a pound character # are ignored.)
diff --git a/sites/all/modules/contrib/views/views/handlers/views_handler_argument_null.inc b/sites/all/modules/contrib/views/views/handlers/views_handler_argument_null.inc
index ac668fbb..afe0c606 100644
--- a/sites/all/modules/contrib/views/views/handlers/views_handler_argument_null.inc
+++ b/sites/all/modules/contrib/views/views/handlers/views_handler_argument_null.inc
@@ -44,7 +44,7 @@ class views_handler_argument_null extends views_handler_argument {
*/
public function default_actions($which = NULL) {
if ($which) {
- if (in_array($which, array('ignore', 'not found', 'empty', 'default'))) {
+ if (in_array($which, array('ignore', 'not found', 'empty', 'default', 'access denied'))) {
return parent::default_actions($which);
}
return;
diff --git a/sites/all/modules/contrib/views/views/handlers/views_handler_field.inc b/sites/all/modules/contrib/views/views/handlers/views_handler_field.inc
index 15057f13..f33cf884 100644
--- a/sites/all/modules/contrib/views/views/handlers/views_handler_field.inc
+++ b/sites/all/modules/contrib/views/views/handlers/views_handler_field.inc
@@ -390,8 +390,7 @@ class views_handler_field extends views_handler {
* Optional name of the field where the value is stored.
*/
public function get_value($values, $field = NULL) {
- // $alias = isset($field) ? $this->aliases[$field] : $this->field_alias;
- $alias = isset($field) && isset($this->aliases[$field]) ? $this->aliases[$field] : $this->field_alias;
+ $alias = isset($field) ? $this->aliases[$field] : $this->field_alias;
if (isset($values->{$alias})) {
return $values->{$alias};
}
diff --git a/sites/all/modules/contrib/views/views/handlers/views_handler_field_serialized.inc b/sites/all/modules/contrib/views/views/handlers/views_handler_field_serialized.inc
index ae18712b..d0242b71 100644
--- a/sites/all/modules/contrib/views/views/handlers/views_handler_field_serialized.inc
+++ b/sites/all/modules/contrib/views/views/handlers/views_handler_field_serialized.inc
@@ -71,7 +71,7 @@ class views_handler_field_serialized extends views_handler_field {
return check_plain($value[$this->options['key']]);
}
- return $value;
+ return check_plain($value);
}
}
diff --git a/sites/all/modules/contrib/views/views/includes/handlers.inc b/sites/all/modules/contrib/views/views/includes/handlers.inc
index 0e7af4ae..d631c052 100644
--- a/sites/all/modules/contrib/views/views/includes/handlers.inc
+++ b/sites/all/modules/contrib/views/views/includes/handlers.inc
@@ -996,58 +996,39 @@ class views_many_to_one_helper {
return $this->handler->table_alias;
}
- // Case 2: it's an 'and' or an 'or'.
+ // Case 2: it's anything but an 'or'.
// We do one join per selected value.
- if ($this->handler->operator != 'not') {
- // Clone the join for each table.
- $this->handler->table_aliases = array();
- foreach ($this->handler->value as $value) {
- $join = $this->get_join();
- if ($this->handler->operator == 'and') {
- $join->type = 'INNER';
- }
- $join->extra = array(
- array(
- 'field' => $this->handler->real_field,
- 'value' => $value,
- 'numeric' => !empty($this->handler->definition['numeric']),
- ),
- );
- // The table alias needs to be unique to this value across the
- // multiple times the filter or argument is called by the view.
- if (!isset($this->handler->view->many_to_one_aliases[$field][$value])) {
- if (!isset($this->handler->view->many_to_one_count[$this->handler->table])) {
- $this->handler->view->many_to_one_count[$this->handler->table] = 0;
- }
- $this->handler->view->many_to_one_aliases[$field][$value] = $this->handler->table . '_value_' . ($this->handler->view->many_to_one_count[$this->handler->table]++);
+ // Clone the join for each table:
+ $this->handler->table_aliases = array();
+ foreach ($this->handler->value as $value) {
+ $join = $this->get_join();
+ if ($this->handler->operator == 'and') {
+ $join->type = 'INNER';
+ }
+ if (empty($join->extra)) {
+ $join->extra = array();
+ }
+ $join->extra[] = array(
+ 'field' => $this->handler->real_field,
+ 'value' => $value,
+ 'numeric' => !empty($this->handler->definition['numeric']),
+ );
+ // The table alias needs to be unique to this value across the
+ // multiple times the filter or argument is called by the view.
+ if (!isset($this->handler->view->many_to_one_aliases[$field][$value])) {
+ if (!isset($this->handler->view->many_to_one_count[$this->handler->table])) {
+ $this->handler->view->many_to_one_count[$this->handler->table] = 0;
}
- $alias = $this->handler->table_aliases[$value] = $this->add_table($join, $this->handler->view->many_to_one_aliases[$field][$value]);
-
+ $this->handler->view->many_to_one_aliases[$field][$value] = $this->handler->table . '_value_' . ($this->handler->view->many_to_one_count[$this->handler->table]++);
+ $alias = $this->handler->table_aliases[$value] = $this->add_table($join,
+ $this->handler->view->many_to_one_aliases[$field][$value]);
// and set table_alias to the first of these.
if (empty($this->handler->table_alias)) {
$this->handler->table_alias = $alias;
}
}
}
- // Case 3: it's a 'not'.
- // We just do one join. We'll add a where clause during the query phase
- // to ensure that $table.$field IS NULL.
- else {
- $join = $this->get_join();
- $join->type = 'LEFT';
- $join->extra = array();
- $join->extra_type = 'OR';
- foreach ($this->handler->value as $value) {
- $join->extra[] = array(
- 'field' => $this->handler->real_field,
- 'value' => $value,
- 'numeric' => !empty($this->handler->definition['numeric']),
- );
- }
-
- $this->handler->table_alias = $this->add_table($join);
- }
}
return $this->handler->table_alias;
}
@@ -1081,12 +1062,7 @@ class views_many_to_one_helper {
// Determine whether a single expression is enough(FALSE) or the conditions
// should be added via an db_or()/db_and() (TRUE).
$add_condition = TRUE;
- if ($operator == 'not') {
- $value = NULL;
- $operator = 'IS NULL';
- $add_condition = FALSE;
- }
- elseif ($operator == 'or' && empty($options['reduce_duplicates'])) {
+ if ($operator == 'or' && empty($options['reduce_duplicates'])) {
if (count($value) > 1) {
$operator = 'IN';
}
@@ -1120,6 +1096,9 @@ class views_many_to_one_helper {
$field = $this->handler->real_field;
$clause = $operator == 'or' ? db_or() : db_and();
foreach ($this->handler->table_aliases as $value => $alias) {
+ if ($operator == 'not') {
+ $value = NULL;
+ }
$clause->condition("$alias.$field", $value);
}
diff --git a/sites/all/modules/contrib/views/views/includes/view.inc b/sites/all/modules/contrib/views/views/includes/view.inc
index 13e4987f..ae6df4c6 100644
--- a/sites/all/modules/contrib/views/views/includes/view.inc
+++ b/sites/all/modules/contrib/views/views/includes/view.inc
@@ -1236,7 +1236,7 @@ class view extends views_db_object {
if (!empty($this->build_info['fail'])) {
return;
}
- if (!empty($this->view->build_info['denied'])) {
+ if (!empty($this->build_info['denied'])) {
return;
}
diff --git a/sites/all/modules/contrib/views/views/plugins/views_plugin_display_feed.inc b/sites/all/modules/contrib/views/views/plugins/views_plugin_display_feed.inc
index 07e5bc2f..a3c2333c 100644
--- a/sites/all/modules/contrib/views/views/plugins/views_plugin_display_feed.inc
+++ b/sites/all/modules/contrib/views/views/plugins/views_plugin_display_feed.inc
@@ -51,6 +51,9 @@ class views_plugin_display_feed extends views_plugin_display_page {
*/
public function execute() {
$output = $this->view->render();
+ if (!empty($this->view->build_info['denied'])) {
+ return MENU_ACCESS_DENIED;
+ }
if (empty($output)) {
return MENU_NOT_FOUND;
}
diff --git a/sites/all/modules/contrib/views/views/tests/views_argument_validator.test b/sites/all/modules/contrib/views/views/tests/views_argument_validator.test
index 6e2eedba..6927584d 100644
--- a/sites/all/modules/contrib/views/views/tests/views_argument_validator.test
+++ b/sites/all/modules/contrib/views/views/tests/views_argument_validator.test
@@ -40,10 +40,27 @@ class ViewsArgumentValidatorTest extends ViewsSqlTest {
$this->assertTrue($view->argument['null']->validate_arg(12));
}
+ /**
+ * Make sure argument validation works properly.
+ */
+ function testArgumentValidatePhpFailure() {
+ $view = $this->view_test_argument_validate_php_failure();
+ $view->save();
+ $this->drupalGet('test-php-failure');
+
+ // This should return a 403, indicating that the arguments validation fails.
+ $this->assertResponse(403);
+
+ $this->drupalGet('test-php-failure-feed');
+
+ // This should return a 403, indicating that the arguments validation fails.
+ $this->assertResponse(403);
+ }
+
function view_test_argument_validate_php($string) {
$code = 'return $argument == \'' . $string . '\';';
$view = new view();
- $view->name = 'view_argument_validate_numeric';
+ $view->name = 'view_argument_validate_php';
$view->description = '';
$view->tag = '';
$view->view_php = '';
@@ -104,4 +121,68 @@ class ViewsArgumentValidatorTest extends ViewsSqlTest {
return $view;
}
+ /**
+ *
+ *
+ * @return view $view
+ * The required view object.
+ */
+ function view_test_argument_validate_php_failure() {
+ $view = new view();
+ $view->name = 'view_argument_validate_php_failure';
+ $view->description = '';
+ $view->tag = '';
+ $view->base_table = 'node';
+ $view->human_name = '';
+ $view->core = 0;
+ $view->api_version = '3.0';
+ $view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */
+
+ /* Display: Master */
+ $handler = $view->new_display('default', 'Master', 'default');
+ $handler->display->display_options['use_more_always'] = FALSE;
+ $handler->display->display_options['access']['type'] = 'none';
+ $handler->display->display_options['cache']['type'] = 'none';
+ $handler->display->display_options['query']['type'] = 'views_query';
+ $handler->display->display_options['exposed_form']['type'] = 'basic';
+ $handler->display->display_options['pager']['type'] = 'none';
+ $handler->display->display_options['style_plugin'] = 'default';
+ $handler->display->display_options['row_plugin'] = 'fields';
+ /* Field: Content: Title */
+ $handler->display->display_options['fields']['title']['id'] = 'title';
+ $handler->display->display_options['fields']['title']['table'] = 'node';
+ $handler->display->display_options['fields']['title']['field'] = 'title';
+ $handler->display->display_options['fields']['title']['label'] = '';
+ $handler->display->display_options['fields']['title']['element_label_colon'] = FALSE;
+ $handler->display->display_options['fields']['title']['link_to_node'] = FALSE;
+ /* Contextual filter: Global: Null */
+ $handler->display->display_options['arguments']['null']['id'] = 'null';
+ $handler->display->display_options['arguments']['null']['table'] = 'views';
+ $handler->display->display_options['arguments']['null']['field'] = 'null';
+ $handler->display->display_options['arguments']['null']['default_action'] = 'default';
+ $handler->display->display_options['arguments']['null']['default_argument_type'] = 'fixed';
+ $handler->display->display_options['arguments']['null']['default_argument_options']['argument'] = 'No filter';
+ $handler->display->display_options['arguments']['null']['summary']['number_of_records'] = '0';
+ $handler->display->display_options['arguments']['null']['summary']['format'] = 'default_summary';
+ $handler->display->display_options['arguments']['null']['summary_options']['items_per_page'] = '25';
+ $handler->display->display_options['arguments']['null']['specify_validation'] = TRUE;
+ $handler->display->display_options['arguments']['null']['validate']['type'] = 'php';
+ $handler->display->display_options['arguments']['null']['validate_options']['code'] = 'return FALSE;';
+ $handler->display->display_options['arguments']['null']['validate']['fail'] = 'access denied';
+
+ /* Display: Page */
+ $handler = $view->new_display('page', 'Page', 'page_1');
+ $handler->display->display_options['path'] = 'test-php-failure';
+
+ /* Display: Feed */
+ $handler = $view->new_display('feed', 'Feed', 'feed_1');
+ $handler->display->display_options['path'] = 'test-php-failure-feed';
+ $handler->display->display_options['pager']['type'] = 'none';
+ $handler->display->display_options['pager']['options']['offset'] = '0';
+ $handler->display->display_options['style_plugin'] = 'rss';
+ $handler->display->display_options['row_plugin'] = 'node_rss';
+
+ return $view;
+ }
+
}
diff --git a/sites/all/modules/contrib/views/views/tests/views_handler_filter.test b/sites/all/modules/contrib/views/views/tests/views_handler_filter.test
new file mode 100644
index 00000000..e41b35a3
--- /dev/null
+++ b/sites/all/modules/contrib/views/views/tests/views_handler_filter.test
@@ -0,0 +1,161 @@
+ 'Handler filter test',
+ 'description' => 'test filter handler definitions',
+ 'group' => 'Views',
+ );
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function setUp() {
+ // The Views and Views UI modules will be enabled with this.
+ parent::setUp();
+
+ // Assign vocabulary 'tag' to user entity.
+ $field_definition = field_read_field('field_tags');
+ $instance_definition = array(
+ 'field_name' => $field_definition['field_name'],
+ 'entity_type' => 'user',
+ 'bundle' => 'user',
+ 'widget' => array(
+ 'type' => 'taxonomy_autocomplete',
+ ),
+ 'display' => array(
+ 'default' => array(
+ 'type' => 'taxonomy_term_reference_link',
+ 'weight' => 10,
+ ),
+ 'teaser' => array(
+ 'type' => 'taxonomy_term_reference_link',
+ 'weight' => 10,
+ ),
+ ),
+ );
+ field_create_instance($instance_definition);
+ }
+
+ /**
+ * Tests "is all of" of filter operation.
+ */
+ function testFilterInOperatorUi() {
+ $term = $this->drupalCreateTerm(1);
+
+ $node1 = $this->drupalCreateNode(array('type' => 'article','field_tags_tid' => $term->tid, 'created' => REQUEST_TIME));
+ $node2 = $this->drupalCreateNode(array('type' => 'article', 'created' => REQUEST_TIME + 1));
+ $user2 = $this->drupalCreateUser(array('access content'));
+ // $this->drupalLogin($this->drupalCreateUser(array('administer users'));
+ $this->drupalLogin($this->drupalCreateUser(array('administer users', 'access administration pages', 'administer site configuration', 'administer nodes', 'bypass node access')));
+
+ $this->drupalGet('node/1/edit');
+ $edit['field_tags' . '[' . LANGUAGE_NONE . ']'] = $term->name;
+ $this->drupalPost('node/' . $node1->nid . '/edit', $edit, t('Save'));
+
+ $edit['field_tags' . '[' . LANGUAGE_NONE . ']'] = $term->name;
+ $this->drupalPost('user/' . $user2->uid . '/edit', $edit, t('Save'));
+
+ $result[] = array('nid' => $node1->nid);
+ $view = $this->get_sample_view();
+ $this->executeView($view);
+ $this->assertIdenticalResultset($view, $result);
+ }
+
+ /**
+ * Sample view.
+ *
+ * @return \view
+ */
+ protected function get_sample_view() {
+ $view = new view();
+ $view->name = 'article';
+ $view->description = '';
+ $view->tag = 'default';
+ $view->base_table = 'node';
+ $view->human_name = 'Article';
+ $view->core = 7;
+ $view->api_version = '3.0';
+ $view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */
+
+ /* Display: Master */
+ $handler = $view->new_display('default', 'Master', 'default');
+ $handler->display->display_options['title'] = 'Article';
+ $handler->display->display_options['use_more_always'] = FALSE;
+ $handler->display->display_options['access']['type'] = 'perm';
+ $handler->display->display_options['cache']['type'] = 'none';
+ $handler->display->display_options['query']['type'] = 'views_query';
+ $handler->display->display_options['exposed_form']['type'] = 'basic';
+ $handler->display->display_options['pager']['type'] = 'full';
+ $handler->display->display_options['pager']['options']['items_per_page'] = '10';
+ $handler->display->display_options['style_plugin'] = 'table';
+ $handler->display->display_options['style_options']['columns'] = array(
+ 'title' => 'title',
+ );
+ $handler->display->display_options['style_options']['default'] = '-1';
+ $handler->display->display_options['style_options']['info'] = array(
+ 'title' => array(
+ 'sortable' => 0,
+ 'default_sort_order' => 'asc',
+ 'align' => '',
+ 'separator' => '',
+ 'empty_column' => 0,
+ ),
+ );
+ /* Field: Content: Nid */
+ $handler->display->display_options['fields']['nid']['id'] = 'nid';
+ $handler->display->display_options['fields']['nid']['table'] = 'node';
+ $handler->display->display_options['fields']['nid']['field'] = 'nid';
+ $handler->display->display_options['fields']['nid']['label'] = '';
+ $handler->display->display_options['fields']['nid']['element_label_colon'] = FALSE;
+ /* Sort criterion: Content: Post date */
+ $handler->display->display_options['sorts']['created']['id'] = 'created';
+ $handler->display->display_options['sorts']['created']['table'] = 'node';
+ $handler->display->display_options['sorts']['created']['field'] = 'created';
+ $handler->display->display_options['sorts']['created']['order'] = 'DESC';
+ /* Filter criterion: Content: Published */
+ $handler->display->display_options['filters']['status']['id'] = 'status';
+ $handler->display->display_options['filters']['status']['table'] = 'node';
+ $handler->display->display_options['filters']['status']['field'] = 'status';
+ $handler->display->display_options['filters']['status']['value'] = 1;
+ $handler->display->display_options['filters']['status']['group'] = 1;
+ $handler->display->display_options['filters']['status']['expose']['operator'] = FALSE;
+ /* Filter criterion: Field: Tags (field_tags) */
+ $handler->display->display_options['filters']['field_tags_tid']['id'] = 'field_tags_tid';
+ $handler->display->display_options['filters']['field_tags_tid']['table'] = 'field_data_field_tags';
+ $handler->display->display_options['filters']['field_tags_tid']['field'] = 'field_tags_tid';
+ $handler->display->display_options['filters']['field_tags_tid']['operator'] = 'and';
+ $handler->display->display_options['filters']['field_tags_tid']['value'] = array(
+ 0 => '1',
+ );
+ $handler->display->display_options['filters']['field_tags_tid']['expose']['operator_id'] = 'field_tags_tid_op';
+ $handler->display->display_options['filters']['field_tags_tid']['expose']['label'] = 'Tags (field_tags)';
+ $handler->display->display_options['filters']['field_tags_tid']['expose']['operator'] = 'field_tags_tid_op';
+ $handler->display->display_options['filters']['field_tags_tid']['expose']['identifier'] = 'field_tags_tid';
+ $handler->display->display_options['filters']['field_tags_tid']['expose']['remember_roles'] = array(
+ 2 => '2',
+ );
+ $handler->display->display_options['filters']['field_tags_tid']['vocabulary'] = 'tags';
+
+ /* Display: Page */
+ $handler = $view->new_display('page', 'Page', 'page');
+ $handler->display->display_options['path'] = 'article';
+
+ return $view;
+ }
+
+}
diff --git a/sites/all/modules/contrib/views/views/tests/views_query.test b/sites/all/modules/contrib/views/views/tests/views_query.test
index 1146cc05..5acf01e9 100644
--- a/sites/all/modules/contrib/views/views/tests/views_query.test
+++ b/sites/all/modules/contrib/views/views/tests/views_query.test
@@ -135,6 +135,23 @@ abstract class ViewsTestCase extends DrupalWebTestCase {
$this->verbose('Executed view: ' . ((string) $view->build_info['query']) . '
');
}
+ /**
+ * Log in as user 1.
+ */
+ protected function loginUser1() {
+ $password = user_password();
+ // Reset the user 1 password.
+ $account = user_load(1);
+ $edit = array(
+ 'pass' => $password,
+ );
+ $account = user_save($account, $edit);
+ $account->pass_raw = $password;
+
+ // Log in as user 1.
+ $this->drupalLogin($account);
+ }
+
}
/**
@@ -167,6 +184,24 @@ abstract class ViewsSqlTest extends ViewsTestCase {
$this->checkPermissions(array(), TRUE);
}
+ /**
+ * Create a term.
+ *
+ * @param int $vid
+ * The vocabulary ID that the term is to be added to.
+ *
+ * @return object
+ * A full term object with a random name.
+ */
+ protected function drupalCreateTerm($vid) {
+ $term = new stdClass();
+ $term->name = $this->randomName();
+ $term->description = $this->randomName();
+ $term->vid = $vid;
+ taxonomy_term_save($term);
+ return $term;
+ }
+
/**
* This function allows to enable views ui from a higher class which can't
* change the setup function anymore.
diff --git a/sites/all/modules/contrib/views/views/tests/views_test.info b/sites/all/modules/contrib/views/views/tests/views_test.info
index 1b0e8c01..5095b7f2 100644
--- a/sites/all/modules/contrib/views/views/tests/views_test.info
+++ b/sites/all/modules/contrib/views/views/tests/views_test.info
@@ -5,8 +5,8 @@ core = 7.x
dependencies[] = views
hidden = TRUE
-; Information added by Drupal.org packaging script on 2018-04-14
-version = "7.x-3.20"
+; Information added by Drupal.org packaging script on 2019-04-03
+version = "7.x-3.22"
core = "7.x"
project = "views"
-datestamp = "1523668093"
+datestamp = "1554307093"
diff --git a/sites/all/modules/contrib/views/views/views.info b/sites/all/modules/contrib/views/views/views.info
index 1dd74a50..d9d1c116 100644
--- a/sites/all/modules/contrib/views/views/views.info
+++ b/sites/all/modules/contrib/views/views/views.info
@@ -308,6 +308,7 @@ files[] = tests/views_exposed_form.test
files[] = tests/field/views_fieldapi.test
files[] = tests/views_glossary.test
files[] = tests/views_groupby.test
+files[] = tests/views_handler_filter.test
files[] = tests/views_handlers.test
files[] = tests/views_module.test
files[] = tests/views_pager.test
@@ -328,8 +329,8 @@ files[] = tests/views_cache.test
files[] = tests/views_view.test
files[] = tests/views_ui.test
-; Information added by Drupal.org packaging script on 2018-04-14
-version = "7.x-3.20"
+; Information added by Drupal.org packaging script on 2019-04-03
+version = "7.x-3.22"
core = "7.x"
project = "views"
-datestamp = "1523668093"
+datestamp = "1554307093"
diff --git a/sites/all/modules/contrib/views/views/views_ui.info b/sites/all/modules/contrib/views/views/views_ui.info
index addebb2b..3053db91 100644
--- a/sites/all/modules/contrib/views/views/views_ui.info
+++ b/sites/all/modules/contrib/views/views/views_ui.info
@@ -8,8 +8,8 @@ dependencies[] = views
files[] = views_ui.module
files[] = plugins/views_wizard/views_ui_base_views_wizard.class.php
-; Information added by Drupal.org packaging script on 2018-04-14
-version = "7.x-3.20"
+; Information added by Drupal.org packaging script on 2019-04-03
+version = "7.x-3.22"
core = "7.x"
project = "views"
-datestamp = "1523668093"
+datestamp = "1554307093"