Projet

Général

Profil

Révision 39a181a4

Ajouté par Assos Assos il y a environ 6 ans

Weekly update of contrib modules

Voir les différences:

drupal7/sites/all/modules/link/link.module
10 10
define('LINK_FRONT', 'front');
11 11
define('LINK_EMAIL', 'email');
12 12
define('LINK_NEWS', 'news');
13
define('LINK_DOMAINS', 'aero|arpa|asia|biz|build|com|cat|ceo|coop|edu|gov|info|int|jobs|mil|museum|name|nato|net|org|post|pro|tel|travel|mobi|local|xxx');
14

  
15 13
define('LINK_TARGET_DEFAULT', 'default');
16 14
define('LINK_TARGET_NEW_WINDOW', '_blank');
17 15
define('LINK_TARGET_TOP', '_top');
......
22 20
 */
23 21
define('LINK_URL_MAX_LENGTH', 2048);
24 22

  
23
/**
24
 * Implements hook_help().
25
 */
26
function link_help($path, $arg) {
27
  switch ($path) {
28
    case 'admin/help#link':
29
      $output = '<p><strong>About</strong></p>';
30
      $output .= '<p>' . '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.' . '</p>';
31
      $output .= '<p>' . '<strong>Requirements / Dependencies</strong>' . '</p>';
32
      $output .= '<p>' . 'Fields API is provided already by core [no dependencies].' . '</p>';
33
      $output .= '<p><strong>Configuration</strong></p>';
34
      $output .= '<p>' . '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.' . '</p>';
35
      return $output;
36
  }
37
}
38

  
25 39
/**
26 40
 * Implements hook_field_info().
27 41
 */
......
98 112
    'optional' => t('Optional Title'),
99 113
    'required' => t('Required Title'),
100 114
    'value' => t('Static Title'),
115
    'select' => t('Selected Title'),
101 116
    'none' => t('No Title'),
102 117
  );
103 118

  
......
111 126

  
112 127
  $form['title_value'] = array(
113 128
    '#type' => 'textfield',
114
    '#title' => t('Static title'),
129
    '#title' => t('Static or default title'),
115 130
    '#default_value' => isset($instance['settings']['title_value']) ? $instance['settings']['title_value'] : '',
116
    '#description' => t('This title will always be used if &ldquo;Static Title&rdquo; is selected above.'),
131
    '#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.'),
132
    '#states' => array(
133
      'visible' => array(
134
        ':input[name="instance[settings][title]"]' => array('value' => 'value'),
135
      ),
136
    ),
137
  );
138

  
139
  $form['title_allowed_values'] = array(
140
    '#type' => 'textarea',
141
    '#title' => t('Title allowed values'),
142
    '#default_value' => isset($instance['settings']['title_allowed_values']) ? $instance['settings']['title_allowed_values'] : '',
143
    '#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.'),
144
    '#states' => array(
145
      'visible' => array(
146
        ':input[name="instance[settings][title]"]' => array('value' => 'select'),
147
      ),
148
    ),
117 149
  );
118 150

  
119 151
  $form['title_label_use_field_label'] = array(
......
181 213
  $form['attributes']['rel'] = array(
182 214
    '#type' => 'textfield',
183 215
    '#title' => t('Rel Attribute'),
184
    '#description' => t('When output, this link will have this rel attribute. The most common usage is <a href="http://en.wikipedia.org/wiki/Nofollow">rel=&quot;nofollow&quot;</a> which prevents some search engines from spidering entered links.'),
216
    '#description' => t('When output, this link will have this rel attribute. The most common usage is <a href="http://en.wikipedia.org/wiki/Nofollow" target="blank">rel=&quot;nofollow&quot;</a> which prevents some search engines from spidering entered links.'),
185 217
    '#default_value' => empty($instance['settings']['attributes']['rel']) ? '' : $instance['settings']['attributes']['rel'],
186 218
    '#field_prefix' => 'rel = "',
187 219
    '#field_suffix' => '"',
......
218 250
  $form['attributes']['title'] = array(
219 251
    '#title' => t("Default link 'title' Attribute"),
220 252
    '#type' => 'textfield',
221
    '#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 <a href="http://www.w3.org/TR/WCAG10-HTML-TECHS/#links">WCAG 1.0 Guidelines</a> for links comformances. Tokens values will be evaluated.'),
253
    '#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 <a href="http://www.w3.org/TR/WCAG10-HTML-TECHS/#links" target="blank">WCAG 1.0 Guidelines</a> for links comformances. Tokens values will be evaluated.'),
222 254
    '#default_value' => empty($instance['settings']['attributes']['title']) ? '' : $instance['settings']['attributes']['title'],
223 255
    '#field_prefix' => 'title = "',
224 256
    '#field_suffix' => '"',
......
228 260
}
229 261

  
230 262
/**
263
 * Form validate.
264
 *
231 265
 * #element_validate handler for link_field_instance_settings_form().
232 266
 */
