I'm the maintainer of the Unique Field module, which has been suggested as a solution for implementing a requirement that the link field have a unique value (#88037: How to avoid duplicate entries for a link field?). I'm following up on a frequent issue for people who try to do this.

Since the Link module does not cleanup URLs (like by adding "http://") before storing them, two URLs that look identical when displayed (after being cleaned up) are not stored with the same value in the database, and therefore are not easily detected as duplicate values by the Unique Field module.

Would you consider a change to the Link module so URLs are normalized before being saved?

Comments

mlncn’s picture

I'm also interested in this feature but like "the Drupal way" of cleaning up user-input content on display.

Ah. But the SQL query to find matching values is so much better if we clean up URLs on input.

Therefore, i second the request to have Link module clean up URLs.

Would a patch be accepted to have Link standardize URLs on save:

  • provide http:// if nothing provided
  • (less certain about this one) no slash on the end

This only sort of helps, though. For my purposes i could assume that www and no www links are identical, but Link module cannot standardize that on save.

Maybe the query has to be ugly, or a separate index table maintained? Which module should this go in?

I'm also very interested in having the check done by AJAX, would either module accept that?

benjamin, agaric

daveparrish’s picture

sub

aac’s picture

Could you got any solution to this problem. I am trying to develop an ajax based module for checking the duplicacy of urls stored in the database.

mlncn’s picture

aac, i'm working on http://drupal.org/project/formmsgs for Drupal 7.

aac’s picture

Thanks for your response!! Its nice that you are developing a generic module for ajax style checking of form fields, but it is for drupal 7 only.
At present i am trying to get this functionality for Drupal 6. I have gone through each and every issue of unique field module and link module issue queues. In fact i have written a generic module for title checking and now i am trying to make another module for urls submitted by cck link field module. In fact, i have written it, but i am facing some issue. So i am looking for some help. I am mentioning the issue here, if you are able to help me in solving the issue, it would be much appreciable.

My module is based on http://data.agaric.com/node/365.
In my *.module file, i am getting the url value submitted by a user in the following way-

/**
 * Main AJAX callback function: cck url field originality check menu callback.
 */
function url_ajax_check_callback() {
  $output = array();

  $type = check_plain($_GET['type']);

  // List of cck url fields (for which uniqueness is to be checked) for this content type.
  $fields = array('field_my_url');

  foreach ($fields as $f) {
    $field = content_fields($f);
    $field_name = $field['field_name'];

    $db_info = content_database_info($field);
    $table = $db_info['table'];

    $urlvalue = $_GET[$field['field_name']['url']];   //current inputted url. When i check in firebug my $_GET shows me http://www.mywebsite.com/url_ajax_check/isunique?urlvalue=http%3A%2F%2Fwww.xyz.com&type=my_custom_type. It is encoding the url. ':' as %3A and '/' as %2F where www.xyz.com is the url typed in the url/link field.

    $nids = url_ajax_check_duplicate($urlvalue, $field_name, $table, $type); // Run SQL Query here.

    if (!empty($nids)) {
      // This cck url value already exists.
      $output['allowed'] = FALSE;
      foreach ($nids as $nid) {
        // There should only ever be one duplicate if this check is in place.
        $output['msg'] = t('The field_my_url !urlvalue already exists.', array(
          '!urlvalue' => l(field_my_url, 'node/' . $nid),)
        );
      }
    }
    else {
      $output['allowed'] = TRUE;
      $output['msg'] = t('This urlvalue is available.');
    }

    drupal_json($output);
    exit();
  }
}

My SQL query function is-

function url_ajax_check_duplicate($urlvalue, $field_name, $table, $type) {
  $field_format = $field_name . '_url';

  $sql = "SELECT n.nid, n.title FROM {node} n LEFT JOIN {" . $table . "} tbl ON tbl.nid = n.nid WHERE tbl." . $field_format . " = " . $urlvalue . " AND type = '%s', " . $type;

  $results = db_query($sql);

  $nids = array();
  while ($row = db_fetch_object($results)) {
    if ($row && $row->nid && $row->title) {
      $nids[] = $row->nid;
      $title = $row->title;
    }
  }
  return array_unique($nids);
}

And my *.js file is using following-

function url_ajax_check(urlField) {
  clearTimeout(Drupal.UrlAjaxCheckTimer);
  Drupal.CheckUrl = urlField.val();

  $.ajax({
    url: Drupal.settings.UrlAjaxCheck.ajaxUrl,
    data: {
      urlvalue: Drupal.CheckUrl,
      type: Drupal.settings.UrlAjaxCheck.type
    },
    dataType: 'json',
    beforeSend: function() {....

Now, my issue is that if i type a url (which, i know, is already available in my database) in the cck url/link field , this module shows me that this url does not exist in the database (while it should be opposite) (Actually, I checked the same sql query in phpmyadmin and it gives the 'nid' and 'title' of the node where this url value is being used.). In fact, it shows the similar behaviour for any url submitted. So i assume that either there is some issue with my sql query function or i need to convert the url in some other format before comparing it to the database value of the url.

Thanks in advance for any help!!

mlncn’s picture

Heh, that data.agaric code is mine. I just expanded on that start with some horrible hard-coded hacky, wastefully duplicated JavaScript, etc.— http://drupal.org/sandbox/mlncn/1129680

As for your difficulties, your /browser/ might be showing things as urlencoded that aren't? Also is $_GET what i use in the sandbox module? And finally if it is urlencoded perhaps it has to be urldecoded.

aac’s picture

I have byepassed the sql query in my main Ajax function url_ajax_check_callback() above and just tried to print the value of $urlvalue through ajax as shown below-

$output['msg'] = 'You have typed ' . $urlvalue . ' in field_my_url.';

I have found that

$urlvalue = $_GET[$field['field_name']['url']];

is not getting anyvalue in $urlvalue.

If i use

$output['msg'] = 'You have typed ' . $type . ' in field_my_url.';

It prints $type correctly in ajax.
Any help??

jcfiala’s picture

Well, on the one hand I like the way the module works one.

On the other hand, I see what you mean.

Would it be possible to have a canonical field for links, where I stick what I think the canonical value would be, and you could key off of that?

aac’s picture

Thanks a lot Jcfiala for your response!!
But i am not getting what you are saying here!! Please make it more clear as i am not an expert in development, i am only knowing more than a beginner.
I think i am stuck only to get the value typed in the url field in some variable (say $urlvalue) using $_GET. (I have disabled the title field for link module.). What would be the syntax for that?

DamienMcKenna’s picture

Issue summary: View changes
Status: Active » Closed (won't fix)

Thank you all for your efforts, but I'm sorry to say that the D6 version is no longer supported.