Index: unique_field.module =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/unique_field/unique_field.module,v retrieving revision 1.6.2.6 diff -u -p -r1.6.2.6 unique_field.module --- unique_field.module 13 Nov 2009 01:30:15 -0000 1.6.2.6 +++ unique_field.module 28 Nov 2009 21:44:40 -0000 @@ -24,6 +24,12 @@ define('UNIQUE_FIELD_SCOPE_TYPE', 'type' define('UNIQUE_FIELD_SCOPE_LANGUAGE', 'language'); define('UNIQUE_FIELD_SCOPE_ALL', 'all'); +// additional link definitions +define('UNIQUE_FIELD_LINK_OPTIONS_WWW', 'www'); +define('UNIQUE_FIELD_LINK_OPTIONS_HTTP', 'http'); +define('UNIQUE_FIELD_LINK_OPTIONS_TRAILING_SLASH', 'trailing-slash'); +define('UNIQUE_FIELD_LINK_OPTIONS_TRIM', 'trim'); + // query comparison definitions define('UNIQUE_FIELD_COMP_EACH', 'each'); define('UNIQUE_FIELD_COMP_ALL', 'all'); @@ -72,6 +78,7 @@ function unique_field_nodeapi(&$node, $o // get list of unique fields for node type $fields = variable_get('unique_field_fields_'. $node->type, array()); + $fieldsLink = variable_get('unique_field_link_fields_'. $node->type, array()); // check if there are unique fields for this node type if (count($fields)) { @@ -154,6 +161,13 @@ function unique_field_nodeapi(&$node, $o foreach ($f as $index => $value) { if (is_numeric($index) && is_array($value)) { $values[] = $value; + + // Add additional values for link fields + if(in_array($field, $fieldsLink)) { + // Generate other similar URLs to additionally check for + $additionalLinkValues = generate_additional_url_values($value, variable_get('unique_field_link_options_'. $node->type, array())); + $values = array_merge($values, $additionalLinkValues); + } } } } @@ -322,6 +336,7 @@ function unique_field_match_value($field $q .= "JOIN {". $qtbl ."} AS ". $qtbl ." USING (vid) "; } $q .= "WHERE ". $qwhere; + //print '
';var_dump($q);print '';die(); $res = db_query($q); $nids = array(); while ($obj = db_fetch_object($res)) { @@ -345,11 +360,16 @@ function unique_field_node_settings_form if (module_exists('locale') && variable_get('language_content_type_'. $ntype, 0)) { $fieldopts[UNIQUE_FIELD_FIELDS_LANGUAGE] = t('Language'); } + $fieldLinkOptions = array(); if (module_exists('content')) { $ctype = content_types($ntype); if (is_array($ctype) && is_array($ctype['fields'])) { foreach ($ctype['fields'] as $field => $info) { $fieldopts[$field] = $info['widget']['label'] .' ('. $field .')'; + // Create list of fields that are of type 'link' + if(module_exists('link') && $info['type'] == 'link') { + $fieldLinkOptions[$field] = $info['widget']['label'] .' ('. $field .')'; + } } } } @@ -397,6 +417,29 @@ function unique_field_node_settings_form '#options' => array(UNIQUE_FIELD_SHOW_MATCHES => t('Enabled')), '#default_value' => variable_get('unique_field_show_matches_'. $ntype, array()), ); + // Additional options for Link fields + if($fieldLinkOptions) { + $form['unique_field']['unique_field_link_fields'] = array( + '#type' => 'checkboxes', + '#title' => t('Choose the fields to do additional URL checking'), + '#options' => $fieldLinkOptions, + '#default_value' => variable_get('unique_field_link_fields_'. $ntype, array()), + '#description' => t('Additional URL checks will go into making sure URL values are truely unique. For example http://example.com/ will match www.example.com/. Notice: This probably does not work with node scope and has not been tested with multiple URLs per field.'), + ); + + $form['unique_field']['unique_field_link_options'] = array( + '#type' => 'checkboxes', + '#title' => t('Choose the additional checks for URLs'), + '#options' => array( + UNIQUE_FIELD_LINK_OPTIONS_WWW => t('With or without www.'), + UNIQUE_FIELD_LINK_OPTIONS_HTTP => t('With or without http://'), + UNIQUE_FIELD_LINK_OPTIONS_TRAILING_SLASH => t('With or without trailing /'), + UNIQUE_FIELD_LINK_OPTIONS_TRIM => t('Trim whitespace before and after URL'), + ), + '#default_value' => variable_get('unique_field_link_options_'. $ntype, array()), + '#description' => t('Choose the additional checks to be performed on the Link fields selected above.'), + ); + } // add validation function $form['#validate'][] = 'unique_field_node_settings_form_validate'; @@ -415,3 +458,190 @@ function unique_field_node_settings_form } } } + +/** + * Generates and returns addition url values that can be used by unique_field_match_value + * to check for unique truely unique URLs + * + * @param array $value Should be in the form + * @param array List of options for do additional checks + * @return array Array of new $value arrays + */ +function generate_additional_url_values($value, $link_options) { + + $url = array(); + $additionalValues = array(); + + $urlMatches = get_url_sections($value['url']); + + if($urlMatches = null) { + // URL isn't valid so return + // TODO: Some kind of message here? + return($additionalValues); + } + + /* define('UNIQUE_FIELD_LINK_OPTIONS_WWW', 'www'); +define('UNIQUE_FIELD_LINK_OPTIONS_HTTP', 'http'); +define('UNIQUE_FIELD_LINK_OPTIONS_TRAILING_SLASH', 'trailing-slash'); +define('UNIQUE_FIELD_LINK_OPTIONS_TRIM', 'trim'); */ + + // Add additional URL checks here + if(in_array(UNIQUE_FIELD_LINK_OPTIONS_HTTP, $link_options)) { // HTTP check + $additionalValues = array_merge($additionalValues, create_http_values($value)); + } + + // WWW check + if(in_array(UNIQUE_FIELD_LINK_OPTIONS_WWW, $link_options)) { + // Add check to additional URLs created + foreach($additionalValues as $additionalValue) { + $additionalValues = array_merge($additionalValues, create_www_values($additionalValue)); + } + $additionalValues = array_merge($additionalValues, create_www_values($value)); + } + + // Trailing slashes check + if(in_array(UNIQUE_FIELD_LINK_OPTIONS_TRAILING_SLASH, $link_options)) { + // Add check to additional URLs created + foreach($additionalValues as $additionalValue) { + $additionalValues = array_merge($additionalValues, create_trailing_slash_values($additionalValue)); + } + $additionalValues = array_merge($additionalValues, create_trailing_slash_values($value)); + } + + // Create trimmed URLs + if(in_array(UNIQUE_FIELD_LINK_OPTIONS_TRIM, $link_options)) { + // Add check to additional URLs created + foreach($additionalValues as $additionalValue) { + $additionalValues = array_merge($additionalValues, create_trim_values($additionalValue)); + } + $additionalValues = array_merge($additionalValues, create_trim_values($value)); + } + + return($additionalValues); +} + +/** + * Create new URLs for HTTP checks from the $value param + */ +function create_http_values($value){ + $urlSections = get_url_sections($value['url']); + $newValues = array(); + + if(!$urlSections) { + // URL isn't valid so return + // TODO: Some kind of message here? + return($newValues); + } + + // Add HTTP checks + if(strcasecmp($urlSections['scheme'], 'http://') == 0) { + // Create url without http:// + $newValues[] = create_new_link_value($urlSections['all_except_scheme'], $value); + } else if(!$urlSections['scheme']) { + // Create url with http:// + $newValues[] = create_new_link_value('http://' . $urlSections['all_except_scheme'], $value); + } + + return($newValues); +} + +/** + * Create new URLs for WWW checks from the $value param + */ +function create_www_values($value){ + $urlSections = get_url_sections($value['url']); + $newValues = array(); + + if(!$urlSections) { + // URL isn't valid so return + // TODO: Some kind of message here? + return($newValues); + } + + //break apart hostname + $hostname_sections = explode('.', $urlSections['all_except_scheme']); + + // Add WWW checks + if(strcasecmp($hostname_sections[0],'www') == 0) { + // Create url without www + $newURL = implode('.', array_slice($hostname_sections, 1)); + + $newValues[] = create_new_link_value($urlSections['scheme']. $newURL, $value); + } else { + // Create url with www + $newValues[] = create_new_link_value($urlSections['scheme'] . 'www.' . $urlSections['all_except_scheme'], $value); + } + + //print '
';var_dump($newValues);print '';//die(); + + return($newValues); +} + +/** + * Create new URLs for trailing slash checks from the $value param + */ +function create_trailing_slash_values($value){ + $newValues = array(); + + if(preg_match('/\/(\s*)$/', $value['url'])) { + // Remove trailing slash + $newValues[] = create_new_link_value(preg_replace('/\/(\s*)$/', '$1', $value['url']), $value); + } else { + // Add a trailing slash + if(preg_match('/(\s*)$/', $value['url'])) { + $newValues[] = create_new_link_value(preg_replace('/(\s*)$/', '/$1', $value['url']), $value); + } else { + $newValues[] = create_new_link_value($value['url'] . '/', $value); + } + } + + return($newValues); +} + +/** + * Create new URLs for trimmed string checks from the $value param + */ +function create_trim_values($value) { + $newValues = array(); + + $trimmedUrl = trim($value['url']); + + if($trimmedUrl != $value['url']) { + $newValues[] = create_new_link_value($trimmedUrl, $value); + } + + return($newValues); +} + +/** + * Helper to get the URL sections + * @param string The url to break apart + * @return array The sections pulled out of the URL + */ +function get_url_sections($url){ + // Match different sections of the URL ( Copied and modified from http://www.php.net/manual/en/function.preg-match.php#93824 ) + $regex = "(?P