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/README.txt
1
Module description
2
------------------
3
The link module can be count to the top 50 modules in Drupal installations and provides a standard custom content field for links. With this module links can be added easily 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.
1
CONTENTS OF THIS FILE
2
---------------------
3
   
4
 * Introduction
5
 * Requirements
6
 * Installation
7
 * Configuration
8
 * Example
9
 * Theming and Output
10
 * Maintainers
11

  
12

  
13
INTRODUCTION
14
------------
15

  
16
The link can be count to the top 50 projects in Drupal installations and
17
provides a standard custom content field for links. With this module links can
18
be added easily to any content types and profiles and include advanced
19
validating and different ways of storing internal or external links and URLs. It
20
also supports additional link text title, site wide tokens for titles and title
21
attributes, target attributes, css class attribution, static repeating values,
22
input conversion, and many more.
23

  
24

  
25

  
26
REQUIREMENTS
27
------------
28

  
29
Project in Drupal 7 requires the following modules:
4 30

  
5
Requirements / Dependencies
6
---------------------------
7
1. Drupal 6: Custom content module (CCK)
8
2. Drupal 7: Fields API is provided already by core [no dependencies].
9
3. Drupal 8: Link module is in core now. No module installation needed. Yay! Don't forget to activate it. It's deactivated by default.
31
 * Fields API (Fields API is provided already by core)
