annotate sites/all/modules/link/link.module @ 11:b0ee71395280

deleted .DS_Store files
author danieleb <danielebarchiesi@me.com>
date Mon, 28 Oct 2013 16:12:13 +0000
parents ce11bbd8f642
children
rev   line source
danielebarchiesi@4 1 <?php
danielebarchiesi@4 2
danielebarchiesi@4 3 /**
danielebarchiesi@4 4 * @file
danielebarchiesi@4 5 * Defines simple link field types.
danielebarchiesi@4 6 */
danielebarchiesi@4 7
danielebarchiesi@4 8 define('LINK_EXTERNAL', 'external');
danielebarchiesi@4 9 define('LINK_INTERNAL', 'internal');
danielebarchiesi@4 10 define('LINK_FRONT', 'front');
danielebarchiesi@4 11 define('LINK_EMAIL', 'email');
danielebarchiesi@4 12 define('LINK_NEWS', 'news');
danielebarchiesi@4 13 define('LINK_DOMAINS', 'aero|arpa|asia|biz|com|cat|coop|edu|gov|info|int|jobs|mil|museum|name|nato|net|org|pro|travel|mobi|local');
danielebarchiesi@4 14
danielebarchiesi@4 15 define('LINK_TARGET_DEFAULT', 'default');
danielebarchiesi@4 16 define('LINK_TARGET_NEW_WINDOW', '_blank');
danielebarchiesi@4 17 define('LINK_TARGET_TOP', '_top');
danielebarchiesi@4 18 define('LINK_TARGET_USER', 'user');
danielebarchiesi@4 19
danielebarchiesi@4 20 /**
danielebarchiesi@4 21 * Maximum URLs length - needs to match value in link.install.
danielebarchiesi@4 22 */
danielebarchiesi@4 23 define('LINK_URL_MAX_LENGTH', 2048);
danielebarchiesi@4 24
danielebarchiesi@4 25 /**
danielebarchiesi@4 26 * Implements hook_field_info().
danielebarchiesi@4 27 */
danielebarchiesi@4 28 function link_field_info() {
danielebarchiesi@4 29 return array(
danielebarchiesi@4 30 'link_field' => array(
danielebarchiesi@4 31 'label' => t('Link'),
danielebarchiesi@4 32 'description' => t('Store a title, href, and attributes in the database to assemble a link.'),
danielebarchiesi@4 33 'settings' => array(
danielebarchiesi@4 34 'attributes' => _link_default_attributes(),
danielebarchiesi@4 35 'url' => 0,
danielebarchiesi@4 36 'title' => 'optional',
danielebarchiesi@4 37 'title_value' => '',
danielebarchiesi@4 38 'title_maxlength' => 128,
danielebarchiesi@4 39 'enable_tokens' => 1,
danielebarchiesi@4 40 'display' => array(
danielebarchiesi@4 41 'url_cutoff' => 80,
danielebarchiesi@4 42 ),
danielebarchiesi@4 43 ),
danielebarchiesi@4 44 'instance_settings' => array(
danielebarchiesi@4 45 'attributes' => _link_default_attributes(),
danielebarchiesi@4 46 'url' => 0,
danielebarchiesi@4 47 'title' => 'optional',
danielebarchiesi@4 48 'title_value' => '',
danielebarchiesi@4 49 'title_maxlength' => 128,
danielebarchiesi@4 50 'enable_tokens' => 1,
danielebarchiesi@4 51 'display' => array(
danielebarchiesi@4 52 'url_cutoff' => 80,
danielebarchiesi@4 53 ),
danielebarchiesi@4 54 'validate_url' => 1,
danielebarchiesi@4 55 ),
danielebarchiesi@4 56 'default_widget' => 'link_field',
danielebarchiesi@4 57 'default_formatter' => 'link_default',
danielebarchiesi@4 58 // Support hook_entity_property_info() from contrib "Entity API".
danielebarchiesi@4 59 'property_type' => 'field_item_link',
danielebarchiesi@4 60 'property_callbacks' => array('link_field_property_info_callback'),
danielebarchiesi@4 61 ),
danielebarchiesi@4 62 );
danielebarchiesi@4 63 }
danielebarchiesi@4 64
danielebarchiesi@4 65 /**
danielebarchiesi@4 66 * Implements hook_field_instance_settings_form().
danielebarchiesi@4 67 */
danielebarchiesi@4 68 function link_field_instance_settings_form($field, $instance) {
danielebarchiesi@4 69 $form = array(
danielebarchiesi@4 70 '#element_validate' => array('link_field_settings_form_validate'),
danielebarchiesi@4 71 );
danielebarchiesi@4 72
danielebarchiesi@4 73 $form['validate_url'] = array(
danielebarchiesi@4 74 '#type' => 'checkbox',
danielebarchiesi@4 75 '#title' => t('Validate URL'),
danielebarchiesi@4 76 '#default_value' => isset($instance['settings']['validate_url']) && ($instance['settings']['validate_url'] !== '') ? $instance['settings']['validate_url'] : TRUE,
danielebarchiesi@4 77 '#description' => t('If checked, the URL field will be verified as a valid URL during validation.'),
danielebarchiesi@4 78 );
danielebarchiesi@4 79
danielebarchiesi@4 80 $form['url'] = array(
danielebarchiesi@4 81 '#type' => 'checkbox',
danielebarchiesi@4 82 '#title' => t('Optional URL'),
danielebarchiesi@4 83 '#default_value' => isset($instance['settings']['url']) ? $instance['settings']['url'] : '',
danielebarchiesi@4 84 '#return_value' => 'optional',
danielebarchiesi@4 85 '#description' => t('If checked, the URL field is optional and submitting a title alone will be acceptable. If the URL is omitted, the title will be displayed as plain text.'),
danielebarchiesi@4 86 );
danielebarchiesi@4 87
danielebarchiesi@4 88 $title_options = array(
danielebarchiesi@4 89 'optional' => t('Optional Title'),
danielebarchiesi@4 90 'required' => t('Required Title'),
danielebarchiesi@4 91 'value' => t('Static Title'),
danielebarchiesi@4 92 'none' => t('No Title'),
danielebarchiesi@4 93 );
danielebarchiesi@4 94
danielebarchiesi@4 95 $form['title'] = array(
danielebarchiesi@4 96 '#type' => 'radios',
danielebarchiesi@4 97 '#title' => t('Link Title'),
danielebarchiesi@4 98 '#default_value' => isset($instance['settings']['title']) ? $instance['settings']['title'] : 'optional',
danielebarchiesi@4 99 '#options' => $title_options,
danielebarchiesi@4 100 '#description' => t('If the link title is optional or required, a field will be displayed to the end user. If the link title is static, the link will always use the same title. If <a href="http://drupal.org/project/token">token module</a> is installed, the static title value may use any other entity field as its value. Static and token-based titles may include most inline XHTML tags such as <em>strong</em>, <em>em</em>, <em>img</em>, <em>span</em>, etc.'),
danielebarchiesi@4 101 );
danielebarchiesi@4 102
danielebarchiesi@4 103 $form['title_value'] = array(
danielebarchiesi@4 104 '#type' => 'textfield',
danielebarchiesi@4 105 '#title' => t('Static title'),
danielebarchiesi@4 106 '#default_value' => isset($instance['settings']['title_value']) ? $instance['settings']['title_value'] : '',
danielebarchiesi@4 107 '#description' => t('This title will always be used if &ldquo;Static Title&rdquo; is selected above.'),
danielebarchiesi@4 108 );
danielebarchiesi@4 109
danielebarchiesi@4 110 $form['title_maxlength'] = array(
danielebarchiesi@4 111 '#type' => 'textfield',
danielebarchiesi@4 112 '#title' => t('Max length of title field'),
danielebarchiesi@4 113 '#default_value' => isset($instance['settings']['title_maxlength']) ? $instance['settings']['title_maxlength'] : '128',
danielebarchiesi@4 114 '#description' => t('Set a maximum length on the title field (applies only if Link Title is optional or required). The maximum limit is 255 characters.'),
danielebarchiesi@4 115 '#maxlength' => 3,
danielebarchiesi@4 116 '#size' => 3,
danielebarchiesi@4 117 );
danielebarchiesi@4 118
danielebarchiesi@4 119 if (module_exists('token')) {
danielebarchiesi@4 120 // Add token module replacements fields
danielebarchiesi@4 121 $form['tokens'] = array(
danielebarchiesi@4 122 '#type' => 'fieldset',
danielebarchiesi@4 123 '#collapsible' => TRUE,
danielebarchiesi@4 124 '#collapsed' => TRUE,
danielebarchiesi@4 125 '#title' => t('Placeholder tokens'),
danielebarchiesi@4 126 '#description' => t("The following placeholder tokens can be used in both paths and titles. When used in a path or title, they will be replaced with the appropriate values."),
danielebarchiesi@4 127 );
danielebarchiesi@4 128 $entity_info = entity_get_info($instance['entity_type']);
danielebarchiesi@4 129 $form['tokens']['help'] = array(
danielebarchiesi@4 130 '#theme' => 'token_tree',
danielebarchiesi@4 131 '#token_types' => array($entity_info['token type']),
danielebarchiesi@4 132 '#global_types' => TRUE,
danielebarchiesi@4 133 '#click_insert' => TRUE,
danielebarchiesi@4 134 );
danielebarchiesi@4 135
danielebarchiesi@4 136 $form['enable_tokens'] = array(
danielebarchiesi@4 137 '#type' => 'checkbox',
danielebarchiesi@4 138 '#title' => t('Allow user-entered tokens'),
danielebarchiesi@4 139 '#default_value' => isset($instance['settings']['enable_tokens']) ? $instance['settings']['enable_tokens'] : 1,
danielebarchiesi@4 140 '#description' => t('Checking will allow users to enter tokens in URLs and Titles on the entity edit form. This does not affect the field settings on this page.'),
danielebarchiesi@4 141 );
danielebarchiesi@4 142 }
danielebarchiesi@4 143
danielebarchiesi@4 144 $form['display'] = array(
danielebarchiesi@4 145 '#tree' => TRUE,
danielebarchiesi@4 146 );
danielebarchiesi@4 147 $form['display']['url_cutoff'] = array(
danielebarchiesi@4 148 '#type' => 'textfield',
danielebarchiesi@4 149 '#title' => t('URL Display Cutoff'),
danielebarchiesi@4 150 '#default_value' => isset($instance['settings']['display']['url_cutoff']) ? $instance['settings']['display']['url_cutoff'] : '80',
danielebarchiesi@4 151 '#description' => t('If the user does not include a title for this link, the URL will be used as the title. When should the link title be trimmed and finished with an elipsis (&hellip;)? Leave blank for no limit.'),
danielebarchiesi@4 152 '#maxlength' => 3,
danielebarchiesi@4 153 '#size' => 3,
danielebarchiesi@4 154 );
danielebarchiesi@4 155
danielebarchiesi@4 156 $target_options = array(
danielebarchiesi@4 157 LINK_TARGET_DEFAULT => t('Default (no target attribute)'),
danielebarchiesi@4 158 LINK_TARGET_TOP => t('Open link in window root'),
danielebarchiesi@4 159 LINK_TARGET_NEW_WINDOW => t('Open link in new window'),
danielebarchiesi@4 160 LINK_TARGET_USER => t('Allow the user to choose'),
danielebarchiesi@4 161 );
danielebarchiesi@4 162 $form['attributes'] = array(
danielebarchiesi@4 163 '#tree' => TRUE,
danielebarchiesi@4 164 );
danielebarchiesi@4 165 $form['attributes']['target'] = array(
danielebarchiesi@4 166 '#type' => 'radios',
danielebarchiesi@4 167 '#title' => t('Link Target'),
danielebarchiesi@4 168 '#default_value' => empty($instance['settings']['attributes']['target']) ? LINK_TARGET_DEFAULT : $instance['settings']['attributes']['target'],
danielebarchiesi@4 169 '#options' => $target_options,
danielebarchiesi@4 170 );
danielebarchiesi@4 171 $form['attributes']['rel'] = array(
danielebarchiesi@4 172 '#type' => 'textfield',
danielebarchiesi@4 173 '#title' => t('Rel Attribute'),
danielebarchiesi@4 174 '#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.'),
danielebarchiesi@4 175 '#default_value' => empty($instance['settings']['attributes']['rel']) ? '' : $instance['settings']['attributes']['rel'],
danielebarchiesi@4 176 '#field_prefix' => 'rel = "',
danielebarchiesi@4 177 '#field_suffix' => '"',
danielebarchiesi@4 178 '#size' => 20,
danielebarchiesi@4 179 );
danielebarchiesi@4 180 $rel_remove_options = array(
danielebarchiesi@4 181 'default' => t('Keep rel as set up above (untouched/default)'),
danielebarchiesi@4 182 'rel_remove_external' => t('Remove rel if given link is external'),
danielebarchiesi@4 183 'rel_remove_internal' => t('Remove rel if given link is internal'),
danielebarchiesi@4 184 );
danielebarchiesi@4 185 $form['rel_remove'] = array(
danielebarchiesi@4 186 '#type' => 'radios',
danielebarchiesi@4 187 '#title' => t('Remove rel attribute automatically'),
danielebarchiesi@4 188 '#default_value' => !isset($instance['settings']['rel_remove']) ? 'default' : $instance['settings']['rel_remove'],
danielebarchiesi@4 189 '#description' => t('Turn on/off if rel attribute should be removed automatically, if user given link is internal/external'),
danielebarchiesi@4 190 '#options' => $rel_remove_options,
danielebarchiesi@4 191 );
danielebarchiesi@4 192 $form['attributes']['class'] = array(
danielebarchiesi@4 193 '#type' => 'textfield',
danielebarchiesi@4 194 '#title' => t('Additional CSS Class'),
danielebarchiesi@4 195 '#description' => t('When output, this link will have this class attribute. Multiple classes should be separated by spaces.'),
danielebarchiesi@4 196 '#default_value' => empty($instance['settings']['attributes']['class']) ? '' : $instance['settings']['attributes']['class'],
danielebarchiesi@4 197 );
danielebarchiesi@4 198 $form['attributes']['configurable_title'] = array(
danielebarchiesi@4 199 '#title' => t("Allow the user to enter a link 'title' attribute"),
danielebarchiesi@4 200 '#type' => 'checkbox',
danielebarchiesi@4 201 '#default_value' => empty($instance['settings']['attributes']['configurable_title']) ? '' : $instance['settings']['attributes']['configurable_title'],
danielebarchiesi@4 202 );
danielebarchiesi@4 203 $form['attributes']['title'] = array(
danielebarchiesi@4 204 '#title' => t("Default link 'title' Attribute"),
danielebarchiesi@4 205 '#type' => 'textfield',
danielebarchiesi@4 206 '#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.'),
danielebarchiesi@4 207 '#default_value' => empty($instance['settings']['attributes']['title']) ? '' : $instance['settings']['attributes']['title'],
danielebarchiesi@4 208 '#field_prefix' => 'title = "',
danielebarchiesi@4 209 '#field_suffix' => '"',
danielebarchiesi@4 210 '#size' => 20,
danielebarchiesi@4 211 );
danielebarchiesi@4 212 return $form;
danielebarchiesi@4 213 }
danielebarchiesi@4 214
danielebarchiesi@4 215 /**
danielebarchiesi@4 216 * #element_validate handler for link_field_instance_settings_form().
danielebarchiesi@4 217 */
danielebarchiesi@4 218 function link_field_settings_form_validate($element, &$form_state, $complete_form) {
danielebarchiesi@4 219 if ($form_state['values']['instance']['settings']['title'] === 'value' && empty($form_state['values']['instance']['settings']['title_value'])) {
danielebarchiesi@4 220 form_set_error('title_value', t('A default title must be provided if the title is a static value.'));
danielebarchiesi@4 221 }
danielebarchiesi@4 222 if (!empty($form_state['values']['instance']['settings']['display']['url_cutoff']) && !is_numeric($form_state['values']['instance']['settings']['display']['url_cutoff'])) {
danielebarchiesi@4 223 form_set_error('display', t('URL Display Cutoff value must be numeric.'));
danielebarchiesi@4 224 }
danielebarchiesi@4 225 if (empty($form_state['values']['instance']['settings']['title_maxlength'])) {
danielebarchiesi@4 226 form_set_value($element['title_maxlength'], '128', $form_state);
danielebarchiesi@4 227 }
danielebarchiesi@4 228 elseif (!is_numeric($form_state['values']['instance']['settings']['title_maxlength'])) {
danielebarchiesi@4 229 form_set_error('title_maxlength', t('The max length of the link title must be numeric.'));
danielebarchiesi@4 230 }
danielebarchiesi@4 231 elseif ($form_state['values']['instance']['settings']['title_maxlength'] > 255) {
danielebarchiesi@4 232 form_set_error('title_maxlength', t('The max length of the link title cannot be greater than 255 characters.'));
danielebarchiesi@4 233 }
danielebarchiesi@4 234 }
danielebarchiesi@4 235
danielebarchiesi@4 236 /**
danielebarchiesi@4 237 * Implements hook_field_is_empty().
danielebarchiesi@4 238 */
danielebarchiesi@4 239 function link_field_is_empty($item, $field) {
danielebarchiesi@4 240 return empty($item['title']) && empty($item['url']);
danielebarchiesi@4 241 }
danielebarchiesi@4 242
danielebarchiesi@4 243 /**
danielebarchiesi@4 244 * Implements hook_field_load().
danielebarchiesi@4 245 */
danielebarchiesi@4 246 function link_field_load($entity_type, $entities, $field, $instances, $langcode, &$items, $age) {
danielebarchiesi@4 247 foreach ($entities as $id => $entity) {
danielebarchiesi@4 248 foreach ($items[$id] as $delta => $item) {
danielebarchiesi@4 249 $items[$id][$delta]['attributes'] = _link_load($field, $item, $instances[$id]);
danielebarchiesi@4 250 }
danielebarchiesi@4 251 }
danielebarchiesi@4 252 }
danielebarchiesi@4 253
danielebarchiesi@4 254 /**
danielebarchiesi@4 255 * Implements hook_field_validate().
danielebarchiesi@4 256 */
danielebarchiesi@4 257 function link_field_validate($entity_type, $entity, $field, $instance, $langcode, $items, &$errors) {
danielebarchiesi@4 258 $optional_field_found = FALSE;
danielebarchiesi@4 259 if ($instance['settings']['validate_url'] !== 0 || is_null($instance['settings']['validate_url']) || !isset($instance['settings']['validate_url'])) {
danielebarchiesi@4 260 foreach ($items as $delta => $value) {
danielebarchiesi@4 261 _link_validate($items[$delta], $delta, $field, $entity, $instance, $langcode, $optional_field_found);
danielebarchiesi@4 262 }
danielebarchiesi@4 263 }
danielebarchiesi@4 264
danielebarchiesi@4 265 if ($instance['settings']['url'] === 'optional' && $instance['settings']['title'] === 'optional' && $instance['required'] && !$optional_field_found) {
danielebarchiesi@4 266 form_set_error($field['field_name'] . '][' . $langcode . '][0][title', t('At least one title or URL must be entered.'));
danielebarchiesi@4 267 }
danielebarchiesi@4 268 }
danielebarchiesi@4 269
danielebarchiesi@4 270 /**
danielebarchiesi@4 271 * Implements hook_field_insert().
danielebarchiesi@4 272 */
danielebarchiesi@4 273 function link_field_insert($entity_type, $entity, $field, $instance, $langcode, &$items) {
danielebarchiesi@4 274 foreach ($items as $delta => $value) {
danielebarchiesi@4 275 _link_process($items[$delta], $delta, $field, $entity);
danielebarchiesi@4 276 }
danielebarchiesi@4 277 }
danielebarchiesi@4 278
danielebarchiesi@4 279 /**
danielebarchiesi@4 280 * Implements hook_field_update().
danielebarchiesi@4 281 */
danielebarchiesi@4 282 function link_field_update($entity_type, $entity, $field, $instance, $langcode, &$items) {
danielebarchiesi@4 283 foreach ($items as $delta => $value) {
danielebarchiesi@4 284 _link_process($items[$delta], $delta, $field, $entity);
danielebarchiesi@4 285 }
danielebarchiesi@4 286 }
danielebarchiesi@4 287
danielebarchiesi@4 288 /**
danielebarchiesi@4 289 * Implements hook_field_prepare_view().
danielebarchiesi@4 290 */
danielebarchiesi@4 291 function link_field_prepare_view($entity_type, $entities, $field, $instances, $langcode, &$items) {
danielebarchiesi@4 292 foreach ($items as $entity_id => $entity_items) {
danielebarchiesi@4 293 foreach ($entity_items as $delta => $value) {
danielebarchiesi@4 294 _link_sanitize($items[$entity_id][$delta], $delta, $field, $instances[$entity_id], $entities[$entity_id]);
danielebarchiesi@4 295 }
danielebarchiesi@4 296 }
danielebarchiesi@4 297 }
danielebarchiesi@4 298
danielebarchiesi@4 299 /**
danielebarchiesi@4 300 * Implements hook_field_widget_info().
danielebarchiesi@4 301 */
danielebarchiesi@4 302 function link_field_widget_info() {
danielebarchiesi@4 303 return array(
danielebarchiesi@4 304 'link_field' => array(
danielebarchiesi@4 305 'label' => 'Link',
danielebarchiesi@4 306 'field types' => array('link_field'),
danielebarchiesi@4 307 'multiple values' => FIELD_BEHAVIOR_DEFAULT,
danielebarchiesi@4 308 ),
danielebarchiesi@4 309 );
danielebarchiesi@4 310 }
danielebarchiesi@4 311
danielebarchiesi@4 312 /**
danielebarchiesi@4 313 * Implements hook_field_widget_form().
danielebarchiesi@4 314 */
danielebarchiesi@4 315 function link_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) {
danielebarchiesi@4 316 $element += array(
danielebarchiesi@4 317 '#type' => $instance['widget']['type'],
danielebarchiesi@4 318 '#default_value' => isset($items[$delta]) ? $items[$delta] : '',
danielebarchiesi@4 319 );
danielebarchiesi@4 320 return $element;
danielebarchiesi@4 321 }
danielebarchiesi@4 322
danielebarchiesi@4 323 /**
danielebarchiesi@4 324 * Unpacks the item attributes for use.
danielebarchiesi@4 325 */
danielebarchiesi@4 326 function _link_load($field, $item, $instance) {
danielebarchiesi@4 327 if (isset($item['attributes'])) {
danielebarchiesi@4 328 if (!is_array($item['attributes'])) {
danielebarchiesi@4 329 $item['attributes'] = unserialize($item['attributes']);
danielebarchiesi@4 330 }
danielebarchiesi@4 331 return $item['attributes'];
danielebarchiesi@4 332 }
danielebarchiesi@4 333 elseif (isset($instance['settings']['attributes'])) {
danielebarchiesi@4 334 return $instance['settings']['attributes'];
danielebarchiesi@4 335 }
danielebarchiesi@4 336 else {
danielebarchiesi@4 337 return $field['settings']['attributes'];
danielebarchiesi@4 338 }
danielebarchiesi@4 339 }
danielebarchiesi@4 340
danielebarchiesi@4 341 /**
danielebarchiesi@4 342 * Prepares the item attributes and url for storage.
danielebarchiesi@4 343 */
danielebarchiesi@4 344 function _link_process(&$item, $delta = 0, $field, $entity) {
danielebarchiesi@4 345 // Trim whitespace from URL.
danielebarchiesi@4 346 $item['url'] = trim($item['url']);
danielebarchiesi@4 347
danielebarchiesi@4 348 // If no attributes are set then make sure $item['attributes'] is an empty
danielebarchiesi@4 349 // array, so $field['attributes'] can override it.
danielebarchiesi@4 350 if (empty($item['attributes'])) {
danielebarchiesi@4 351 $item['attributes'] = array();
danielebarchiesi@4 352 }
danielebarchiesi@4 353
danielebarchiesi@4 354 // Serialize the attributes array.
danielebarchiesi@4 355 if (!is_string($item['attributes'])) {
danielebarchiesi@4 356 $item['attributes'] = serialize($item['attributes']);
danielebarchiesi@4 357 }
danielebarchiesi@4 358
danielebarchiesi@4 359 // Don't save an invalid default value (e.g. 'http://').
danielebarchiesi@4 360 if ((isset($field['widget']['default_value'][$delta]['url']) && $item['url'] == $field['widget']['default_value'][$delta]['url']) && is_object($entity)) {
danielebarchiesi@4 361 if (!link_validate_url($item['url'])) {
danielebarchiesi@4 362 unset($item['url']);
danielebarchiesi@4 363 }
danielebarchiesi@4 364 }
danielebarchiesi@4 365 }
danielebarchiesi@4 366
danielebarchiesi@4 367 /**
danielebarchiesi@4 368 * Validates that the link field has been entered properly.
danielebarchiesi@4 369 */
danielebarchiesi@4 370 function _link_validate(&$item, $delta, $field, $entity, $instance, $langcode, &$optional_field_found) {
danielebarchiesi@4 371 if ($item['url'] && !(isset($instance['default_value'][$delta]['url']) && $item['url'] === $instance['default_value'][$delta]['url'] && !$instance['required'])) {
danielebarchiesi@4 372 // Validate the link.
danielebarchiesi@4 373 if (link_validate_url(trim($item['url'])) == FALSE) {
danielebarchiesi@4 374 form_set_error($field['field_name'] . '][' . $langcode . '][' . $delta . '][url', t('The value provided for %field is not a valid URL.', array('%field' => $instance['label'])));
danielebarchiesi@4 375 }
danielebarchiesi@4 376 // Require a title for the link if necessary.
danielebarchiesi@4 377 if ($instance['settings']['title'] == 'required' && strlen(trim($item['title'])) == 0) {
danielebarchiesi@4 378 form_set_error($field['field_name'] . '][' . $langcode . '][' . $delta . '][title', t('Titles are required for all links.'));
danielebarchiesi@4 379 }
danielebarchiesi@4 380 }
danielebarchiesi@4 381 // Require a link if we have a title.
danielebarchiesi@4 382 if ($instance['settings']['url'] !== 'optional' && strlen(isset($item['title']) ? $item['title'] : NULL) > 0 && strlen(trim($item['url'])) == 0) {
danielebarchiesi@4 383 form_set_error($field['field_name'] . '][' . $langcode . '][' . $delta . '][url', t('You cannot enter a title without a link url.'));
danielebarchiesi@4 384 }
danielebarchiesi@4 385 // In a totally bizzaro case, where URLs and titles are optional but the field is required, ensure there is at least one link.
danielebarchiesi@4 386 if ($instance['settings']['url'] === 'optional' && $instance['settings']['title'] === 'optional' && (strlen(trim($item['url'])) !== 0 || strlen(trim($item['title'])) !== 0)) {
danielebarchiesi@4 387 $optional_field_found = TRUE;
danielebarchiesi@4 388 }
danielebarchiesi@4 389 // Require entire field
danielebarchiesi@4 390 if ($instance['settings']['url'] === 'optional' && $instance['settings']['title'] === 'optional' && $instance['required'] == 1 && !$optional_field_found && isset($instance['id'])) {
danielebarchiesi@4 391 form_set_error($instance['field_name'] . '][' . $langcode . '][0][title', t('At least one title or URL must be entered.'));
danielebarchiesi@4 392 }
danielebarchiesi@4 393 }
danielebarchiesi@4 394
danielebarchiesi@4 395 /**
danielebarchiesi@4 396 * Clean up user-entered values for a link field according to field settings.
danielebarchiesi@4 397 *
danielebarchiesi@4 398 * @param $item
danielebarchiesi@4 399 * A single link item, usually containing url, title, and attributes.
danielebarchiesi@4 400 * @param $delta
danielebarchiesi@4 401 * The delta value if this field is one of multiple fields.
danielebarchiesi@4 402 * @param $field
danielebarchiesi@4 403 * The CCK field definition.
danielebarchiesi@4 404 * @param $entity
danielebarchiesi@4 405 * The entity containing this link.
danielebarchiesi@4 406 */
danielebarchiesi@4 407 function _link_sanitize(&$item, $delta, &$field, $instance, &$entity) {
danielebarchiesi@4 408 // Don't try to process empty links.
danielebarchiesi@4 409 if (empty($item['url']) && empty($item['title'])) {
danielebarchiesi@4 410 return;
danielebarchiesi@4 411 }
danielebarchiesi@4 412
danielebarchiesi@4 413 // Replace URL tokens.
danielebarchiesi@4 414 $entity_type = $instance['entity_type'];
danielebarchiesi@4 415 $entity_info = entity_get_info($entity_type);
danielebarchiesi@4 416 $property_id = $entity_info['entity keys']['id'];
danielebarchiesi@4 417 $entity_token_type = isset($entity_info['token type']) ? $entity_info['token type'] : (
danielebarchiesi@4 418 $entity_type == 'taxonomy_term' || $entity_type == 'taxonomy_vocabulary' ? str_replace('taxonomy_', '', $entity_type) : $entity_type
danielebarchiesi@4 419 );
danielebarchiesi@4 420 if (isset($instance['settings']['enable_tokens']) && $instance['settings']['enable_tokens']) {
danielebarchiesi@4 421 global $user;
danielebarchiesi@4 422 // Load the entity if necessary for entities in views.
danielebarchiesi@4 423 if (isset($entity->{$property_id})) {
danielebarchiesi@4 424 $entity_loaded = entity_load($entity_type, array($entity->{$property_id}));
danielebarchiesi@4 425 $entity_loaded = array_pop($entity_loaded);
danielebarchiesi@4 426 }
danielebarchiesi@4 427 else {
danielebarchiesi@4 428 $entity_loaded = $entity;
danielebarchiesi@4 429 }
danielebarchiesi@4 430 $item['url'] = token_replace($item['url'], array($entity_token_type => $entity_loaded));
danielebarchiesi@4 431 }
danielebarchiesi@4 432
danielebarchiesi@4 433 $type = link_validate_url($item['url']);
danielebarchiesi@4 434 // If the type of the URL cannot be determined and URL validation is disabled,
danielebarchiesi@4 435 // then assume LINK_EXTERNAL for later processing.
danielebarchiesi@4 436 if ($type == FALSE && $instance['settings']['validate_url'] === 0) {
danielebarchiesi@4 437 $type = LINK_EXTERNAL;
danielebarchiesi@4 438 }
danielebarchiesi@4 439 $url = link_cleanup_url($item['url']);
danielebarchiesi@4 440 $url_parts = _link_parse_url($url);
danielebarchiesi@4 441
danielebarchiesi@4 442 // We can't check_plain('<front>') because it'll break.
danielebarchiesi@4 443 if ($type != LINK_FRONT) {
danielebarchiesi@4 444 $url_parts['url'] = check_plain($url_parts['url']);
danielebarchiesi@4 445 }
danielebarchiesi@4 446
danielebarchiesi@4 447 if (!empty($url_parts['url'])) {
danielebarchiesi@4 448 $item['url'] = url($url_parts['url'],
danielebarchiesi@4 449 array(
danielebarchiesi@4 450 'query' => isset($url_parts['query']) ? $url_parts['query'] : NULL,
danielebarchiesi@4 451 'fragment' => isset($url_parts['fragment']) ? $url_parts['fragment'] : NULL,
danielebarchiesi@4 452 'absolute' => TRUE,
danielebarchiesi@4 453 'html' => TRUE,
danielebarchiesi@4 454 )
danielebarchiesi@4 455 );
danielebarchiesi@4 456 }
danielebarchiesi@4 457
danielebarchiesi@4 458 // Create a shortened URL for display.
danielebarchiesi@4 459 if ($type == LINK_EMAIL) {
danielebarchiesi@4 460 $display_url = str_replace('mailto:', '', $url);
danielebarchiesi@4 461 }
danielebarchiesi@4 462 else {
danielebarchiesi@4 463 $display_url = url($url_parts['url'],
danielebarchiesi@4 464 array(
danielebarchiesi@4 465 'query' => isset($url_parts['query']) ? $url_parts['query'] : NULL,
danielebarchiesi@4 466 'fragment' => isset($url_parts['fragment']) ? $url_parts['fragment'] : NULL,
danielebarchiesi@4 467 'absolute' => TRUE,
danielebarchiesi@4 468 )
danielebarchiesi@4 469 );
danielebarchiesi@4 470 }
danielebarchiesi@4 471 if ($instance['settings']['display']['url_cutoff'] && strlen($display_url) > $instance['settings']['display']['url_cutoff']) {
danielebarchiesi@4 472 $display_url = substr($display_url, 0, $instance['settings']['display']['url_cutoff']) . "...";
danielebarchiesi@4 473 }
danielebarchiesi@4 474 $item['display_url'] = $display_url;
danielebarchiesi@4 475
danielebarchiesi@4 476 // Use the title defined at the instance level.
danielebarchiesi@4 477 if ($instance['settings']['title'] == 'value' && strlen(trim($instance['settings']['title_value']))) {
danielebarchiesi@4 478 $title = $instance['settings']['title_value'];
danielebarchiesi@4 479 if (function_exists('i18n_string_translate')) {
danielebarchiesi@4 480 $i18n_string_name = "field:{$instance['field_name']}:{$instance['bundle']}:title_value";
danielebarchiesi@4 481 $title = i18n_string_translate($i18n_string_name, $title);
danielebarchiesi@4 482 }
danielebarchiesi@4 483 }
danielebarchiesi@4 484 // Use the title defined by the user at the widget level.
danielebarchiesi@4 485 elseif (isset($item['title'])) {
danielebarchiesi@4 486 $title = $item['title'];
danielebarchiesi@4 487 }
danielebarchiesi@4 488 else {
danielebarchiesi@4 489 $title = '';
danielebarchiesi@4 490 }
danielebarchiesi@4 491
danielebarchiesi@4 492 // Replace tokens.
danielebarchiesi@4 493 if ($title && ($instance['settings']['title'] == 'value' || $instance['settings']['enable_tokens'])) {
danielebarchiesi@4 494 // Load the entity if necessary for entities in views.
danielebarchiesi@4 495 if (isset($entity->{$property_id})) {
danielebarchiesi@4 496 $entity_loaded = entity_load($entity_type, array($entity->{$property_id}));
danielebarchiesi@4 497 $entity_loaded = array_pop($entity_loaded);
danielebarchiesi@4 498 }
danielebarchiesi@4 499 else {
danielebarchiesi@4 500 $entity_loaded = $entity;
danielebarchiesi@4 501 }
danielebarchiesi@4 502 $title = token_replace($title, array($entity_token_type => $entity_loaded));
danielebarchiesi@4 503 $title = filter_xss($title, array('b', 'br', 'code', 'em', 'i', 'img', 'span', 'strong', 'sub', 'sup', 'tt', 'u'));
danielebarchiesi@4 504 $item['html'] = TRUE;
danielebarchiesi@4 505 }
danielebarchiesi@4 506 $item['title'] = empty($title) ? $item['display_url'] : $title;
danielebarchiesi@4 507
danielebarchiesi@4 508 if (!isset($item['attributes'])) {
danielebarchiesi@4 509 $item['attributes'] = array();
danielebarchiesi@4 510 }
danielebarchiesi@4 511
danielebarchiesi@4 512 // Unserialize attributtes array if it has not been unserialized yet.
danielebarchiesi@4 513 if (!is_array($item['attributes'])) {
danielebarchiesi@4 514 $item['attributes'] = (array)unserialize($item['attributes']);
danielebarchiesi@4 515 }
danielebarchiesi@4 516
danielebarchiesi@4 517 // Add default attributes.
danielebarchiesi@4 518 if (!is_array($instance['settings']['attributes'])) {
danielebarchiesi@4 519 $instance['settings']['attributes'] = _link_default_attributes();
danielebarchiesi@4 520 }
danielebarchiesi@4 521 else {
danielebarchiesi@4 522 $instance['settings']['attributes'] += _link_default_attributes();
danielebarchiesi@4 523 }
danielebarchiesi@4 524
danielebarchiesi@4 525 // Merge item attributes with attributes defined at the field level.
danielebarchiesi@4 526 $item['attributes'] += $instance['settings']['attributes'];
danielebarchiesi@4 527
danielebarchiesi@4 528 // If user is not allowed to choose target attribute, use default defined at
danielebarchiesi@4 529 // field level.
danielebarchiesi@4 530 if ($instance['settings']['attributes']['target'] != LINK_TARGET_USER) {
danielebarchiesi@4 531 $item['attributes']['target'] = $instance['settings']['attributes']['target'];
danielebarchiesi@4 532 }
danielebarchiesi@4 533 elseif ($item['attributes']['target'] == LINK_TARGET_USER) {
danielebarchiesi@4 534 $item['attributes']['target'] = LINK_TARGET_DEFAULT;
danielebarchiesi@4 535 }
danielebarchiesi@4 536
danielebarchiesi@4 537 // Remove the target attribute if the default (no target) is selected.
danielebarchiesi@4 538 if (empty($item['attributes']) || (isset($item['attributes']['target']) && $item['attributes']['target'] == LINK_TARGET_DEFAULT)) {
danielebarchiesi@4 539 unset($item['attributes']['target']);
danielebarchiesi@4 540 }
danielebarchiesi@4 541
danielebarchiesi@4 542 // Remove rel attribute for internal or external links if selected.
danielebarchiesi@4 543 if (isset($item['attributes']['rel']) && isset($instance['settings']['rel_remove']) && $instance['settings']['rel_remove'] != 'default') {
danielebarchiesi@4 544 if (($instance['settings']['rel_remove'] != 'rel_remove_internal' && $type != LINK_INTERNAL) ||
danielebarchiesi@4 545 ($instance['settings']['rel_remove'] != 'rel_remove_external' && $type != LINK_EXTERNAL)) {
danielebarchiesi@4 546 unset($item['attributes']['rel']);
danielebarchiesi@4 547 }
danielebarchiesi@4 548 }
danielebarchiesi@4 549
danielebarchiesi@4 550 // Handle "title" link attribute.
danielebarchiesi@4 551 if (!empty($item['attributes']['title']) && module_exists('token')) {
danielebarchiesi@4 552 // Load the entity (necessary for entities in views).
danielebarchiesi@4 553 if (isset($entity->{$property_id})) {
danielebarchiesi@4 554 $entity_loaded = entity_load($entity_type, array($entity->{$property_id}));
danielebarchiesi@4 555 $entity_loaded = array_pop($entity_loaded);
danielebarchiesi@4 556 }
danielebarchiesi@4 557 else {
danielebarchiesi@4 558 $entity_loaded = $entity;
danielebarchiesi@4 559 }
danielebarchiesi@4 560 $item['attributes']['title'] = token_replace($item['attributes']['title'], array($entity_token_type => $entity_loaded));
danielebarchiesi@4 561 $item['attributes']['title'] = filter_xss($item['attributes']['title'], array('b', 'br', 'code', 'em', 'i', 'img', 'span', 'strong', 'sub', 'sup', 'tt', 'u'));
danielebarchiesi@4 562 }
danielebarchiesi@4 563 // Remove title attribute if it's equal to link text.
danielebarchiesi@4 564 if (isset($item['attributes']['title']) && $item['attributes']['title'] == $item['title']) {
danielebarchiesi@4 565 unset($item['attributes']['title']);
danielebarchiesi@4 566 }
danielebarchiesi@4 567 unset($item['attributes']['configurable_title']);
danielebarchiesi@4 568
danielebarchiesi@4 569 // Remove empty attributes.
danielebarchiesi@4 570 $item['attributes'] = array_filter($item['attributes']);
danielebarchiesi@4 571
danielebarchiesi@4 572 // Sets title to trimmed url if one exists
danielebarchiesi@4 573 // @todo: Obsolete?
danielebarchiesi@4 574 /*if(!empty($item['display_url']) && empty($item['title'])) {
danielebarchiesi@4 575 $item['title'] = $item['display_url'];
danielebarchiesi@4 576 }
danielebarchiesi@4 577 elseif(!isset($item['title'])) {
danielebarchiesi@4 578 $item['title'] = $item['url'];
danielebarchiesi@4 579 }*/
danielebarchiesi@4 580 }
danielebarchiesi@4 581
danielebarchiesi@4 582 /**
danielebarchiesi@4 583 * Because parse_url doesn't work with relative urls.
danielebarchiesi@4 584 *
danielebarchiesi@4 585 * @param string $url
danielebarchiesi@4 586 * URL to parse.
danielebarchiesi@4 587 *
danielebarchiesi@4 588 * @return Array
danielebarchiesi@4 589 * Array of url pieces - only 'url', 'query', and 'fragment'.
danielebarchiesi@4 590 */
danielebarchiesi@4 591 function _link_parse_url($url) {
danielebarchiesi@4 592 $url_parts = array();
danielebarchiesi@4 593 // Separate out the anchor, if any.
danielebarchiesi@4 594 if (strpos($url, '#') !== FALSE) {
danielebarchiesi@4 595 $url_parts['fragment'] = substr($url, strpos($url, '#') + 1);
danielebarchiesi@4 596 $url = substr($url, 0, strpos($url, '#'));
danielebarchiesi@4 597 }
danielebarchiesi@4 598 // Separate out the query string, if any.
danielebarchiesi@4 599 if (strpos($url, '?') !== FALSE) {
danielebarchiesi@4 600 $query = substr($url, strpos($url, '?') + 1);
danielebarchiesi@4 601 parse_str($query, $query_array);
danielebarchiesi@4 602 // See http://drupal.org/node/1710578
danielebarchiesi@4 603 foreach ($query_array as $key=> &$value) {
danielebarchiesi@4 604 if ($value === '' && FALSE === strpos($query, $key . '=')) {
danielebarchiesi@4 605 $value = NULL;
danielebarchiesi@4 606 }
danielebarchiesi@4 607 }
danielebarchiesi@4 608 $url_parts['query'] = $query_array;
danielebarchiesi@4 609 $url = substr($url, 0, strpos($url, '?'));
danielebarchiesi@4 610 }
danielebarchiesi@4 611 $url_parts['url'] = $url;
danielebarchiesi@4 612 return $url_parts;
danielebarchiesi@4 613 }
danielebarchiesi@4 614
danielebarchiesi@4 615 /**
danielebarchiesi@4 616 * Implements hook_theme().
danielebarchiesi@4 617 */
danielebarchiesi@4 618 function link_theme() {
danielebarchiesi@4 619 return array(
danielebarchiesi@4 620 'link_formatter_link_default' => array(
danielebarchiesi@4 621 'variables' => array('element' => NULL),
danielebarchiesi@4 622 ),
danielebarchiesi@4 623 'link_formatter_link_plain' => array(
danielebarchiesi@4 624 'variables' => array('element' => NULL),
danielebarchiesi@4 625 ),
danielebarchiesi@4 626 'link_formatter_link_absolute' => array(
danielebarchiesi@4 627 'variables' => array('element' => NULL),
danielebarchiesi@4 628 ),
danielebarchiesi@4 629 'link_formatter_link_domain' => array(
danielebarchiesi@4 630 'variables' => array('element' => NULL, 'display' => NULL),
danielebarchiesi@4 631 ),
danielebarchiesi@4 632 'link_formatter_link_title_plain' => array(
danielebarchiesi@4 633 'variables' => array('element' => NULL),
danielebarchiesi@4 634 ),
danielebarchiesi@4 635 'link_formatter_link_url' => array(
danielebarchiesi@4 636 'variables' => array('element' => NULL),
danielebarchiesi@4 637 ),
danielebarchiesi@4 638 'link_formatter_link_short' => array(
danielebarchiesi@4 639 'variables' => array('element' => NULL),
danielebarchiesi@4 640 ),
danielebarchiesi@4 641 'link_formatter_link_label' => array(
danielebarchiesi@4 642 'variables' => array('element' => NULL, 'field' => NULL),
danielebarchiesi@4 643 ),
danielebarchiesi@4 644 'link_formatter_link_separate' => array(
danielebarchiesi@4 645 'variables' => array('element' => NULL),
danielebarchiesi@4 646 ),
danielebarchiesi@4 647 'link_field' => array(
danielebarchiesi@4 648 'render element' => 'element',
danielebarchiesi@4 649 ),
danielebarchiesi@4 650 );
danielebarchiesi@4 651 }
danielebarchiesi@4 652
danielebarchiesi@4 653 /**
danielebarchiesi@4 654 * Formats a link field widget.
danielebarchiesi@4 655 */
danielebarchiesi@4 656 function theme_link_field($vars) {
danielebarchiesi@4 657 drupal_add_css(drupal_get_path('module', 'link') . '/link.css');
danielebarchiesi@4 658 $element = $vars['element'];
danielebarchiesi@4 659 // Prefix single value link fields with the name of the field.
danielebarchiesi@4 660 if (empty($element['#field']['multiple'])) {
danielebarchiesi@4 661 if (isset($element['url']) && !isset($element['title'])) {
danielebarchiesi@4 662 $element['url']['#title_display'] = 'invisible';
danielebarchiesi@4 663 }
danielebarchiesi@4 664 }
danielebarchiesi@4 665
danielebarchiesi@4 666 $output = '';
danielebarchiesi@4 667 $output .= '<div class="link-field-subrow clearfix">';
danielebarchiesi@4 668 if (isset($element['title'])) {
danielebarchiesi@4 669 $output .= '<div class="link-field-title link-field-column">' . drupal_render($element['title']) . '</div>';
danielebarchiesi@4 670 }
danielebarchiesi@4 671 $output .= '<div class="link-field-url' . (isset($element['title']) ? ' link-field-column' : '') . '">'. drupal_render($element['url']) . '</div>';
danielebarchiesi@4 672 $output .= '</div>';
danielebarchiesi@4 673 if (!empty($element['attributes']['target'])) {
danielebarchiesi@4 674 $output .= '<div class="link-attributes">' . drupal_render($element['attributes']['target']) . '</div>';
danielebarchiesi@4 675 }
danielebarchiesi@4 676 if (!empty($element['attributes']['title'])) {
danielebarchiesi@4 677 $output .= '<div class="link-attributes">' . drupal_render($element['attributes']['title']) . '</div>';
danielebarchiesi@4 678 }
danielebarchiesi@4 679 return $output;
danielebarchiesi@4 680 }
danielebarchiesi@4 681
danielebarchiesi@4 682 /**
danielebarchiesi@4 683 * Implements hook_element_info().
danielebarchiesi@4 684 */
danielebarchiesi@4 685 function link_element_info() {
danielebarchiesi@4 686 $elements = array();
danielebarchiesi@4 687 $elements['link_field'] = array(
danielebarchiesi@4 688 '#input' => TRUE,
danielebarchiesi@4 689 '#process' => array('link_field_process'),
danielebarchiesi@4 690 '#theme' => 'link_field',
danielebarchiesi@4 691 '#theme_wrappers' => array('form_element'),
danielebarchiesi@4 692 );
danielebarchiesi@4 693 return $elements;
danielebarchiesi@4 694 }
danielebarchiesi@4 695
danielebarchiesi@4 696 /**
danielebarchiesi@4 697 * Returns the default attributes and their values.
danielebarchiesi@4 698 */
danielebarchiesi@4 699 function _link_default_attributes() {
danielebarchiesi@4 700 return array(
danielebarchiesi@4 701 'target' => LINK_TARGET_DEFAULT,
danielebarchiesi@4 702 'class' => '',
danielebarchiesi@4 703 'rel' => '',
danielebarchiesi@4 704 );
danielebarchiesi@4 705 }
danielebarchiesi@4 706
danielebarchiesi@4 707 /**
danielebarchiesi@4 708 * Processes the link type element before displaying the field.
danielebarchiesi@4 709 *
danielebarchiesi@4 710 * Build the form element. When creating a form using FAPI #process,
danielebarchiesi@4 711 * note that $element['#value'] is already set.
danielebarchiesi@4 712 *
danielebarchiesi@4 713 * The $fields array is in $complete_form['#field_info'][$element['#field_name']].
danielebarchiesi@4 714 */
danielebarchiesi@4 715 function link_field_process($element, $form_state, $complete_form) {
danielebarchiesi@4 716 $instance = field_widget_instance($element, $form_state);
danielebarchiesi@4 717 $settings = $instance['settings'];
danielebarchiesi@4 718 $element['url'] = array(
danielebarchiesi@4 719 '#type' => 'textfield',
danielebarchiesi@4 720 '#maxlength' => LINK_URL_MAX_LENGTH,
danielebarchiesi@4 721 '#title' => t('URL'),
danielebarchiesi@4 722 '#required' => ($element['#delta'] == 0 && $settings['url'] !== 'optional') ? $element['#required'] : FALSE,
danielebarchiesi@4 723 '#default_value' => isset($element['#value']['url']) ? $element['#value']['url'] : NULL,
danielebarchiesi@4 724 );
danielebarchiesi@4 725 if ($settings['title'] !== 'none' && $settings['title'] !== 'value') {
danielebarchiesi@4 726 $element['title'] = array(
danielebarchiesi@4 727 '#type' => 'textfield',
danielebarchiesi@4 728 '#maxlength' => $settings['title_maxlength'],
danielebarchiesi@4 729 '#title' => t('Title'),
danielebarchiesi@4 730 '#description' => t('The link title is limited to @maxlength characters maximum.', array('@maxlength' => $settings['title_maxlength'])),
danielebarchiesi@4 731 '#required' => ($settings['title'] == 'required' && (($element['#delta'] == 0 && $element['#required']) || !empty($element['#value']['url']))) ? TRUE : FALSE,
danielebarchiesi@4 732 '#default_value' => isset($element['#value']['title']) ? $element['#value']['title'] : NULL,
danielebarchiesi@4 733 );
danielebarchiesi@4 734 }
danielebarchiesi@4 735
danielebarchiesi@4 736 // Initialize field attributes as an array if it is not an array yet.
danielebarchiesi@4 737 if (!is_array($settings['attributes'])) {
danielebarchiesi@4 738 $settings['attributes'] = array();
danielebarchiesi@4 739 }
danielebarchiesi@4 740 // Add default attributes.
danielebarchiesi@4 741 $settings['attributes'] += _link_default_attributes();
danielebarchiesi@4 742 $attributes = isset($element['#value']['attributes']) ? $element['#value']['attributes'] : $settings['attributes'];
danielebarchiesi@4 743 if (!empty($settings['attributes']['target']) && $settings['attributes']['target'] == LINK_TARGET_USER) {
danielebarchiesi@4 744 $element['attributes']['target'] = array(
danielebarchiesi@4 745 '#type' => 'checkbox',
danielebarchiesi@4 746 '#title' => t('Open URL in a New Window'),
danielebarchiesi@4 747 '#return_value' => LINK_TARGET_NEW_WINDOW,
danielebarchiesi@4 748 '#default_value' => isset($attributes['target']) ? $attributes['target'] : FALSE,
danielebarchiesi@4 749 );
danielebarchiesi@4 750 }
danielebarchiesi@4 751 if (!empty($settings['attributes']['configurable_title']) && $settings['attributes']['configurable_title'] == 1) {
danielebarchiesi@4 752 $element['attributes']['title'] = array(
danielebarchiesi@4 753 '#type' => 'textfield',
danielebarchiesi@4 754 '#title' => t('Link "title" attribute'),
danielebarchiesi@4 755 '#default_value' => isset($attributes['title']) ? $attributes['title'] : '',
danielebarchiesi@4 756 '#field_prefix' => 'title = "',
danielebarchiesi@4 757 '#field_suffix' => '"',
danielebarchiesi@4 758 );
danielebarchiesi@4 759 }
danielebarchiesi@4 760
danielebarchiesi@4 761 // If the title field is avaliable or there are field accepts multiple values
danielebarchiesi@4 762 // then allow the individual field items display the required asterisk if needed.
danielebarchiesi@4 763 if (isset($element['title']) || isset($element['_weight'])) {
danielebarchiesi@4 764 // To prevent an extra required indicator, disable the required flag on the
danielebarchiesi@4 765 // base element since all the sub-fields are already required if desired.
danielebarchiesi@4 766 $element['#required'] = FALSE;
danielebarchiesi@4 767 }
danielebarchiesi@4 768
danielebarchiesi@4 769 return $element;
danielebarchiesi@4 770 }
danielebarchiesi@4 771
danielebarchiesi@4 772 /**
danielebarchiesi@4 773 * Implements hook_field_formatter_info().
danielebarchiesi@4 774 */
danielebarchiesi@4 775 function link_field_formatter_info() {
danielebarchiesi@4 776 return array(
danielebarchiesi@4 777 'link_default' => array(
danielebarchiesi@4 778 'label' => t('Title, as link (default)'),
danielebarchiesi@4 779 'field types' => array('link_field'),
danielebarchiesi@4 780 'multiple values' => FIELD_BEHAVIOR_DEFAULT,
danielebarchiesi@4 781 ),
danielebarchiesi@4 782 'link_title_plain' => array(
danielebarchiesi@4 783 'label' => t('Title, as plain text'),
danielebarchiesi@4 784 'field types' => array('link_field'),
danielebarchiesi@4 785 'multiple values' => FIELD_BEHAVIOR_DEFAULT,
danielebarchiesi@4 786 ),
danielebarchiesi@4 787 'link_url' => array(
danielebarchiesi@4 788 'label' => t('URL, as link'),
danielebarchiesi@4 789 'field types' => array('link_field'),
danielebarchiesi@4 790 'multiple values' => FIELD_BEHAVIOR_DEFAULT,
danielebarchiesi@4 791 ),
danielebarchiesi@4 792 'link_plain' => array(
danielebarchiesi@4 793 'label' => t('URL, as plain text'),
danielebarchiesi@4 794 'field types' => array('link_field'),
danielebarchiesi@4 795 'multiple values' => FIELD_BEHAVIOR_DEFAULT,
danielebarchiesi@4 796 ),
danielebarchiesi@4 797 'link_absolute' => array(
danielebarchiesi@4 798 'label' => t('URL, absolute'),
danielebarchiesi@4 799 'field types' => array('link_field'),
danielebarchiesi@4 800 'multiple values' => FIELD_BEHAVIOR_DEFAULT,
danielebarchiesi@4 801 ),
danielebarchiesi@4 802 'link_domain' => array(
danielebarchiesi@4 803 'label' => t('Domain, as link'),
danielebarchiesi@4 804 'field types' => array('link_field'),
danielebarchiesi@4 805 'multiple values' => FIELD_BEHAVIOR_DEFAULT,
danielebarchiesi@4 806 'settings' => array(
danielebarchiesi@4 807 'strip_www' => FALSE,
danielebarchiesi@4 808 ),
danielebarchiesi@4 809 ),
danielebarchiesi@4 810 'link_short' => array(
danielebarchiesi@4 811 'label' => t('Short, as link with title "Link"'),
danielebarchiesi@4 812 'field types' => array('link_field'),
danielebarchiesi@4 813 'multiple values' => FIELD_BEHAVIOR_DEFAULT,
danielebarchiesi@4 814 ),
danielebarchiesi@4 815 'link_label' => array(
danielebarchiesi@4 816 'label' => t('Label, as link with label as title'),
danielebarchiesi@4 817 'field types' => array('link_field'),
danielebarchiesi@4 818 'multiple values' => FIELD_BEHAVIOR_DEFAULT,
danielebarchiesi@4 819 ),
danielebarchiesi@4 820 'link_separate' => array(
danielebarchiesi@4 821 'label' => t('Separate title and URL'),
danielebarchiesi@4 822 'field types' => array('link_field'),
danielebarchiesi@4 823 'multiple values' => FIELD_BEHAVIOR_DEFAULT,
danielebarchiesi@4 824 ),
danielebarchiesi@4 825 );
danielebarchiesi@4 826 }
danielebarchiesi@4 827
danielebarchiesi@4 828 /**
danielebarchiesi@4 829 * Implements hook_field_formatter_settings_form().
danielebarchiesi@4 830 */
danielebarchiesi@4 831 function link_field_formatter_settings_form($field, $instance, $view_mode, $form, &$form_state) {
danielebarchiesi@4 832 $display = $instance['display'][$view_mode];
danielebarchiesi@4 833 $settings = $display['settings'];
danielebarchiesi@4 834 $element = array();
danielebarchiesi@4 835 if ($display['type'] == 'link_domain') {
danielebarchiesi@4 836 $element['strip_www'] = array(
danielebarchiesi@4 837 '#title' => t('Strip www. from domain'),
danielebarchiesi@4 838 '#type' => 'checkbox',
danielebarchiesi@4 839 '#default_value' => $settings['strip_www'],
danielebarchiesi@4 840 );
danielebarchiesi@4 841 }
danielebarchiesi@4 842 return $element;
danielebarchiesi@4 843 }
danielebarchiesi@4 844
danielebarchiesi@4 845 /**
danielebarchiesi@4 846 * Implements hook_field_formatter_settings_summary().
danielebarchiesi@4 847 */
danielebarchiesi@4 848 function link_field_formatter_settings_summary($field, $instance, $view_mode) {
danielebarchiesi@4 849 $display = $instance['display'][$view_mode];
danielebarchiesi@4 850 $settings = $display['settings'];
danielebarchiesi@4 851 if ($display['type'] == 'link_domain') {
danielebarchiesi@4 852 if ($display['settings']['strip_www']) {
danielebarchiesi@4 853 return t('Strip www. from domain');
danielebarchiesi@4 854 }
danielebarchiesi@4 855 else {
danielebarchiesi@4 856 return t('Leave www. in domain');
danielebarchiesi@4 857 }
danielebarchiesi@4 858 }
danielebarchiesi@4 859 return '';
danielebarchiesi@4 860 }
danielebarchiesi@4 861
danielebarchiesi@4 862 /**
danielebarchiesi@4 863 * Implements hook_field_formatter_view().
danielebarchiesi@4 864 */
danielebarchiesi@4 865 function link_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) {
danielebarchiesi@4 866 $elements = array();
danielebarchiesi@4 867 foreach ($items as $delta => $item) {
danielebarchiesi@4 868 $elements[$delta] = array(
danielebarchiesi@4 869 '#theme' => 'link_formatter_' . $display['type'],
danielebarchiesi@4 870 '#element' => $item,
danielebarchiesi@4 871 '#field' => $instance,
danielebarchiesi@4 872 '#display' => $display,
danielebarchiesi@4 873 );
danielebarchiesi@4 874 }
danielebarchiesi@4 875 return $elements;
danielebarchiesi@4 876 }
danielebarchiesi@4 877
danielebarchiesi@4 878 /**
danielebarchiesi@4 879 * Formats a link.
danielebarchiesi@4 880 */
danielebarchiesi@4 881 function theme_link_formatter_link_default($vars) {
danielebarchiesi@4 882 $link_options = $vars['element'];
danielebarchiesi@4 883 unset($link_options['title']);
danielebarchiesi@4 884 unset($link_options['url']);
danielebarchiesi@4 885
danielebarchiesi@4 886 if (isset($link_options['attributes']['class'])) {
danielebarchiesi@4 887 $link_options['attributes']['class'] = array($link_options['attributes']['class']);
danielebarchiesi@4 888 }
danielebarchiesi@4 889
danielebarchiesi@4 890 // Display a normal link if both title and URL are available.
danielebarchiesi@4 891 if (!empty($vars['element']['title']) && !empty($vars['element']['url'])) {
danielebarchiesi@4 892 return l($vars['element']['title'], $vars['element']['url'], $link_options);
danielebarchiesi@4 893 }
danielebarchiesi@4 894 // If only a title, display the title.
danielebarchiesi@4 895 elseif (!empty($vars['element']['title'])) {
danielebarchiesi@4 896 return check_plain($vars['element']['title']);
danielebarchiesi@4 897 }
danielebarchiesi@4 898 elseif (!empty($vars['element']['url'])) {
danielebarchiesi@4 899 return l($vars['element']['title'], $vars['element']['url'], $link_options);
danielebarchiesi@4 900 }
danielebarchiesi@4 901 }
danielebarchiesi@4 902
danielebarchiesi@4 903 /**
danielebarchiesi@4 904 * Formats a link (or its title) as plain text.
danielebarchiesi@4 905 */
danielebarchiesi@4 906 function theme_link_formatter_link_plain($vars) {
danielebarchiesi@4 907 $link_options = $vars['element'];
danielebarchiesi@4 908 if (isset($link_options['title'])) {
danielebarchiesi@4 909 unset($link_options['title']);
danielebarchiesi@4 910 }
danielebarchiesi@4 911 else {
danielebarchiesi@4 912 $vars['element']['title'] = '';
danielebarchiesi@4 913 }
danielebarchiesi@4 914 unset($link_options['url']);
danielebarchiesi@4 915 return empty($vars['element']['url']) ? check_plain($vars['element']['title']) : url($vars['element']['url'], $link_options);
danielebarchiesi@4 916 }
danielebarchiesi@4 917
danielebarchiesi@4 918 /**
danielebarchiesi@4 919 * Formats a link as an absolute URL
danielebarchiesi@4 920 */
danielebarchiesi@4 921 function theme_link_formatter_link_absolute($vars) {
danielebarchiesi@4 922 $absolute = array('absolute' => TRUE);
danielebarchiesi@4 923 return empty($vars['element']['url']) ? '' : url($vars['element']['url'], $absolute + $vars['element']);
danielebarchiesi@4 924 }
danielebarchiesi@4 925
danielebarchiesi@4 926 /**
danielebarchiesi@4 927 * Formats a link using the URL's domain for it's link text.
danielebarchiesi@4 928 */
danielebarchiesi@4 929 function theme_link_formatter_link_domain($vars) {
danielebarchiesi@4 930 $link_options = $vars['element'];
danielebarchiesi@4 931 unset($link_options['title']);
danielebarchiesi@4 932 unset($link_options['url']);
danielebarchiesi@4 933 $domain = parse_url($vars['element']['display_url'], PHP_URL_HOST);
danielebarchiesi@4 934 if (!empty($vars['display']['settings']['strip_www'])) {
danielebarchiesi@4 935 $domain = str_replace('www.', '', $domain);
danielebarchiesi@4 936 }
danielebarchiesi@4 937 return $vars['element']['url'] ? l($domain, $vars['element']['url'], $link_options) : '';
danielebarchiesi@4 938 }
danielebarchiesi@4 939
danielebarchiesi@4 940 /**
danielebarchiesi@4 941 * Formats a link's title as plain text.
danielebarchiesi@4 942 */
danielebarchiesi@4 943 function theme_link_formatter_link_title_plain($vars) {
danielebarchiesi@4 944 return empty($vars['element']['title']) ? '' : check_plain($vars['element']['title']);
danielebarchiesi@4 945 }
danielebarchiesi@4 946
danielebarchiesi@4 947 /**
danielebarchiesi@4 948 * Formats a link using an alternate display URL for its link text.
danielebarchiesi@4 949 */
danielebarchiesi@4 950 function theme_link_formatter_link_url($vars) {
danielebarchiesi@4 951 $link_options = $vars['element'];
danielebarchiesi@4 952 unset($link_options['title']);
danielebarchiesi@4 953 unset($link_options['url']);
danielebarchiesi@4 954 return $vars['element']['url'] ? l($vars['element']['display_url'], $vars['element']['url'], $link_options) : '';
danielebarchiesi@4 955 }
danielebarchiesi@4 956
danielebarchiesi@4 957 /**
danielebarchiesi@4 958 * Formats a link using "Link" as the link text.
danielebarchiesi@4 959 */
danielebarchiesi@4 960 function theme_link_formatter_link_short($vars) {
danielebarchiesi@4 961 $link_options = $vars['element'];
danielebarchiesi@4 962 unset($link_options['title']);
danielebarchiesi@4 963 unset($link_options['url']);
danielebarchiesi@4 964 return $vars['element']['url'] ? l(t('Link'), $vars['element']['url'], $link_options) : '';
danielebarchiesi@4 965 }
danielebarchiesi@4 966
danielebarchiesi@4 967 /**
danielebarchiesi@4 968 * Formats a link using the field's label as link text.
danielebarchiesi@4 969 */
danielebarchiesi@4 970 function theme_link_formatter_link_label($vars) {
danielebarchiesi@4 971 $link_options = $vars['element'];
danielebarchiesi@4 972 unset($link_options['title']);
danielebarchiesi@4 973 unset($link_options['url']);
danielebarchiesi@4 974 return $vars['element']['url'] ? l($vars['field']['label'], $vars['element']['url'], $link_options) : '';
danielebarchiesi@4 975 }
danielebarchiesi@4 976
danielebarchiesi@4 977 /**
danielebarchiesi@4 978 * Formats a link as separate title and URL elements.
danielebarchiesi@4 979 */
danielebarchiesi@4 980 function theme_link_formatter_link_separate($vars) {
danielebarchiesi@4 981 $class = empty($vars['element']['attributes']['class']) ? '' : ' ' . $vars['element']['attributes']['class'];
danielebarchiesi@4 982 unset($vars['element']['attributes']['class']);
danielebarchiesi@4 983 $link_options = $vars['element'];
danielebarchiesi@4 984 unset($link_options['title']);
danielebarchiesi@4 985 unset($link_options['url']);
danielebarchiesi@4 986 $title = empty($vars['element']['title']) ? '' : check_plain($vars['element']['title']);
danielebarchiesi@4 987
danielebarchiesi@4 988 /**
danielebarchiesi@4 989 * @TODO static html markup looks not very elegant
danielebarchiesi@4 990 * needs smarter output solution and an optional title/url seperator
danielebarchiesi@4 991 */
danielebarchiesi@4 992 $url_parts = _link_parse_url($vars['element']['url']);
danielebarchiesi@4 993 $output = '';
danielebarchiesi@4 994 $output .= '<div class="link-item ' . $class . '">';
danielebarchiesi@4 995 if (!empty($title)) {
danielebarchiesi@4 996 $output .= '<div class="link-title">' . $title . '</div>';
danielebarchiesi@4 997 }
danielebarchiesi@4 998 $output .= '<div class="link-url">' . l($url_parts['url'], $vars['element']['url'], $link_options) . '</div>';
danielebarchiesi@4 999 $output .= '</div>';
danielebarchiesi@4 1000 return $output;
danielebarchiesi@4 1001 }
danielebarchiesi@4 1002
danielebarchiesi@4 1003 /**
danielebarchiesi@4 1004 * Implements hook_token_list().
danielebarchiesi@4 1005 */
danielebarchiesi@4 1006 function link_token_list($type = 'all') {
danielebarchiesi@4 1007 if ($type === 'field' || $type === 'all') {
danielebarchiesi@4 1008 $tokens = array();
danielebarchiesi@4 1009 $tokens['link']['url'] = t("Link URL");
danielebarchiesi@4 1010 $tokens['link']['title'] = t("Link title");
danielebarchiesi@4 1011 $tokens['link']['view'] = t("Formatted html link");
danielebarchiesi@4 1012 return $tokens;
danielebarchiesi@4 1013 }
danielebarchiesi@4 1014 }
danielebarchiesi@4 1015
danielebarchiesi@4 1016 function link_token_values($type, $object = NULL) {
danielebarchiesi@4 1017 if ($type === 'field') {
danielebarchiesi@4 1018 $item = $object[0];
danielebarchiesi@4 1019
danielebarchiesi@4 1020 $tokens['url'] = $item['url'];
danielebarchiesi@4 1021 $tokens['title'] = $item['title'];
danielebarchiesi@4 1022 $tokens['view'] = isset($item['view']) ? $item['view'] : '';
danielebarchiesi@4 1023
danielebarchiesi@4 1024 return $tokens;
danielebarchiesi@4 1025 }
danielebarchiesi@4 1026 }
danielebarchiesi@4 1027
danielebarchiesi@4 1028 /**
danielebarchiesi@4 1029 * Implements hook_views_api().
danielebarchiesi@4 1030 */
danielebarchiesi@4 1031 function link_views_api() {
danielebarchiesi@4 1032 return array(
danielebarchiesi@4 1033 'api' => 2,
danielebarchiesi@4 1034 'path' => drupal_get_path('module', 'link') . '/views',
danielebarchiesi@4 1035 );
danielebarchiesi@4 1036 }
danielebarchiesi@4 1037
danielebarchiesi@4 1038 /**
danielebarchiesi@4 1039 * Forms a valid URL if possible from an entered address.
danielebarchiesi@4 1040 *
danielebarchiesi@4 1041 * Trims whitespace and automatically adds an http:// to addresses without a
danielebarchiesi@4 1042 * protocol specified
danielebarchiesi@4 1043 *
danielebarchiesi@4 1044 * @param string $url
danielebarchiesi@4 1045 * @param string $protocol
danielebarchiesi@4 1046 * The protocol to be prepended to the url if one is not specified
danielebarchiesi@4 1047 */
danielebarchiesi@4 1048 function link_cleanup_url($url, $protocol = 'http') {
danielebarchiesi@4 1049 $url = trim($url);
danielebarchiesi@4 1050 $type = link_validate_url($url);
danielebarchiesi@4 1051
danielebarchiesi@4 1052 if ($type === LINK_EXTERNAL) {
danielebarchiesi@4 1053 // Check if there is no protocol specified.
danielebarchiesi@4 1054 $protocol_match = preg_match("/^([a-z0-9][a-z0-9\.\-_]*:\/\/)/i", $url);
danielebarchiesi@4 1055 if (empty($protocol_match)) {
danielebarchiesi@4 1056 // But should there be? Add an automatic http:// if it starts with a domain name.
danielebarchiesi@4 1057 $LINK_DOMAINS = _link_domains();
danielebarchiesi@4 1058 $domain_match = preg_match('/^(([a-z0-9]([a-z0-9\-_]*\.)+)(' . $LINK_DOMAINS . '|[a-z]{2}))/i', $url);
danielebarchiesi@4 1059 if (!empty($domain_match)) {
danielebarchiesi@4 1060 $url = $protocol . "://" . $url;
danielebarchiesi@4 1061 }
danielebarchiesi@4 1062 }
danielebarchiesi@4 1063 }
danielebarchiesi@4 1064
danielebarchiesi@4 1065 return $url;
danielebarchiesi@4 1066 }
danielebarchiesi@4 1067
danielebarchiesi@4 1068 /**
danielebarchiesi@4 1069 * Validates a URL.
danielebarchiesi@4 1070 *
danielebarchiesi@4 1071 * Accepts all URLs following RFC 1738 standard for URL formation and all e-mail
danielebarchiesi@4 1072 * addresses following the RFC 2368 standard for mailto address formation.
danielebarchiesi@4 1073 *
danielebarchiesi@4 1074 * @param string $text
danielebarchiesi@4 1075 *
danielebarchiesi@4 1076 * @return mixed
danielebarchiesi@4 1077 * Returns boolean FALSE if the URL is not valid. On success, returns one of
danielebarchiesi@4 1078 * the LINK_(linktype) constants.
danielebarchiesi@4 1079 */
danielebarchiesi@4 1080 function link_validate_url($text) {
danielebarchiesi@4 1081 // @TODO Complete letters.
danielebarchiesi@4 1082 $LINK_ICHARS_DOMAIN = (string) html_entity_decode(implode("", array(
danielebarchiesi@4 1083 "&#x00E6;", // æ
danielebarchiesi@4 1084 "&#x00C6;", // Æ
danielebarchiesi@4 1085 "&#x00C0;", // À
danielebarchiesi@4 1086 "&#x00E0;", // à
danielebarchiesi@4 1087 "&#x00C1;", // Á
danielebarchiesi@4 1088 "&#x00E1;", // á
danielebarchiesi@4 1089 "&#x00C2;", // Â
danielebarchiesi@4 1090 "&#x00E2;", // â
danielebarchiesi@4 1091 "&#x00E5;", // å
danielebarchiesi@4 1092 "&#x00C5;", // Å
danielebarchiesi@4 1093 "&#x00E4;", // ä
danielebarchiesi@4 1094 "&#x00C4;", // Ä
danielebarchiesi@4 1095 "&#x00C7;", // Ç
danielebarchiesi@4 1096 "&#x00E7;", // ç
danielebarchiesi@4 1097 "&#x00D0;", // Ð
danielebarchiesi@4 1098 "&#x00F0;", // ð
danielebarchiesi@4 1099 "&#x00C8;", // È
danielebarchiesi@4 1100 "&#x00E8;", // è
danielebarchiesi@4 1101 "&#x00C9;", // É
danielebarchiesi@4 1102 "&#x00E9;", // é
danielebarchiesi@4 1103 "&#x00CA;", // Ê
danielebarchiesi@4 1104 "&#x00EA;", // ê
danielebarchiesi@4 1105 "&#x00CB;", // Ë
danielebarchiesi@4 1106 "&#x00EB;", // ë
danielebarchiesi@4 1107 "&#x00CE;", // Î
danielebarchiesi@4 1108 "&#x00EE;", // î
danielebarchiesi@4 1109 "&#x00CF;", // Ï
danielebarchiesi@4 1110 "&#x00EF;", // ï
danielebarchiesi@4 1111 "&#x00F8;", // ø
danielebarchiesi@4 1112 "&#x00D8;", // Ø
danielebarchiesi@4 1113 "&#x00F6;", // ö
danielebarchiesi@4 1114 "&#x00D6;", // Ö
danielebarchiesi@4 1115 "&#x00D4;", // Ô
danielebarchiesi@4 1116 "&#x00F4;", // ô
danielebarchiesi@4 1117 "&#x00D5;", // Õ
danielebarchiesi@4 1118 "&#x00F5;", // õ
danielebarchiesi@4 1119 "&#x0152;", // Œ
danielebarchiesi@4 1120 "&#x0153;", // œ
danielebarchiesi@4 1121 "&#x00FC;", // ü
danielebarchiesi@4 1122 "&#x00DC;", // Ü
danielebarchiesi@4 1123 "&#x00D9;", // Ù
danielebarchiesi@4 1124 "&#x00F9;", // ù
danielebarchiesi@4 1125 "&#x00DB;", // Û
danielebarchiesi@4 1126 "&#x00FB;", // û
danielebarchiesi@4 1127 "&#x0178;", // Ÿ
danielebarchiesi@4 1128 "&#x00FF;", // ÿ
danielebarchiesi@4 1129 "&#x00D1;", // Ñ
danielebarchiesi@4 1130 "&#x00F1;", // ñ
danielebarchiesi@4 1131 "&#x00FE;", // þ
danielebarchiesi@4 1132 "&#x00DE;", // Þ
danielebarchiesi@4 1133 "&#x00FD;", // ý
danielebarchiesi@4 1134 "&#x00DD;", // Ý
danielebarchiesi@4 1135 "&#x00BF;", // ¿
danielebarchiesi@4 1136 )), ENT_QUOTES, 'UTF-8');
danielebarchiesi@4 1137
danielebarchiesi@4 1138 $LINK_ICHARS = $LINK_ICHARS_DOMAIN . (string) html_entity_decode(implode("", array(
danielebarchiesi@4 1139 "&#x00DF;", // ß
danielebarchiesi@4 1140 )), ENT_QUOTES, 'UTF-8');
danielebarchiesi@4 1141 $allowed_protocols = variable_get('filter_allowed_protocols', array('http', 'https', 'ftp', 'news', 'nntp', 'telnet', 'mailto', 'irc', 'ssh', 'sftp', 'webcal'));
danielebarchiesi@4 1142 $LINK_DOMAINS = _link_domains();
danielebarchiesi@4 1143
danielebarchiesi@4 1144 // Starting a parenthesis group with (?: means that it is grouped, but is not captured
danielebarchiesi@4 1145 $protocol = '((?:' . implode("|", $allowed_protocols) . '):\/\/)';
danielebarchiesi@4 1146 $authentication = "(?:(?:(?:[\w\.\-\+!$&'\(\)*\+,;=" . $LINK_ICHARS . "]|%[0-9a-f]{2})+(?::(?:[\w" . $LINK_ICHARS . "\.\-\+%!$&'\(\)*\+,;=]|%[0-9a-f]{2})*)?)?@)";
danielebarchiesi@4 1147 $domain = '(?:(?:[a-z0-9' . $LINK_ICHARS_DOMAIN . ']([a-z0-9' . $LINK_ICHARS_DOMAIN . '\-_\[\]])*)(\.(([a-z0-9' . $LINK_ICHARS_DOMAIN . '\-_\[\]])+\.)*(' . $LINK_DOMAINS . '|[a-z]{2}))?)';
danielebarchiesi@4 1148 $ipv4 = '(?:[0-9]{1,3}(\.[0-9]{1,3}){3})';
danielebarchiesi@4 1149 $ipv6 = '(?:[0-9a-fA-F]{1,4}(\:[0-9a-fA-F]{1,4}){7})';
danielebarchiesi@4 1150 $port = '(?::([0-9]{1,5}))';
danielebarchiesi@4 1151
danielebarchiesi@4 1152 // Pattern specific to external links.
danielebarchiesi@4 1153 $external_pattern = '/^' . $protocol . '?' . $authentication . '?(' . $domain . '|' . $ipv4 . '|' . $ipv6 . ' |localhost)' . $port . '?';
danielebarchiesi@4 1154
danielebarchiesi@4 1155 // Pattern specific to internal links.
danielebarchiesi@4 1156 $internal_pattern = "/^(?:[a-z0-9" . $LINK_ICHARS . "_\-+\[\] ]+)";
danielebarchiesi@4 1157 $internal_pattern_file = "/^(?:[a-z0-9" . $LINK_ICHARS . "_\-+\[\]\. \/\(\)][a-z0-9" . $LINK_ICHARS . "_\-+\[\]\. \(\)][a-z0-9" . $LINK_ICHARS . "_\-+\[\]\. \/\(\)]+)$/i";
danielebarchiesi@4 1158
danielebarchiesi@4 1159 $directories = "(?:\/[a-z0-9" . $LINK_ICHARS . "_\-\.~+%=&,$'#!():;*@\[\]]*)*";
danielebarchiesi@4 1160 // Yes, four backslashes == a single backslash.
danielebarchiesi@4 1161 $query = "(?:\/?\?([?a-z0-9" . $LINK_ICHARS . "+_|\-\.~\/\\\\%=&,$'():;*@\[\]{} ]*))";
danielebarchiesi@4 1162 $anchor = "(?:#[a-z0-9" . $LINK_ICHARS . "_\-\.~+%=&,$'():;*@\[\]\/\?]*)";
danielebarchiesi@4 1163
danielebarchiesi@4 1164 // The rest of the path for a standard URL.
danielebarchiesi@4 1165 $end = $directories . '?' . $query . '?' . $anchor . '?' . '$/i';
danielebarchiesi@4 1166
danielebarchiesi@4 1167 $message_id = '[^@].*@' . $domain;
danielebarchiesi@4 1168 $newsgroup_name = '(?:[0-9a-z+-]*\.)*[0-9a-z+-]*';
danielebarchiesi@4 1169 $news_pattern = '/^news:(' . $newsgroup_name . '|' . $message_id . ')$/i';
danielebarchiesi@4 1170
danielebarchiesi@4 1171 $user = '[a-zA-Z0-9' . $LINK_ICHARS . '_\-\.\+\^!#\$%&*+\/\=\?\`\|\{\}~\'\[\]]+';
danielebarchiesi@4 1172 $email_pattern = '/^mailto:' . $user . '@'.'(?:' . $domain . '|' . $ipv4 . '|' . $ipv6 . '|localhost)' . $query . '?$/';
danielebarchiesi@4 1173
danielebarchiesi@4 1174 if (strpos($text, '<front>') === 0) {
danielebarchiesi@4 1175 return LINK_FRONT;
danielebarchiesi@4 1176 }
danielebarchiesi@4 1177 if (in_array('mailto', $allowed_protocols) && preg_match($email_pattern, $text)) {
danielebarchiesi@4 1178 return LINK_EMAIL;
danielebarchiesi@4 1179 }
danielebarchiesi@4 1180 if (in_array('news', $allowed_protocols) && preg_match($news_pattern, $text)) {
danielebarchiesi@4 1181 return LINK_NEWS;
danielebarchiesi@4 1182 }
danielebarchiesi@4 1183 if (preg_match($internal_pattern . $end, $text)) {
danielebarchiesi@4 1184 return LINK_INTERNAL;
danielebarchiesi@4 1185 }
danielebarchiesi@4 1186 if (preg_match($external_pattern . $end, $text)) {
danielebarchiesi@4 1187 return LINK_EXTERNAL;
danielebarchiesi@4 1188 }
danielebarchiesi@4 1189 if (preg_match($internal_pattern_file, $text)) {
danielebarchiesi@4 1190 return LINK_INTERNAL;
danielebarchiesi@4 1191 }
danielebarchiesi@4 1192
danielebarchiesi@4 1193 return FALSE;
danielebarchiesi@4 1194 }
danielebarchiesi@4 1195
danielebarchiesi@4 1196 /**
danielebarchiesi@4 1197 * Returns the list of allowed domains, including domains added by admins via variable_set/$config.
danielebarchiesi@4 1198 */
danielebarchiesi@4 1199 function _link_domains() {
danielebarchiesi@4 1200 $link_extra_domains = variable_get('link_extra_domains', array());
danielebarchiesi@4 1201 return empty($link_extra_domains) ? LINK_DOMAINS : LINK_DOMAINS . '|' . implode('|', $link_extra_domains);
danielebarchiesi@4 1202 }
danielebarchiesi@4 1203
danielebarchiesi@4 1204 /**
danielebarchiesi@4 1205 * Implements hook_migrate_field_alter().
danielebarchiesi@4 1206 */
danielebarchiesi@4 1207 function link_content_migrate_field_alter(&$field_value, $instance_value) {
danielebarchiesi@4 1208 if ($field_value['type'] == 'link') {
danielebarchiesi@4 1209 // Adjust the field type.
danielebarchiesi@4 1210 $field_value['type'] = 'link_field';
danielebarchiesi@4 1211 // Remove settings that are now on the instance.
danielebarchiesi@4 1212 foreach (array('attributes', 'display', 'url', 'title', 'title_value', 'enable_tokens', 'validate_url') as $setting) {
danielebarchiesi@4 1213 unset($field_value['settings'][$setting]);
danielebarchiesi@4 1214 }
danielebarchiesi@4 1215 }
danielebarchiesi@4 1216 }
danielebarchiesi@4 1217
danielebarchiesi@4 1218 /**
danielebarchiesi@4 1219 * Implements hook_migrate_instance_alter().
danielebarchiesi@4 1220 *
danielebarchiesi@4 1221 * Widget type also changed to link_field.
danielebarchiesi@4 1222 */
danielebarchiesi@4 1223 function link_content_migrate_instance_alter(&$instance_value, $field_value) {
danielebarchiesi@4 1224 if ($field_value['type'] == 'link') {
danielebarchiesi@4 1225 // Grab settings that were previously on the field.
danielebarchiesi@4 1226 foreach (array('attributes', 'display', 'url', 'title', 'title_value', 'enable_tokens', 'validate_url') as $setting) {
danielebarchiesi@4 1227 if (isset($field_value['settings'][$setting])) {
danielebarchiesi@4 1228 $instance_value['settings'][$setting] = $field_value['settings'][$setting];
danielebarchiesi@4 1229 }
danielebarchiesi@4 1230 }
danielebarchiesi@4 1231 // Adjust widget type.
danielebarchiesi@4 1232 if ($instance_value['widget']['type'] == 'link') {
danielebarchiesi@4 1233 $instance_value['widget']['type'] = 'link_field';
danielebarchiesi@4 1234 }
danielebarchiesi@4 1235 // Adjust formatter types.
danielebarchiesi@4 1236 foreach ($instance_value['display'] as $context => $settings) {
danielebarchiesi@4 1237 if (in_array($settings['type'], array('default', 'title_plain', 'url', 'plain', 'short', 'label', 'separate'))) {
danielebarchiesi@4 1238 $instance_value['display'][$context]['type'] = 'link_' . $settings['type'];
danielebarchiesi@4 1239 }
danielebarchiesi@4 1240 }
danielebarchiesi@4 1241 }
danielebarchiesi@4 1242 }
danielebarchiesi@4 1243
danielebarchiesi@4 1244 /**
danielebarchiesi@4 1245 * Implements hook_field_settings_form().
danielebarchiesi@4 1246 */
danielebarchiesi@4 1247 function link_field_settings_form() {
danielebarchiesi@4 1248 return array();
danielebarchiesi@4 1249 }
danielebarchiesi@4 1250
danielebarchiesi@4 1251 /**
danielebarchiesi@4 1252 * Additional callback to adapt the property info of link fields.
danielebarchiesi@4 1253 *
danielebarchiesi@4 1254 * @see entity_metadata_field_entity_property_info().
danielebarchiesi@4 1255 */
danielebarchiesi@4 1256 function link_field_property_info_callback(&$info, $entity_type, $field, $instance, $field_type) {
danielebarchiesi@4 1257 $property = &$info[$entity_type]['bundles'][$instance['bundle']]['properties'][$field['field_name']];
danielebarchiesi@4 1258 // Define a data structure so it's possible to deal with both the link title
danielebarchiesi@4 1259 // and URL.
danielebarchiesi@4 1260 $property['getter callback'] = 'entity_metadata_field_verbatim_get';
danielebarchiesi@4 1261 $property['setter callback'] = 'entity_metadata_field_verbatim_set';
danielebarchiesi@4 1262
danielebarchiesi@4 1263 // Auto-create the field item as soon as a property is set.
danielebarchiesi@4 1264 $property['auto creation'] = 'link_field_item_create';
danielebarchiesi@4 1265
danielebarchiesi@4 1266 $property['property info'] = link_field_item_property_info();
danielebarchiesi@4 1267 $property['property info']['url']['required'] = !$instance['settings']['url'];
danielebarchiesi@4 1268 $property['property info']['title']['required'] = ($instance['settings']['title'] == 'required');
danielebarchiesi@4 1269 if ($instance['settings']['title'] == 'none') {
danielebarchiesi@4 1270 unset($property['property info']['title']);
danielebarchiesi@4 1271 }
danielebarchiesi@4 1272 unset($property['query callback']);
danielebarchiesi@4 1273 }
danielebarchiesi@4 1274
danielebarchiesi@4 1275 /**
danielebarchiesi@4 1276 * Callback for creating a new, empty link field item.
danielebarchiesi@4 1277 *
danielebarchiesi@4 1278 * @see link_field_property_info_callback()
danielebarchiesi@4 1279 */
danielebarchiesi@4 1280 function link_field_item_create() {
danielebarchiesi@4 1281 return array('title' => NULL, 'url' => NULL);
danielebarchiesi@4 1282 }
danielebarchiesi@4 1283
danielebarchiesi@4 1284 /**
danielebarchiesi@4 1285 * Defines info for the properties of the link-field item data structure.
danielebarchiesi@4 1286 */
danielebarchiesi@4 1287 function link_field_item_property_info() {
danielebarchiesi@4 1288 $properties['title'] = array(
danielebarchiesi@4 1289 'type' => 'text',
danielebarchiesi@4 1290 'label' => t('The title of the link.'),
danielebarchiesi@4 1291 'setter callback' => 'entity_property_verbatim_set',
danielebarchiesi@4 1292 );
danielebarchiesi@4 1293 $properties['url'] = array(
danielebarchiesi@4 1294 'type' => 'uri',
danielebarchiesi@4 1295 'label' => t('The URL of the link.'),
danielebarchiesi@4 1296 'setter callback' => 'entity_property_verbatim_set',
danielebarchiesi@4 1297 );
danielebarchiesi@4 1298 return $properties;
danielebarchiesi@4 1299 }
danielebarchiesi@4 1300
danielebarchiesi@4 1301 /**
danielebarchiesi@4 1302 * Implements hook_field_update_instance().
danielebarchiesi@4 1303 */
danielebarchiesi@4 1304 function link_field_update_instance($instance, $prior_instance) {
danielebarchiesi@4 1305 if (function_exists('i18n_string_update') && $prior_instance['settings']['title_value'] != $instance['settings']['title_value']) {
danielebarchiesi@4 1306 $i18n_string_name = "field:{$instance['field_name']}:{$instance['bundle']}:title_value";
danielebarchiesi@4 1307 i18n_string_update($i18n_string_name, $instance['settings']['title_value']);
danielebarchiesi@4 1308 }
danielebarchiesi@4 1309 }
danielebarchiesi@4 1310
danielebarchiesi@4 1311 /**
danielebarchiesi@4 1312 * Implements hook_i18n_string_list_TEXTGROUP_alter().
danielebarchiesi@4 1313 */
danielebarchiesi@4 1314 function link_i18n_string_list_field_alter(&$strings, $type = NULL, $object = NULL) {
danielebarchiesi@4 1315 if ($type == 'field_instance' && $object && $object['widget']['type'] == 'link_field') {
danielebarchiesi@4 1316 if (isset($object['settings']['title_value'])) {
danielebarchiesi@4 1317 $strings['field'][$object['field_name']][$object['bundle']]['title_value']['string'] = $object['settings']['title_value'];
danielebarchiesi@4 1318 }
danielebarchiesi@4 1319 }
danielebarchiesi@4 1320 }