Skip to content

Commit

Permalink
Support for WPML
Browse files Browse the repository at this point in the history
Use a NOT IN statement when checking for conflicting post_ids to
support WPML since the meta values will be set for each language but
shouldn’t count as a duplicate.
  • Loading branch information
doublesharp committed Jun 30, 2014
1 parent a184b64 commit f2d9403
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 17 deletions.
1 change: 1 addition & 0 deletions readme.txt
Expand Up @@ -45,6 +45,7 @@ Validated Field will appear as a new input type in the field group editor.
== Changelog ==
= 1.3rc1 =
* Support front end validation using [`acf_form()`](http://www.advancedcustomfields.com/resources/functions/acf_form/).
* Support for WPML, props @gunnyst.
* Move configuration to WordPress Admin under `Custom Fields > Validated Field Settings`.
* Improved SQL for unique queries to support Relationship fields - check arrays and single IDs.
* Fix conflicts with ACF client side validation.
Expand Down
59 changes: 42 additions & 17 deletions validated_field_v4.php
Expand Up @@ -298,23 +298,34 @@ function ajax_validate_fields() {
if ( $valid && ! empty( $value ) && ! empty( $unique ) && $unique != 'non-unique' ){
global $wpdb;
$status_in = "'" . implode( "','", $field['unique_statuses'] ) . "'";

// WPML compatibility, get code list of active languages
if ( function_exists( 'icl_object_id' ) ){
$languages = $wpdb->get_results( "SELECT code FROM {$wpdb->prefix}icl_languages WHERE active = 1", ARRAY_A );
$wpml_ids = array();
foreach( $languages as $lang ){
$wpml_ids[] = (int) icl_object_id( $post_id, $post_type, true, $lang['code'] );
}
$post_ids = implode( ',', array_unique( $wpml_ids ) );
} else {
$post_ids = array( (int) $post_id );
}

$sql_prefix = "SELECT pm.meta_id AS meta_id, pm.post_id AS post_id, p.post_title AS post_title FROM {$wpdb->postmeta} pm JOIN {$wpdb->posts} p ON p.ID = pm.post_id AND p.post_status IN ($status_in)";
switch ( $unique ){
case 'global':
// check to see if this value exists anywhere in the postmeta table
$sql = $wpdb->prepare(
"{$sql_prefix} AND post_id != %d WHERE ( meta_value = %s OR meta_value LIKE %s )",
$post_id,
"{$sql_prefix} AND post_id NOT IN [NOT_IN] WHERE ( meta_value = %s OR meta_value LIKE %s )",
$value,
'%"' . like_escape( $value ) . '"%'
);
break;
case 'post_type':
// check to see if this value exists in the postmeta table with this $post_id
$sql = $wpdb->prepare(
"{$sql_prefix} AND p.post_type = %s AND post_id != %d WHERE ( meta_value = %s OR meta_value LIKE %s )",
$post_type,
$post_id,
"{$sql_prefix} AND p.post_type = %s AND post_id NOT IN [NOT_IN] WHERE ( meta_value = %s OR meta_value LIKE %s )",
$post_type,
$value,
'%"' . like_escape( $value ) . '"%'
);
Expand All @@ -324,23 +335,20 @@ function ajax_validate_fields() {
if ( $is_repeater ){
$this_key = $parent_field['name'] . '_' . $index . '_' . $field['name'];
$meta_key = $parent_field['name'] . '_%_' . $field['name'];
$sql = $wpdb->prepare(
"{$sql_prefix} AND p.post_type = %s WHERE ( ( post_id = %d AND meta_key != %s AND meta_key LIKE %s ) OR ( post_id != %d AND meta_key LIKE %s ) ) AND ( meta_value = %s OR meta_value LIKE %s )",
$post_type,
$post_id,
$this_key,
$meta_key,
$post_id,
$meta_key,
$sql = $wpdb->prepare(
"{$sql_prefix} AND p.post_type = %s WHERE ( ( post_id NOT IN [NOT_IN] AND meta_key != %s AND meta_key LIKE %s ) OR ( post_id NOT IN [NOT_IN] AND meta_key LIKE %s ) ) AND ( meta_value = %s OR meta_value LIKE %s )",
$post_type,
$this_key,
$meta_key,
$meta_key,
$value,
'%"' . like_escape( $value ) . '"%'
);
} else {
$sql = $wpdb->prepare(
"{$sql_prefix} AND p.post_type = %s AND post_id != %d WHERE meta_key = %s AND ( meta_value = %s OR meta_value LIKE %s )",
$post_type,
$post_id,
$field['name'],
"{$sql_prefix} AND p.post_type = %s AND post_id NOT IN ([NOT_IN]) WHERE meta_key = %s AND ( meta_value = %s OR meta_value LIKE %s )",
$post_type,
$field['name'],
$value,
'%"' . like_escape( $value ) . '"%'
);
Expand All @@ -354,6 +362,10 @@ function ajax_validate_fields() {

// Only run if we hit a condition above
if ( ! empty( $sql ) ){

// Update the [NOT_IN] values
$sql = $this->prepare_not_in( $sql, $post_ids );

// Execute the SQL
$rows = $wpdb->get_results( $sql );
if ( count( $rows ) ){
Expand Down Expand Up @@ -382,6 +394,19 @@ function ajax_validate_fields() {
die();
}

private function prepare_not_in( $sql, $post_ids ){
global $wpdb;
$not_in_count = substr_count( $sql, '[NOT_IN]' );
if ( $not_in_count > 0 ){
$args = array( str_replace( '[NOT_IN]', implode( ', ', array_fill( 0, count( $post_ids ), '%d' ) ), str_replace( '%', '%%', $sql ) ) );
for ( $i=0; $i < substr_count( $sql, '[NOT_IN]' ); $i++ ) {
$args = array_merge( $args, $post_ids );
}
$sql = call_user_func_array( array( $wpdb, 'prepare' ), $args );
}
return $sql;
}

/*
* create_options()
*
Expand Down

0 comments on commit f2d9403

Please sign in to comment.