32
 * Panels (https://drupal.org/project/panels)
10 33

  
11
INFO Since some misleading user reports we need to clarify here - Link module is NOT about to add links to any menus or the navigation nor primary/secondary menu. This can be done with default menu module (part of Drupal core). The Link module provides an additional custom field for storing and validating links to be added with any content type, which means another input block additional to your text-body, title, image and any other input you can make on new content creation.
34
Drupal 8:
12 35

  
13
Installation
36
 * Link is in core now. No installation needed. Yay! Don't forget to activate
37
   it. It's deactivated by default.
38

  
39

  
40
INSTALLATION
14 41
------------
15
1. Drop the entire link module directory into your 'sites/all/modules' folder
16
2. Enable the module from the Administration area modules page (admin/build/modules)
17
3. Create or Edit a content-type and add a new field of type link (admin/content/types in D6, admin/structure/types in D7)
18 42

  
19
Configuration
43
Install as you would normally install a contributed Drupal module. See:
44
https://drupal.org/documentation/install/modules-themes/modules-7 for further
45
information.
46

  
47

  
48
CONFIGURATION
20 49
-------------
21
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. More info at Wikipedia (http://en.wikipedia.org/wiki/Spam_in_blogs#rel.3D.22nofollow.22).
22 50

  
23
Example
51
 * Configuration is only slightly more complicated than a text field. Link text
52
   titles for URLs can be made required, set as instead of URL, optional
53
   (default), or left out entirely. If no link text title is provided, the
54
   trimmed version of the complete URL will be displayed. The target attribute
55
   should be set to "_blank", "top", or left out completely (checkboxes provide
56
   info). The rel=nofollow attribute prevents the link from being followed by
57
   certain search engines. More info at Wikipedia
58
   (http://en.wikipedia.org/wiki/Spam_in_blogs#rel.3D.22nofollow.22).
59

  
60

  
61
EXAMPLE
24 62
-------
25
If you were to create a field named 'My New Link', the default display of the link would be:  <em><div class="field_my_new_link" target="[target_value]"><a href="[URL]">[Title]</a></div></em> where items between [] characters would be customized based on the user input.
63
If you were to create a field named 'My New Link', the default display of the
64
link would be:
65
<em><div class="field_my_new_link" target="[target_value]"><a href="[URL]">
66
[Title]</a></div></em> where items between [] characters would be customized
67
based on the user input.
68

  
69
The link project supports both, internal and external URLs. URLs are validated
70
on input. Here are some examples of data input and the default view of a link:
71
http://drupal.org results in http://drupal.org, but drupal.org results in
72
http://drupal.org, while <front> will convert into http://drupal.org and
73
node/74971 into http://drupal.org/project/link
26 74

  
27
The link module supports both, internal and external URLs. URLs are validated on input. Here are some examples of data input and the default view of a link:  http://drupal.org results in http://drupal.org, but drupal.org results in http://drupal.org, while <front> will convert into http://drupal.org and node/74971 into http://drupal.org/project/link
75
Anchors and query strings may also be used in any of these cases, including:
76
node/74971/edit?destination=node/74972<front>#pager
28 77

  
29
Anchors and query strings may also be used in any of these cases, including:  node/74971/edit?destination=node/74972<front>#pager
30 78

  
31
Theming and Output
79
THEMING AND OUTPUT
32 80
------------------
33
Since link module is mainly a data storage field in a modular framework, the theming and output is up to the site builder and other additional modules. There are many modules in the Drupal repository, which control the output of fields perfectly and can handle rules, user actions, markup dependencies, and can vary the output under many different conditions, with much more efficience and flexibility for different scenarios. Please check out modules like views, display suite, panels, etc for such needs.
81
Since link module is mainly a data storage field in a modular framework, the
82
theming and output is up to the site builder and other additional modules. There
83
are many modules in the Drupal repository, which control the output of fields
84
perfectly and can handle rules, user actions, markup dependencies, and can vary
85
the output under many different conditions, with much more efficience and
86
flexibility for different scenarios. Please check out modules like views,
87
display suite, panels, etc for such needs
88

  
89

  
90
MAINTAINERS
91
-----------
92

  
93
Current maintainers:
94
 * John C Fiala (jcfiala) - https://www.drupal.org/user/163643
95
 * Renato Gonçalves (RenatoG) - https://www.drupal.org/user/3326031
96
 * Clemens Tolboom (clemens.tolboom) - https://www.drupal.org/user/125814
97
 * diqidoq - https://www.drupal.org/user/1001934
98
 * dropcube - https://www.drupal.org/user/37031
99
 * Tom Kirkpatrick (mrfelton) - https://www.drupal.org/user/305669
100
 * Sumit Madan (sumitmadan) - https://www.drupal.org/user/1538790
101
 * Daniel Kudwien (sun) - https://www.drupal.org/user/54136
drupal7/sites/all/modules/link/link-rtl.css
1 1
.link-field-column {
2 2
  float: right;
3 3
}
4

  
5 4
.link-field-column.link-field-url .form-text {
6 5
  direction: ltr;
7 6
  text-align: left;
drupal7/sites/all/modules/link/link.css
2 2
  float: left;
3 3
  width: 48%;
4 4
}
5

  
6 5
.link-field-column .form-text {
7 6
  width: 95%;
8 7
}
drupal7/sites/all/modules/link/link.diff.inc
11 11
function link_field_diff_view($items, $context) {
12 12
  $diff_items = array();
13 13
  foreach ($items as $delta => $item) {
14
    if ($item['url'] && $item['title']) {
14
    if ($item['url'] && isset($item['title'])) {
15 15
      $diff_items[$delta] = $item['title'] . ' (' . $item['url'] . ')';
16 16
    }
17 17
    else {
18
      $diff_items[$delta] = $item['title'] . $item['url'];
18
      $diff_items[$delta] = $item['url'];
19 19
    }
20 20
  }
21 21
  return $diff_items;
drupal7/sites/all/modules/link/link.info
3 3
core = 7.x
4 4
package = Fields
5 5

  
6
files[] = link.module
7 6
files[] = link.migrate.inc
8 7

  
9 8
; Tests
......
19 18
files[] = views/link_views_handler_argument_target.inc
20 19
files[] = views/link_views_handler_filter_protocol.inc
21 20

  
22
; Information added by Drupal.org packaging script on 2016-01-15
23
version = "7.x-1.4"
21
; Information added by Drupal.org packaging script on 2018-05-13
22
version = "7.x-1.5"
24 23
core = "7.x"
25 24
project = "link"
26
datestamp = "1452830642"
27

  
25
datestamp = "1526190487"
drupal7/sites/all/modules/link/link.install
6 6
 */
7 7

  
8 8
/**
9
 * Upgrade notes:
10
 * Things we need to make sure work when upgrading from Drupal 6 to Drupal 7:
9
 * Upgrade notes.
10
 *
11
 * Things we need to make sure work when upgrading from Drupal 6 to Drupal 7:.
11 12
 */
12 13

  
14
/**
15
 * Implements hook_uninstall().
16
 */
17
function link_install() {
18
  // Notify the user they may want to install token.
19
  if (!module_exists('token')) {
20
    $t = get_t();
21
    drupal_set_message($t('If you install the <a href="!url" target="blank">Token</a>, static title can use any other entity field as its value.', array(
22
      '!url' => 'http://drupal.org/project/token',
23
    )));
24
  }
25
}
26

  
27
/**
28
 * Removes unused link_extra_domains variable.
29
 */
30
function link_update_7002() {
31
  variable_del('link_extra_domains');
32
}
33

  
34
/**
35
 * Implements hook_uninstall().
36
 */
37
function link_uninstall() {
38
  variable_del('link_allowed_domains');
39
}
40

  
13 41
/**
14 42
 * Implements hook_field_schema().
15 43
 */
......
46 74
}
47 75

  
48 76
/**
49
 * Handles moving settings data from field_config.data to field_config_instance.data.
77
 * Implements hook_update_N().
78
 *
79
 * Handles moving settings data from field_config.data to
80
 * field_config_instance.data.
50 81
 */
51 82
function link_update_7000() {
52
  
53
  // For each field that is a link field, we need to copy the settings from the general field level down to the instance.
54
  //$field_data = array();
83

  
84
  // For each field that is a link field, we need to copy the settings from the
85
  // general field level down to the instance.
55 86
  $result = db_query("SELECT id, field_name, data FROM {field_config} WHERE module = 'link' AND type = 'link_field'");
56 87
  foreach ($result as $field) {
57
    $field_id = $field->id;
58
    $name = $field->field_name;
88

  
59 89
    $field_data = unserialize($field->data);
60
    
61
    $instances = db_query("SELECT id, data FROM {field_config_instance} WHERE field_id = :field_id", array(':field_id' => $field_id));
90

  
91
    $instances = db_query("SELECT id, data FROM {field_config_instance} WHERE field_id = :field_id", array(':field_id' => $field->id));
62 92
    foreach ($instances as $instance) {
63 93
      // If this field has been updated already, we want to skip it.
64 94
      $instance_data = unserialize($instance->data);
......
71 101
          }
72 102
        }
73 103
        if ($update_instance) {
74
          // update the database.
75
          $num_updated = db_update('field_config_instance')
104
          // Update the database.
105
          db_update('field_config_instance')
76 106
            ->fields(array('data' => serialize($instance_data)))
77 107
            ->condition('id', $instance->id)
78 108
            ->execute();
......
80 110
      }
81 111
    }
82 112
  }
83
  
113

  
84 114
  return t("Instance settings have been set with the data from the field settings.");
85 115
}
86 116

  
87 117
/**
88
 * Renames all displays from foobar to link_foobar
118
 * Renames all displays from foobar to link_foobar.
89 119
 */
90 120
function link_update_7001() {
91 121
  // Update the display type for each link field type.
92 122
  $result = db_query("SELECT id, field_name, data FROM {field_config} WHERE module = 'link' AND type = 'link_field'");
93 123
  foreach ($result as $field) {
94
    $field_id = $field->id;
95
    $name = $field->field_name;
96
    $field_data = unserialize($field->data);
97
    
98
    $instances = db_query("SELECT id, data FROM {field_config_instance} WHERE field_id = :field_id", array(':field_id' => $field_id));
124

  
125
    $instances = db_query("SELECT id, data FROM {field_config_instance} WHERE field_id = :field_id", array(':field_id' => $field->id));
99 126
    foreach ($instances as $instance) {
100 127
      // If this field has been updated already, we want to skip it.
101 128
      $instance_data = unserialize($instance->data);
drupal7/sites/all/modules/link/link.migrate.inc
11 11
 * $this->addFieldMapping('field_my_link', 'source_url');
12 12
 * $this->addFieldMapping('field_my_link:title', 'source_title');
13 13
 * $this->addFieldMapping('field_my_link:attributes', 'source_attributes');
14
 * @endcode
15 14
 *
16
 * With earlier versions of Migrate, you must pass an arguments array:
15
 * # With earlier versions of Migrate, you must pass an arguments array:
17 16
 *
18
 * @code
19 17
 * $link_args = array(
20 18
 *   'title' => array('source_field' => 'source_title'),
21 19
 *   'attributes' => array('source_field' => 'source_attributes'),
......
25 23
 * @endcode
26 24
 */
27 25

  
26
if (!class_exists('MigrateFieldHandler')) {
27
  return;
28
}
29

  
28 30
/**
29 31
 * Implements hook_migrate_api().
30 32
 */
......
35 37
  );
36 38
}
37 39

  
40
// @codingStandardsIgnoreLine
38 41
class MigrateLinkFieldHandler extends MigrateFieldHandler {
42

  
43
  /**
44
   * Construct.
45
   */
39 46
  public function __construct() {
40 47
    $this->registerTypes(array('link_field'));
41 48
  }
42 49

  
43
  static function arguments($title = NULL, $attributes = NULL, $language = NULL) {
50
  /**
51
   * Arguments.
52
   */
53
  public static function arguments($title = NULL, $attributes = NULL, $language = NULL) {
44 54
    $arguments = array();
45 55
    if (!is_null($title)) {
46 56
      $arguments['title'] = $title;
......
57 67
  /**
58 68
   * Implementation of MigrateFieldHandler::fields().
59 69
   *
60
   * @param $type
61
   *  The field type.
62
   * @param $instance
63
   *  Instance info for the field.
70
   * @param array $type
71
   *   The field type.
72
   * @param array $instance
73
   *   Instance info for the field.
64 74
   * @param Migration $migration
65
   *  The migration context for the parent field. We can look at the mappings
66
   *  and determine which subfields are relevant.
75
   *   The migration context for the parent field. We can look at the mappings
76
   *   and determine which subfields are relevant.
77
   *
67 78
   * @return array
79
   *   Array with values.
80
   *
81
   * @codingStandardsIgnoreStart
68 82
   */
69 83
  public function fields($type, $instance, $migration = NULL) {
84
    // @codingStandardsIgnoreEnd
70 85
    return array(
71 86
      'title' => t('Subfield: The link title attribute'),
72 87
      'attributes' => t('Subfield: The attributes for this link'),
......
74 89
    );
75 90
  }
76 91

  
92
  /**
93
   * Prepare.
94
   */
77 95
  public function prepare($entity, array $field_info, array $instance, array $values) {
78 96
    if (isset($values['arguments'])) {
79 97
      $arguments = $values['arguments'];
......
105 123
        }
106 124
      }
107 125
      $item['url'] = $value;
108
      $return[$language][$delta] = $item;
126

  
127
      if (is_array($language)) {
128
        $current_language = $language[$delta];
129
      }
130
      else {
131
        $current_language = $language;
132
      }
133
      $return[$current_language][$delta] = $item;
109 134
    }
110 135

  
111 136
    return isset($return) ? $return : NULL;
112 137
  }
138

  
113 139
}
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
  }
drupal7/sites/all/modules/link/tests/link.attribute.test
5 5
 * Basic simpletests to test options on link module.
6 6
 */
7 7

  
8
/**
9
 * Attribute Crud Test.
10
 */
8 11
class LinkAttributeCrudTest extends DrupalWebTestCase {
12

  
9 13
  private $zebra;
10 14

  
11 15
  protected $permissions = array(
......
19 23
    'access administration pages',
20 24
  );
21 25

  
26
  /**
27
   * Get Info.
28
   */
22 29
  public static function getInfo() {
23 30
    return array(
24 31
      'name' => 'Link Attribute Tests',
......
27 34
    );
28 35
  }
29 36

  
30
  function setup() {
37
  /**
38
   * Setup.
39
   */
40
  public function setup() {
31 41
    parent::setup('field_ui', 'link');
32 42
    $this->zebra = 0;
33 43
    // Create and login user.
34
    $this->web_user = $this->drupalCreateUser(array('administer content types'));
44
    $this->web_user = $this->drupalCreateUser(array(
45
      'administer content types',
46
      'administer fields',
47
    ));
35 48
    $this->drupalLogin($this->web_user);
36 49
  }
37 50

  
51
  /**
52
   * Create Link.
53
   */
38 54
  protected function createLink($url, $title, $attributes = array()) {
39 55
    return array(
40 56
      'url' => $url,
......
43 59
    );
44 60
  }
45 61

  
62
  /**
63
   * Assert Link On Node.
64
   */
46 65
  protected function assertLinkOnNode($field_name, $link_value, $message = '', $group = 'Other') {
47 66
    $this->zebra++;
48 67
    $zebra_string = ($this->zebra % 2 == 0) ? 'even' : 'odd';
49 68
    $cssFieldLocator = 'field-' . str_replace('_', '-', $field_name);
50 69
    $this->assertPattern('@<div class="field field-type-link ' . $cssFieldLocator . '".*<div class="field-item ' . $zebra_string . '">\s*' . $link_value . '\s*</div>@is',
51
                         $message,
52
                         $group);
70
      $message,
71
      $group);
53 72
  }
54 73

  
55 74
  /**
56
   * A simple test that just creates a new node type, adds a link field to it, creates a new node of that type, and makes sure
57
   * that the node is being displayed.
75
   * Test Basic.
76
   *
77
   * A simple test that just creates a new node type, adds a link field to it,
78
   * creates a new node of that type, and makes sure that the node is being
79
   * displayed.
58 80
   */
59
  function testBasic() {
81
  public function testBasic() {
60 82
    $content_type_friendly = $this->randomName(20);
61 83
    $content_type_machine = strtolower($this->randomName(10));
62 84
    $title = $this->randomName(20);
......
76 98
    // Now add a singleton field.
77 99
    $single_field_name_friendly = $this->randomName(20);
78 100
    $single_field_name_machine = strtolower($this->randomName(10));
79
    $single_field_name = 'field_' . $single_field_name_machine;
101

  
80 102
    $edit = array(
81 103
      'fields[_add_new_field][label]' => $single_field_name_friendly,
82 104
      'fields[_add_new_field][field_name]' => $single_field_name_machine,
......
101 123
    $this->assertTrue($type_exists, 'The new content type has been created in the database.');
102 124

  
103 125
    $permission = 'create ' . $content_type_machine . ' content';
104
    $permission_edit = 'edit ' . $content_type_machine . ' content';
126

  
105 127
    // Reset the permissions cache.
106 128
    $this->checkPermissions(array($permission), TRUE);
107 129

  
......
122 144
    );
123 145

  
124 146
    $this->drupalPost(NULL, $edit, t('Save'));
125
    $this->assertText(t('@content_type_friendly @title has been created', array('@content_type_friendly' => $content_type_friendly, '@title' => $title)));
147
    $this->assertText(t('@content_type_friendly @title has been created', array(
148
      '@content_type_friendly' => $content_type_friendly,
149
      '@title' => $title,
150
    )));
126 151

  
127 152
    $this->drupalGet('node/add/' . $content_type_machine);
128 153

  
......
135 160

  
136 161
    // Now we can fill in the second item in the multivalue field and save.
137 162
    $this->drupalPost(NULL, $edit, t('Save'));
138
    $this->assertText(t('@content_type_friendly @title has been created', array('@content_type_friendly' => $content_type_friendly, '@title' => $title)));
163
    $this->assertText(t('@content_type_friendly @title has been created', array(
164
      '@content_type_friendly' => $content_type_friendly,
165
      '@title' => $title,
166
    )));
139 167

  
140 168
    $this->assertText('Display');
141 169
    $this->assertLinkByHref('http://www.example.com');
142 170
  }
143 171

  
172
  /**
173
   * Create Simple Link Field.
174
   */
144 175
  protected function createSimpleLinkField($single_field_name_machine, $single_field_name_friendly, $content_type_machine) {
145 176
    $this->drupalGet('admin/structure/types/manage/' . $content_type_machine . '/fields');
146 177
    $edit = array(
......
166 197
    $this->assertTrue($type_exists, 'The new content type has been created in the database.');
167 198
  }
168 199

  
200
  /**
201
   * Create Node Type User.
202
   */
169 203
  protected function createNodeTypeUser($content_type_machine) {
170 204
    $permission = 'create ' . $content_type_machine . ' content';
171
    $permission_edit = 'edit ' . $content_type_machine . ' content';
172 205
    // Reset the permissions cache.
173 206
    $this->checkPermissions(array($permission), TRUE);
174 207

  
......
179 212
    $this->drupalLogin($this->web_user);
180 213
  }
181 214

  
215
  /**
216
   * Create Node For Testing.
217
   */
182 218
  protected function createNodeForTesting($content_type_machine, $content_type_friendly, $single_field_name_machine, $title, $url, $node_title = '') {
183 219
    $this->drupalGet('node/add/' . $content_type_machine);
184 220

  
......
196 232
    }
197 233

  
198 234
    $this->drupalPost(NULL, $edit, t('Save'));
199
    $this->assertText(t('@content_type_friendly @title has been created', array('@content_type_friendly' => $content_type_friendly, '@title' => $node_title)));
235
    $this->assertText(t('@content_type_friendly @title has been created', array(
236
      '@content_type_friendly' => $content_type_friendly,
237
      '@title' => $node_title,
238
    )));
200 239

  
201 240
  }
202 241

  
203 242
  /**
204 243
   * Test the link_plain formatter and it's output.
205 244
   */
206
  function testFormatterPlain() {
245
  public function testFormatterPlain() {
207 246
    $content_type_friendly = $this->randomName(20);
208 247
    $content_type_machine = strtolower($this->randomName(10));
209 248

  
......
215 254
    // Now add a singleton field.
216 255
    $single_field_name_friendly = $this->randomName(20);
217 256
    $single_field_name_machine = strtolower($this->randomName(10));
218
    //$single_field_name = 'field_'. $single_field_name_machine;
257
    // $single_field_name = 'field_'. $single_field_name_machine;.
219 258
    $this->createSimpleLinkField($single_field_name_machine, $single_field_name_friendly, $content_type_machine);
220 259

  
221 260
    // Okay, now we want to make sure this display is changed:
......
227 266
    $this->drupalPost(NULL, $edit, t('Save'));
228 267

  
229 268
    $this->createNodeTypeUser($content_type_machine);
230
    
269

  
231 270
    $link_tests = array(
232 271
      'plain' => array(
233 272
        'text' => 'Display',
......
243 282
      ),
244 283
    );
245 284

  
246
    foreach ($link_tests as $key => $link_test) {
285
    foreach ($link_tests as $link_test) {
247 286
      $link_text = $link_test['text'];
248 287
      $link_url = $link_test['url'];
249 288
      $this->createNodeForTesting($content_type_machine, $content_type_friendly, $single_field_name_machine, $link_text, $link_url);
250
  
... Ce différentiel a été tronqué car il excède la taille maximale pouvant être affichée.

Formats disponibles : Unified diff