233 267
function link_field_settings_form_validate($element, &$form_state, $complete_form) {
234 268
  if ($form_state['values']['instance']['settings']['title'] === 'value' && empty($form_state['values']['instance']['settings']['title_value'])) {
235
    form_set_error('title_value', t('A default title must be provided if the title is a static value.'));
269
    form_set_error('instance][settings][title_value', t('A default title must be provided if the title is a static value.'));
270
  }
271
  if ($form_state['values']['instance']['settings']['title'] === 'select'
272
    && empty($form_state['values']['instance']['settings']['title_allowed_values'])) {
273
    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.'));
236 274
  }
237 275
  if (!empty($form_state['values']['instance']['settings']['display']['url_cutoff']) && !is_numeric($form_state['values']['instance']['settings']['display']['url_cutoff'])) {
238 276
    form_set_error('display', t('URL Display Cutoff value must be numeric.'));
......
343 381
 * Implements hook_field_widget_error().
344 382
 */
345 383
function link_field_widget_error($element, $error, $form, &$form_state) {
346
  if ($error['error_element']['title']) {
384
  if (!empty($error['error_element']['title'])) {
347 385
    form_error($element['title'], $error['message']);
348 386
  }
349
  elseif ($error['error_element']['url']) {
387
  elseif (!empty($error['error_element']['url'])) {
350 388
    form_error($element['url'], $error['message']);
351 389
  }
352 390
}
......
372 410
/**
373 411
 * Prepares the item attributes and url for storage.
374 412
 *
375
 * @param $item
376
 *    Link field values.
377
 *
378
 * @param $delta
379
 *    The sequence number for current values.
380
 *
381
 * @param $field
382
 *    The field structure array.
383
 *
384
 * @param $entity
385
 *    Entity object.
386
 *
387
 * @param $instance
388
 *    The instance structure for $field on $entity's bundle.
413
 * @param array $item
414
 *   Link field values.
415
 * @param array $delta
416
 *   The sequence number for current values.
417
 * @param array $field
418
 *   The field structure array.
419
 * @param object $entity
420
 *   Entity object.
421
 * @param array $instance
422
 *   The instance structure for $field on $entity's bundle.
389 423
 *
424
 * @codingStandardsIgnoreStart
390 425
 */
391 426
function _link_process(&$item, $delta, $field, $entity, $instance) {
427
  // @codingStandardsIgnoreEnd
392 428
  // Trim whitespace from URL.
393 429
  if (!empty($item['url'])) {
394 430
    $item['url'] = trim($item['url']);
......
447 483
      'error_element' => array('url' => TRUE, 'title' => FALSE),
448 484
    );
449 485
  }
450
  // In a totally bizzaro case, where URLs and titles are optional but the field is required, ensure there is at least one link.
486
  // In a totally bizzaro case, where URLs and titles are optional but the field
487
  // is required, ensure there is at least one link.
451 488
  if ($instance['settings']['url'] === 'optional' && $instance['settings']['title'] === 'optional'
452
      && (strlen(trim($item['url'])) !== 0 || strlen(trim($item['title'])) !== 0)) {
489
    && (strlen(trim($item['url'])) !== 0 || strlen(trim($item['title'])) !== 0)) {
453 490
    $optional_field_found = TRUE;
454 491
  }
455 492
  // Require entire field.
......
465 502
/**
466 503
 * Clean up user-entered values for a link field according to field settings.
467 504
 *
468
 * @param array $item 
505
 * @param array $item
469 506
 *   A single link item, usually containing url, title, and attributes.
470
 * @param int $delta 
507
 * @param int $delta
471 508
 *   The delta value if this field is one of multiple fields.
472
 * @param array $field 
509
 * @param array $field
473 510
 *   The CCK field definition.
474
 * @param object $entity 
511
 * @param object $entity
475 512
 *   The entity containing this link.
513
 *
514
 * @codingStandardsIgnoreStart
476 515
 */
477 516
function _link_sanitize(&$item, $delta, &$field, $instance, &$entity) {
517
  // @codingStandardsIgnoreEnd
478 518
  // Don't try to process empty links.
479 519
  if (empty($item['url']) && empty($item['title'])) {
480 520
    return;
......
488 528
  $entity_info = entity_get_info($entity_type);
489 529
  $property_id = $entity_info['entity keys']['id'];
490 530
  $entity_token_type = isset($entity_info['token type']) ? $entity_info['token type'] : (
491
    $entity_type == 'taxonomy_term' || $entity_type == 'taxonomy_vocabulary' ? str_replace('taxonomy_', '', $entity_type) : $entity_type
531
  $entity_type == 'taxonomy_term' || $entity_type == 'taxonomy_vocabulary' ? str_replace('taxonomy_', '', $entity_type) : $entity_type
492 532
  );
493 533
  if (isset($instance['settings']['enable_tokens']) && $instance['settings']['enable_tokens']) {
494 534
    $text_tokens = token_scan($item['url']);
......
516 556

  
517 557
  if (!empty($url_parts['url'])) {
518 558
    $item['url'] = url($url_parts['url'],
519
      array('query' => isset($url_parts['query']) ? $url_parts['query'] : NULL,
520
      'fragment' => isset($url_parts['fragment']) ? $url_parts['fragment'] : NULL,
521
      'absolute' => !empty($instance['settings']['absolute_url']),
522
      'html' => TRUE,
559
      array(
560
        'query' => isset($url_parts['query']) ? $url_parts['query'] : NULL,
561
        'fragment' => isset($url_parts['fragment']) ? $url_parts['fragment'] : NULL,
562
        'absolute' => !empty($instance['settings']['absolute_url']),
563
        'html' => TRUE,
523 564
      )
524 565
    );
525 566
  }
......
551 592
    }
552 593
  }
553 594
  // Use the title defined by the user at the widget level.
554
  elseif (isset($item['title'])) {
595
  elseif (drupal_strlen(trim($item['title']))) {
555 596
    $title = $item['title'];
556 597
  }
598
  // Use the static title if a user-defined title is optional and a static title
599
  // has been defined.
600
  elseif ($instance['settings']['title'] == 'optional' && drupal_strlen(trim($instance['settings']['title_value']))) {
601
    $title = $instance['settings']['title_value'];
602
  }
557 603
  else {
558 604
    $title = '';
559 605
  }
560 606

  
561 607
  // Replace title tokens.
562
  if ($title && ($instance['settings']['title'] == 'value' || $instance['settings']['enable_tokens'])) {
608
  if ($title && $instance['settings']['enable_tokens']) {
563 609
    $text_tokens = token_scan($title);
564 610
    if (!empty($text_tokens)) {
565 611
      // Load the entity if necessary for entities in views.
......
572 618
      }
573 619
      $title = token_replace($title, array($entity_token_type => $entity_loaded));
574 620
    }
575
    $title = filter_xss($title, array('b', 'br', 'code', 'em', 'i', 'img', 'span', 'strong', 'sub', 'sup', 'tt', 'u'));
621
  }
622
  if ($title && ($instance['settings']['title'] == 'value' || $instance['settings']['enable_tokens'])) {
623
    $title = filter_xss($title, array(
624
      'b',
625
      'br',
626
      'code',
627
      'em',
628
      'i',
629
      'img',
630
      'span',
631
      'strong',
632
      'sub',
633
      'sup',
634
      'tt',
635
      'u',
636
    ));
576 637
    $item['html'] = TRUE;
577 638
  }
578
  $item['title'] = empty($title) ? $item['display_url'] : $title;
639
  $item['title'] = empty($title) && $title !== '0' ? $item['display_url'] : $title;
579 640

  
580 641
  if (!isset($item['attributes'])) {
581 642
    $item['attributes'] = array();
......
622 683
  // Handle "title" link attribute.
623 684
  if (!empty($item['attributes']['title']) && module_exists('token')) {
624 685
    $text_tokens = token_scan($item['attributes']['title']);
625
      if (!empty($text_tokens)) {
686
    if (!empty($text_tokens)) {
626 687
      // Load the entity (necessary for entities in views).
627 688
      if (isset($entity->{$property_id})) {
628 689
        $entity_loaded = entity_load($entity_type, array($entity->{$property_id}));
......
633 694
      }
634 695
      $item['attributes']['title'] = token_replace($item['attributes']['title'], array($entity_token_type => $entity_loaded));
635 696
    }
636
    $item['attributes']['title'] = filter_xss($item['attributes']['title'], array('b', 'br', 'code', 'em', 'i', 'img', 'span', 'strong', 'sub', 'sup', 'tt', 'u'));
697
    $item['attributes']['title'] = filter_xss($item['attributes']['title'], array(
698
      'b',
699
      'br',
700
      'code',
701
      'em',
702
      'i',
703
      'img',
704
      'span',
705
      'strong',
706
      'sub',
707
      'sup',
708
      'tt',
709
      'u',
710
    ));
637 711
  }
638 712
  // Handle attribute classes.
639 713
  if (!empty($item['attributes']['class'])) {
......
685 759
 * Replaces the PHP parse_str() function.
686 760
 *
687 761
 * Because parse_str replaces the following characters in query parameters name
688
 * in order to maintain compatibility with deprecated register_globals directive:
762
 * in order to maintain compatibility with deprecated register_globals
763
 * directive:
689 764
 *
690 765
 *   - chr(32) ( ) (space)
691 766
 *   - chr(46) (.) (dot)
......
732 807
      'variables' => array('element' => NULL, 'field' => NULL),
733 808
    ),
734 809
    'link_formatter_link_domain' => array(
735
      'variables' => array('element' => NULL, 'display' => NULL, 'field' => NULL),
810
      'variables' => array(
811
        'element' => NULL,
812
        'display' => NULL,
813
        'field' => NULL,
814
      ),
815
    ),
816
    'link_formatter_link_no_protocol' => array(
817
      'variables' => array('element' => NULL, 'field' => NULL),
736 818
    ),
737 819
    'link_formatter_link_title_plain' => array(
738 820
      'variables' => array('element' => NULL, 'field' => NULL),
......
819 901
 * Build the form element. When creating a form using FAPI #process,
820 902
 * note that $element['#value'] is already set.
821 903
 *
822
 * The $fields array is in $complete_form['#field_info'][$element['#field_name']].
904
 * The $fields array is in
905
 * $complete_form['#field_info'][$element['#field_name']].
823 906
 */
824 907
function link_field_process($element, $form_state, $complete_form) {
825 908
  $instance = field_widget_instance($element, $form_state);
......
831 914
    '#required' => ($element['#delta'] == 0 && $settings['url'] !== 'optional') ? $element['#required'] : FALSE,
832 915
    '#default_value' => isset($element['#value']['url']) ? $element['#value']['url'] : NULL,
833 916
  );
834
  if ($settings['title'] !== 'none' && $settings['title'] !== 'value') {
917
  if (in_array($settings['title'], array('optional', 'required'))) {
835 918
    // Figure out the label of the title field.
836 919
    if (!empty($settings['title_label_use_field_label'])) {
837 920
      // Use the element label as the title field label.
......
843 926
      $title_label = t('Title');
844 927
    }
845 928

  
929
    // Default value.
930
    $title_maxlength = 128;
931
    if (!empty($settings['title_maxlength'])) {
932
      $title_maxlength = $settings['title_maxlength'];
933
    }
934

  
846 935
    $element['title'] = array(
847 936
      '#type' => 'textfield',
848
      '#maxlength' => $settings['title_maxlength'],
937
      '#maxlength' => $title_maxlength,
849 938
      '#title' => $title_label,
850
      '#description' => t('The link title is limited to @maxlength characters maximum.', array('@maxlength' => $settings['title_maxlength'])),
939
      '#description' => t('The link title is limited to @maxlength characters maximum.', array('@maxlength' => $title_maxlength)),
851 940
      '#required' => ($settings['title'] == 'required' && (($element['#delta'] == 0 && $element['#required']) || !empty($element['#value']['url']))) ? TRUE : FALSE,
852 941
      '#default_value' => isset($element['#value']['title']) ? $element['#value']['title'] : NULL,
853 942
    );
854 943
  }
944
  elseif ($settings['title'] == 'select') {
945
    $options = drupal_map_assoc(array_filter(explode("\n", str_replace("\r", "\n", trim($settings['title_allowed_values'])))));
946
    $element['title'] = array(
947
      '#type' => 'select',
948
      '#title' => t('Title'),
949
      '#description' => t('Select the a title for this link.'),
950
      '#default_value' => isset($element['#value']['title']) ? $element['#value']['title'] : NULL,
951
      '#options' => $options,
952
    );
953
  }
855 954

  
856 955
  // Initialize field attributes as an array if it is not an array yet.
857 956
  if (!is_array($settings['attributes'])) {
......
888 987
  }
889 988

  
890 989
  // If the title field is available or there are field accepts multiple values
891
  // then allow the individual field items display the required asterisk if needed.
990
  // then allow the individual field items display the required asterisk if
991
  // needed.
892 992
  if (isset($element['title']) || isset($element['_weight'])) {
893 993
    // To prevent an extra required indicator, disable the required flag on the
894 994
    // base element since all the sub-fields are already required if desired.
......
941 1041
        'strip_www' => FALSE,
942 1042
      ),
943 1043
    ),
1044
    'link_no_protocol' => array(
1045
      'label' => t('URL with the protocol removed'),
1046
      'field types' => array('link_field'),
1047
      'multiple values' => FIELD_BEHAVIOR_DEFAULT,
1048
    ),
944 1049
    'link_short' => array(
945 1050
      'label' => t('Short, as link with title "Link"'),
946 1051
      'field types' => array('link_field'),
......
980 1085
 * Implements hook_field_formatter_settings_summary().
981 1086
 */
982 1087
function link_field_formatter_settings_summary($field, $instance, $view_mode) {
1088

  
983 1089
  $display = $instance['display'][$view_mode];
984
  $settings = $display['settings'];
1090

  
985 1091
  if ($display['type'] == 'link_domain') {
986 1092
    if ($display['settings']['strip_www']) {
987 1093
      return t('Strip www. from domain');
......
1026 1132
  }
1027 1133
  // If only a title, display the title.
1028 1134
  elseif (!empty($vars['element']['title'])) {
1029
    return $link_options['html'] ? $vars['element']['title'] : check_plain($vars['element']['title']);
1135
    return !empty($link_options['html']) ? $vars['element']['title'] : check_plain($vars['element']['title']);
1030 1136
  }
1031 1137
  elseif (!empty($vars['element']['url'])) {
1032 1138
    return l($vars['element']['title'], $vars['element']['url'], $link_options);
......
1078 1184
  return $vars['element']['url'] ? l($domain, $vars['element']['url'], $link_options) : '';
1079 1185
}
1080 1186

  
1187
/**
1188
 * Formats a link without the http:// or https://.
1189
 */
1190
function theme_link_formatter_link_no_protocol($vars) {
1191
  $link_options = $vars['element'];
1192
  unset($link_options['title']);
1193
  unset($link_options['url']);
1194
  // We drop any scheme of the url.
1195
  $scheme = parse_url($vars['element']['url']);
1196
  $search = '/' . preg_quote($scheme['scheme'] . '://', '/') . '/';
1197
  $replace = '';
1198
  $display_url = preg_replace($search, $replace, $vars['element']['url'], 1);
1199

  
1200
  return $vars['element']['url'] ? l($display_url, $vars['element']['url'], $link_options) : '';
1201
}
1202

  
1081 1203
/**
1082 1204
 * Formats a link's title as plain text.
1083 1205
 */
1084 1206
function theme_link_formatter_link_title_plain($vars) {
1085
  return empty($vars['element']['title']) ? '' : check_plain($vars['element']['title']);
1207
  return empty($vars['element']['title']) ? '' : check_plain(decode_entities($vars['element']['title']));
1086 1208
}
1087 1209

  
1088 1210
/**
......
1142 1264
/**
1143 1265
 * Implements hook_token_list().
1144 1266
 *
1145
 * @TODO: hook_token_list no longer exists - this should change to hook_token_info().
1267
 * @TODO: hook_token_list no longer exists - this should change to
1268
 *   hook_token_info().
1146 1269
 */
1147 1270
function link_token_list($type = 'all') {
1148 1271
  if ($type === 'field' || $type === 'all') {
......
1157 1280
/**
1158 1281
 * Implements hook_token_values().
1159 1282
 *
1160
 * @TODO: hook_token_values no longer exists - this should change to hook_tokens().
1283
 * @TODO: hook_token_values no longer exists - this should change to
1284
 *   hook_tokens().
1161 1285
 */
1162 1286
function link_token_values($type, $object = NULL) {
1163 1287
  if ($type === 'field') {
......
1185 1309
 * Forms a valid URL if possible from an entered address.
1186 1310
 *
1187 1311
 * Trims whitespace and automatically adds an http:// to addresses without a
1188
 * protocol specified
1312
 * protocol specified.
1189 1313
 *
1190 1314
 * @param string $url
1191 1315
 *   The url entered by the user.
1192 1316
 * @param string $protocol
1193
 *   The protocol to be prepended to the url if one is not specified
1317
 *   The protocol to be prepended to the url if one is not specified.
1194 1318
 */
1195 1319
function link_cleanup_url($url, $protocol = 'http') {
1196 1320
  $url = trim($url);
......
1200 1324
    // Check if there is no protocol specified.
1201 1325
    $protocol_match = preg_match("/^([a-z0-9][a-z0-9\.\-_]*:\/\/)/i", $url);
1202 1326
    if (empty($protocol_match)) {
1203
      // But should there be? Add an automatic http:// if it starts with a domain name.
1204
      $LINK_DOMAINS = _link_domains();
1205
      $domain_match = preg_match('/^(([a-z0-9]([a-z0-9\-_]*\.)+)(' . $LINK_DOMAINS . '|[a-z]{2}))/i', $url);
1327
      // But should there be? Add an automatic http:// if it starts with a
1328
      // domain name.
1329
      $link_domains = _link_domains();
1330
      $domain_match = preg_match('/^(([a-z0-9]([a-z0-9\-_]*\.)+)(' . $link_domains . '|[a-z]{2}))/i', $url);
1206 1331
      if (!empty($domain_match)) {
1207 1332
        $url = $protocol . "://" . $url;
1208 1333
      }
......
1215 1340
/**
1216 1341
 * Validates a URL.
1217 1342
 *
1218
 * @param $text
1343
 * @param string $text
1219 1344
 *   Url to be validated.
1220
 *
1221
 * @param $langcode
1345
 * @param string $langcode
1222 1346
 *   An optional language code to look up the path in.
1223 1347
 *
1224
 * @return boolean
1348
 * @return bool
1225 1349
 *   True if a valid link, FALSE otherwise.
1226 1350
 */
1227 1351
function link_validate_url($text, $langcode = NULL) {
1352

  
1353
  $text = _link_clean_relative($text);
1228 1354
  $text = link_cleanup_url($text);
1229 1355
  $type = link_url_type($text);
1230 1356

  
......
1253 1379
  return $flag;
1254 1380
}
1255 1381

  
1382
/**
1383
 * Cleaner of relatives urls.
1384
 *
1385
 * @param string $url
1386
 *   The url to clean up the relative protocol.
1387
 */
1388
function _link_clean_relative($url) {
1389
  $check = substr($url, 0, 2);
1390
  if (isset($_SERVER['HTTPS']) &&
1391
    ($_SERVER['HTTPS'] == 'on' || $_SERVER['HTTPS'] == 1) ||
1392
    isset($_SERVER['HTTP_X_FORWARDED_PROTO']) &&
1393
    $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https') {
1394
    $protocol = 'https://';
1395
  }
1396
  else {
1397
    $protocol = 'http://';
1398
  }
1399

  
1400
  if ($check == '//') {
1401
    $url = str_replace('//', $protocol, $url);
1402
  }
1403

  
1404
  return $url;
1405
}
1406

  
1256 1407
/**
1257 1408
 * Type check a URL.
1258 1409
 *
......
1261 1412
 *
1262 1413
 * @param string $text
1263 1414
 *   Url to be checked.
1264
 * 
1415
 *
1265 1416
 * @return mixed
1266 1417
 *   Returns boolean FALSE if the URL is not valid. On success, returns one of
1267 1418
 *   the LINK_(linktype) constants.
1268 1419
 */
1269 1420
function link_url_type($text) {
1270 1421
  // @TODO Complete letters.
1271
  $LINK_ICHARS_DOMAIN = (string) html_entity_decode(implode("", array(
1272
    "&#x00E6;", // æ
1273
    "&#x00C6;", // Æ
1422
  // @codingStandardsIgnoreStart
1423
  $link_ichars_domain = (string) html_entity_decode(implode("", array(
1424
    "&#x00BF;", // ¿
1274 1425
    "&#x00C0;", // À
1275
    "&#x00E0;", // à
1276 1426
    "&#x00C1;", // Á
1277
    "&#x00E1;", // á
1278 1427
    "&#x00C2;", // Â
1279
    "&#x00E2;", // â
1280
    "&#x00E5;", // å
1281
    "&#x00C5;", // Å
1282
    "&#x00E4;", // ä
1428
    "&#x00C3;", // Ã
1283 1429
    "&#x00C4;", // Ä
1430
    "&#x00C5;", // Å
1431
    "&#x00C6;", // Æ
1284 1432
    "&#x00C7;", // Ç
1285
    "&#x00E7;", // ç
1286
    "&#x00D0;", // Ð
1287
    "&#x00F0;", // ð
1288 1433
    "&#x00C8;", // È
1289
    "&#x00E8;", // è
1290 1434
    "&#x00C9;", // É
1291
    "&#x00E9;", // é
1292 1435
    "&#x00CA;", // Ê
1293
    "&#x00EA;", // ê
1294 1436
    "&#x00CB;", // Ë
1295
    "&#x00EB;", // ë
1437
    "&#x00CC;", // Ì
1438
    "&#x00CD;", // Í
1296 1439
    "&#x00CE;", // Î
1297
    "&#x00EE;", // î
1298 1440
    "&#x00CF;", // Ï
1299
    "&#x00EF;", // ï
1300
    "&#x00F8;", // ø
1301
    "&#x00D8;", // Ø
1302
    "&#x00F6;", // ö
1303
    "&#x00D6;", // Ö
1441
    "&#x00D0;", // Ð
1442
    "&#x00D1;", // Ñ
1443
    "&#x00D2;", // Ò
1444
    "&#x00D3;", // Ó
1304 1445
    "&#x00D4;", // Ô
1305
    "&#x00F4;", // ô
1306 1446
    "&#x00D5;", // Õ
1307
    "&#x00F5;", // õ
1308
    "&#x0152;", // Œ
1309
    "&#x0153;", // œ
1310
    "&#x00FC;", // ü
1311
    "&#x00DC;", // Ü
1447
    "&#x00D6;", // Ö
1448
    // ×
1449
    "&#x00D8;", // Ø
1312 1450
    "&#x00D9;", // Ù
1313
    "&#x00F9;", // ù
1451
    "&#x00DA;", // Ú
1314 1452
    "&#x00DB;", // Û
1315
    "&#x00FB;", // û
1316
    "&#x0178;", // Ÿ
1317
    "&#x00FF;", // ÿ
1318
    "&#x00D1;", // Ñ
1319
    "&#x00F1;", // ñ
1320
    "&#x00FE;", // þ
1453
    "&#x00DC;", // Ü
1454
    "&#x00DD;", // Ý
1321 1455
    "&#x00DE;", // Þ
1456
    // ß (see LINK_ICHARS)
1457
    "&#x00E0;", // à
1458
    "&#x00E1;", // á
1459
    "&#x00E2;", // â
1460
    "&#x00E3;", // ã
1461
    "&#x00E4;", // ä
1462
    "&#x00E5;", // å
1463
    "&#x00E6;", // æ
1464
    "&#x00E7;", // ç
1465
    "&#x00E8;", // è
1466
    "&#x00E9;", // é
1467
    "&#x00EA;", // ê
1468
    "&#x00EB;", // ë
1469
    "&#x00EC;", // ì
1470
    "&#x00ED;", // í
1471
    "&#x00EE;", // î
1472
    "&#x00EF;", // ï
1473
    "&#x00F0;", // ð
1474
    "&#x00F1;", // ñ
1475
    "&#x00F2;", // ò
1476
    "&#x00F3;", // ó
1477
    "&#x00F4;", // ô
1478
    "&#x00F5;", // õ
1479
    "&#x00F6;", // ö
1480
    // ÷
1481
    "&#x00F8;", // ø
1482
    "&#x00F9;", // ù
1483
    "&#x00FA;", // ú
1484
    "&#x00FB;", // û
1485
    "&#x00FC;", // ü
1322 1486
    "&#x00FD;", // ý
1323
    "&#x00DD;", // Ý
1324
    "&#x00BF;", // ¿
1325
  )), ENT_QUOTES, 'UTF-8');
1326

  
1327
  $LINK_ICHARS = $LINK_ICHARS_DOMAIN . (string) html_entity_decode(implode("", array(
1328
    "&#x00DF;", // ß
1487
    "&#x00FE;", // þ
1488
    "&#x00FF;", // ÿ
1489
    "&#x0152;", // Œ
1490
    "&#x0153;", // œ
1491
    "&#x0178;", // Ÿ
1329 1492
  )), ENT_QUOTES, 'UTF-8');
1330
  $allowed_protocols = variable_get('filter_allowed_protocols', array('http', 'https', 'ftp', 'news', 'nntp', 'telnet', 'mailto', 'irc', 'ssh', 'sftp', 'webcal'));
1331
  $LINK_DOMAINS = _link_domains();
1332

  
1333
  // Starting a parenthesis group with (?: means that it is grouped, but is not captured.
1493
  // @codingStandardsIgnoreEnd
1494

  
1495
  $link_ichars = $link_ichars_domain . (string) html_entity_decode(implode("", array(
1496
      // ß.
1497
      "&#x00DF;",
1498
    )), ENT_QUOTES, 'UTF-8');
1499
  $allowed_protocols = variable_get('filter_allowed_protocols', array(
1500
    'http',
1501
    'https',
1502
    'ftp',
1503
    'news',
1504
    'nntp',
1505
    'telnet',
1506
    'mailto',
1507
    'irc',
1508
    'ssh',
1509
    'sftp',
1510
    'webcal',
1511
  ));
1512
  $link_domains = _link_domains();
1513

  
1514
  // Starting a parenthesis group with (?: means that it is grouped, but is not
1515
  // captured.
1334 1516
  $protocol = '((?:' . implode("|", $allowed_protocols) . '):\/\/)';
1335
  $authentication = "(?:(?:(?:[\w\.\-\+!$&'\(\)*\+,;=" . $LINK_ICHARS . "]|%[0-9a-f]{2})+(?::(?:[\w" . $LINK_ICHARS . "\.\-\+%!$&'\(\)*\+,;=]|%[0-9a-f]{2})*)?)?@)";
1336
  $domain = '(?:(?:[a-z0-9' . $LINK_ICHARS_DOMAIN . ']([a-z0-9' . $LINK_ICHARS_DOMAIN . '\-_\[\]])*)(\.(([a-z0-9' . $LINK_ICHARS_DOMAIN . '\-_\[\]])+\.)*(' . $LINK_DOMAINS . '|[a-z]{2}))?)';
1517
  $authentication = "(?:(?:(?:[\w\.\-\+!$&'\(\)*\+,;=" . $link_ichars . "]|%[0-9a-f]{2})+(?::(?:[\w" . $link_ichars . "\.\-\+%!$&'\(\)*\+,;=]|%[0-9a-f]{2})*)?)?@)";
1518
  $domain = '(?:(?:[a-z0-9' . $link_ichars_domain . ']([a-z0-9' . $link_ichars_domain . '\-_\[\]])*)(\.(([a-z0-9' . $link_ichars_domain . '\-_\[\]])+\.)*(' . $link_domains . '|[a-z]{2}))?)';
1337 1519
  $ipv4 = '(?:[0-9]{1,3}(\.[0-9]{1,3}){3})';
1338 1520
  $ipv6 = '(?:[0-9a-fA-F]{1,4}(\:[0-9a-fA-F]{1,4}){7})';
1339 1521
  $port = '(?::([0-9]{1,5}))';
1340

  
1341 1522
  // Pattern specific to external links.
1342 1523
  $external_pattern = '/^' . $protocol . '?' . $authentication . '?(' . $domain . '|' . $ipv4 . '|' . $ipv6 . ' |localhost)' . $port . '?';
1343 1524

  
1344 1525
  // Pattern specific to internal links.
1345
  $internal_pattern = "/^(?:[a-z0-9" . $LINK_ICHARS . "_\-+\[\] ]+)";
1346
  $internal_pattern_file = "/^(?:[a-z0-9" . $LINK_ICHARS . "_\-+\[\]\. \/\(\)][a-z0-9" . $LINK_ICHARS . "_\-+\[\]\. \(\)][a-z0-9" . $LINK_ICHARS . "_\-+\[\]\. \/\(\)]+)$/i";
1526
  $internal_pattern = "/^(?:[a-z0-9" . $link_ichars . "_\-+\[\] ]+)";
1527
  $internal_pattern_file = "/^(?:[a-z0-9" . $link_ichars . "_\-+\[\]\. \/\(\)][a-z0-9" . $link_ichars . "_\-+\[\]\. \(\)][a-z0-9" . $link_ichars . "_\-+\[\]\. \/\(\)]+)$/i";
1347 1528

  
1348
  $directories = "(?:\/[a-z0-9" . $LINK_ICHARS . "_\-\.~+%=&,$'#!():;*@\[\]]*)*";
1529
  $directories = "(?:\/[a-z0-9" . $link_ichars . "_\-\.~+%=&,$'#!():;*@\[\]]*)*";
1349 1530
  // Yes, four backslashes == a single backslash.
1350
  $query = "(?:\/?\?([?a-z0-9" . $LINK_ICHARS . "+_|\-\.~\/\\\\%=&,$'!():;*@\[\]{} ]*))";
1351
  $anchor = "(?:#[a-z0-9" . $LINK_ICHARS . "_\-\.~+%=&,$'():;*@\[\]\/\?]*)";
1531
  $query = "(?:\/?\?([?a-z0-9" . $link_ichars . "+_|\-\.~\/\\\\%=&,$'!():;*@\[\]{} ]*))";
1532
  $anchor = "(?:#[a-z0-9" . $link_ichars . "_\-\.~+%=&,$'():;*@\[\]\/\?]*)";
1352 1533

  
1353 1534
  // The rest of the path for a standard URL.
1535
  // @codingStandardsIgnoreLine
1354 1536
  $end = $directories . '?' . $query . '?' . $anchor . '?' . '$/i';
1355 1537

  
1356 1538
  $message_id = '[^@].*@' . $domain;
1357 1539
  $newsgroup_name = '(?:[0-9a-z+-]*\.)*[0-9a-z+-]*';
1358 1540
  $news_pattern = '/^news:(' . $newsgroup_name . '|' . $message_id . ')$/i';
1359 1541

  
1360
  $user = '[a-zA-Z0-9' . $LINK_ICHARS . '_\-\.\+\^!#\$%&*+\/\=\?\`\|\{\}~\'\[\]]+';
1542
  $user = '[a-zA-Z0-9' . $link_ichars . '_\-\.\+\^!#\$%&*+\/\=\?\`\|\{\}~\'\[\]]+';
1361 1543
  $email_pattern = '/^mailto:' . $user . '@' . '(?:' . $domain . '|' . $ipv4 . '|' . $ipv6 . '|localhost)' . $query . '?$/';
1362 1544

  
1363 1545
  if (strpos($text, '<front>') === 0) {
......
1372 1554
  if (preg_match($internal_pattern . $end, $text)) {
1373 1555
    return LINK_INTERNAL;
1374 1556
  }
1557
  if (drupal_valid_path($text) && url_is_external($text) == FALSE) {
1558
    return LINK_INTERNAL;
1559
  }
1375 1560
  if (preg_match($external_pattern . $end, $text)) {
1376 1561
    return LINK_EXTERNAL;
1377 1562
  }
......
1383 1568
}
1384 1569

  
1385 1570
/**
1386
 * Returns the list of allowed domains, including domains added by admins via variable_set/$config.
1571
 * Returns the list of allowed domains.
1572
 *
1573
 * If the variable link_allowed_domains is set, restrict allowed domains to the
1574
 * strings in that array. If the variable link_allowed_domains is not set, allow
1575
 * all domains between 2 and 63 characters in length.
1576
 * See https://tools.ietf.org/html/rfc1034.
1387 1577
 */
1388 1578
function _link_domains() {
1389
  $link_extra_domains = variable_get('link_extra_domains', array());
1390
  return empty($link_extra_domains) ? LINK_DOMAINS : LINK_DOMAINS . '|' . implode('|', $link_extra_domains);
1579
  $link_allowed_domains = variable_get('link_allowed_domains', array());
1580
  return empty($link_allowed_domains) ? '[a-z][a-z0-9-]{1,62}' : implode('|', $link_allowed_domains);
1391 1581
}
1392 1582

  
1393 1583
/**
......
1398 1588
    // Adjust the field type.
1399 1589
    $field_value['type'] = 'link_field';
1400 1590
    // Remove settings that are now on the instance.
1401
    foreach (array('attributes', 'display', 'url', 'title', 'title_value', 'enable_tokens', 'validate_url') as $setting) {
1591
    foreach (array(
1592
               'attributes',
1593
               'display',
1594
               'url',
1595
               'title',
1596
               'title_value',
1597
               'enable_tokens',
1598
               'validate_url',
1599
             ) as $setting) {
1402 1600
      unset($field_value['settings'][$setting]);
1403 1601
    }
1404 1602
  }
......
1412 1610
function link_content_migrate_instance_alter(&$instance_value, $field_value) {
1413 1611
  if ($field_value['type'] == 'link') {
1414 1612
    // Grab settings that were previously on the field.
1415
    foreach (array('attributes', 'display', 'url', 'title', 'title_value', 'enable_tokens', 'validate_url') as $setting) {
1613
    foreach (array(
1614
               'attributes',
1615
               'display',
1616
               'url',
1617
               'title',
1618
               'title_value',
1619
               'enable_tokens',
1620
               'validate_url',
1621
             ) as $setting) {
1416 1622
      if (isset($field_value['settings'][$setting])) {
1417 1623
        $instance_value['settings'][$setting] = $field_value['settings'][$setting];
1418 1624
      }
......
1423 1629
    }
1424 1630
    // Adjust formatter types.
1425 1631
    foreach ($instance_value['display'] as $context => $settings) {
1426
      if (in_array($settings['type'], array('default', 'title_plain', 'url', 'plain', 'short', 'label', 'separate'))) {
1632
      if (in_array($settings['type'], array(
1633
        'default',
1634
        'title_plain',
1635
        'url',
1636
        'plain',
1637
        'short',
1638
        'label',
1639
        'separate',
1640
      ))) {
1427 1641
        $instance_value['display'][$context]['type'] = 'link_' . $settings['type'];
1428 1642
      }
1429 1643
    }
......
1439 1653

  
1440 1654
/**
1441 1655
 * Additional callback to adapt the property info of link fields.
1442
 * 
1656
 *
1443 1657
 * @see entity_metadata_field_entity_property_info()
1444 1658
 */
1445 1659
function link_field_property_info_callback(&$info, $entity_type, $field, $instance, $field_type) {
......
1467 1681
 * @see link_field_property_info_callback()
1468 1682
 */
1469 1683
function link_field_item_create() {
1470
  return array('title' => NULL, 'url' => NULL);
1684
  return array('title' => NULL, 'url' => NULL, 'display_url' => NULL);
1471 1685
}
1472 1686

  
1473 1687
/**
......
1480 1694
    'setter callback' => 'entity_property_verbatim_set',
1481 1695
  );
1482 1696
  $properties['url'] = array(
1483
    'type' => 'uri',
1697
    'type' => 'text',
1484 1698
    'label' => t('The URL of the link.'),
1485 1699
    'setter callback' => 'entity_property_verbatim_set',
1486 1700
  );
......
1490 1704
    'setter callback' => 'entity_property_verbatim_set',
1491 1705
    'getter callback' => 'link_attribute_property_get',
1492 1706
  );
1707
  $properties['display_url'] = array(
1708
    'type' => 'uri',
1709
    'label' => t('The full URL of the link.'),
1710
    'setter callback' => 'entity_property_verbatim_set',
1711
  );
1493 1712
  return $properties;
1494 1713
}
1495 1714

  
......
1504 1723
 * Implements hook_field_update_instance().
1505 1724
 */
1506 1725
function link_field_update_instance($instance, $prior_instance) {
1507
  if (function_exists('i18n_string_update') && $instance['widget']['type'] == 'link_field' && $prior_instance['settings']['title_value'] != $instance['settings']['title_value']) {
1726
  if (function_exists('i18n_string_update') && isset($instance['widget']) && $instance['widget']['type'] == 'link_field' && $prior_instance['settings']['title_value'] != $instance['settings']['title_value']) {
1508 1727
    $i18n_string_name = "field:{$instance['field_name']}:{$instance['bundle']}:title_value";
1509 1728
    i18n_string_update($i18n_string_name, $instance['settings']['title_value']);
1510 1729
  }

Formats disponibles : Unified diff