From bc2bba5c742706ebef11d639c1de9f6494cf3b4d Mon Sep 17 00:00:00 2001
From: sun <sun@unleashedmind.com>
Date: Sat, 7 Jul 2012 01:32:07 +0200
Subject: [PATCH 01/13] Fixed docs and coding style to adhere to Drupal coding
 standards.

---
 link.css                                     |    5 +-
 link.devel_generate.inc                      |    1 +
 link.install                                 |   23 +--
 link.migrate.inc                             |    5 +-
 link.module                                  |  259 ++++++++++++--------------
 views/link_views_handler_argument_target.inc |    3 +-
 views/link_views_handler_filter_protocol.inc |    9 +-
 7 files changed, 141 insertions(+), 164 deletions(-)

diff --git a/link.css b/link.css
index 7bdec9e..6250df7 100644
--- a/link.css
+++ b/link.css
@@ -1,8 +1,7 @@
-div.link-field-column {
+.link-field-column {
   float: left;
   width: 48%;
 }
-
-div.link-field-column .form-text {
+.link-field-column .form-text {
   width: 95%;
 }
diff --git a/link.devel_generate.inc b/link.devel_generate.inc
index 7be4a0d..eb24c49 100644
--- a/link.devel_generate.inc
+++ b/link.devel_generate.inc
@@ -27,3 +27,4 @@ function _link_devel_generate($object, $field, $instance, $bundle) {
     'attributes' => _link_default_attributes(),
   );
 }
+
diff --git a/link.install b/link.install
index fdfc5d1..bcef6ef 100644
--- a/link.install
+++ b/link.install
@@ -18,20 +18,19 @@ function link_field_schema($field) {
     'columns' => array(
       'url' => array(
         'type' => 'varchar',
-        'length' => 2048, // Maximum URLs length.
+        // Maximum URLs length.
+        'length' => 2048,
         'not null' => FALSE,
-        'sortable' => TRUE
       ),
       'title' => array(
         'type' => 'varchar',
         'length' => 255,
         'not null' => FALSE,
-        'sortable' => TRUE
       ),
       'attributes' => array(
         'type' => 'text',
         'size' => 'medium',
-        'not null' => FALSE
+        'not null' => FALSE,
       ),
     ),
   );
@@ -48,7 +47,6 @@ function link_update_last_removed() {
  * Handles moving settings data from field_config.data to field_config_instance.data.
  */
 function link_update_7000() {
-  
   // For each field that is a link field, we need to copy the settings from the general field level down to the instance.
   //$field_data = array();
   $result = db_query("SELECT id, field_name, data FROM {field_config} WHERE module = 'link' AND type = 'link_field'");
@@ -56,7 +54,7 @@ function link_update_7000() {
     $field_id = $field->id;
     $name = $field->field_name;
     $field_data = unserialize($field->data);
-    
+
     $instances = db_query("SELECT id, data FROM {field_config_instance} WHERE field_id = :field_id", array(':field_id' => $field_id));
     foreach ($instances as $instance) {
       // If this field has been updated already, we want to skip it.
@@ -79,7 +77,7 @@ function link_update_7000() {
       }
     }
   }
-  
+
   return t("Instance settings have been set with the data from the field settings.");
 }
 
@@ -87,14 +85,13 @@ function link_update_7000() {
  * Renames all displays from foobar to link_foobar
  */
 function link_update_7001() {
-  // for each field that is a link field, we need to update the display types:
-  
+  // Update the display type for each link field type.
   $result = db_query("SELECT id, field_name, data FROM {field_config} WHERE module = 'link' AND type = 'link_field'");
   foreach ($result as $field) {
     $field_id = $field->id;
     $name = $field->field_name;
     $field_data = unserialize($field->data);
-    
+
     $instances = db_query("SELECT id, data FROM {field_config_instance} WHERE field_id = :field_id", array(':field_id' => $field_id));
     foreach ($instances as $instance) {
       // If this field has been updated already, we want to skip it.
@@ -102,13 +99,12 @@ function link_update_7001() {
       $update_instance = FALSE;
       foreach ($instance_data['display'] as $display_name => $display_data) {
         if ($display_data['type'] && (0 !== strpos($display_data['type'], 'link_'))) {
-          $instance_data['display'][$display_name]['type'] = 'link_'. $display_data['type'];
+          $instance_data['display'][$display_name]['type'] = 'link_' . $display_data['type'];
           $update_instance = TRUE;
         }
       }
       if ($update_instance) {
-        // update the database.
-        $num_updated = db_update('field_config_instance')
+        db_update('field_config_instance')
           ->fields(array('data' => serialize($instance_data)))
           ->condition('id', $instance->id)
           ->execute();
@@ -116,3 +112,4 @@ function link_update_7001() {
     }
   }
 }
+
diff --git a/link.migrate.inc b/link.migrate.inc
index e1f8ada..7ea3081 100644
--- a/link.migrate.inc
+++ b/link.migrate.inc
@@ -35,13 +35,13 @@ class MigrateLinkFieldHandler extends MigrateFieldHandler {
 
     $language = $this->getFieldLanguage($entity, $field_info, $arguments);
 
-    foreach($values as $delta => $value) {
+    foreach ($values as $delta => $value) {
       $item = array();
       if (isset($arguments['title'])) {
         if (!is_array($arguments['title'])) {
           $item['title'] = $arguments['title'];
         }
-        else if (isset($arguments['title'][$delta])) {
+        elseif (isset($arguments['title'][$delta])) {
           $item['title'] = $arguments['title'][$delta];
         }
       }
@@ -56,3 +56,4 @@ class MigrateLinkFieldHandler extends MigrateFieldHandler {
     return isset($return) ? $return : NULL;
   }
 }
+
diff --git a/link.module b/link.module
index 676811b..2b7d873 100644
--- a/link.module
+++ b/link.module
@@ -35,7 +35,7 @@ function link_field_info() {
         'url' => 0,
         'title' => 'optional',
         'title_value' => '',
-        'title_maxlength' => 128, //patch #1307788 from nmc
+        'title_maxlength' => 128,
         'enable_tokens' => 1,
         'display' => array(
           'url_cutoff' => 80,
@@ -46,7 +46,7 @@ function link_field_info() {
         'url' => 0,
         'title' => 'optional',
         'title_value' => '',
-        'title_maxlength' => 128, // patch #1307788 from nmc
+        'title_maxlength' => 128,
         'enable_tokens' => 1,
         'display' => array(
           'url_cutoff' => 80,
@@ -106,15 +106,14 @@ function link_field_instance_settings_form($field, $instance) {
     '#default_value' => isset($instance['settings']['title_value']) ? $instance['settings']['title_value'] : '',
     '#description' => t('This title will always be used if &ldquo;Static Title&rdquo; is selected above.'),
   );
-
-  $form['title_maxlength'] = array( // patch #1307788 from nmc
+  $form['title_maxlength'] = array(
     '#type' => 'textfield',
     '#title' => t('Max length of title field'),
     '#default_value' => isset($instance['settings']['title_maxlength']) ? $instance['settings']['title_maxlength'] : '128',
     '#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.'),
     '#maxlength' => 3,
     '#size' => 3,
-    );
+  );
 
   if (module_exists('token')) {
     // Add token module replacements fields
@@ -154,7 +153,7 @@ function link_field_instance_settings_form($field, $instance) {
     '#default_value' => isset($instance['settings']['display']['url_cutoff']) ? $instance['settings']['display']['url_cutoff'] : '80',
     '#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.'),
     '#maxlength' => 3,
-   '#size' => 3,
+    '#size' => 3,
   );
 
   $target_options = array(
@@ -217,29 +216,28 @@ function link_field_instance_settings_form($field, $instance) {
 }
 
 /**
- * Validate the field settings form.
+ * #element_validate handler for link_field_instance_settings_form().
  */
 function link_field_settings_form_validate($element, &$form_state, $complete_form) {
-  if ($form_state['values']['instance']['settings']['title'] === 'value'
-      && empty($form_state['values']['instance']['settings']['title_value'])) {
+  if ($form_state['values']['instance']['settings']['title'] === 'value' && empty($form_state['values']['instance']['settings']['title_value'])) {
     form_set_error('title_value', t('A default title must be provided if the title is a static value.'));
   }
-  if (!empty($form_state['values']['instance']['settings']['display']['url_cutoff'])  // patch #1307788 from nmc
-      && !is_numeric($form_state['values']['instance']['settings']['display']['url_cutoff'])) {
+  if (!empty($form_state['values']['instance']['settings']['display']['url_cutoff']) && !is_numeric($form_state['values']['instance']['settings']['display']['url_cutoff'])) {
     form_set_error('display', t('URL Display Cutoff value must be numeric.'));
   }
-  if (empty($form_state['values']['instance']['settings']['title_maxlength'])) {     // patch #1307788 from nmc
+  if (empty($form_state['values']['instance']['settings']['title_maxlength'])) {
     form_set_value($element['title_maxlength'], '128', $form_state);
-  } elseif (!is_numeric($form_state['values']['instance']['settings']['title_maxlength'])) {
+  }
+  elseif (!is_numeric($form_state['values']['instance']['settings']['title_maxlength'])) {
     form_set_error('title_maxlength', t('The max length of the link title must be numeric.'));
-  } elseif ($form_state['values']['instance']['settings']['title_maxlength'] > 255) {
+  }
+  elseif ($form_state['values']['instance']['settings']['title_maxlength'] > 255) {
     form_set_error('title_maxlength', t('The max length of the link title cannot be greater than 255 characters.'));
   }
-
 }
 
 /**
- * Implement hook_field_is_empty().
+ * Implements hook_field_is_empty().
  */
 function link_field_is_empty($item, $field) {
   return empty($item['title']) && empty($item['url']);
@@ -320,16 +318,13 @@ function link_field_widget_form(&$form, &$form_state, $field, $instance, $langco
  * Unpacks the item attributes for use.
  */
 function _link_load($field, $item, $instance) {
-  /*return $item['attributes'] = isset($item['attributes']) ?
-                                unserialize($item['attributes']) :
-                                $instance['settings']['attributes'];*/
   if (isset($item['attributes'])) {
     if (!is_array($item['attributes'])) {
       $item['attributes'] = unserialize($item['attributes']);
     }
     return $item['attributes'];
   }
-  else if (isset($instance['settings']['attributes'])) {
+  elseif (isset($instance['settings']['attributes'])) {
     return $instance['settings']['attributes'];
   }
   else {
@@ -344,7 +339,8 @@ function _link_process(&$item, $delta = 0, $field, $entity) {
   // Trim whitespace from URL.
   $item['url'] = trim($item['url']);
 
-  // if no attributes are set then make sure $item['attributes'] is an empty array - this lets $field['attributes'] override it.
+  // If no attributes are set then make sure $item['attributes'] is an empty
+  // array, so $field['attributes'] can override it.
   if (empty($item['attributes'])) {
     $item['attributes'] = array();
   }
@@ -355,14 +351,12 @@ function _link_process(&$item, $delta = 0, $field, $entity) {
   }
 
   // Don't save an invalid default value (e.g. 'http://').
-  if ((isset($field['widget']['default_value'][$delta]['url']) && $item['url'] == $field['widget']['default_value'][$delta]['url'])
-      && is_object($node)) {
+  if ((isset($field['widget']['default_value'][$delta]['url']) && $item['url'] == $field['widget']['default_value'][$delta]['url']) && is_object($node)) {
     if (!link_validate_url($item['url'])) {
       unset($item['url']);
     }
   }
 
-  // token from the patch http://drupal.org/files/link_query_fragment.patch @ Issue #1321482
   if (!empty($item['query'])) {
     $item['url'] .= '?' . http_build_query($item['query']);
   }
@@ -375,44 +369,32 @@ function _link_process(&$item, $delta = 0, $field, $entity) {
  * Validates that the link field has been entered properly.
  */
 function _link_validate(&$item, $delta, $field, $node, $instance, $langcode, &$optional_field_found) {
-  if ($item['url']
-      && !(isset($instance['default_value'][$delta]['url'])
-      && $item['url'] === $instance['default_value'][$delta]['url']
-      && !$instance['required'])) {
+  if ($item['url'] && !(isset($instance['default_value'][$delta]['url']) && $item['url'] === $instance['default_value'][$delta]['url'] && !$instance['required'])) {
     // Validate the link.
     if (link_validate_url(trim($item['url'])) == FALSE) {
-      form_set_error($field['field_name'] . '][' . $langcode . ']['. $delta .'][url', t('Not a valid URL.'));
+      form_set_error($field['field_name'] . '][' . $langcode . '][' . $delta . '][url', t('Not a valid URL.'));
     }
     // Require a title for the link if necessary.
     if ($instance['settings']['title'] == 'required' && strlen(trim($item['title'])) == 0) {
-      form_set_error($field['field_name'] . '][' . $langcode . ']['. $delta .'][title', t('Titles are required for all links.'));
+      form_set_error($field['field_name'] . '][' . $langcode . '][' . $delta . '][title', t('Titles are required for all links.'));
     }
   }
   // Require a link if we have a title.
-  if ($instance['settings']['url'] !== 'optional'
-      && strlen(isset($item['title']) ? $item['title'] : NULL) > 0
-      && strlen(trim($item['url'])) == 0) {
-    form_set_error($field['field_name'] . '][' . $langcode . ']['. $delta .'][url', t('You cannot enter a title without a link url.'));
+  if ($instance['settings']['url'] !== 'optional' && strlen(isset($item['title']) ? $item['title'] : NULL) > 0 && strlen(trim($item['url'])) == 0) {
+    form_set_error($field['field_name'] . '][' . $langcode . '][' . $delta . '][url', t('You cannot enter a title without a link url.'));
   }
   // In a totally bizzaro case, where URLs and titles are optional but the field is required, ensure there is at least one link.
-  if ($instance['settings']['url'] === 'optional'
-      && $instance['settings']['title'] === 'optional'
-      && (strlen(trim($item['url'])) !== 0 || strlen(trim($item['title'])) !== 0)) {
+  if ($instance['settings']['url'] === 'optional' && $instance['settings']['title'] === 'optional' && (strlen(trim($item['url'])) !== 0 || strlen(trim($item['title'])) !== 0)) {
     $optional_field_found = TRUE;
   }
   // Require entire field
-  if ($instance['settings']['url'] === 'optional'
-    && $instance['settings']['title'] === 'optional'
-    && $instance['required'] == 1
-    && !$optional_field_found
-    && isset($instance['id'])) {
-    form_set_error($instance['field_name'] . '][' . $langcode . '][0][title',
-                   t('At least one title or URL must be entered.'));
+  if ($instance['settings']['url'] === 'optional' && $instance['settings']['title'] === 'optional' && $instance['required'] == 1 && !$optional_field_found && isset($instance['id'])) {
+    form_set_error($instance['field_name'] . '][' . $langcode . '][0][title', t('At least one title or URL must be entered.'));
   }
 }
 
 /**
- * Cleanup user-entered values for a link field according to field settings.
+ * Clean up user-entered values for a link field according to field settings.
  *
  * @param $item
  *   A single link item, usually containing url, title, and attributes.
@@ -438,19 +420,19 @@ function _link_sanitize(&$item, $delta, &$field, $instance, &$node) {
   }
 
   $type = link_validate_url($item['url']);
-  // If we can't determine the type of url, and we've been told not to validate it,
-  // then we assume it's a LINK_EXTERNAL type for later processing. #357604
+  // If the type of the URL cannot be determined and URL validation is disabled,
+  // then assume LINK_EXTERNAL for later processing.
   if ($type == FALSE && $instance['settings']['validate_url'] === 0) {
     $type = LINK_EXTERNAL;
   }
   $url = link_cleanup_url($item['url']);
 
-  // Separate out the anchor if any.
+  // Separate out the anchor, if any.
   if (strpos($url, '#') !== FALSE) {
     $item['fragment'] = substr($url, strpos($url, '#') + 1);
     $url = substr($url, 0, strpos($url, '#'));
   }
-  // Separate out the query string if any.
+  // Separate out the query string, if any.
   if (strpos($url, '?') !== FALSE) {
     $query = substr($url, strpos($url, '?') + 1);
     parse_str($query, $query_array);
@@ -461,17 +443,18 @@ function _link_sanitize(&$item, $delta, &$field, $instance, &$node) {
   $item['url'] = check_plain($url);
 
   // Create a shortened URL for display.
-  $display_url = $type == LINK_EMAIL ?
-                  str_replace('mailto:', '', $url) :
-                  url($url, array('query' => isset($item['query']) ?
-                                              $item['query'] :
-                                              NULL,
-                                  'fragment' => isset($item['fragment']) ?
-                                                $item['fragment'] :
-                                                NULL,
-                                  'absolute' => TRUE));
+  if ($type == LINK_EMAIL) {
+    $display_url = str_replace('mailto:', '', $url);
+  }
+  else {
+    $display_url = url($url, array(
+      'query' => isset($item['query']) ? $item['query'] : NULL,
+      'fragment' => isset($item['fragment']) ? $item['fragment'] : NULL,
+      'absolute' => TRUE,
+    ));
+  }
   if ($instance['settings']['display']['url_cutoff'] && strlen($display_url) > $instance['settings']['display']['url_cutoff']) {
-    $display_url = substr($display_url, 0, $instance['settings']['display']['url_cutoff']) ."...";
+    $display_url = substr($display_url, 0, $instance['settings']['display']['url_cutoff']) . "...";
   }
   $item['display_url'] = $display_url;
 
@@ -480,7 +463,7 @@ function _link_sanitize(&$item, $delta, &$field, $instance, &$node) {
     $title = $instance['settings']['title_value'];
   }
   // Use the title defined by the user at the widget level.
-  else if (isset($item['title'])) {
+  elseif (isset($item['title'])) {
     $title = $item['title'];
   }
   else {
@@ -491,8 +474,8 @@ function _link_sanitize(&$item, $delta, &$field, $instance, &$node) {
   if ($title && ($instance['settings']['title'] == 'value' || $instance['settings']['enable_tokens'])) {
     // Load the node if necessary for nodes in views.
     $token_node = isset($node->nid) ? node_load($node->nid) : $node;
-    $title = filter_xss(token_replace($title, array('node' => $token_node)),
-                        array('b', 'br', 'code', 'em', 'i', 'img', 'span', 'strong', 'sub', 'sup', 'tt', 'u'));
+    $title = token_replace($title, array('node' => $token_node));
+    $title = filter_xss($title, array('b', 'br', 'code', 'em', 'i', 'img', 'span', 'strong', 'sub', 'sup', 'tt', 'u'));
     $item['html'] = TRUE;
   }
   $item['title'] = empty($title) ? $item['display_url'] : $title;
@@ -507,7 +490,7 @@ function _link_sanitize(&$item, $delta, &$field, $instance, &$node) {
   }
 
   // Add default attributes.
-  if (!is_array($instance['settings']['attributes'])){
+  if (!is_array($instance['settings']['attributes'])) {
     $instance['settings']['attributes'] = _link_default_attributes();
   }
   else {
@@ -534,8 +517,8 @@ function _link_sanitize(&$item, $delta, &$field, $instance, &$node) {
   // Remove rel attribute for internal or external links if selected.
   if (isset($item['attributes']['rel']) && isset($instance['settings']['rel_remove']) && $instance['settings']['rel_remove'] != 'default') {
     if (($instance['settings']['rel_remove'] != 'rel_remove_internal' && $type != LINK_INTERNAL) ||
-            ($instance['settings']['rel_remove'] != 'rel_remove_external' && $type != LINK_EXTERNAL)) {
-    unset($item['attributes']['rel']);
+      ($instance['settings']['rel_remove'] != 'rel_remove_external' && $type != LINK_EXTERNAL)) {
+      unset($item['attributes']['rel']);
     }
   }
 
@@ -543,8 +526,8 @@ function _link_sanitize(&$item, $delta, &$field, $instance, &$node) {
   if (!empty($item['attributes']['title']) && module_exists('token')) {
     // Load the node (necessary for nodes in views).
     $token_node = isset($node->nid) ? node_load($node->nid) : $node;
-    $item['attributes']['title'] = filter_xss(token_replace($item['attributes']['title'], array('node' => $token_node)),
-                        array('b', 'br', 'code', 'em', 'i', 'img', 'span', 'strong', 'sub', 'sup', 'tt', 'u'));
+    $item['attributes']['title'] = token_replace($item['attributes']['title'], array('node' => $token_node));
+    $item['attributes']['title'] = filter_xss($item['attributes']['title'], array('b', 'br', 'code', 'em', 'i', 'img', 'span', 'strong', 'sub', 'sup', 'tt', 'u'));
   }
   // Remove title attribute if it's equal to link text.
   if (isset($item['attributes']['title']) && $item['attributes']['title'] == $item['title']) {
@@ -556,14 +539,13 @@ function _link_sanitize(&$item, $delta, &$field, $instance, &$node) {
   $item['attributes'] = array_filter($item['attributes']);
 
   // Sets title to trimmed url if one exists
-  // @TODO: Do we need this?  It seems not.
+  // @todo Obsolete?
   /*if(!empty($item['display_url']) && empty($item['title'])) {
     $item['title'] = $item['display_url'];
   }
   elseif(!isset($item['title'])) {
     $item['title'] = $item['url'];
   }*/
-
 }
 
 /**
@@ -571,9 +553,6 @@ function _link_sanitize(&$item, $delta, &$field, $instance, &$node) {
  */
 function link_theme() {
   return array(
-    /*'link_field_settings' => array(
-      'variables' => array('element' => NULL),
-    ),*/
     'link_formatter_link_default' => array(
       'variables' => array('element' => NULL),
     ),
@@ -605,10 +584,10 @@ function link_theme() {
 }
 
 /**
- * FAPI theme for an individual text elements.
+ * Formats a link field widget.
  */
 function theme_link_field($vars) {
-  drupal_add_css(drupal_get_path('module', 'link') .'/link.css');
+  drupal_add_css(drupal_get_path('module', 'link') . '/link.css');
 
   $element = $vars['element'];
   // Prefix single value link fields with the name of the field.
@@ -621,15 +600,15 @@ function theme_link_field($vars) {
   $output = '';
   $output .= '<div class="link-field-subrow clearfix">';
   if (isset($element['title'])) {
-    $output .= '<div class="link-field-title link-field-column">'. drupal_render($element['title']) .'</div>';
+    $output .= '<div class="link-field-title link-field-column">' . drupal_render($element['title']) . '</div>';
   }
-  $output .= '<div class="link-field-url'. (isset($element['title']) ? ' link-field-column' : '') .'">'. drupal_render($element['url']) .'</div>';
+  $output .= '<div class="link-field-url' . (isset($element['title']) ? ' link-field-column' : '') . '">' . drupal_render($element['url']) . '</div>';
   $output .= '</div>';
   if (!empty($element['attributes']['target'])) {
-    $output .= '<div class="link-attributes">'. drupal_render($element['attributes']['target']) .'</div>';
+    $output .= '<div class="link-attributes">' . drupal_render($element['attributes']['target']) . '</div>';
   }
   if (!empty($element['attributes']['title'])) {
-    $output .= '<div class="link-attributes">'. drupal_render($element['attributes']['title']) .'</div>';
+    $output .= '<div class="link-attributes">' . drupal_render($element['attributes']['title']) . '</div>';
   }
   return $output;
 }
@@ -638,8 +617,7 @@ function theme_link_field($vars) {
  * Implements hook_element_info().
  */
 function link_element_info() {
-  $elements = array();
-  $elements['link_field'] =  array(
+  $elements['link_field'] = array(
     '#input' => TRUE,
     '#process' => array('link_field_process'),
     '#theme' => 'link_field',
@@ -657,7 +635,7 @@ function _link_default_attributes() {
 }
 
 /**
- * Process the link type element before displaying the field.
+ * Processes the link type element before displaying the field.
  *
  * Build the form element. When creating a form using FAPI #process,
  * note that $element['#value'] is already set.
@@ -677,10 +655,10 @@ function link_field_process($element, $form_state, $complete_form) {
   if ($settings['title'] !== 'none' && $settings['title'] !== 'value') {
     $element['title'] = array(
       '#type' => 'textfield',
-      '#maxlength' => $settings['title_maxlength'],  // patch #1307788 from nmc
+      '#maxlength' => $settings['title_maxlength'],
       '#title' => t('Title'),
       '#description' => t('The link title is limited to @maxlength characters maximum.', array('@maxlength' => $settings['title_maxlength'])),
-      '#required' => ($settings['title'] == 'required' && (($element['#delta'] == 0 && $element['#required']) || !empty($element['#value']['url']))) ? TRUE : FALSE, // davereids patch from jan 2011
+      '#required' => ($settings['title'] == 'required' && (($element['#delta'] == 0 && $element['#required']) || !empty($element['#value']['url']))) ? TRUE : FALSE,
       '#default_value' => isset($element['#value']['title']) ? $element['#value']['title'] : NULL,
     );
   }
@@ -722,7 +700,7 @@ function link_field_process($element, $form_state, $complete_form) {
 }
 
 /**
- * Implementation of hook_field_formatter_info().
+ * Implements hook_field_formatter_info().
  */
 function link_field_formatter_info() {
   return array(
@@ -776,21 +754,20 @@ function link_field_formatter_view($entity_type, $entity, $field, $instance, $la
   $elements = array();
   foreach ($items as $delta => $item) {
     $elements[$delta] = array(
-      '#markup' => theme('link_formatter_'. $display['type'], array('element' => $item, 'field' => $instance)),
+      '#markup' => theme('link_formatter_' . $display['type'], array('element' => $item, 'field' => $instance)),
     );
   }
   return $elements;
 }
 
 /**
- * Theme function for 'default' text field formatter.
+ * Formats a link.
  */
 function theme_link_formatter_link_default($vars) {
   $link_options = $vars['element'];
   unset($link_options['title']);
   unset($link_options['url']);
 
-  // Issue #1199806 by ss81: Fixes fatal error when the link URl is equal to page URL
   if (isset($link_options['attributes']['class'])) {
     $link_options['attributes']['class'] = array($link_options['attributes']['class']);
   }
@@ -809,7 +786,7 @@ function theme_link_formatter_link_default($vars) {
 }
 
 /**
- * Theme function for 'plain' text field formatter.
+ * Formats a link (or its title) as plain text.
  */
 function theme_link_formatter_link_plain($vars) {
   $link_options = $vars['element'];
@@ -820,13 +797,11 @@ function theme_link_formatter_link_plain($vars) {
     $vars['element']['title'] = '';
   }
   unset($link_options['url']);
-  return empty($vars['element']['url']) ?
-    check_plain($vars['element']['title']) :
-    url($vars['element']['url'], $link_options);
+  return empty($vars['element']['url']) ? check_plain($vars['element']['title']) : url($vars['element']['url'], $link_options);
 }
 
 /**
- * Theme function for 'absolute' text field formatter.
+ * Formats a link as absolute URL.
  */
 function theme_link_formatter_link_absolute($vars) {
   $absolute = array('absolute' => TRUE);
@@ -834,14 +809,14 @@ function theme_link_formatter_link_absolute($vars) {
 }
 
 /**
- * Theme function for 'title_plain' text field formatter.
+ * Formats a link's title as plain text.
  */
 function theme_link_formatter_link_title_plain($vars) {
   return empty($vars['element']['title']) ? '' : check_plain($vars['element']['title']);
 }
 
 /**
- * Theme function for 'url' text field formatter.
+ * Formats a link using an alternate display URL for its link text.
  */
 function theme_link_formatter_link_url($vars) {
   $link_options = $vars['element'];
@@ -851,7 +826,7 @@ function theme_link_formatter_link_url($vars) {
 }
 
 /**
- * Theme function for 'short' text field formatter.
+ * Formats a link using "Link" as the link text.
  */
 function theme_link_formatter_link_short($vars) {
   $link_options = $vars['element'];
@@ -861,7 +836,7 @@ function theme_link_formatter_link_short($vars) {
 }
 
 /**
- * Theme function for 'label' text field formatter.
+ * Formats a link using the field's label as link text.
  */
 function theme_link_formatter_link_label($vars) {
   $link_options = $vars['element'];
@@ -871,11 +846,10 @@ function theme_link_formatter_link_label($vars) {
 }
 
 /**
- * Theme function for 'separate' text field formatter.
+ * Formats a link as separate title and URL elements.
  */
-
 function theme_link_formatter_link_separate($vars) {
-  $class = empty($vars['element']['attributes']['class']) ? '' : ' '. $vars['element']['attributes']['class'];
+  $class = empty($vars['element']['attributes']['class']) ? '' : ' ' . $vars['element']['attributes']['class'];
   unset($vars['element']['attributes']['class']);
   $link_options = $vars['element'];
   unset($link_options['title']);
@@ -887,24 +861,20 @@ function theme_link_formatter_link_separate($vars) {
    * needs smarter output solution and an optional title/url seperator
    */
   $output = '';
-  $output .= '<div class="link-item '. $class .'">';
+  $output .= '<div class="link-item ' . $class . '">';
   if (!empty($title)) {
-    $output .= '<div class="link-title">'. $title .'</div>';
+    $output .= '<div class="link-title">' . $title . '</div>';
   }
-  $output .= '<div class="link-url">'. l($vars['element']['url'], $vars['element']['url'], $link_options) .'</div>';
+  $output .= '<div class="link-url">' . l($vars['element']['url'], $vars['element']['url'], $link_options) . '</div>';
   $output .= '</div>';
   return $output;
 }
 
-
 function link_token_list($type = 'all') {
   if ($type === 'field' || $type === 'all') {
-    $tokens = array();
-
     $tokens['link']['url'] = t("Link URL");
     $tokens['link']['title'] = t("Link title");
     $tokens['link']['view'] = t("Formatted html link");
-
     return $tokens;
   }
 }
@@ -912,11 +882,9 @@ function link_token_list($type = 'all') {
 function link_token_values($type, $object = NULL) {
   if ($type === 'field') {
     $item = $object[0];
-
     $tokens['url'] = $item['url'];
     $tokens['title'] = $item['title'];
     $tokens['view'] = isset($item['view']) ? $item['view'] : '';
-
     return $tokens;
   }
 }
@@ -927,7 +895,7 @@ function link_token_values($type, $object = NULL) {
 function link_views_api() {
   return array(
     'api' => 2,
-    'path' => drupal_get_path('module', 'link') .'/views',
+    'path' => drupal_get_path('module', 'link') . '/views',
   );
 }
 
@@ -935,17 +903,22 @@ function link_views_api() {
  * Implements hook_migrate_api().
  */
 function link_migrate_api() {
-  return array('api' => 2);
+  return array(
+    'api' => 2,
+  );
 }
 
 /**
  * Forms a valid URL if possible from an entered address.
- * Trims whitespace and automatically adds an http:// to addresses without a protocol specified
+ *
+ * Trims whitespace and automatically adds an http:// to addresses without a
+ * protocol specified.
  *
  * @param string $url
- * @param string $protocol The protocol to be prepended to the url if one is not specified
+ * @param string $protocol
+ *   The protocol to prepend to $url if none is specified.
  */
-function link_cleanup_url($url, $protocol = "http") {
+function link_cleanup_url($url, $protocol = 'http') {
   $url = trim($url);
   $type = link_validate_url($url);
 
@@ -954,9 +927,9 @@ function link_cleanup_url($url, $protocol = "http") {
     $protocol_match = preg_match("/^([a-z0-9][a-z0-9\.\-_]*:\/\/)/i", $url);
     if (empty($protocol_match)) {
       // But should there be? Add an automatic http:// if it starts with a domain name.
-      $domain_match = preg_match('/^(([a-z0-9]([a-z0-9\-_]*\.)+)('. LINK_DOMAINS .'|[a-z]{2}))/i', $url);
+      $domain_match = preg_match('/^(([a-z0-9]([a-z0-9\-_]*\.)+)(' . LINK_DOMAINS . '|[a-z]{2}))/i', $url);
       if (!empty($domain_match)) {
-        $url = $protocol ."://". $url;
+        $url = $protocol . "://" . $url;
       }
     }
   }
@@ -965,16 +938,20 @@ function link_cleanup_url($url, $protocol = "http") {
 }
 
 /**
- * A lenient verification for URLs. Accepts all URLs following RFC 1738 standard
- * for URL formation and all email addresses following the RFC 2368 standard for
- * mailto address formation.
+ * Validates a URL.
+ *
+ * Accepts all URLs following RFC 1738 standard for URL formation and all e-mail
+ * addresses following the RFC 2368 standard for mailto address formation.
  *
  * @param string $text
- * @return mixed Returns boolean FALSE if the URL is not valid. On success,
- * returns one of the LINK_(linktype) constants.
+ *
+ * @return mixed
+ *   Returns boolean FALSE if the URL is not valid. On success, returns one of
+ *   the LINK_(linktype) constants.
  */
 function link_validate_url($text) {
-  $LINK_ICHARS_DOMAIN = (string) html_entity_decode(implode("", array( // @TODO completing letters ...
+  // @todo Complete letters.
+  $LINK_ICHARS_DOMAIN = (string) html_entity_decode(implode("", array(
     "&#x00E6;", // æ
     "&#x00C6;", // Æ
     "&#x00C0;", // À
@@ -1036,34 +1013,33 @@ function link_validate_url($text) {
   $allowed_protocols = variable_get('filter_allowed_protocols', array('http', 'https', 'ftp', 'news', 'nntp', 'telnet', 'mailto', 'irc', 'ssh', 'sftp', 'webcal'));
 
   // Starting a parenthesis group with (?: means that it is grouped, but is not captured
-  $protocol = '((?:'. implode("|", $allowed_protocols) .'):\/\/)';
-  $authentication = "(?:(?:(?:[\w\.\-\+!$&'\(\)*\+,;=" . $LINK_ICHARS . "]|%[0-9a-f]{2})+(?::(?:[\w". $LINK_ICHARS ."\.\-\+%!$&'\(\)*\+,;=]|%[0-9a-f]{2})*)?)?@)";
-  $domain = '(?:(?:[a-z0-9' . $LINK_ICHARS_DOMAIN . ']([a-z0-9'. $LINK_ICHARS_DOMAIN . '\-_\[\]])*)(\.(([a-z0-9' . $LINK_ICHARS_DOMAIN . '\-_\[\]])+\.)*('. LINK_DOMAINS .'|[a-z]{2}))?)';
+  $protocol = '((?:' . implode("|", $allowed_protocols) . '):\/\/)';
+  $authentication = "(?:(?:(?:[\w\.\-\+!$&'\(\)*\+,;=" . $LINK_ICHARS . "]|%[0-9a-f]{2})+(?::(?:[\w" . $LINK_ICHARS . "\.\-\+%!$&'\(\)*\+,;=]|%[0-9a-f]{2})*)?)?@)";
+  $domain = '(?:(?:[a-z0-9' . $LINK_ICHARS_DOMAIN . ']([a-z0-9' . $LINK_ICHARS_DOMAIN . '\-_\[\]])*)(\.(([a-z0-9' . $LINK_ICHARS_DOMAIN . '\-_\[\]])+\.)*(' . LINK_DOMAINS . '|[a-z]{2}))?)';
   $ipv4 = '(?:[0-9]{1,3}(\.[0-9]{1,3}){3})';
   $ipv6 = '(?:[0-9a-fA-F]{1,4}(\:[0-9a-fA-F]{1,4}){7})';
   $port = '(?::([0-9]{1,5}))';
 
   // Pattern specific to external links.
-  $external_pattern = '/^'. $protocol .'?'. $authentication .'?('. $domain .'|'. $ipv4 .'|'. $ipv6 .' |localhost)'. $port .'?';
+  $external_pattern = '/^' . $protocol . '?' . $authentication . '?(' . $domain . '|' . $ipv4 . '|' . $ipv6 . ' |localhost)' . $port . '?';
 
   // Pattern specific to internal links.
-  $internal_pattern = "/^(?:[a-z0-9". $LINK_ICHARS ."_\-+\[\] ]+)";
-  $internal_pattern_file = "/^(?:[a-z0-9". $LINK_ICHARS ."_\-+\[\]\. \/\(\)]+)$/i";
+  $internal_pattern = "/^(?:[a-z0-9" . $LINK_ICHARS . "_\-+\[\] ]+)";
+  $internal_pattern_file = "/^(?:[a-z0-9" . $LINK_ICHARS . "_\-+\[\]\. \/\(\)]+)$/i";
 
-  $directories = "(?:\/[a-z0-9". $LINK_ICHARS ."_\-\.~+%=&,$'#!():;*@\[\]]*)*";
-  // Yes, four backslashes == a single backslash.
-  $query = "(?:\/?\?([?a-z0-9". $LINK_ICHARS ."+_|\-\.~\/\\\\%=&,$'():;*@\[\]{} ]*))";
-  $anchor = "(?:#[a-z0-9". $LINK_ICHARS ."_\-\.~+%=&,$'():;*@\[\]\/\?]*)";
+  $directories = "(?:\/[a-z0-9" . $LINK_ICHARS . "_\-\.~+%=&,$'#!():;*@\[\]]*)*";
+  $query = "(?:\/?\?([?a-z0-9" . $LINK_ICHARS . "+_|\-\.~\/\\\\%=&,$'():;*@\[\]{} ]*))";
+  $anchor = "(?:#[a-z0-9" . $LINK_ICHARS . "_\-\.~+%=&,$'():;*@\[\]\/\?]*)";
 
   // The rest of the path for a standard URL.
-  $end = $directories .'?'. $query .'?'. $anchor .'?'.'$/i';
+  $end = $directories . '?' . $query . '?' . $anchor . '?' . '$/i';
 
-  $message_id = '[^@].*@'. $domain;
+  $message_id = '[^@].*@' . $domain;
   $newsgroup_name = '(?:[0-9a-z+-]*\.)*[0-9a-z+-]*';
-  $news_pattern = '/^news:('. $newsgroup_name .'|'. $message_id .')$/i';
+  $news_pattern = '/^news:(' . $newsgroup_name . '|' . $message_id . ')$/i';
 
-  $user = '[a-zA-Z0-9'. $LINK_ICHARS .'_\-\.\+\^!#\$%&*+\/\=\?\`\|\{\}~\'\[\]]+';
-  $email_pattern = '/^mailto:'. $user .'@'.'(?:'. $domain .'|'. $ipv4 .'|'. $ipv6 .'|localhost)'. $query .'?$/';
+  $user = '[a-zA-Z0-9' . $LINK_ICHARS . '_\-\.\+\^!#\$%&*+\/\=\?\`\|\{\}~\'\[\]]+';
+  $email_pattern = '/^mailto:' . $user . '@' . '(?:' . $domain . '|' . $ipv4 . '|' . $ipv6 . '|localhost)' . $query . '?$/';
 
   if (strpos($text, '<front>') === 0) {
     return LINK_FRONT;
@@ -1092,7 +1068,7 @@ function link_validate_url($text) {
  */
 function link_content_migrate_field_alter(&$field_value, $instance_value) {
   if ($field_value['type'] == 'link') {
-    // Adjust the field type:
+    // Adjust the field type.
     $field_value['type'] = 'link_field';
     // Remove settings that are now on the instance.
     foreach (array('attributes', 'display', 'url', 'title', 'title_value', 'enable_tokens', 'validate_url') as $setting) {
@@ -1114,7 +1090,7 @@ function link_content_migrate_instance_alter(&$instance_value, $field_value) {
         $instance_value['settings'][$setting] = $field_value['settings'][$setting];
       }
     }
-    // Adjust widget type
+    // Adjust widget type.
     if ($instance_value['widget']['type'] == 'link') {
       $instance_value['widget']['type'] = 'link_field';
     }
@@ -1136,7 +1112,8 @@ function link_field_settings_form() {
 
 /**
  * Additional callback to adapt the property info of link fields.
- * @see entity_metadata_field_entity_property_info().
+ *
+ * @see entity_metadata_field_entity_property_info()
  */
 function link_field_property_info_callback(&$info, $entity_type, $field, $instance, $field_type) {
   $property = &$info[$entity_type]['bundles'][$instance['bundle']]['properties'][$field['field_name']];
@@ -1146,7 +1123,7 @@ function link_field_property_info_callback(&$info, $entity_type, $field, $instan
   $property['setter callback'] = 'entity_metadata_field_verbatim_set';
 
   // Auto-create the field item as soon as a property is set.
- $property['auto creation'] = 'link_field_item_create';
+  $property['auto creation'] = 'link_field_item_create';
 
   $property['property info'] = link_field_item_property_info();
   $property['property info']['url']['required'] = !$instance['settings']['url'];
@@ -1154,7 +1131,6 @@ function link_field_property_info_callback(&$info, $entity_type, $field, $instan
   if ($instance['settings']['title'] == 'none') {
     unset($property['property info']['title']);
   }
-
   unset($property['query callback']);
 }
 
@@ -1183,3 +1159,4 @@ function link_field_item_property_info() {
   );
   return $properties;
 }
+
diff --git a/views/link_views_handler_argument_target.inc b/views/link_views_handler_argument_target.inc
index fcd398b..33f66f8 100644
--- a/views/link_views_handler_argument_target.inc
+++ b/views/link_views_handler_argument_target.inc
@@ -144,6 +144,7 @@ class link_views_handler_argument_target extends views_handler_argument {
     $this->ensure_my_table();
     // Because attributes are stored serialized, our only option is to also
     // serialize the data we're searching for and use LIKE to find similar data.
-    $this->query->add_where(0, $this->table_alias .'.'. $this->real_field ." LIKE '%%%s%'", serialize(array('target' => $this->argument)));
+    $this->query->add_where(0, $this->table_alias . '.' . $this->real_field . " LIKE '%%%s%'", serialize(array('target' => $this->argument)));
   }
 }
+
diff --git a/views/link_views_handler_filter_protocol.inc b/views/link_views_handler_filter_protocol.inc
index f43e345..a580d4d 100644
--- a/views/link_views_handler_filter_protocol.inc
+++ b/views/link_views_handler_filter_protocol.inc
@@ -80,7 +80,7 @@ class link_views_handler_filter_protocol extends views_handler_filter_string {
     $where_conditions = array();
     foreach ($protocols as $protocol) {
       // Simple case, the URL begins with the specified protocol.
-      $condition = $field .' LIKE \''. $protocol .'%\'';
+      $condition = $field . ' LIKE \'' . $protocol . '%\'';
 
       // More complex case, no protocol specified but is automatically cleaned up
       // by link_cleanup_url(). RegEx is required for this search operation.
@@ -89,18 +89,19 @@ class link_views_handler_filter_protocol extends views_handler_filter_string {
           // PostGreSQL code has NOT been tested. Please report any problems to the link issue queue.
           // pgSQL requires all slashes to be double escaped in regular expressions.
           // See http://www.postgresql.org/docs/8.1/static/functions-matching.html#FUNCTIONS-POSIX-REGEXP
-          $condition .= ' OR '. $field .' ~* \''.'^(([a-z0-9]([a-z0-9\\-_]*\\.)+)('. LINK_DOMAINS .'|[a-z][a-z]))'.'\'';
+          $condition .= ' OR ' . $field . ' ~* \'' . '^(([a-z0-9]([a-z0-9\\-_]*\\.)+)(' . LINK_DOMAINS . '|[a-z][a-z]))' . '\'';
         }
         else {
           // mySQL requires backslashes to be double (triple?) escaped within character classes.
           // See http://dev.mysql.com/doc/refman/5.0/en/string-comparison-functions.html#operator_regexp
-          $condition .= ' OR '. $field .' REGEXP \''.'^(([a-z0-9]([a-z0-9\\\-_]*\.)+)('. LINK_DOMAINS .'|[a-z][a-z]))'.'\'';
+          $condition .= ' OR ' . $field . ' REGEXP \'' . '^(([a-z0-9]([a-z0-9\\\-_]*\.)+)(' . LINK_DOMAINS . '|[a-z][a-z]))' . '\'';
         }
       }
 
       $where_conditions[] = $condition;
     }
 
-    $this->query->add_where($this->options['group'], implode(' '. $this->operator .' ', $where_conditions));
+    $this->query->add_where($this->options['group'], implode(' ' . $this->operator . ' ', $where_conditions));
   }
 }
+
-- 
1.7.6.msysgit.0


From 61dd4293049eefee36786450d3d9a960b3eafe16 Mon Sep 17 00:00:00 2001
From: aris8194 <aris8194@1112010.no-reply.drupal.org>
Date: Sat, 7 Jul 2012 02:46:06 +0200
Subject: [PATCH 02/13] - #1309658 by aris8194: Fixed Fragment and query
 string disappear from tokens.

---
 link.module |    3 +--
 1 files changed, 1 insertions(+), 2 deletions(-)

diff --git a/link.module b/link.module
index 2b7d873..aab6fa0 100644
--- a/link.module
+++ b/link.module
@@ -426,6 +426,7 @@ function _link_sanitize(&$item, $delta, &$field, $instance, &$node) {
     $type = LINK_EXTERNAL;
   }
   $url = link_cleanup_url($item['url']);
+  $item['url'] = check_plain($url);
 
   // Separate out the anchor, if any.
   if (strpos($url, '#') !== FALSE) {
@@ -440,8 +441,6 @@ function _link_sanitize(&$item, $delta, &$field, $instance, &$node) {
     $url = substr($url, 0, strpos($url, '?'));
   }
 
-  $item['url'] = check_plain($url);
-
   // Create a shortened URL for display.
   if ($type == LINK_EMAIL) {
     $display_url = str_replace('mailto:', '', $url);
-- 
1.7.6.msysgit.0


From b99aa3feb7942ac0228a112a0d33975362596e8e Mon Sep 17 00:00:00 2001
From: sun <sun@unleashedmind.com>
Date: Sat, 7 Jul 2012 03:32:57 +0200
Subject: [PATCH 03/13] Cleaned up tests.

---
 tests/link.attribute.test    |  200 ++++++++++++++++--------------------------
 tests/link.crud.test         |    6 +-
 tests/link.crud_browser.test |  123 ++------------------------
 tests/link.test              |   19 ++---
 tests/link.token.test        |    7 +-
 tests/link.validate.test     |   19 ++---
 6 files changed, 99 insertions(+), 275 deletions(-)

diff --git a/tests/link.attribute.test b/tests/link.attribute.test
index 398713a..5780e28 100644
--- a/tests/link.attribute.test
+++ b/tests/link.attribute.test
@@ -6,10 +6,9 @@
  */
 
 class LinkAttributeCrudTest extends DrupalWebTestCase {
-
   private $zebra;
 
-  public $permissions = array(
+  protected $permissions = array(
     'access content',
     'administer content types',
     'administer nodes',
@@ -29,15 +28,15 @@ class LinkAttributeCrudTest extends DrupalWebTestCase {
   }
 
   function setup() {
+    parent::setup('field_ui', 'link');
     $this->zebra = 0;
-    parent::setup('field_ui', 'link'); // was 'views'
-    //$this->loginWithPermissions($this->permissions);
+
     // Create and login user.
     $account = $this->drupalCreateUser(array('administer content types'));
     $this->drupalLogin($account);
   }
 
-  function createLink($url, $title, $attributes = array()) {
+  protected function createLink($url, $title, $attributes = array()) {
     return array(
       'url' => $url,
       'title' => $title,
@@ -45,7 +44,7 @@ class LinkAttributeCrudTest extends DrupalWebTestCase {
     );
   }
 
-  private function assertLinkOnNode($field_name, $link_value, $message = '', $group = 'Other') {
+  protected function assertLinkOnNode($field_name, $link_value, $message = '', $group = 'Other') {
     $this->zebra++;
     $zebra_string = ($this->zebra % 2 == 0) ? 'even' : 'odd';
     $cssFieldLocator = 'field-'. str_replace('_', '-', $field_name);
@@ -59,9 +58,6 @@ class LinkAttributeCrudTest extends DrupalWebTestCase {
    * that the node is being displayed.
    */
   function testBasic() {
-    /*$this->acquireContentTypes(1);
-    variable_set('node_options_'. $this->content_types[0]->name, array('status', 'promote'));*/
-
     $content_type_friendly = $this->randomName(20);
     $content_type_machine = strtolower($this->randomName(10));
     $title = $this->randomName(20);
@@ -129,33 +125,9 @@ class LinkAttributeCrudTest extends DrupalWebTestCase {
     $this->drupalPost(NULL, $edit, t('Save'));
     $this->assertText(t('@content_type_friendly @title has been created', array('@content_type_friendly' => $content_type_friendly, '@title' => $title)));
 
-    /*$field_settings = array(
-      'type' => 'link',
-      'widget_type' => 'link',
-      'type_name' => $this->content_types[0]->name,
-      'attributes' => array(), // <-- This is needed or we have an error.
-    );
-
-    $field = $this->createField($field_settings, 0);
-    //$this->pass('<pre>'. print_r($field, TRUE) .'</pre>');
-    $field_db_info = content_database_info($field);*/
-
-    //$this->acquireNodes(2);
-    /*$node = $this->drupalCreateNode(array('type' => $content_type_machine,
-                                          'promote' => 1));
-    $test_nid = $node->nid;*/
-
-    //$node = node_load($this->nodes[0]->nid);
-    //$node->promote = 1; // We want this to show on front page for the teaser test.
-    /*$this->assert('debug', print_r($node, TRUE), 'Debug');
-    $node->{$single_field_name}['und'][0] = $this->createLink('http://www.example.com', 'Test Link');
-    node_save($node);
-    $this->assert('debug', print_r($node, TRUE), 'Debug');*/
-
-    //$this->drupalGet('node/'. $test_nid .'/edit');
     $this->drupalGet('node/add/'. $content_type_machine);
 
-    // lets add a node:
+    // Create a node.
     $edit = array(
       'title' => $title,
       'field_' . $single_field_name_machine . '[und][0][url]' => 'http://www.example.com/',
@@ -171,21 +143,7 @@ class LinkAttributeCrudTest extends DrupalWebTestCase {
     $this->assertLinkByHref('http://www.example.com');
   }
 
-  private function createNodeType($content_type_machine, $content_type_friendly) {
-    $this->drupalGet('admin/structure/types');
-
-    // Create the content type.
-    $this->clickLink(t('Add content type'));
-
-    $edit = array (
-      'name' => $content_type_friendly,
-      'type' => $content_type_machine,
-    );
-    $this->drupalPost(NULL, $edit, t('Save and add fields'));
-    $this->assertText(t('The content type @name has been added.', array('@name' => $content_type_friendly)));
-  }
-
-  private function createSimpleLinkField($single_field_name_machine, $single_field_name_friendly, $content_type_machine) {
+  protected function createSimpleLinkField($single_field_name_machine, $single_field_name_friendly, $content_type_machine) {
     $edit = array (
       'fields[_add_new_field][label]' => $single_field_name_friendly,
       'fields[_add_new_field][field_name]' => $single_field_name_machine,
@@ -209,7 +167,7 @@ class LinkAttributeCrudTest extends DrupalWebTestCase {
     $this->assertTrue($type_exists, 'The new content type has been created in the database.');
   }
 
-  function createNodeTypeUser($content_type_machine) {
+  protected function createNodeTypeUser($content_type_machine) {
     $permission = 'create ' . $content_type_machine . ' content';
     $permission_edit = 'edit ' . $content_type_machine . ' content';
     // Reset the permissions cache.
@@ -222,8 +180,7 @@ class LinkAttributeCrudTest extends DrupalWebTestCase {
     $this->drupalLogin($account);
   }
 
-  function createNodeForTesting($content_type_machine, $content_type_friendly, $single_field_name_machine, $title, $url, $node_title = '') {
-    // Go to page.
+  protected function createNodeForTesting($content_type_machine, $content_type_friendly, $single_field_name_machine, $title, $url, $node_title = '') {
     $this->drupalGet('node/add/'. $content_type_machine);
 
     if (!$node_title) {
@@ -248,8 +205,10 @@ class LinkAttributeCrudTest extends DrupalWebTestCase {
   function testFormatterPlain() {
     $content_type_friendly = $this->randomName(20);
     $content_type_machine = strtolower($this->randomName(10));
-
-    $this->createNodeType($content_type_machine, $content_type_friendly);
+    $this->drupalCreateContentType(array(
+      'type' => $content_type_machine,
+      'name' => $content_type_friendly,
+    ));
 
     // Now add a singleton field.
     $single_field_name_friendly = $this->randomName(20);
@@ -279,8 +238,10 @@ class LinkAttributeCrudTest extends DrupalWebTestCase {
   function testFormatterPlainWithQuerystring() {
     $content_type_friendly = $this->randomName(20);
     $content_type_machine = strtolower($this->randomName(10));
-
-    $this->createNodeType($content_type_machine, $content_type_friendly);
+    $this->drupalCreateContentType(array(
+      'type' => $content_type_machine,
+      'name' => $content_type_friendly,
+    ));
 
     // Now add a singleton field.
     $single_field_name_friendly = $this->randomName(20);
@@ -310,8 +271,10 @@ class LinkAttributeCrudTest extends DrupalWebTestCase {
   function testFormatterPlainWithFragment() {
     $content_type_friendly = $this->randomName(20);
     $content_type_machine = strtolower($this->randomName(10));
-
-    $this->createNodeType($content_type_machine, $content_type_friendly);
+    $this->drupalCreateContentType(array(
+      'type' => $content_type_machine,
+      'name' => $content_type_friendly,
+    ));
 
     // Now add a singleton field.
     $single_field_name_friendly = $this->randomName(20);
@@ -341,8 +304,10 @@ class LinkAttributeCrudTest extends DrupalWebTestCase {
   function testFormatterURL() {
     $content_type_friendly = $this->randomName(20);
     $content_type_machine = strtolower($this->randomName(10));
-
-    $this->createNodeType($content_type_machine, $content_type_friendly);
+    $this->drupalCreateContentType(array(
+      'type' => $content_type_machine,
+      'name' => $content_type_friendly,
+    ));
 
     // Now add a singleton field.
     $single_field_name_friendly = $this->randomName(20);
@@ -371,8 +336,10 @@ class LinkAttributeCrudTest extends DrupalWebTestCase {
   function testFormatterURLWithQuerystring() {
     $content_type_friendly = $this->randomName(20);
     $content_type_machine = strtolower($this->randomName(10));
-
-    $this->createNodeType($content_type_machine, $content_type_friendly);
+    $this->drupalCreateContentType(array(
+      'type' => $content_type_machine,
+      'name' => $content_type_friendly,
+    ));
 
     // Now add a singleton field.
     $single_field_name_friendly = $this->randomName(20);
@@ -401,8 +368,10 @@ class LinkAttributeCrudTest extends DrupalWebTestCase {
   function testFormatterURLWithAnchor() {
     $content_type_friendly = $this->randomName(20);
     $content_type_machine = strtolower($this->randomName(10));
-
-    $this->createNodeType($content_type_machine, $content_type_friendly);
+    $this->drupalCreateContentType(array(
+      'type' => $content_type_machine,
+      'name' => $content_type_friendly,
+    ));
 
     // Now add a singleton field.
     $single_field_name_friendly = $this->randomName(20);
@@ -431,8 +400,10 @@ class LinkAttributeCrudTest extends DrupalWebTestCase {
   function testFormatterShort() {
     $content_type_friendly = $this->randomName(20);
     $content_type_machine = strtolower($this->randomName(10));
-
-    $this->createNodeType($content_type_machine, $content_type_friendly);
+    $this->drupalCreateContentType(array(
+      'type' => $content_type_machine,
+      'name' => $content_type_friendly,
+    ));
 
     // Now add a singleton field.
     $single_field_name_friendly = $this->randomName(20);
@@ -462,8 +433,10 @@ class LinkAttributeCrudTest extends DrupalWebTestCase {
   function testFormatterShortWithQuerystring() {
     $content_type_friendly = $this->randomName(20);
     $content_type_machine = strtolower($this->randomName(10));
-
-    $this->createNodeType($content_type_machine, $content_type_friendly);
+    $this->drupalCreateContentType(array(
+      'type' => $content_type_machine,
+      'name' => $content_type_friendly,
+    ));
 
     // Now add a singleton field.
     $single_field_name_friendly = $this->randomName(20);
@@ -493,8 +466,10 @@ class LinkAttributeCrudTest extends DrupalWebTestCase {
   function testFormatterShortWithFragment() {
     $content_type_friendly = $this->randomName(20);
     $content_type_machine = strtolower($this->randomName(10));
-
-    $this->createNodeType($content_type_machine, $content_type_friendly);
+    $this->drupalCreateContentType(array(
+      'type' => $content_type_machine,
+      'name' => $content_type_friendly,
+    ));
 
     // Now add a singleton field.
     $single_field_name_friendly = $this->randomName(20);
@@ -524,8 +499,10 @@ class LinkAttributeCrudTest extends DrupalWebTestCase {
   function testFormatterLabel() {
     $content_type_friendly = $this->randomName(20);
     $content_type_machine = strtolower($this->randomName(10));
-
-    $this->createNodeType($content_type_machine, $content_type_friendly);
+    $this->drupalCreateContentType(array(
+      'type' => $content_type_machine,
+      'name' => $content_type_friendly,
+    ));
 
     // Now add a singleton field.
     $single_field_name_friendly = $this->randomName(20);
@@ -555,8 +532,10 @@ class LinkAttributeCrudTest extends DrupalWebTestCase {
   function testFormatterLabelWithQuerystring() {
     $content_type_friendly = $this->randomName(20);
     $content_type_machine = strtolower($this->randomName(10));
-
-    $this->createNodeType($content_type_machine, $content_type_friendly);
+    $this->drupalCreateContentType(array(
+      'type' => $content_type_machine,
+      'name' => $content_type_friendly,
+    ));
 
     // Now add a singleton field.
     $single_field_name_friendly = $this->randomName(20);
@@ -586,8 +565,10 @@ class LinkAttributeCrudTest extends DrupalWebTestCase {
   function testFormatterLabelWithFragment() {
     $content_type_friendly = $this->randomName(20);
     $content_type_machine = strtolower($this->randomName(10));
-
-    $this->createNodeType($content_type_machine, $content_type_friendly);
+    $this->drupalCreateContentType(array(
+      'type' => $content_type_machine,
+      'name' => $content_type_friendly,
+    ));
 
     // Now add a singleton field.
     $single_field_name_friendly = $this->randomName(20);
@@ -617,8 +598,10 @@ class LinkAttributeCrudTest extends DrupalWebTestCase {
   function testFormatterSeparate() {
     $content_type_friendly = $this->randomName(20);
     $content_type_machine = strtolower($this->randomName(10));
-
-    $this->createNodeType($content_type_machine, $content_type_friendly);
+    $this->drupalCreateContentType(array(
+      'type' => $content_type_machine,
+      'name' => $content_type_friendly,
+    ));
 
     // Now add a singleton field.
     $single_field_name_friendly = $this->randomName(20);
@@ -648,8 +631,10 @@ class LinkAttributeCrudTest extends DrupalWebTestCase {
   function testFormatterSeparateWithQuerystring() {
     $content_type_friendly = $this->randomName(20);
     $content_type_machine = strtolower($this->randomName(10));
-
-    $this->createNodeType($content_type_machine, $content_type_friendly);
+    $this->drupalCreateContentType(array(
+      'type' => $content_type_machine,
+      'name' => $content_type_friendly,
+    ));
 
     // Now add a singleton field.
     $single_field_name_friendly = $this->randomName(20);
@@ -679,8 +664,10 @@ class LinkAttributeCrudTest extends DrupalWebTestCase {
   function testFormatterSeparateWithFragment() {
     $content_type_friendly = $this->randomName(20);
     $content_type_machine = strtolower($this->randomName(10));
-
-    $this->createNodeType($content_type_machine, $content_type_friendly);
+    $this->drupalCreateContentType(array(
+      'type' => $content_type_machine,
+      'name' => $content_type_friendly,
+    ));
 
     // Now add a singleton field.
     $single_field_name_friendly = $this->randomName(20);
@@ -710,9 +697,11 @@ class LinkAttributeCrudTest extends DrupalWebTestCase {
   function testFormatterPlainTitle() {
     $content_type_friendly = $this->randomName(20);
     $content_type_machine = strtolower($this->randomName(10));
-    
-    $this->createNodeType($content_type_machine, $content_type_friendly);
-    
+    $this->drupalCreateContentType(array(
+      'type' => $content_type_machine,
+      'name' => $content_type_friendly,
+    ));
+
     // Now add a singleton field.
     $single_field_name_friendly = $this->randomName(20);
     $single_field_name_machine = strtolower($this->randomName(10));
@@ -737,45 +726,4 @@ class LinkAttributeCrudTest extends DrupalWebTestCase {
     $this->assertNoText($link_url);
     $this->assertNoLinkByHref($link_url);
   }
-
-  /**
-   * This test sees that we can create a link field with a defined class, and make sure
-   * that class displays properly when the link is displayed.
-   */
-  /*function testLinkWithClassOnField() {
-    $this->acquireContentTypes(1);
-    $field_settings = array(
-      'type' => 'link',
-      'widget_type' => 'link',
-      'type_name' => $this->content_types[0]->name,
-      'attributes' => array(
-        'class' => 'test-class',
-        'target' => 'default',
-        'rel' => FALSE,
-      ),
-    );
-
-    $field = $this->createField($field_settings, 0);
-    //$this->pass('<pre>'. print_r($field, TRUE) .'</pre>');
-    $field_db_info = content_database_info($field);
-
-    $this->acquireNodes(2);
-
-    $node = node_load($this->nodes[0]->nid);
-    $node->promote = 1; // We want this to show on front page for the teaser test.
-    $node->{$field['field_name']}[0] = $this->createLink('http://www.example.com', 'Test Link');
-    node_save($node);
-
-    // Does this display on the node page?
-    $this->drupalGet('node/'. $this->nodes[0]->nid);
-    //$this->outputScreenContents('Link field with class', 'link_');
-    $this->assertLinkOnNode($field['field_name'], l('Test Link', 'http://www.example.com', array('attributes' => array('class' => 'test-class'))));
-
-    // Does this display on the front page?
-    $this->drupalGet('<front>');
-    // reset the zebra!
-    $this->zebra = 0;
-    $this->assertLinkOnNode($field['field_name'], l('Test Link', 'http://www.example.com', array('attributes' => array('class' => 'test-class'))));
-  }*/
-
 }
diff --git a/tests/link.crud.test b/tests/link.crud.test
index cdd7fc5..87cccb9 100644
--- a/tests/link.crud.test
+++ b/tests/link.crud.test
@@ -6,7 +6,6 @@
  */
 
 class LinkContentCrudTest extends DrupalWebTestCase {
-
   public static function getInfo() {
     return array(
       'name' => 'Link CRUD - Basic API tests',
@@ -16,8 +15,7 @@ class LinkContentCrudTest extends DrupalWebTestCase {
   }
 
   function setUp() {
-    parent::setUp('field_ui', 'link'); // was views?
-    //$this->loginWithPermissions();
+    parent::setUp('field_ui', 'link');
   }
 
   /**
@@ -38,7 +36,6 @@ class LinkContentCrudTest extends DrupalWebTestCase {
     // Create the content type.
     $this->clickLink(t('Add content type'));
 
-
     $edit = array (
       'name' => $content_type_friendly,
       'type' => $content_type_machine,
@@ -55,7 +52,6 @@ class LinkContentCrudTest extends DrupalWebTestCase {
       'fields[_add_new_field][field_name]' => $single_field_name_machine,
       'fields[_add_new_field][type]' => 'link_field',
       'fields[_add_new_field][widget_type]' => 'link_field',
-
     );
     $this->drupalPost(NULL, $edit, t('Save'));
 
diff --git a/tests/link.crud_browser.test b/tests/link.crud_browser.test
index 7b01da0..32a2070 100644
--- a/tests/link.crud_browser.test
+++ b/tests/link.crud_browser.test
@@ -42,12 +42,14 @@ class LinkUITest extends DrupalWebTestcase {
    */
   function testLinkCreate() {
     //libxml_use_internal_errors(true);
-    $account = $this->drupalCreateUser(array('administer content types',
-                                             'administer nodes',
-                                             'administer filters',
-                                             'access content',
-                                             'create page content',
-                                             'access administration pages'));
+    $account = $this->drupalCreateUser(array(
+      'administer content types',
+      'administer nodes',
+      'administer filters',
+      'access content',
+      'create page content',
+      'access administration pages',
+    ));
     $this->drupalLogin($account);
 
     // create field
@@ -168,115 +170,6 @@ class LinkUITest extends DrupalWebTestcase {
   }
 
   /**
-   * Creates a link field for the "page" type and creates a page with a link.
-   * Just like the above test, only here we're turning off the validation on the field.
-   */
-  /*function testLinkCreate_NoValidation() {
-    //libxml_use_internal_errors(true);
-    $account = $this->drupalCreateUser(array('administer content types', 'access content', 'create page content'));
-    $this->drupalLogin($account);
-
-    // create field
-    $name = strtolower($this->randomName());
-    $edit = array(
-      'fields[_add_new_field][label]' => $name,
-      'fields[_add_new_field][field_name]' => $name,
-      'fields[_add_new_field][type]' => 'link_field',
-      'fields[_add_new_field][widget_type]' => 'link_field',
-    );
-    $this->drupalPost('admin/structure/types/manage/page/fields', $edit, t('Save'));
-    $this->drupalPost(NULL, array(), t('Save field settings'));
-    $this->drupalPost(NULL, array('validate_url' => FALSE), t('Save settings'));
-
-    // Is field created?
-    $this->assertRaw(t('Saved %label configuration', array('%label' => $name)), 'Field added');
-    _content_type_info(TRUE);
-    $fields = content_fields();
-    $this->assertTRUE(0 === $fields['field_'. $name]['validate_url'], 'Make sure validation is off.');
-
-    // create page form
-    $this->drupalGet('node/add/page');
-    $field_name = 'field_' . $name;
-    $this->assertField($field_name . '[0][title]', 'Title found');
-    $this->assertField($field_name . '[0][url]', 'URL found');
-
-    $input_test_cases = array(
-      array(
-        'href' => 'http://example.com/' . $this->randomName(),
-        'label' => $this->randomName(),
-        'msg' => 'Link found',
-        'type' => self::LINK_INPUT_TYPE_GOOD
-      ),
-      array(
-        'href' => 'http://example.com/' . $this->randomName(),
-        'label' => $this->randomName() . '<script>alert("hi");</script>',
-        'msg' => 'js label',
-        'type' => self::LINK_INPUT_TYPE_BAD_TITLE
-      ),
-      array(
-        'href' => 'http://example.com/' . $this->randomName(),
-        'label' => $this->randomName() . '<script src="http://devil.site.com"></script>',
-        'msg' => 'js label',
-        'type' => self::LINK_INPUT_TYPE_BAD_TITLE
-      ),
-      array(
-        'href' => 'http://example.com/' . $this->randomName(),
-        'label' => $this->randomName() . '" onmouseover="alert(\'hi\')',
-        'msg' => 'js label',
-        'type' => self::LINK_INPUT_TYPE_BAD_TITLE
-      ),
-       array(
-        'href' => 'http://example.com/' . $this->randomName(),
-        'label' => $this->randomName() . '\' onmouseover="alert(\'hi\')',
-        'msg' => 'js label',
-        'type' => self::LINK_INPUT_TYPE_BAD_TITLE
-      ),
-     array(
-        'href' => 'javascript:alert("http://example.com/' . $this->randomName() . '")',
-        'label' => $this->randomName(),
-        'msg' => 'js url',
-        'type' => self::LINK_INPUT_TYPE_BAD_URL
-      ),
-    );
-    foreach ($input_test_cases as $input) {
-      $this->drupalLogin($account);
-      $this->drupalGet('node/add/page');
-
-      $edit = array(
-        'title' => $input['label'],
-        $field_name . '[0][title]' => $input['label'],
-        $field_name . '[0][url]' => $input['href'],
-      );
-      $this->drupalPost(NULL, $edit, t('Save'));
-      if ($input['type'] == self::LINK_INPUT_TYPE_BAD_URL) {
-        //$this->assertRaw(t('Not a valid URL.'), 'Not a valid URL: ' . $input['href']);
-        $this->assertNoRaw($input['href']);
-        $this->assertRaw(t('@type %title has been created.', array('@type' => 'Basic Page', '%title' => $edit['title'])), 'Page created: ' . $input['href']);
-        continue;
-      }
-      else {
-        $this->assertRaw(t('@type %title has been created.', array('@type' => 'Basic Page', '%title' => $edit['title'])), 'Page created: ' . $input['href']);
-      }
-      $url = $this->getUrl();
-
-      // change to anonym user
-      $this->drupalLogout();
-
-      $this->drupalGet($url);
-      //debug($this);
-      // If simpletest starts using something to override the error system, this will flag
-      // us and let us know it's broken.
-      $this->assertFalse(libxml_use_internal_errors(TRUE));
-      $path = '//a[@href="'. $input['href'] .'" and text()="'. $input['label'] .'"]';
-      //$this->pass(htmlentities($path));
-      $elements = $this->xpath($path);
-      libxml_use_internal_errors(FALSE);
-      $this->assertIdentical(isset($elements[0]), $input['type'] == self::LINK_INPUT_TYPE_GOOD, $input['msg']);
-    }
-    //libxml_use_internal_errors(FALSE);
-  }*/
-
-  /**
    * Testing that if you use <strong> in a static title for your link, that the
    * title actually displays <strong>.
    */
diff --git a/tests/link.test b/tests/link.test
index dfb4dda..ed3e56b 100644
--- a/tests/link.test
+++ b/tests/link.test
@@ -6,7 +6,7 @@
  */
 
 class LinkBaseTestClass extends DrupalWebTestCase {
-  public $permissions = array(
+  protected $permissions = array(
     'access content',
     'administer content types',
     'administer nodes',
@@ -17,21 +17,18 @@ class LinkBaseTestClass extends DrupalWebTestCase {
     'create page content',
   );
 
-  public $account;
+  function setUp() {
+    $modules = func_get_args();
+    $modules = (isset($modules[0]) && is_array($modules[0]) ? $modules[0] : $modules);
+    $modules[] = 'field_ui';
+    $modules[] = 'link';
+    parent::setUp($modules);
 
-  function setUp($modules = array()) {
-    if ($modules) {
-      parent::setUp($modules);
-    }
-    else {
-      parent::setUp('field_ui', 'link');
-    }
     $this->account = $this->drupalCreateUser($this->permissions);
     $this->drupalLogin($this->account);
   }
 
-  function createLinkField($node_type = 'page',
-                           $settings = array()) {
+  protected function createLinkField($node_type = 'page', $settings = array()) {
     $name = strtolower($this->randomName());
     $edit = array(
       'fields[_add_new_field][label]' => $name,
diff --git a/tests/link.token.test b/tests/link.token.test
index d23f46a..6e5bbf6 100644
--- a/tests/link.token.test
+++ b/tests/link.token.test
@@ -19,11 +19,8 @@ class LinkTokenTest extends LinkBaseTestClass {
     );
   }
 
-  function setUp($modules = array()) {
-    $modules[] = 'field_ui';
-    $modules[] = 'link';
-    $modules[] = 'token';
-    parent::setUp($modules);
+  function setUp() {
+    parent::setUp(array('token'));
   }
 
   /**
diff --git a/tests/link.validate.test b/tests/link.validate.test
index 7f18ef8..4f42333 100644
--- a/tests/link.validate.test
+++ b/tests/link.validate.test
@@ -7,11 +7,7 @@
 
 class LinkValidateTestCase extends LinkBaseTestClass {
 
-  function setUp($modules = array()) {
-    parent::setUp($modules);
-  }
-
-  function createLink($url, $title, $attributes = array()) {
+  protected function createLink($url, $title, $attributes = array()) {
     return array(
       'url' => $url,
       'title' => $title,
@@ -22,7 +18,7 @@ class LinkValidateTestCase extends LinkBaseTestClass {
   /**
    * Takes a url, and sees if it can validate that the url is valid.
    */
-  public function link_test_validate_url($url) {
+  protected function link_test_validate_url($url) {
 
     $field_name = $this->createLinkField();
 
@@ -360,13 +356,6 @@ class LinkValidateSpecificURL extends LinkValidateTestCase {
  * Validation is guided by the rules in http://tools.ietf.org/html/rfc1738 !
  */
 class LinkValidateUrlLight extends DrupalWebTestCase {
-
-  function setUp() {
-    parent::setUp();
-    // Load the module file instead of enabling it to save time.
-    module_load_include('module', 'link');
-  }
-
   public static function getInfo() {
     return array(
       'name' => 'Link Light Validation Tests',
@@ -375,6 +364,10 @@ class LinkValidateUrlLight extends DrupalWebTestCase {
     );
   }
 
+  function setUp() {
+    parent::setUp(array('link'));
+  }
+
   /**
    * Translates the LINK type constants to english for display and debugging of tests
    */
-- 
1.7.6.msysgit.0


From 0812453fdb1f131b9e4e83a5479cf3029e3d37e7 Mon Sep 17 00:00:00 2001
From: sun <sun@unleashedmind.com>
Date: Sat, 7 Jul 2012 03:38:45 +0200
Subject: [PATCH 04/13] Fixed $account should be $this->web_user in tests.

---
 tests/link.attribute.test    |   12 ++++----
 tests/link.crud.test         |    4 +-
 tests/link.crud_browser.test |   14 ++++----
 tests/link.test              |    4 +-
 tests/link.token.test        |   24 ++++++++--------
 tests/link.validate.test     |   64 +++++++++++++++++++++++------------------
 6 files changed, 65 insertions(+), 57 deletions(-)

diff --git a/tests/link.attribute.test b/tests/link.attribute.test
index 5780e28..fa3bfac 100644
--- a/tests/link.attribute.test
+++ b/tests/link.attribute.test
@@ -32,8 +32,8 @@ class LinkAttributeCrudTest extends DrupalWebTestCase {
     $this->zebra = 0;
 
     // Create and login user.
-    $account = $this->drupalCreateUser(array('administer content types'));
-    $this->drupalLogin($account);
+    $this->web_user = $this->drupalCreateUser(array('administer content types'));
+    $this->drupalLogin($this->web_user);
   }
 
   protected function createLink($url, $title, $attributes = array()) {
@@ -109,8 +109,8 @@ class LinkAttributeCrudTest extends DrupalWebTestCase {
     // Now that we have a new content type, create a user that has privileges
     // on the content type.
     $permissions = array_merge($this->permissions, array($permission));
-    $account = $this->drupalCreateUser($permissions);
-    $this->drupalLogin($account);
+    $this->web_user = $this->drupalCreateUser($permissions);
+    $this->drupalLogin($this->web_user);
 
     // Go to page.
     $this->drupalGet('node/add/'. $content_type_machine);
@@ -176,8 +176,8 @@ class LinkAttributeCrudTest extends DrupalWebTestCase {
     // Now that we have a new content type, create a user that has privileges
     // on the content type.
     $permissions = array_merge($this->permissions, array($permission));
-    $account = $this->drupalCreateUser($permissions);
-    $this->drupalLogin($account);
+    $this->web_user = $this->drupalCreateUser($permissions);
+    $this->drupalLogin($this->web_user);
   }
 
   protected function createNodeForTesting($content_type_machine, $content_type_friendly, $single_field_name_machine, $title, $url, $node_title = '') {
diff --git a/tests/link.crud.test b/tests/link.crud.test
index 87cccb9..e1e25db 100644
--- a/tests/link.crud.test
+++ b/tests/link.crud.test
@@ -28,8 +28,8 @@ class LinkContentCrudTest extends DrupalWebTestCase {
     $title = $this->randomName(20);
 
     // Create and login user.
-    $account = $this->drupalCreateUser(array('administer content types'));
-    $this->drupalLogin($account);
+    $this->web_user = $this->drupalCreateUser(array('administer content types'));
+    $this->drupalLogin($this->web_user);
 
     $this->drupalGet('admin/structure/types');
 
diff --git a/tests/link.crud_browser.test b/tests/link.crud_browser.test
index 32a2070..f9952cd 100644
--- a/tests/link.crud_browser.test
+++ b/tests/link.crud_browser.test
@@ -42,7 +42,7 @@ class LinkUITest extends DrupalWebTestcase {
    */
   function testLinkCreate() {
     //libxml_use_internal_errors(true);
-    $account = $this->drupalCreateUser(array(
+    $this->web_user = $this->drupalCreateUser(array(
       'administer content types',
       'administer nodes',
       'administer filters',
@@ -50,7 +50,7 @@ class LinkUITest extends DrupalWebTestcase {
       'create page content',
       'access administration pages',
     ));
-    $this->drupalLogin($account);
+    $this->drupalLogin($this->web_user);
 
     // create field
     $name = strtolower($this->randomName());
@@ -127,7 +127,7 @@ class LinkUITest extends DrupalWebTestcase {
     $input_test_cases[] = $test_case;
 
     foreach ($input_test_cases as $input) {
-      $this->drupalLogin($account);
+      $this->drupalLogin($this->web_user);
       $this->drupalGet('node/add/page');
 
       $edit = array(
@@ -174,8 +174,8 @@ class LinkUITest extends DrupalWebTestcase {
    * title actually displays <strong>.
    */
   function testStaticLinkCreate() {
-    $account = $this->drupalCreateUser(array('administer content types', 'access content', 'create page content'));
-    $this->drupalLogin($account);
+    $this->web_user = $this->drupalCreateUser(array('administer content types', 'access content', 'create page content'));
+    $this->drupalLogin($this->web_user);
 
     // create field
     $name = strtolower($this->randomName());
@@ -223,8 +223,8 @@ class LinkUITest extends DrupalWebTestcase {
    * sure they are set to the expected results.
    */
   function testCRUDCreateFieldDefaults() {
-    $account = $this->drupalCreateUser(array('administer content types', 'access content', 'create page content'));
-    $this->drupalLogin($account);
+    $this->web_user = $this->drupalCreateUser(array('administer content types', 'access content', 'create page content'));
+    $this->drupalLogin($this->web_user);
 
     // create field
     $name = strtolower($this->randomName());
diff --git a/tests/link.test b/tests/link.test
index ed3e56b..71ee35d 100644
--- a/tests/link.test
+++ b/tests/link.test
@@ -24,8 +24,8 @@ class LinkBaseTestClass extends DrupalWebTestCase {
     $modules[] = 'link';
     parent::setUp($modules);
 
-    $this->account = $this->drupalCreateUser($this->permissions);
-    $this->drupalLogin($this->account);
+    $this->web_user = $this->drupalCreateUser($this->permissions);
+    $this->drupalLogin($this->web_user);
   }
 
   protected function createLinkField($node_type = 'page', $settings = array()) {
diff --git a/tests/link.token.test b/tests/link.token.test
index 6e5bbf6..3223a6d 100644
--- a/tests/link.token.test
+++ b/tests/link.token.test
@@ -28,8 +28,8 @@ class LinkTokenTest extends LinkBaseTestClass {
    * Creates a node with a token in the link title and checks the value.
    */
   function testUserTokenLinkCreate() {
-    /*$account = $this->drupalCreateUser(array('administer content types', 'access content', 'create page content'));
-    $this->drupalLogin($account);*/
+    /*$this->web_user = $this->drupalCreateUser(array('administer content types', 'access content', 'create page content'));
+    $this->drupalLogin($this->web_user);*/
 
     // create field
     $settings = array(
@@ -49,7 +49,7 @@ class LinkTokenTest extends LinkBaseTestClass {
         'label' => $this->randomName(),
     );
 
-    //$this->drupalLogin($account);
+    //$this->drupalLogin($this->web_user);
     $this->drupalGet('node/add/page');
 
     $edit = array(
@@ -89,7 +89,7 @@ class LinkTokenTest extends LinkBaseTestClass {
       'href' => 'http://example.com/' . $this->randomName()
     );
 
-    //$this->drupalLogin($account);
+    //$this->drupalLogin($this->web_user);
     $this->drupalGet('node/add/page');
 
     $edit = array(
@@ -132,7 +132,7 @@ class LinkTokenTest extends LinkBaseTestClass {
       'href' => 'http://example.com/' . $this->randomName()
     );
 
-    //$this->drupalLogin($account);
+    //$this->drupalLogin($this->web_user);
     $this->drupalGet('node/add/page');
 
     $edit = array(
@@ -277,8 +277,8 @@ class LinkTokenTest extends LinkBaseTestClass {
    *  Trying to set the url to contain a token.
    */
   function _testUserTokenLinkCreateInURL() {
-    $account = $this->drupalCreateUser(array('administer content types', 'access content', 'create page content'));
-    $this->drupalLogin($account);
+    $this->web_user = $this->drupalCreateUser(array('administer content types', 'access content', 'create page content'));
+    $this->drupalLogin($this->web_user);
 
     // create field
     $name = strtolower($this->randomName());
@@ -307,7 +307,7 @@ class LinkTokenTest extends LinkBaseTestClass {
         'label' => $this->randomName(),
     );
 
-    $this->drupalLogin($account);
+    $this->drupalLogin($this->web_user);
     $this->drupalGet('node/add/page');
 
     $edit = array(
@@ -330,8 +330,8 @@ class LinkTokenTest extends LinkBaseTestClass {
    *  Trying to set the url to contain a token.
    */
   function _testUserTokenLinkCreateInURL2() {
-    $account = $this->drupalCreateUser(array('administer content types', 'access content', 'create page content'));
-    $this->drupalLogin($account);
+    $this->web_user = $this->drupalCreateUser(array('administer content types', 'access content', 'create page content'));
+    $this->drupalLogin($this->web_user);
 
     // create field
     $name = strtolower($this->randomName());
@@ -360,7 +360,7 @@ class LinkTokenTest extends LinkBaseTestClass {
         'label' => $this->randomName(),
     );
 
-    $this->drupalLogin($account);
+    $this->drupalLogin($this->web_user);
     $this->drupalGet('node/add/page');
 
     $edit = array(
@@ -375,6 +375,6 @@ class LinkTokenTest extends LinkBaseTestClass {
     $this->drupalLogout();
     $this->drupalGet($url);
 
-    $this->assertRaw(l($input['label'], $input['href'] .'/'. $account->uid));
+    $this->assertRaw(l($input['label'], $input['href'] .'/'. $this->web_user->uid));
   }
 }
diff --git a/tests/link.validate.test b/tests/link.validate.test
index 4f42333..590870a 100644
--- a/tests/link.validate.test
+++ b/tests/link.validate.test
@@ -62,13 +62,15 @@ class LinkValidateTest extends LinkValidateTestCase {
    * Test if we're stopped from posting a bad url on default validation.
    */
   function test_link_validate_bad_url_validate_default() {
-    $account = $this->drupalCreateUser(array('administer content types',
-                                             'administer nodes',
-                                             'administer filters',
-                                             'access content',
-                                             'create page content',
-                                             'access administration pages'));
-    $this->drupalLogin($account);
+    $this->web_user = $this->drupalCreateUser(array(
+      'administer content types',
+      'administer nodes',
+      'administer filters',
+      'access content',
+      'create page content',
+      'access administration pages',
+    ));
+    $this->drupalLogin($this->web_user);
 
     // create field
     $name = strtolower($this->randomName());
@@ -107,13 +109,15 @@ class LinkValidateTest extends LinkValidateTestCase {
    * Test if we're stopped from posting a bad url with validation on.
    */
   function test_link_validate_bad_url_validate_on() {
-    $account = $this->drupalCreateUser(array('administer content types',
-                                             'administer nodes',
-                                             'administer filters',
-                                             'access content',
-                                             'create page content',
-                                             'access administration pages'));
-    $this->drupalLogin($account);
+    $this->web_user = $this->drupalCreateUser(array(
+      'administer content types',
+      'administer nodes',
+      'administer filters',
+      'access content',
+      'create page content',
+      'access administration pages',
+    ));
+    $this->drupalLogin($this->web_user);
 
     // create field
     $name = strtolower($this->randomName());
@@ -153,13 +157,15 @@ class LinkValidateTest extends LinkValidateTestCase {
    * Test if we can post a bad url if the validation is expressly turned off.
    */
   function test_link_validate_bad_url_validate_off() {
-    $account = $this->drupalCreateUser(array('administer content types',
-                                             'administer nodes',
-                                             'administer filters',
-                                             'access content',
-                                             'create page content',
-                                             'access administration pages'));
-    $this->drupalLogin($account);
+    $this->web_user = $this->drupalCreateUser(array(
+      'administer content types',
+      'administer nodes',
+      'administer filters',
+      'access content',
+      'create page content',
+      'access administration pages',
+    ));
+    $this->drupalLogin($this->web_user);
 
     // create field
     $name = strtolower($this->randomName());
@@ -204,13 +210,15 @@ class LinkValidateTest extends LinkValidateTestCase {
    */
   function x_test_link_validate_switching_between_validation_status() {
     $this->acquireContentTypes(1);
-    $account = $this->drupalCreateUser(array('administer content types',
-                                             'administer nodes',
-                                             'access administration pages',
-                                             'access content',
-                                             'create '. $this->content_types[0]->type .' content',
-                                             'edit any '. $this->content_types[0]->type .' content'));
-    $this->drupalLogin($account);
+    $this->web_user = $this->drupalCreateUser(array(
+      'administer content types',
+      'administer nodes',
+      'access administration pages',
+      'access content',
+      'create '. $this->content_types[0]->type .' content',
+      'edit any '. $this->content_types[0]->type .' content',
+    ));
+    $this->drupalLogin($this->web_user);
     variable_set('node_options_'. $this->content_types[0]->name, array('status', 'promote'));
     $field_settings = array(
       'type' => 'link',
-- 
1.7.6.msysgit.0


From 693a12a630b84caa1a6b7060e8f1f9ed71e5e108 Mon Sep 17 00:00:00 2001
From: sun <sun@unleashedmind.com>
Date: Sat, 7 Jul 2012 04:05:46 +0200
Subject: [PATCH 05/13] Prepared test case class files for PSR-0.
 (backportable)

---
 link.info                                          |   12 +-
 ...nk.crud_browser.test => LinkFieldCRUDTest.test} |   63 +++++++-
 ....attribute.test => LinkFieldFormatterTest.test} |   15 +--
 ....validate.test => LinkFieldValidationTest.test} |  187 +-------------------
 tests/{link.test => LinkTestBase.test}             |   11 +-
 tests/{link.token.test => LinkTokenTest.test}      |    2 +-
 tests/LinkValidateURLUnitTest.test                 |  151 ++++++++++++++++
 tests/link.crud.test                               |   81 ---------
 8 files changed, 236 insertions(+), 286 deletions(-)
 rename tests/{link.crud_browser.test => LinkFieldCRUDTest.test} (78%)
 rename tests/{link.attribute.test => LinkFieldFormatterTest.test} (98%)
 rename tests/{link.validate.test => LinkFieldValidationTest.test} (65%)
 rename tests/{link.test => LinkTestBase.test} (88%)
 rename tests/{link.token.test => LinkTokenTest.test} (99%)
 create mode 100644 tests/LinkValidateURLUnitTest.test
 delete mode 100644 tests/link.crud.test

diff --git a/link.info b/link.info
index 4272506..992880c 100644
--- a/link.info
+++ b/link.info
@@ -8,12 +8,12 @@ files[] = link.install
 files[] = link.migrate.inc
 
 ; Tests
-files[] = tests/link.test
-files[] = tests/link.attribute.test
-files[] = tests/link.crud.test
-files[] = tests/link.crud_browser.test
-files[] = tests/link.token.test
-files[] = tests/link.validate.test
+files[] = tests/LinkTestBase.test
+files[] = tests/LinkFieldCRUDTest.test
+files[] = tests/LinkFieldFormatterTest.test
+files[] = tests/LinkFieldValidationTest.test
+files[] = tests/LinkTokenTest.test
+files[] = tests/LinkValidateURLUnitTest.test
 
 ; Views Handlers
 files[] = views/link_views_handler_argument_target.inc
diff --git a/tests/link.crud_browser.test b/tests/LinkFieldCRUDTest.test
similarity index 78%
rename from tests/link.crud_browser.test
rename to tests/LinkFieldCRUDTest.test
index f9952cd..a5f4787 100644
--- a/tests/link.crud_browser.test
+++ b/tests/LinkFieldCRUDTest.test
@@ -8,7 +8,7 @@
 /**
  * Testing that users can not input bad URLs or labels
  */
-class LinkUITest extends DrupalWebTestcase {
+class LinkFieldCRUDTest extends LinkTestBase {
 
   /**
    * Link supposed to be good
@@ -33,8 +33,65 @@ class LinkUITest extends DrupalWebTestcase {
     );
   }
 
-  function setUp() {
-    parent::setUp('field_ui', 'link');
+  /**
+   * All we're doing here is creating a content type, creating a simple link field
+   * on that content type.
+   */
+  function testLinkCreateFieldAPI() {
+    $content_type_friendly = $this->randomName(20);
+    $content_type_machine = strtolower($this->randomName(10));
+    $title = $this->randomName(20);
+
+    // Create and login user.
+    $this->web_user = $this->drupalCreateUser(array('administer content types'));
+    $this->drupalLogin($this->web_user);
+
+    $this->drupalGet('admin/structure/types');
+
+    // Create the content type.
+    $this->clickLink(t('Add content type'));
+
+    $edit = array (
+      'name' => $content_type_friendly,
+      'type' => $content_type_machine,
+    );
+    $this->drupalPost(NULL, $edit, t('Save and add fields'));
+    $this->assertText(t('The content type @name has been added.', array('@name' => $content_type_friendly)));
+
+    //$field = $this->createField(array('type' => 'link', 'widget_type' => 'link'), 0);
+    // Now add a singleton field.
+    $single_field_name_friendly = $this->randomName(20);
+    $single_field_name_machine = strtolower($this->randomName(10));
+    $edit = array (
+      'fields[_add_new_field][label]' => $single_field_name_friendly,
+      'fields[_add_new_field][field_name]' => $single_field_name_machine,
+      'fields[_add_new_field][type]' => 'link_field',
+      'fields[_add_new_field][widget_type]' => 'link_field',
+    );
+    $this->drupalPost(NULL, $edit, t('Save'));
+
+    // We'll go with the default settings for this run-through.
+    $this->drupalPost(NULL, array(), t('Save field settings'));
+
+    // Using all the default settings, so press the button.
+    $this->drupalPost(NULL, array(), t('Save settings'));
+    $this->assertText(t('Saved @name configuration.', array('@name' => $single_field_name_friendly)));
+
+    // Somehow clicking "save" isn't enough, and we have to do a
+    // node_types_rebuild().
+    node_types_rebuild();
+    menu_rebuild();
+    $type_exists = db_query('SELECT 1 FROM {node_type} WHERE type = :type', array(':type' => $content_type_machine))->fetchField();
+    $this->assertTrue($type_exists, 'The new content type has been created in the database.');
+
+    /*$table_schema = drupal_get_schema();
+    $this->assertEqual(1, 1, print_r(array_keys($table_schema), TRUE));
+    // Check the schema - the values should be in the per-type table.
+    $this->assertSchemaMatchesTables(array(
+      'per_type' => array(
+        $this->content_types[0]->type => array($field['field_name'] => array('url', 'title', 'attributes')),
+      ),
+    ));*/
   }
 
   /**
diff --git a/tests/link.attribute.test b/tests/LinkFieldFormatterTest.test
similarity index 98%
rename from tests/link.attribute.test
rename to tests/LinkFieldFormatterTest.test
index fa3bfac..e1e3fdb 100644
--- a/tests/link.attribute.test
+++ b/tests/LinkFieldFormatterTest.test
@@ -5,20 +5,9 @@
  * Basic simpletests to test options on link module.
  */
 
-class LinkAttributeCrudTest extends DrupalWebTestCase {
+class LinkFieldFormatterTest extends LinkTestBase {
   private $zebra;
 
-  protected $permissions = array(
-    'access content',
-    'administer content types',
-    'administer nodes',
-    'administer filters',
-    'access comments',
-    'post comments',
-    'skip comment approval',
-    'access administration pages',
-  );
-
   public static function getInfo() {
     return array(
       'name' => 'Link Attribute Tests',
@@ -28,7 +17,7 @@ class LinkAttributeCrudTest extends DrupalWebTestCase {
   }
 
   function setup() {
-    parent::setup('field_ui', 'link');
+    parent::setup();
     $this->zebra = 0;
 
     // Create and login user.
diff --git a/tests/link.validate.test b/tests/LinkFieldValidationTest.test
similarity index 65%
rename from tests/link.validate.test
rename to tests/LinkFieldValidationTest.test
index 590870a..d8386b6 100644
--- a/tests/link.validate.test
+++ b/tests/LinkFieldValidationTest.test
@@ -5,7 +5,14 @@
  * Tests that exercise the validation functions in the link module.
  */
 
-class LinkValidateTestCase extends LinkBaseTestClass {
+class LinkFieldValidationTest extends LinkTestBase {
+  public static function getInfo() {
+    return array(
+      'name' => 'Link Validation Tests',
+      'description' => 'Tests the field validation.',
+      'group' => 'Link',
+    );
+  }
 
   protected function createLink($url, $title, $attributes = array()) {
     return array(
@@ -19,7 +26,6 @@ class LinkValidateTestCase extends LinkBaseTestClass {
    * Takes a url, and sees if it can validate that the url is valid.
    */
   protected function link_test_validate_url($url) {
-
     $field_name = $this->createLinkField();
 
     $permission = 'create page content';
@@ -42,17 +48,6 @@ class LinkValidateTestCase extends LinkBaseTestClass {
 
     $this->assertEqual($url, $node->{$field_name}['und'][0]['url']);
   }
-}
-
-class LinkValidateTest extends LinkValidateTestCase {
-
-  public static function getInfo() {
-    return array(
-      'name' => 'Link Validation Tests',
-      'description' => 'Tests the field validation.',
-      'group' => 'Link',
-    );
-  }
 
   function test_link_validate_basic_url() {
     $this->link_test_validate_url('http://www.example.com');
@@ -293,17 +288,6 @@ class LinkValidateTest extends LinkValidateTestCase {
   function test_link_ftp() {
     $this->link_test_validate_url('ftp://www.example.com/');
   }
-}
-
-class LinkValidateTestNews extends LinkValidateTestCase {
-
-  public static function getInfo() {
-    return array(
-      'name' => 'Link News Validation Tests',
-      'description' => 'Tests the field validation for usenet urls.',
-      'group' => 'Link',
-    );
-  }
 
   // Validate a news link to a message group
   function test_link_news() {
@@ -314,16 +298,6 @@ class LinkValidateTestNews extends LinkValidateTestCase {
   function test_link_news_message() {
     $this->link_test_validate_url('news:hj0db8$vrm$1@news.eternal-september.org');
   }
-}
-
-class LinkValidateSpecificURL extends LinkValidateTestCase {
-  public static function getInfo() {
-    return array(
-      'name' => 'Link Specific URL Validation Tests',
-      'description' => 'Tests field validation with unusual urls',
-      'group' => 'Link',
-    );
-  }
 
   // Lets throw in a lot of umlouts for testing!
   function test_umlout_url() {
@@ -355,149 +329,4 @@ class LinkValidateSpecificURL extends LinkValidateTestCase {
     $long_url = 'http://th.wikipedia.org/wiki/%E0%B9%82%E0%B8%A3%E0%B8%87%E0%B9%80%E0%B8%A3%E0%B8%B5%E0%B8%A2%E0%B8%99%E0%B9%80%E0%B8%9A%E0%B8%8D%E0%B8%88%E0%B8%A1%E0%B8%A3%E0%B8%B2%E0%B8%8A%E0%B8%B9%E0%B8%97%E0%B8%B4%E0%B8%A8_%E0%B8%99%E0%B8%84%E0%B8%A3%E0%B8%A8%E0%B8%A3%E0%B8%B5%E0%B8%98%E0%B8%A3%E0%B8%A3%E0%B8%A1%E0%B8%A3%E0%B8%B2%E0%B8%8A';
     $this->link_test_validate_url($long_url);
   }
-
-}
-
-/**
- * A series of tests of links, only going against the link_validate_url function in link.module.
- *
- * Validation is guided by the rules in http://tools.ietf.org/html/rfc1738 !
- */
-class LinkValidateUrlLight extends DrupalWebTestCase {
-  public static function getInfo() {
-    return array(
-      'name' => 'Link Light Validation Tests',
-      'description' => 'Tests the link_validate_url() function by itself, without invoking the full drupal/cck lifecycle.',
-      'group' => 'Link',
-    );
-  }
-
-  function setUp() {
-    parent::setUp(array('link'));
-  }
-
-  /**
-   * Translates the LINK type constants to english for display and debugging of tests
-   */
-  function name_Link_Type($type) {
-    switch ($type) {
-      case LINK_FRONT:
-        return "Front";
-      case LINK_EMAIL:
-        return "Email";
-      case LINK_NEWS:
-        return "Newsgroup";
-      case LINK_INTERNAL:
-        return "Internal Link";
-      case LINK_EXTERNAL:
-        return "External Link";
-      case FALSE:
-        return "Invalid Link";
-      default:
-        return "Bad Value:". $type;
-    }
-  }
-
-  // Make sure that a link labelled <front> works.
-  function testValidateFrontLink() {
-    $valid = link_validate_url('<front>');
-    $this->assertEqual(LINK_FRONT, $valid, 'Make sure that front link is verfied and identified');
-  }
-
-  function testValidateEmailLink() {
-    $valid = link_validate_url('mailto:bob@example.com');
-    $this->assertEqual(LINK_EMAIL, $valid, "Make sure a basic mailto is verified and identified");
-  }
-
-  function testValidateEmailLinkBad() {
-    $valid = link_validate_url(':bob@example.com');
-    $this->assertEqual(FALSE, $valid, 'Make sure just a bad address is correctly failed');
-  }
-
-  function testValidateNewsgroupLink() {
-    $valid = link_validate_url('news:comp.infosystems.www.misc');
-    $this->assertEqual(LINK_NEWS, $valid, 'Make sure link to newsgroup validates as news.');
-  }
-
-  function testValidateNewsArticleLink() {
-    $valid = link_validate_url('news:hj0db8$vrm$1@news.eternal-september.org');
-    $this->assertEqual(LINK_NEWS, $valid, 'Make sure link to specific article valiates as news.');
-  }
-
-  function testValidateBadNewsgroupLink() {
-    $valid = link_validate_url('news:comp.bad_name.misc');
-    $this->assertEqual(FALSE, $valid, 'newsgroup names can\'t contain underscores, so it should come back as invalid.');
-  }
-
-  function testValidateInternalLink() {
-    $valid = link_validate_url('node/5');
-    $this->assertEqual(LINK_INTERNAL, $valid, 'Test normal internal link.');
-  }
-
-  function testValidateInternalLinkWithDot() {
-    $valid = link_validate_url('rss.xml');
-    $this->assertEqual(LINK_INTERNAL, $valid, 'Test rss.xml internal link.');
-  }
-
-  function testValidateInternalLinkToFile() {
-    $valid = link_validate_url('files/test.jpg');
-    $this->assertEqual(LINK_INTERNAL, $valid, 'Test files/test.jpg internal link.');
-  }
-
-  function testValidateExternalLinks() {
-    $links = array(
-      'http://localhost:8080/',
-      'www.example.com',
-      'www.example.com/',
-      'http://username:p%40ssw0rd!@www.example.com/',
-      'http://@www.example.com/',
-      'http://username:@www.example.com/',
-      'http://username:password@www.example.com:8080/',
-      'http://127.0.0.1:80/',
-      'http://127.173.24.255:4723/',
-      '127.173.24.255:4723/',
-      'http://255.255.255.255:4823/',
-      'www.test-site.com',
-      'http://example.com/index.php?q=node/123',
-      'http://example.com/index.php?page=this\that',
-      'http://example.com/?first_name=Joe Bob&last_name=Smith',
-      // Anchors
-      'http://www.example.com/index.php#test',
-      'http://www.example.com/index.php#this@that.',
-      'http://www.example.com/index.php#',
-      'http://www.cnn.com/video/#/video/politics/2008/12/09/intv.madeleine.albright.cnn',
-      'http://www.archive.org/stream/aesopsfables00aesorich#page/n7/mode/2up',
-      'http://www.example.com/blah/#this@that?',
-    );
-    // Test all of the protocols.
-    $allowed_protocols = variable_get('filter_allowed_protocols', array('http', 'https', 'ftp', 'news', 'nntp', 'telnet', 'mailto', 'irc', 'ssh', 'sftp', 'webcal'));
-    foreach ($allowed_protocols as $protocol) {
-      if ($protocol !== 'news' && $protocol !== 'mailto') {
-        $links[] = $protocol .'://www.example.com';
-      }
-    }
-    foreach ($links as $link) {
-      $valid = link_validate_url($link);
-      $this->assertEqual(LINK_EXTERNAL, $valid, 'Testing that '. $link .' is a valid external link.');
-      // The following two lines are commented out and only used for comparisons.
-      //$valid2 = valid_url($link, TRUE);
-      //$this->assertEqual(TRUE, $valid2, "Using valid_url() on $link.");
-    }
-  }
-
-  function testInvalidExternalLinks() {
-    $links = array(
-      'http://www.ex ample.com/',
-      '//www.example.com/',
-      'http://25.0.0/', // bad ip!
-      'http://4827.0.0.2/',
-      'http://www.testß.com/', // ß not allowed in domain names!
-      //'http://www.-fudge.com/', // domains can't have sections starting with a dash.
-    );
-    foreach ($links as $link) {
-      $valid = link_validate_url($link);
-      $this->assertEqual(FALSE, $valid, 'Testing that '. $link .' is not a valid link.');
-    }
-  }
-
 }
diff --git a/tests/link.test b/tests/LinkTestBase.test
similarity index 88%
rename from tests/link.test
rename to tests/LinkTestBase.test
index 71ee35d..e5766cc 100644
--- a/tests/link.test
+++ b/tests/LinkTestBase.test
@@ -5,15 +5,18 @@
  * Link base test file - contains common functions for testing links.
  */
 
-class LinkBaseTestClass extends DrupalWebTestCase {
+class LinkTestBase extends DrupalWebTestCase {
+  protected $profile = 'testing';
+
   protected $permissions = array(
-    'access content',
     'administer content types',
     'administer nodes',
     'administer filters',
+    'access administration pages',
+    'access content',
     'access comments',
     'post comments',
-    'access administration pages',
+    'skip comment approval',
     'create page content',
   );
 
@@ -24,6 +27,8 @@ class LinkBaseTestClass extends DrupalWebTestCase {
     $modules[] = 'link';
     parent::setUp($modules);
 
+    $this->drupalCreateContentType(array('type' => 'page', 'name' => 'Page'));
+
     $this->web_user = $this->drupalCreateUser($this->permissions);
     $this->drupalLogin($this->web_user);
   }
diff --git a/tests/link.token.test b/tests/LinkTokenTest.test
similarity index 99%
rename from tests/link.token.test
rename to tests/LinkTokenTest.test
index 3223a6d..6430a3d 100644
--- a/tests/link.token.test
+++ b/tests/LinkTokenTest.test
@@ -8,7 +8,7 @@
 /**
  * Testing that tokens can be used in link titles
  */
-class LinkTokenTest extends LinkBaseTestClass {
+class LinkTokenTest extends LinkTestBase {
 
   public static function getInfo() {
     return array(
diff --git a/tests/LinkValidateURLUnitTest.test b/tests/LinkValidateURLUnitTest.test
new file mode 100644
index 0000000..473aa48
--- /dev/null
+++ b/tests/LinkValidateURLUnitTest.test
@@ -0,0 +1,151 @@
+<?php
+
+/**
+ * @file
+ * Tests that exercise the validation functions in the link module.
+ */
+
+/**
+ * A series of tests of links, only going against the link_validate_url function in link.module.
+ *
+ * Validation is guided by the rules in http://tools.ietf.org/html/rfc1738 !
+ */
+class LinkValidateURLUnitTest extends DrupalUnitTestCase {
+  public static function getInfo() {
+    return array(
+      'name' => 'Link Light Validation Tests',
+      'description' => 'Tests the link_validate_url() function by itself, without invoking the full drupal/cck lifecycle.',
+      'group' => 'Link',
+    );
+  }
+
+  function setUp() {
+    parent::setUp();
+    drupal_load('module', 'link');
+  }
+
+  /**
+   * Translates the LINK type constants to english for display and debugging of tests
+   */
+  function name_Link_Type($type) {
+    switch ($type) {
+      case LINK_FRONT:
+        return "Front";
+      case LINK_EMAIL:
+        return "Email";
+      case LINK_NEWS:
+        return "Newsgroup";
+      case LINK_INTERNAL:
+        return "Internal Link";
+      case LINK_EXTERNAL:
+        return "External Link";
+      case FALSE:
+        return "Invalid Link";
+      default:
+        return "Bad Value:". $type;
+    }
+  }
+
+  // Make sure that a link labelled <front> works.
+  function testValidateFrontLink() {
+    $valid = link_validate_url('<front>');
+    $this->assertEqual(LINK_FRONT, $valid, 'Make sure that front link is verfied and identified');
+  }
+
+  function testValidateEmailLink() {
+    $valid = link_validate_url('mailto:bob@example.com');
+    $this->assertEqual(LINK_EMAIL, $valid, "Make sure a basic mailto is verified and identified");
+  }
+
+  function testValidateEmailLinkBad() {
+    $valid = link_validate_url(':bob@example.com');
+    $this->assertEqual(FALSE, $valid, 'Make sure just a bad address is correctly failed');
+  }
+
+  function testValidateNewsgroupLink() {
+    $valid = link_validate_url('news:comp.infosystems.www.misc');
+    $this->assertEqual(LINK_NEWS, $valid, 'Make sure link to newsgroup validates as news.');
+  }
+
+  function testValidateNewsArticleLink() {
+    $valid = link_validate_url('news:hj0db8$vrm$1@news.eternal-september.org');
+    $this->assertEqual(LINK_NEWS, $valid, 'Make sure link to specific article valiates as news.');
+  }
+
+  function testValidateBadNewsgroupLink() {
+    $valid = link_validate_url('news:comp.bad_name.misc');
+    $this->assertEqual(FALSE, $valid, 'newsgroup names can\'t contain underscores, so it should come back as invalid.');
+  }
+
+  function testValidateInternalLink() {
+    $valid = link_validate_url('node/5');
+    $this->assertEqual(LINK_INTERNAL, $valid, 'Test normal internal link.');
+  }
+
+  function testValidateInternalLinkWithDot() {
+    $valid = link_validate_url('rss.xml');
+    $this->assertEqual(LINK_INTERNAL, $valid, 'Test rss.xml internal link.');
+  }
+
+  function testValidateInternalLinkToFile() {
+    $valid = link_validate_url('files/test.jpg');
+    $this->assertEqual(LINK_INTERNAL, $valid, 'Test files/test.jpg internal link.');
+  }
+
+  function testValidateExternalLinks() {
+    $links = array(
+      'http://localhost:8080/',
+      'www.example.com',
+      'www.example.com/',
+      'http://username:p%40ssw0rd!@www.example.com/',
+      'http://@www.example.com/',
+      'http://username:@www.example.com/',
+      'http://username:password@www.example.com:8080/',
+      'http://127.0.0.1:80/',
+      'http://127.173.24.255:4723/',
+      '127.173.24.255:4723/',
+      'http://255.255.255.255:4823/',
+      'www.test-site.com',
+      'http://example.com/index.php?q=node/123',
+      'http://example.com/index.php?page=this\that',
+      'http://example.com/?first_name=Joe Bob&last_name=Smith',
+      // Anchors
+      'http://www.example.com/index.php#test',
+      'http://www.example.com/index.php#this@that.',
+      'http://www.example.com/index.php#',
+      'http://www.cnn.com/video/#/video/politics/2008/12/09/intv.madeleine.albright.cnn',
+      'http://www.archive.org/stream/aesopsfables00aesorich#page/n7/mode/2up',
+      'http://www.example.com/blah/#this@that?',
+    );
+    // Test all of the protocols.
+    $allowed_protocols = variable_get('filter_allowed_protocols', array('http', 'https', 'ftp', 'news', 'nntp', 'telnet', 'mailto', 'irc', 'ssh', 'sftp', 'webcal'));
+    foreach ($allowed_protocols as $protocol) {
+      if ($protocol !== 'news' && $protocol !== 'mailto') {
+        $links[] = $protocol .'://www.example.com';
+      }
+    }
+    foreach ($links as $link) {
+      $valid = link_validate_url($link);
+      $this->assertEqual(LINK_EXTERNAL, $valid, 'Testing that '. $link .' is a valid external link.');
+      // The following two lines are commented out and only used for comparisons.
+      //$valid2 = valid_url($link, TRUE);
+      //$this->assertEqual(TRUE, $valid2, "Using valid_url() on $link.");
+    }
+  }
+
+  function testInvalidExternalLinks() {
+    $links = array(
+      'http://www.ex ample.com/',
+      '//www.example.com/',
+      'http://25.0.0/', // bad ip!
+      'http://4827.0.0.2/',
+      'http://www.testß.com/', // ß not allowed in domain names!
+      //'http://www.-fudge.com/', // domains can't have sections starting with a dash.
+    );
+    foreach ($links as $link) {
+      $valid = link_validate_url($link);
+      $this->assertEqual(FALSE, $valid, 'Testing that '. $link .' is not a valid link.');
+    }
+  }
+
+}
diff --git a/tests/link.crud.test b/tests/link.crud.test
deleted file mode 100644
index e1e25db..0000000
--- a/tests/link.crud.test
+++ /dev/null
@@ -1,81 +0,0 @@
-<?php
-
-/**
- * @file
- * Basic CRUD simpletests for the link module, based off of content.crud.test in CCK.
- */
-
-class LinkContentCrudTest extends DrupalWebTestCase {
-  public static function getInfo() {
-    return array(
-      'name' => 'Link CRUD - Basic API tests',
-      'description' => 'Tests the field CRUD (create, read, update, delete) API.',
-      'group' => 'Link',
-    );
-  }
-
-  function setUp() {
-    parent::setUp('field_ui', 'link');
-  }
-
-  /**
-   * All we're doing here is creating a content type, creating a simple link field
-   * on that content type.
-   */
-  function testLinkCreateFieldAPI() {
-    $content_type_friendly = $this->randomName(20);
-    $content_type_machine = strtolower($this->randomName(10));
-    $title = $this->randomName(20);
-
-    // Create and login user.
-    $this->web_user = $this->drupalCreateUser(array('administer content types'));
-    $this->drupalLogin($this->web_user);
-
-    $this->drupalGet('admin/structure/types');
-
-    // Create the content type.
-    $this->clickLink(t('Add content type'));
-
-    $edit = array (
-      'name' => $content_type_friendly,
-      'type' => $content_type_machine,
-    );
-    $this->drupalPost(NULL, $edit, t('Save and add fields'));
-    $this->assertText(t('The content type @name has been added.', array('@name' => $content_type_friendly)));
-
-    //$field = $this->createField(array('type' => 'link', 'widget_type' => 'link'), 0);
-    // Now add a singleton field.
-    $single_field_name_friendly = $this->randomName(20);
-    $single_field_name_machine = strtolower($this->randomName(10));
-    $edit = array (
-      'fields[_add_new_field][label]' => $single_field_name_friendly,
-      'fields[_add_new_field][field_name]' => $single_field_name_machine,
-      'fields[_add_new_field][type]' => 'link_field',
-      'fields[_add_new_field][widget_type]' => 'link_field',
-    );
-    $this->drupalPost(NULL, $edit, t('Save'));
-
-    // We'll go with the default settings for this run-through.
-    $this->drupalPost(NULL, array(), t('Save field settings'));
-
-    // Using all the default settings, so press the button.
-    $this->drupalPost(NULL, array(), t('Save settings'));
-    $this->assertText(t('Saved @name configuration.', array('@name' => $single_field_name_friendly)));
-
-    // Somehow clicking "save" isn't enough, and we have to do a
-    // node_types_rebuild().
-    node_types_rebuild();
-    menu_rebuild();
-    $type_exists = db_query('SELECT 1 FROM {node_type} WHERE type = :type', array(':type' => $content_type_machine))->fetchField();
-    $this->assertTrue($type_exists, 'The new content type has been created in the database.');
-
-    /*$table_schema = drupal_get_schema();
-    $this->assertEqual(1, 1, print_r(array_keys($table_schema), TRUE));
-    // Check the schema - the values should be in the per-type table.
-    $this->assertSchemaMatchesTables(array(
-      'per_type' => array(
-        $this->content_types[0]->type => array($field['field_name'] => array('url', 'title', 'attributes')),
-      ),
-    ));*/
-  }
-}
-- 
1.7.6.msysgit.0


From 1420298da5703ca9e42a3b308be741d1f5df440a Mon Sep 17 00:00:00 2001
From: sun <sun@unleashedmind.com>
Date: Sat, 7 Jul 2012 05:21:11 +0200
Subject: [PATCH 06/13] Fixed Field API field/instance settings form callback
 names.

---
 link.module |   18 +++++++++---------
 1 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/link.module b/link.module
index aab6fa0..0181ede 100644
--- a/link.module
+++ b/link.module
@@ -63,11 +63,18 @@ function link_field_info() {
 }
 
 /**
+ * Implements hook_field_settings_form().
+ */
+function link_field_settings_form() {
+  return array();
+}
+
+/**
  * Implements hook_field_instance_settings_form().
  */
 function link_field_instance_settings_form($field, $instance) {
   $form = array(
-    '#element_validate' => array('link_field_settings_form_validate'),
+    '#element_validate' => array('link_field_instance_settings_form_validate'),
   );
 
   $form['validate_url'] = array(
@@ -218,7 +225,7 @@ function link_field_instance_settings_form($field, $instance) {
 /**
  * #element_validate handler for link_field_instance_settings_form().
  */
-function link_field_settings_form_validate($element, &$form_state, $complete_form) {
+function link_field_instance_settings_form_validate($element, &$form_state, $complete_form) {
   if ($form_state['values']['instance']['settings']['title'] === 'value' && empty($form_state['values']['instance']['settings']['title_value'])) {
     form_set_error('title_value', t('A default title must be provided if the title is a static value.'));
   }
@@ -1103,13 +1110,6 @@ function link_content_migrate_instance_alter(&$instance_value, $field_value) {
 }
 
 /**
- * Implements hook_field_settings_form().
- */
-function link_field_settings_form() {
-  return array();
-}
-
-/**
  * Additional callback to adapt the property info of link fields.
  *
  * @see entity_metadata_field_entity_property_info()
-- 
1.7.6.msysgit.0


From d30baa22be1946fa5702a4b51d72bb794df9e506 Mon Sep 17 00:00:00 2001
From: sun <sun@unleashedmind.com>
Date: Sat, 7 Jul 2012 05:33:48 +0200
Subject: [PATCH 07/13] Refactored _link_load() into hook_field_load().

---
 link.module |   24 ++++--------------------
 1 files changed, 4 insertions(+), 20 deletions(-)

diff --git a/link.module b/link.module
index 0181ede..400d2d8 100644
--- a/link.module
+++ b/link.module
@@ -255,8 +255,10 @@ function link_field_is_empty($item, $field) {
  */
 function link_field_load($entity_type, $entities, $field, $instances, $langcode, &$items, $age) {
   foreach ($entities as $id => $entity) {
-    foreach ($items[$id] as $delta => $item) {
-      $items[$id][$delta]['attributes'] = _link_load($field, $item, $instances[$id]);
+    foreach ($items[$id] as $delta => &$item) {
+      // Unserialize the attributes array.
+      // @todo Widget does not always set 'attributes'.
+      $item['attributes'] = (isset($item['attributes']) ? unserialize($item['attributes']) : array());
     }
   }
 }
@@ -322,24 +324,6 @@ function link_field_widget_form(&$form, &$form_state, $field, $instance, $langco
 }
 
 /**
- * Unpacks the item attributes for use.
- */
-function _link_load($field, $item, $instance) {
-  if (isset($item['attributes'])) {
-    if (!is_array($item['attributes'])) {
-      $item['attributes'] = unserialize($item['attributes']);
-    }
-    return $item['attributes'];
-  }
-  elseif (isset($instance['settings']['attributes'])) {
-    return $instance['settings']['attributes'];
-  }
-  else {
-    return $field['settings']['attributes'];
-  }
-}
-
-/**
  * Prepares the item attributes and url for storage.
  */
 function _link_process(&$item, $delta = 0, $field, $entity) {
-- 
1.7.6.msysgit.0


From 3f15c3450a4bba2aa349f6ea683e27fecb8cfdba Mon Sep 17 00:00:00 2001
From: sun <sun@unleashedmind.com>
Date: Sat, 7 Jul 2012 05:48:22 +0200
Subject: [PATCH 08/13] Refactored _link_process() into hook_field_presave().

---
 link.module |   49 ++++++++++++++-----------------------------------
 1 files changed, 14 insertions(+), 35 deletions(-)

diff --git a/link.module b/link.module
index 400d2d8..37af605 100644
--- a/link.module
+++ b/link.module
@@ -283,8 +283,20 @@ function link_field_validate($entity_type, $entity, $field, $instance, $langcode
  * Implements hook_field_presave().
  */
 function link_field_presave($entity_type, $entity, $field, $instance, $langcode, &$items) {
-  foreach ($items as $delta => $value) {
-    _link_process($items[$delta], $delta, $field, $entity);
+  foreach ($items as $delta => &$item) {
+    // Trim whitespace from URL.
+    $item['url'] = trim($item['url']);
+
+    // Serialize the attributes array.
+    // @todo Widget does not always set 'attributes'.
+    if (isset($item['attributes'])) {
+      $item['attributes'] = serialize($item['attributes']);
+    }
+
+    // Do not save the default value (e.g. 'http://').
+    if (isset($field['widget']['default_value'][$delta]['url']) && $item['url'] == $field['widget']['default_value'][$delta]['url'] && !link_validate_url($item['url'])) {
+      unset($item['url']);
+    }
   }
 }
 
@@ -324,39 +336,6 @@ function link_field_widget_form(&$form, &$form_state, $field, $instance, $langco
 }
 
 /**
- * Prepares the item attributes and url for storage.
- */
-function _link_process(&$item, $delta = 0, $field, $entity) {
-  // Trim whitespace from URL.
-  $item['url'] = trim($item['url']);
-
-  // If no attributes are set then make sure $item['attributes'] is an empty
-  // array, so $field['attributes'] can override it.
-  if (empty($item['attributes'])) {
-    $item['attributes'] = array();
-  }
-
-  // Serialize the attributes array.
-  if (!is_string($item['attributes'])) {
-    $item['attributes'] = serialize($item['attributes']);
-  }
-
-  // Don't save an invalid default value (e.g. 'http://').
-  if ((isset($field['widget']['default_value'][$delta]['url']) && $item['url'] == $field['widget']['default_value'][$delta]['url']) && is_object($node)) {
-    if (!link_validate_url($item['url'])) {
-      unset($item['url']);
-    }
-  }
-
-  if (!empty($item['query'])) {
-    $item['url'] .= '?' . http_build_query($item['query']);
-  }
-  if (!empty($item['fragment'])) {
-    $item['url'] .= '#' . $item['fragment'];
-  }
-}
-
-/**
  * Validates that the link field has been entered properly.
  */
 function _link_validate(&$item, $delta, $field, $node, $instance, $langcode, &$optional_field_found) {
-- 
1.7.6.msysgit.0


From 456eca86e6f7439457b03795ae61fcb316e02251 Mon Sep 17 00:00:00 2001
From: sun <sun@unleashedmind.com>
Date: Sat, 7 Jul 2012 05:52:08 +0200
Subject: [PATCH 09/13] Refactored _link_validate() into
 hook_field_validate().

---
 link.module |   53 +++++++++++++++++++++++------------------------------
 1 files changed, 23 insertions(+), 30 deletions(-)

diff --git a/link.module b/link.module
index 37af605..8e9e3ed 100644
--- a/link.module
+++ b/link.module
@@ -269,8 +269,29 @@ function link_field_load($entity_type, $entities, $field, $instances, $langcode,
 function link_field_validate($entity_type, $entity, $field, $instance, $langcode, $items, &$errors) {
   $optional_field_found = FALSE;
   if ($instance['settings']['validate_url'] !== 0 || is_null($instance['settings']['validate_url']) || !isset($instance['settings']['validate_url'])) {
-    foreach ($items as $delta => $value) {
-      _link_validate($items[$delta], $delta, $field, $entity, $instance, $langcode, $optional_field_found);
+    foreach ($items as $delta => &$item) {
+      if ($item['url'] && !(isset($instance['default_value'][$delta]['url']) && $item['url'] === $instance['default_value'][$delta]['url'] && !$instance['required'])) {
+        // Validate the link.
+        if (link_validate_url(trim($item['url'])) == FALSE) {
+          form_set_error($field['field_name'] . '][' . $langcode . '][' . $delta . '][url', t('Not a valid URL.'));
+        }
+        // Require a title for the link if necessary.
+        if ($instance['settings']['title'] == 'required' && strlen(trim($item['title'])) == 0) {
+          form_set_error($field['field_name'] . '][' . $langcode . '][' . $delta . '][title', t('Titles are required for all links.'));
+        }
+      }
+      // Require a link if we have a title.
+      if ($instance['settings']['url'] !== 'optional' && strlen(isset($item['title']) ? $item['title'] : NULL) > 0 && strlen(trim($item['url'])) == 0) {
+        form_set_error($field['field_name'] . '][' . $langcode . '][' . $delta . '][url', t('You cannot enter a title without a link url.'));
+      }
+      // In a totally bizzaro case, where URLs and titles are optional but the field is required, ensure there is at least one link.
+      if ($instance['settings']['url'] === 'optional' && $instance['settings']['title'] === 'optional' && (strlen(trim($item['url'])) !== 0 || strlen(trim($item['title'])) !== 0)) {
+        $optional_field_found = TRUE;
+      }
+      // Require entire field
+      if ($instance['settings']['url'] === 'optional' && $instance['settings']['title'] === 'optional' && $instance['required'] == 1 && !$optional_field_found && isset($instance['id'])) {
+        form_set_error($instance['field_name'] . '][' . $langcode . '][0][title', t('At least one title or URL must be entered.'));
+      }
     }
   }
 
@@ -336,34 +357,6 @@ function link_field_widget_form(&$form, &$form_state, $field, $instance, $langco
 }
 
 /**
- * Validates that the link field has been entered properly.
- */
-function _link_validate(&$item, $delta, $field, $node, $instance, $langcode, &$optional_field_found) {
-  if ($item['url'] && !(isset($instance['default_value'][$delta]['url']) && $item['url'] === $instance['default_value'][$delta]['url'] && !$instance['required'])) {
-    // Validate the link.
-    if (link_validate_url(trim($item['url'])) == FALSE) {
-      form_set_error($field['field_name'] . '][' . $langcode . '][' . $delta . '][url', t('Not a valid URL.'));
-    }
-    // Require a title for the link if necessary.
-    if ($instance['settings']['title'] == 'required' && strlen(trim($item['title'])) == 0) {
-      form_set_error($field['field_name'] . '][' . $langcode . '][' . $delta . '][title', t('Titles are required for all links.'));
-    }
-  }
-  // Require a link if we have a title.
-  if ($instance['settings']['url'] !== 'optional' && strlen(isset($item['title']) ? $item['title'] : NULL) > 0 && strlen(trim($item['url'])) == 0) {
-    form_set_error($field['field_name'] . '][' . $langcode . '][' . $delta . '][url', t('You cannot enter a title without a link url.'));
-  }
-  // In a totally bizzaro case, where URLs and titles are optional but the field is required, ensure there is at least one link.
-  if ($instance['settings']['url'] === 'optional' && $instance['settings']['title'] === 'optional' && (strlen(trim($item['url'])) !== 0 || strlen(trim($item['title'])) !== 0)) {
-    $optional_field_found = TRUE;
-  }
-  // Require entire field
-  if ($instance['settings']['url'] === 'optional' && $instance['settings']['title'] === 'optional' && $instance['required'] == 1 && !$optional_field_found && isset($instance['id'])) {
-    form_set_error($instance['field_name'] . '][' . $langcode . '][0][title', t('At least one title or URL must be entered.'));
-  }
-}
-
-/**
  * Clean up user-entered values for a link field according to field settings.
  *
  * @param $item
-- 
1.7.6.msysgit.0


From 4bef1deb87ede63da8260486ba54ed778fc643e5 Mon Sep 17 00:00:00 2001
From: sun <sun@unleashedmind.com>
Date: Sat, 7 Jul 2012 06:04:27 +0200
Subject: [PATCH 10/13] Refactored _link_sanitize() into
 hook_field_prepare_view().

---
 link.module |  277 ++++++++++++++++++++++++++---------------------------------
 1 files changed, 120 insertions(+), 157 deletions(-)

diff --git a/link.module b/link.module
index 8e9e3ed..fe0971e 100644
--- a/link.module
+++ b/link.module
@@ -325,9 +325,126 @@ function link_field_presave($entity_type, $entity, $field, $instance, $langcode,
  * Implements hook_field_prepare_view().
  */
 function link_field_prepare_view($entity_type, $entities, $field, $instances, $langcode, &$items) {
-  foreach ($items as $entity_id => $entity_items) {
-    foreach ($entity_items as $delta => $value) {
-      _link_sanitize($items[$entity_id][$delta], $delta, $field, $instances[$entity_id], $entities[$entity_id]);
+  foreach ($entities as $id => $entity) {
+    foreach ($items[$id] as $delta => &$item) {
+      // Don't try to process empty links.
+      if (empty($item['url']) && empty($item['title'])) {
+        return;
+      }
+
+      // Replace URL tokens.
+      if (isset($instances[$id]['settings']['enable_tokens']) && $instances[$id]['settings']['enable_tokens']) {
+        $item['url'] = token_replace($item['url'], array($entity_type => $entity));
+      }
+
+      $type = link_validate_url($item['url']);
+      // If the type of the URL cannot be determined and URL validation is disabled,
+      // then assume LINK_EXTERNAL for later processing.
+      if ($type == FALSE && $instances[$id]['settings']['validate_url'] === 0) {
+        $type = LINK_EXTERNAL;
+      }
+      $url = link_cleanup_url($item['url']);
+      $item['url'] = check_plain($url);
+
+      // Separate out the anchor, if any.
+      if (strpos($url, '#') !== FALSE) {
+        $item['fragment'] = substr($url, strpos($url, '#') + 1);
+        $url = substr($url, 0, strpos($url, '#'));
+      }
+      // Separate out the query string, if any.
+      if (strpos($url, '?') !== FALSE) {
+        $query = substr($url, strpos($url, '?') + 1);
+        parse_str($query, $query_array);
+        $item['query'] = $query_array;
+        $url = substr($url, 0, strpos($url, '?'));
+      }
+
+      // Create a shortened URL for display.
+      if ($type == LINK_EMAIL) {
+        $display_url = str_replace('mailto:', '', $url);
+      }
+      else {
+        $display_url = url($url, array(
+          'query' => isset($item['query']) ? $item['query'] : NULL,
+          'fragment' => isset($item['fragment']) ? $item['fragment'] : NULL,
+          'absolute' => TRUE,
+        ));
+      }
+      if ($instances[$id]['settings']['display']['url_cutoff'] && strlen($display_url) > $instances[$id]['settings']['display']['url_cutoff']) {
+        $display_url = substr($display_url, 0, $instances[$id]['settings']['display']['url_cutoff']) . "...";
+      }
+      $item['display_url'] = $display_url;
+
+      // Use the title defined at the instance level.
+      if ($instances[$id]['settings']['title'] == 'value' && strlen(trim($instances[$id]['settings']['title_value']))) {
+        $title = $instances[$id]['settings']['title_value'];
+      }
+      // Use the title defined by the user at the widget level.
+      elseif (isset($item['title'])) {
+        $title = $item['title'];
+      }
+      else {
+        $title = '';
+      }
+
+      // Replace tokens.
+      if ($title && ($instances[$id]['settings']['title'] == 'value' || $instances[$id]['settings']['enable_tokens'])) {
+        $title = token_replace($title, array($entity_type => $entity));
+        $title = filter_xss($title, array('b', 'br', 'code', 'em', 'i', 'img', 'span', 'strong', 'sub', 'sup', 'tt', 'u'));
+        $item['html'] = TRUE;
+      }
+      $item['title'] = empty($title) ? $item['display_url'] : $title;
+
+      // Add field instance attribute defaults.
+      $item['attributes'] += $instances[$id]['settings']['attributes'];
+
+      // Add global default attributes.
+      $item['attributes'] += _link_default_attributes();
+
+      // If user is not allowed to choose target attribute, use default defined at
+      // field level.
+      if ($instances[$id]['settings']['attributes']['target'] != LINK_TARGET_USER) {
+        $item['attributes']['target'] = $instances[$id]['settings']['attributes']['target'];
+      }
+      elseif ($item['attributes']['target'] == LINK_TARGET_USER) {
+        $item['attributes']['target'] = LINK_TARGET_DEFAULT;
+      }
+
+      // Remove the target attribute if the default (no target) is selected.
+      if (empty($item['attributes']) || $item['attributes']['target'] == LINK_TARGET_DEFAULT) {
+        unset($item['attributes']['target']);
+      }
+
+      // Remove rel attribute for internal or external links if selected.
+      if (isset($item['attributes']['rel']) && isset($instances[$id]['settings']['rel_remove']) && $instances[$id]['settings']['rel_remove'] != 'default') {
+        if (($instances[$id]['settings']['rel_remove'] != 'rel_remove_internal' && $type != LINK_INTERNAL) ||
+          ($instances[$id]['settings']['rel_remove'] != 'rel_remove_external' && $type != LINK_EXTERNAL)) {
+          unset($item['attributes']['rel']);
+        }
+      }
+
+      // Handle "title" link attribute.
+      if (!empty($item['attributes']['title']) && module_exists('token')) {
+        $item['attributes']['title'] = token_replace($item['attributes']['title'], array($entity_type => $entity));
+        $item['attributes']['title'] = filter_xss($item['attributes']['title'], array('b', 'br', 'code', 'em', 'i', 'img', 'span', 'strong', 'sub', 'sup', 'tt', 'u'));
+      }
+      // Remove title attribute if it's equal to link text.
+      if (isset($item['attributes']['title']) && $item['attributes']['title'] == $item['title']) {
+        unset($item['attributes']['title']);
+      }
+      unset($item['attributes']['configurable_title']);
+
+      // Remove empty attributes.
+      $item['attributes'] = array_filter($item['attributes']);
+
+      // Sets title to trimmed url if one exists
+      // @todo Obsolete?
+      /*if(!empty($item['display_url']) && empty($item['title'])) {
+        $item['title'] = $item['display_url'];
+      }
+      elseif(!isset($item['title'])) {
+        $item['title'] = $item['url'];
+      }*/
     }
   }
 }
@@ -357,160 +474,6 @@ function link_field_widget_form(&$form, &$form_state, $field, $instance, $langco
 }
 
 /**
- * Clean up user-entered values for a link field according to field settings.
- *
- * @param $item
- *   A single link item, usually containing url, title, and attributes.
- * @param $delta
- *   The delta value if this field is one of multiple fields.
- * @param $field
- *   The CCK field definition.
- * @param $node
- *   The node containing this link.
- */
-function _link_sanitize(&$item, $delta, &$field, $instance, &$node) {
-  // Don't try to process empty links.
-  if (empty($item['url']) && empty($item['title'])) {
-    return;
-  }
-
-  // Replace URL tokens.
-  if (isset($instance['settings']['enable_tokens']) && $instance['settings']['enable_tokens']) {
-    global $user;
-    // Load the node if necessary for nodes in views.
-    $token_node = isset($node->nid) ? node_load($node->nid) : $node;
-    $item['url'] = token_replace($item['url'], array('node' => $token_node));
-  }
-
-  $type = link_validate_url($item['url']);
-  // If the type of the URL cannot be determined and URL validation is disabled,
-  // then assume LINK_EXTERNAL for later processing.
-  if ($type == FALSE && $instance['settings']['validate_url'] === 0) {
-    $type = LINK_EXTERNAL;
-  }
-  $url = link_cleanup_url($item['url']);
-  $item['url'] = check_plain($url);
-
-  // Separate out the anchor, if any.
-  if (strpos($url, '#') !== FALSE) {
-    $item['fragment'] = substr($url, strpos($url, '#') + 1);
-    $url = substr($url, 0, strpos($url, '#'));
-  }
-  // Separate out the query string, if any.
-  if (strpos($url, '?') !== FALSE) {
-    $query = substr($url, strpos($url, '?') + 1);
-    parse_str($query, $query_array);
-    $item['query'] = $query_array;
-    $url = substr($url, 0, strpos($url, '?'));
-  }
-
-  // Create a shortened URL for display.
-  if ($type == LINK_EMAIL) {
-    $display_url = str_replace('mailto:', '', $url);
-  }
-  else {
-    $display_url = url($url, array(
-      'query' => isset($item['query']) ? $item['query'] : NULL,
-      'fragment' => isset($item['fragment']) ? $item['fragment'] : NULL,
-      'absolute' => TRUE,
-    ));
-  }
-  if ($instance['settings']['display']['url_cutoff'] && strlen($display_url) > $instance['settings']['display']['url_cutoff']) {
-    $display_url = substr($display_url, 0, $instance['settings']['display']['url_cutoff']) . "...";
-  }
-  $item['display_url'] = $display_url;
-
-  // Use the title defined at the instance level.
-  if ($instance['settings']['title'] == 'value' && strlen(trim($instance['settings']['title_value']))) {
-    $title = $instance['settings']['title_value'];
-  }
-  // Use the title defined by the user at the widget level.
-  elseif (isset($item['title'])) {
-    $title = $item['title'];
-  }
-  else {
-    $title = '';
-  }
-
-  // Replace tokens.
-  if ($title && ($instance['settings']['title'] == 'value' || $instance['settings']['enable_tokens'])) {
-    // Load the node if necessary for nodes in views.
-    $token_node = isset($node->nid) ? node_load($node->nid) : $node;
-    $title = token_replace($title, array('node' => $token_node));
-    $title = filter_xss($title, array('b', 'br', 'code', 'em', 'i', 'img', 'span', 'strong', 'sub', 'sup', 'tt', 'u'));
-    $item['html'] = TRUE;
-  }
-  $item['title'] = empty($title) ? $item['display_url'] : $title;
-
-  if (!isset($item['attributes'])) {
-    $item['attributes'] = array();
-  }
-
-  // Unserialize attributtes array if it has not been unserialized yet.
-  if (!is_array($item['attributes'])) {
-    $item['attributes'] = (array)unserialize($item['attributes']);
-  }
-
-  // Add default attributes.
-  if (!is_array($instance['settings']['attributes'])) {
-    $instance['settings']['attributes'] = _link_default_attributes();
-  }
-  else {
-    $instance['settings']['attributes'] += _link_default_attributes();
-  }
-
-  // Merge item attributes with attributes defined at the field level.
-  $item['attributes'] += $instance['settings']['attributes'];
-
-  // If user is not allowed to choose target attribute, use default defined at
-  // field level.
-  if ($instance['settings']['attributes']['target'] != LINK_TARGET_USER) {
-    $item['attributes']['target'] = $instance['settings']['attributes']['target'];
-  }
-  elseif ($item['attributes']['target'] == LINK_TARGET_USER) {
-    $item['attributes']['target'] = LINK_TARGET_DEFAULT;
-  }
-
-  // Remove the target attribute if the default (no target) is selected.
-  if (empty($item['attributes']) || $item['attributes']['target'] == LINK_TARGET_DEFAULT) {
-    unset($item['attributes']['target']);
-  }
-
-  // Remove rel attribute for internal or external links if selected.
-  if (isset($item['attributes']['rel']) && isset($instance['settings']['rel_remove']) && $instance['settings']['rel_remove'] != 'default') {
-    if (($instance['settings']['rel_remove'] != 'rel_remove_internal' && $type != LINK_INTERNAL) ||
-      ($instance['settings']['rel_remove'] != 'rel_remove_external' && $type != LINK_EXTERNAL)) {
-      unset($item['attributes']['rel']);
-    }
-  }
-
-  // Handle "title" link attribute.
-  if (!empty($item['attributes']['title']) && module_exists('token')) {
-    // Load the node (necessary for nodes in views).
-    $token_node = isset($node->nid) ? node_load($node->nid) : $node;
-    $item['attributes']['title'] = token_replace($item['attributes']['title'], array('node' => $token_node));
-    $item['attributes']['title'] = filter_xss($item['attributes']['title'], array('b', 'br', 'code', 'em', 'i', 'img', 'span', 'strong', 'sub', 'sup', 'tt', 'u'));
-  }
-  // Remove title attribute if it's equal to link text.
-  if (isset($item['attributes']['title']) && $item['attributes']['title'] == $item['title']) {
-    unset($item['attributes']['title']);
-  }
-  unset($item['attributes']['configurable_title']);
-
-  // Remove empty attributes.
-  $item['attributes'] = array_filter($item['attributes']);
-
-  // Sets title to trimmed url if one exists
-  // @todo Obsolete?
-  /*if(!empty($item['display_url']) && empty($item['title'])) {
-    $item['title'] = $item['display_url'];
-  }
-  elseif(!isset($item['title'])) {
-    $item['title'] = $item['url'];
-  }*/
-}
-
-/**
  * Implements hook_theme().
  */
 function link_theme() {
-- 
1.7.6.msysgit.0


From 4dc434b123cfe988ff64427bab92e6d58a8e91c5 Mon Sep 17 00:00:00 2001
From: sun <sun@unleashedmind.com>
Date: Sat, 7 Jul 2012 06:44:55 +0200
Subject: [PATCH 11/13] Refactored link_field_process() into
 hook_field_widget_form().

---
 link.module |  125 +++++++++++++++++++++--------------------------------------
 1 files changed, 44 insertions(+), 81 deletions(-)

diff --git a/link.module b/link.module
index fe0971e..ad528fa 100644
--- a/link.module
+++ b/link.module
@@ -466,10 +466,51 @@ function link_field_widget_info() {
  * Implements hook_field_widget_form().
  */
 function link_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) {
-  $element += array(
-    '#type' => $instance['widget']['type'],
-    '#default_value' => isset($items[$delta]) ? $items[$delta] : '',
+  $element['#theme'] = 'link_field';
+  $settings = $instance['settings'];
+
+  $element['url'] = array(
+    '#type' => 'textfield',
+    '#maxlength' => LINK_URL_MAX_LENGTH,
+    '#title' => t('URL'),
+    '#required' => $element['#required'] || $settings['url'] === 'optional',
+    '#default_value' => isset($items[$delta]['url']) ? $items[$delta]['url'] : NULL,
   );
+  $element['title'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Title'),
+    '#maxlength' => $settings['title_maxlength'],
+    '#required' => $settings['title'] === 'required',
+    '#default_value' => isset($items[$delta]['title']) ? $items[$delta]['title'] : NULL,
+    '#access' => $settings['title'] !== 'none' && $settings['title'] !== 'value',
+    '#description' => t('The link title is limited to @maxlength characters maximum.', array('@maxlength' => $settings['title_maxlength'])),
+  );
+
+  // Initialize field attributes as an array if it is not an array yet.
+  if (!is_array($settings['attributes'])) {
+    $settings['attributes'] = array();
+  }
+  // Add default attributes.
+  $settings['attributes'] += _link_default_attributes();
+  $attributes = isset($items[$delta]['attributes']) ? $items[$delta]['attributes'] : $settings['attributes'];
+  if (!empty($settings['attributes']['target']) && $settings['attributes']['target'] == LINK_TARGET_USER) {
+    $element['attributes']['target'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Open URL in a New Window'),
+      '#return_value' => LINK_TARGET_NEW_WINDOW,
+      '#default_value' => isset($attributes['target']) ? $attributes['target'] : FALSE,
+    );
+  }
+  if (!empty($settings['attributes']['configurable_title']) && $settings['attributes']['configurable_title'] == 1) {
+    $element['attributes']['title'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Link "title" attribute'),
+      '#default_value' => isset($attributes['title']) ? $attributes['title'] : '',
+      '#field_prefix' => 'title = "',
+      '#field_suffix' => '"',
+    );
+  }
+
   return $element;
 }
 
@@ -538,19 +579,6 @@ function theme_link_field($vars) {
   return $output;
 }
 
-/**
- * Implements hook_element_info().
- */
-function link_element_info() {
-  $elements['link_field'] = array(
-    '#input' => TRUE,
-    '#process' => array('link_field_process'),
-    '#theme' => 'link_field',
-    '#theme_wrappers' => array('form_element'),
-  );
-  return $elements;
-}
-
 function _link_default_attributes() {
   return array(
     'target' => LINK_TARGET_DEFAULT,
@@ -560,71 +588,6 @@ function _link_default_attributes() {
 }
 
 /**
- * Processes the link type element before displaying the field.
- *
- * Build the form element. When creating a form using FAPI #process,
- * note that $element['#value'] is already set.
- *
- * The $fields array is in $complete_form['#field_info'][$element['#field_name']].
- */
-function link_field_process($element, $form_state, $complete_form) {
-  $instance = field_widget_instance($element, $form_state);
-  $settings = $instance['settings'];
-  $element['url'] = array(
-    '#type' => 'textfield',
-    '#maxlength' => LINK_URL_MAX_LENGTH,
-    '#title' => t('URL'),
-    '#required' => ($element['#delta'] == 0 && $settings['url'] !== 'optional') ? $element['#required'] : FALSE,
-    '#default_value' => isset($element['#value']['url']) ? $element['#value']['url'] : NULL,
-  );
-  if ($settings['title'] !== 'none' && $settings['title'] !== 'value') {
-    $element['title'] = array(
-      '#type' => 'textfield',
-      '#maxlength' => $settings['title_maxlength'],
-      '#title' => t('Title'),
-      '#description' => t('The link title is limited to @maxlength characters maximum.', array('@maxlength' => $settings['title_maxlength'])),
-      '#required' => ($settings['title'] == 'required' && (($element['#delta'] == 0 && $element['#required']) || !empty($element['#value']['url']))) ? TRUE : FALSE,
-      '#default_value' => isset($element['#value']['title']) ? $element['#value']['title'] : NULL,
-    );
-  }
-
-  // Initialize field attributes as an array if it is not an array yet.
-  if (!is_array($settings['attributes'])) {
-    $settings['attributes'] = array();
-  }
-  // Add default attributes.
-  $settings['attributes'] += _link_default_attributes();
-  $attributes = isset($element['#value']['attributes']) ? $element['#value']['attributes'] : $settings['attributes'];
-  if (!empty($settings['attributes']['target']) && $settings['attributes']['target'] == LINK_TARGET_USER) {
-    $element['attributes']['target'] = array(
-      '#type' => 'checkbox',
-      '#title' => t('Open URL in a New Window'),
-      '#return_value' => LINK_TARGET_NEW_WINDOW,
-      '#default_value' => isset($attributes['target']) ? $attributes['target'] : FALSE,
-    );
-  }
-  if (!empty($settings['attributes']['configurable_title']) && $settings['attributes']['configurable_title'] == 1) {
-    $element['attributes']['title'] = array(
-      '#type' => 'textfield',
-      '#title' => t('Link "title" attribute'),
-      '#default_value' => isset($attributes['title']) ? $attributes['title'] : '',
-      '#field_prefix' => 'title = "',
-      '#field_suffix' => '"',
-    );
-  }
-
-  // If the title field is avaliable or there are field accepts multiple values
-  // then allow the individual field items display the required asterisk if needed.
-  if (isset($element['title']) || isset($element['_weight'])) {
-    // To prevent an extra required indicator, disable the required flag on the
-    // base element since all the sub-fields are already required if desired.
-    $element['#required'] = FALSE;
-  }
-
-  return $element;
-}
-
-/**
  * Implements hook_field_formatter_info().
  */
 function link_field_formatter_info() {
-- 
1.7.6.msysgit.0


From 05048a0c49de15b4badaadf66af48ef51a778914 Mon Sep 17 00:00:00 2001
From: sun <sun@unleashedmind.com>
Date: Sat, 7 Jul 2012 06:47:33 +0200
Subject: [PATCH 12/13] Fixed link_field_formatter_view() renders field items
 too early.

---
 link.module |    4 +++-
 1 files changed, 3 insertions(+), 1 deletions(-)

diff --git a/link.module b/link.module
index ad528fa..160e441 100644
--- a/link.module
+++ b/link.module
@@ -642,7 +642,9 @@ function link_field_formatter_view($entity_type, $entity, $field, $instance, $la
   $elements = array();
   foreach ($items as $delta => $item) {
     $elements[$delta] = array(
-      '#markup' => theme('link_formatter_' . $display['type'], array('element' => $item, 'field' => $instance)),
+      '#theme' => 'link_formatter_' . $display['type'],
+      '#element' => $item,
+      '#field' => $instance,
     );
   }
   return $elements;
-- 
1.7.6.msysgit.0


From bec9a0e058838572dc17830c37e09137b956d19f Mon Sep 17 00:00:00 2001
From: sun <sun@unleashedmind.com>
Date: Sat, 7 Jul 2012 07:03:57 +0200
Subject: [PATCH 13/13] Refactored link_cleanup_url() into
 hook_field_prepare_view().

---
 link.module |   43 ++++++++++++-------------------------------
 1 files changed, 12 insertions(+), 31 deletions(-)

diff --git a/link.module b/link.module
index 160e441..a0af670 100644
--- a/link.module
+++ b/link.module
@@ -327,6 +327,7 @@ function link_field_presave($entity_type, $entity, $field, $instance, $langcode,
 function link_field_prepare_view($entity_type, $entities, $field, $instances, $langcode, &$items) {
   foreach ($entities as $id => $entity) {
     foreach ($items[$id] as $delta => &$item) {
+      $item['url'] = trim($item['url']);
       // Don't try to process empty links.
       if (empty($item['url']) && empty($item['title'])) {
         return;
@@ -343,8 +344,17 @@ function link_field_prepare_view($entity_type, $entities, $field, $instances, $l
       if ($type == FALSE && $instances[$id]['settings']['validate_url'] === 0) {
         $type = LINK_EXTERNAL;
       }
-      $url = link_cleanup_url($item['url']);
-      $item['url'] = check_plain($url);
+      if ($type === LINK_EXTERNAL) {
+        // Check if there is no protocol specified.
+        if (!preg_match("/^([a-z0-9][a-z0-9\.\-_]*:\/\/)/i", $item['url'])) {
+          // But should there be? Add an automatic http:// if it starts with a domain name.
+          if (preg_match('/^(([a-z0-9]([a-z0-9\-_]*\.)+)(' . LINK_DOMAINS . '|[a-z]{2}))/i', $item['url'])) {
+            $item['url'] = 'http://' . $item['url'];
+          }
+        }
+      }
+      $url = $item['url'];
+      $item['url'] = check_plain($item['url']);
 
       // Separate out the anchor, if any.
       if (strpos($url, '#') !== FALSE) {
@@ -799,35 +809,6 @@ function link_migrate_api() {
 }
 
 /**
- * Forms a valid URL if possible from an entered address.
- *
- * Trims whitespace and automatically adds an http:// to addresses without a
- * protocol specified.
- *
- * @param string $url
- * @param string $protocol
- *   The protocol to prepend to $url if none is specified.
- */
-function link_cleanup_url($url, $protocol = 'http') {
-  $url = trim($url);
-  $type = link_validate_url($url);
-
-  if ($type === LINK_EXTERNAL) {
-    // Check if there is no protocol specified.
-    $protocol_match = preg_match("/^([a-z0-9][a-z0-9\.\-_]*:\/\/)/i", $url);
-    if (empty($protocol_match)) {
-      // But should there be? Add an automatic http:// if it starts with a domain name.
-      $domain_match = preg_match('/^(([a-z0-9]([a-z0-9\-_]*\.)+)(' . LINK_DOMAINS . '|[a-z]{2}))/i', $url);
-      if (!empty($domain_match)) {
-        $url = $protocol . "://" . $url;
-      }
-    }
-  }
-
-  return $url;
-}
-
-/**
  * Validates a URL.
  *
  * Accepts all URLs following RFC 1738 standard for URL formation and all e-mail
-- 
1.7.6.msysgit.0

