add_list_dynamics( $apl_post_list );
$this->query_args_arr = $this->set_query_args_arr( $apl_post_list );
$this->query_args_arr = $this->query_arg_consolidate( $this->query_args_arr );
$this->query_args_arr = $this->query_args_accommodate( $this->query_args_arr );
}
/**
* Add Dynamic values to Post List
*
* Adds the current global post values for any dynamic settings checked.
*
* @ignore
* @since 0.3.b8
* @since 0.4.0 - Changed to use APL_Post_List object.
* @access private
*
* @param APL_Post_List $apl_post_list APL Post List object.
* @return APL_Post_List Modified post list object.
*/
private function add_list_dynamics( $apl_post_list ) {
$post_id = get_the_ID();
if ( ! $post_id ) {
return $apl_post_list;
}
// EXCLUDE CURRENT POST.
if ( $apl_post_list->pl_exclude_current ) {
$apl_post_list->post__not_in[] = $post_id;
}
$current_post_type = get_post_type( $post_id );
$current_taxonomies = get_post_taxonomies( $post_id );
$terms_args = array(
'orderby' => 'term_id',
'order' => 'ASC',
'fields' => 'ids',
);
foreach ( $apl_post_list->post_type as $k1_index => $v1_pt_arr ) {
if ( is_array( $v1_pt_arr ) ) {
// POST TYPES.
foreach ( $v1_pt_arr as $k2_index => $v2_pt_slug ) {
// Current Post Type.
// PAGE PARENT.
if ( $current_post_type === $v2_pt_slug ) {
if ( isset( $apl_post_list->post_parent_dynamic[ $v2_pt_slug ] ) ) {
if ( $apl_post_list->post_parent_dynamic[ $v2_pt_slug ] ) {
// Add current Page as Parent and prevent doubles.
$apl_post_list->post_parent__in[ $v2_pt_slug ][] = $post_id;
$apl_post_list->post_parent__in[ $v2_pt_slug ] = array_values( array_unique( $apl_post_list->post_parent__in[ $v2_pt_slug ] ) );
}
}
}
// TAXONOMIES.
if ( isset( $apl_post_list->tax_query[ $v2_pt_slug ] ) ) {
foreach ( $apl_post_list->tax_query[ $v2_pt_slug ] as $k3_tax_key => &$v3_tax_arr ) {
if ( 'relation' !== $k3_tax_key ) {
if ( in_array( $v3_tax_arr['taxonomy'], $current_taxonomies, true ) ) {
if ( $v3_tax_arr['apl_terms_dynamic'] ) {
// Add Terms.
$current_taxonomy_terms = wp_get_post_terms(
$post_id,
$v3_tax_arr['taxonomy'],
array(
'fields' => 'ids',
)
);
if ( is_wp_error( $current_taxonomy_terms ) ) {
echo '
' . esc_html( $current_taxonomy_terms->get_error_message() ) . '
';
return $apl_post_list;
}
foreach ( $current_taxonomy_terms as $current_term_id ) {
//$apl_post_list->tax_query[ $v2_pt_slug ]['terms'][] = $current_term_id;
$v3_tax_arr['terms'][] = $current_term_id;
}
$apl_post_list->tax_query[ $v2_pt_slug ][ $k3_tax_key ]['terms'] = array_values( array_unique( $v3_tax_arr['terms'] ) );
}
}
}
}
}
}// End Foreach( POST TYPE).
} else { // ANY / ALL.
// TAXONOMIES.
if ( isset( $apl_post_list->tax_query[ $v1_pt_arr ] ) ) {
foreach ( $apl_post_list->tax_query[ $v1_pt_arr ] as $k2_tax_key => &$v2_tax_arr ) {
if ( 'relation' !== $k2_tax_key ) {
if ( in_array( $v2_tax_arr['taxonomy'], $current_taxonomies, true ) ) {
if ( $v2_tax_arr['apl_terms_dynamic'] ) {
// Add Terms.
$current_taxonomy_terms = wp_get_post_terms(
$post_id,
$v2_tax_arr['taxonomy'],
array(
'fields' => 'ids',
)
);
if ( is_wp_error( $current_taxonomy_terms ) ) {
echo '' . esc_html( $current_taxonomy_terms->get_error_message() ) . '
';
}
foreach ( $current_taxonomy_terms as $current_term_id ) {
$v2_tax_arr['terms'][] = $current_term_id;
}
$apl_post_list->tax_query[ $v1_pt_arr ][ $k2_tax_key ]['terms'] = array_values( array_unique( $v2_tax_arr['terms'] ) );
}
}
}
}
}
// Break Post Type Loop (Just in case).
break;
}// End if().
}// End foreach().
return $apl_post_list;
}
/**
* Set Query Args
*
* Sets multiple query_args in query_args_arr.
*
* @ignore
* @since 0.3.b8
* @since 0.4.0 - Changed to use APL_Post_List structure.
* @access private
*
* @see $query_args for WP_Query.
* @link https://gist.github.com/luetkemj/2023628
*
* @param APL_Post_List $apl_post_list APL Post List object.
* @return array Multiple query_args
*/
private function set_query_args_arr( $apl_post_list ) {
$rtn_query_args_arr = array();
foreach ( $apl_post_list->post_type as $v1_pt_arr ) {
$tmp_query_args = array();
// If there is an array of post types, then loop through and add.
if ( is_array( $v1_pt_arr ) ) {
foreach ( $v1_pt_arr as $v2_pt_slug ) {
$tmp_query_args['post_type'] = array( $v2_pt_slug );
//$tmp_query_args['tax_query'] = $apl_post_list->tax_query[ $v2_pt_slug ];
$tmp_tax_query = $apl_post_list->tax_query[ $v2_pt_slug ];
if ( ! empty( $tmp_tax_query ) ) {
$tmp_query_args['tax_query']['relation'] = $tmp_tax_query['relation'];
unset( $tmp_tax_query['relation'] );
foreach ( $tmp_tax_query as $tax_arr ) {
// Any / All.
if ( isset( $tax_arr['terms'][0] ) && 0 === $tax_arr['terms'][0] ) {
$terms_args = array(
'taxonomy' => $tax_arr['taxonomy'],
'fields' => 'ids',
);
$tax_arr['terms'] = get_terms( $terms_args );
$tmp_query_args['tax_query'][] = $tax_arr;
} else {
$tmp_query_args['tax_query'][] = $tax_arr;
}
}
}
// Page Parents.
if ( isset( $apl_post_list->post_parent__in[ $v2_pt_slug ] ) ) {
$tmp_query_args['post_parent__in'] = $apl_post_list->post_parent__in[ $v2_pt_slug ];
}
}
} else { // ANY.
$tmp_query_args['post_type'] = 'any';
//$tmp_query_args['tax_query'] = $apl_post_list->tax_query['any'];
if ( ! empty( $apl_post_list->tax_query[ $v1_pt_arr ] ) ) {
$tmp_tax_query = $apl_post_list->tax_query[ $v1_pt_arr ];
$tmp_query_args['tax_query']['relation'] = $tmp_tax_query['relation'];
unset( $tmp_tax_query['relation'] );
foreach ( $tmp_tax_query as $tax_arr ) {
// Any / All.
if ( 0 === $tax_arr['terms'][0] ) {
$terms_args = array(
'taxonomy' => $tax_arr['taxonomy'],
'fields' => 'ids',
);
$tax_arr['terms'] = get_terms( $terms_args );
$tmp_query_args['tax_query'][] = $tax_arr;
} else {
$tmp_query_args['tax_query'][] = $tax_arr;
}
}
}
// Post Parents is empty in 'Any'
//$tmp_query_args['post_parent__in'] = $apl_post_list->post_parent__in['any'];
}// End if().
// General Filter.
$tmp_query_args['posts_per_page'] = $apl_post_list->posts_per_page;
$tmp_query_args['offset'] = $apl_post_list->offset;
$tmp_query_args['orderby'] = $apl_post_list->order_by;
$tmp_query_args['order'] = $apl_post_list->order;
// Handle post_status in accommodate method.
$tmp_query_args['post_status'] = $apl_post_list->post_status;
if ( 'none' !== $apl_post_list->perm ) {
$tmp_query_args['perm'] = $apl_post_list->perm;
}
if ( 'none' !== $apl_post_list->author__bool ) {
if ( 'in' === $apl_post_list->author__in ) {
$tmp_query_args['author__in'] = $apl_post_list->author__in;
} elseif ( 'not_in' === $apl_post_list->author__in ) {
$tmp_query_args['author__not_in'] = $apl_post_list->author__in;
}
}
$tmp_query_args['ignore_sticky_posts'] = $apl_post_list->ignore_sticky_posts;
$tmp_query_args['post__not_in'] = $apl_post_list->post__not_in;
$rtn_query_args_arr[] = $tmp_query_args;
}// End foreach().
return $rtn_query_args_arr;
}
/**
* Query Args Consolidation
*
* Merges any simular query strings.
*
* STEP 1: Go through string and match post parents with the same post status
* or tax query.
* STEP 2: Return (modified) query_str_array.
*
* @ignore
* @since 0.3.b8
* @access private
*
* @param array $arg_arr Multi-dimensional query_str array.
* @return array Multi-dimensional query_str array.
*/
private function query_arg_consolidate( $arg_arr ) {
$query_count = count( $arg_arr );
for ( $i = 0; $i < $query_count; $i++ ) {
if ( empty( $arg_arr[ $i ]['post_parent'] ) ) {
$query_count = count( $arg_arr );
for ( $j = $i + 1; $j < $query_count; $j++ ) {
// IF there is a post_parents; which would conflict.
// IF both query_arg's tax_query match.
if ( isset( $arg_arr[ $i ]['post_parent'] ) && empty( $arg_arr[ $i ]['post_parent'] ) &&
$this->tax_query_match( $arg_arr[ $i ]['tax_query'], $arg_arr[ $j ]['tax_query'] ) ) {
$arg_arr[ $i ]['post_type'][] = $arg_arr['post_type'][0];
unset( $arg_arr[ $j ] );
$arg_arr = array_values( $arg_arr );
// Set $i back 1 to do next $j properly.
$i--;
}
}
}
}
return $arg_arr;
}
/**
* Match Tax Query Args
*
* Checks to see if there is a 100% relation.
*
* STEP 1: Check and return false if taxomonies do not have 100% relation.
* STEP 2: Return true if there is a 100% relation.
*
* @ignore
* @since 0.3.b8
* @access private
*
* @param array $tax_query1 The query string's tax query.
* @param array $tax_query2 The query string's tax query.
* @return boolean Similar Tax_Querys.
*/
private function tax_query_match( $tax_query1, $tax_query2 ) {
// STEP 1.
if ( $tax_query1['relation'] === $tax_query2['relation'] ) {
$tax_query_count1 = count( $tax_query1 ) - 1;
for ( $i = 0; $i < $tax_query_count1; $i++ ) {
$tax_match_found = false;
$tax_query_count2 = count( $tax_query2 ) - 1;
for ( $j = 0; $j < $tax_query_count2; $j++ ) {
// Would have included the next IF statement if the 2 weren't
// required to have and not have an else return false.
if ( $tax_query1[ $i ]['taxonomy'] === $tax_query2[ $j ]['taxonomy'] ) {
$tax_match_found = true;
if ( $tax_query1[ $i ]['operator'] === $tax_query2[ $j ]['operator'] ) {
foreach ( $tax_query1[ $i ]['terms'] as $key => $value ) {
if ( ! in_array( $value, $tax_query2[ $j ]['terms'], true ) ) {
return false;
}
}
} else {
return false;
}
}
}
if ( ! $tax_match_found ) {
return false;
}
}
} else {
return false;
}
// STEP 2.
return true;
}
/**
* Add/Change Query Args
*
* Modifications for certain enhancements after query array has been consolidated.
*
* @ignore
* @since 0.4.0
* @private
*
* @param array $query_args_arr Old query argument array.
* @return array
*/
private function query_args_accommodate( $query_args_arr ) {
$rtn_query_args_arr = array();
foreach ( $query_args_arr as $v1_query_args ) {
if ( is_array( $v1_query_args['post_status'] ) ) {
$public = array_search( 'public', $v1_query_args['post_status'], true );
$private = array_search( 'private', $v1_query_args['post_status'], true );
if ( $public && $private ) {
unset( $v1_query_args['post_status'][ $public ] );
$rtn_query_args_arr[] = $v1_query_args;
unset( $v1_query_args['post_status'][ $private ] );
$rtn_query_args_arr[] = $v1_query_args;
} elseif ( $public ) {
unset( $v1_query_args['post_status'][ $public ] );
$rtn_query_args_arr[] = $v1_query_args;
} else {
$rtn_query_args_arr[] = $v1_query_args;
}
} elseif ( 'none' === $v1_query_args['post_status'] ) {
// WP Default.
$v1_query_args['post_status'] = array( 'publish' );
$rtn_query_args_arr[] = $v1_query_args;
} elseif ( 'any' === $v1_query_args['post_status'] ) {
$v1_query_args['post_status'] = 'any';
$rtn_query_args_arr[] = $v1_query_args;
}
}
return $rtn_query_args_arr;
}
/**
* APL Query WP
*
* Queries multiple instances of this function if there is more than one
* query_str.
*
* STEP 1: If this is NOT the first and last instance of this function.
* Then repeat this function if more queries are present, and
* query/collect the posts IDs.
* STEP 2: FINAL Query and order the post IDs collected. Return results.
*
* @since 0.3.b8
*
* @see Function/method/class relied on
* @link https://gist.github.com/EkoJr/7352549
* @global type $varname Description.
* @global type $varname Description.
*
* @param array $query_str_array Multi-dimensional query_str array.
* @param boolean $repeated This function repeated.
* @return mixed WP_Query class if unrepeated, otherwise array of post_IDs.
*/
public function query_wp( $query_str_array, $repeated = false ) {
$post_in_IDs = array();
$post_not_in_IDs = array();
/*
* Normally a recursive function will have an exit statement setup first,
* however, it needs to check if it is a repeated instance first before
* moving on to the first/last instance.
*/
// TODO Create function for the repeated query_wp function.
// STEP 1.
if ( true === $repeated ) {
// Shift the args when repeating this method / function.
// If more args exist, then repeat this function.
// Merge returned post ids for pre-final query.
$query_str = array_shift( $query_str_array );
if ( ! empty( $query_str_array ) ) {
$post_in_IDs = array_merge( $this->query_wp( $query_str_array, true ), $post_in_IDs );
}
// Since post__in and post__not_in don't mix at all. The 2 variables
// are stored seperately.
// TODO Create function for Post Include/Exclude.
if ( ! empty( $query_str['post__not_in'] ) && 0 < $query_str['posts_per_page'] ) {
// Removed at final.
//$post_not_in_IDs = $query_str['post__not_in'];
$query_str['posts_per_page'] += count( $query_str['post__not_in'] );
}
unset( $query_str['post__not_in'] );
if ( ! empty( $query_str['post__in'] ) ) {
$post_in_IDs = array_merge( $post_in_IDs, $query_str['post__in'] );
}
unset( $query_str['post__in'] );
// If Posts Per Page is set to -1/Unlimited, then set nopaging to true.
if ( -1 === $query_str['posts_per_page'] ) {
$query_str['nopaging'] = true;
$query_str['offset'] = 0;
}
// Sets the query string to just query IDs.
$query_str['fields'] = 'ids';
$query_obj = new WP_Query( $query_str );
// Collect an array of Post IDs.
$post_IDs = array();
if ( ! empty( $query_obj->posts ) ) {
foreach ( $query_obj->posts as $i => $post_ID ) {
$post_IDs[] = intval( $post_ID );
}
}
$post_IDs = array_merge( $post_IDs, $post_in_IDs );
wp_reset_postdata();
return $post_IDs;
} else {
// STEP 2.
/*
* This is the Initial and Final Query. This is used to collect IDs first
* with 1 or more query_str (that couldn't be consolidated/merged), and
* then do one last query here to return. This allows sorting with other
* custom post types that couldn't be queried together, and allows
* compatability with posts_in & posts_not_in.
*/
$post_in_IDs = array_merge( $this->query_wp( $query_str_array, true ) );
$query_str = array_shift( $query_str_array );
// Filter out excluded posts.
foreach ( $query_str['post__not_in'] as $post_not_value ) {
foreach ( $post_in_IDs as $key => $post_in_value ) {
if ( $post_in_value === $post_not_value ) {
unset( $post_in_IDs[ $key ] );
}
}
}
$post_in_IDs = array_merge( $post_in_IDs );
// Prevent defaulting when there's no posts.
if ( empty( $post_in_IDs ) ) {
$post_in_IDs[] = 0;
}
// STEP.
// Set FINAL query_str with post IDs.
$final_query_str = array(
'post__in' => $post_in_IDs,
'post_type' => 'any',
'posts_per_page' => $query_str['posts_per_page'],
'offset' => $query_str['offset'],
'nopaging' => ( -1 === $query_str['posts_per_page'] ) ? true : false,
'order' => $query_str['order'],
'orderby' => $query_str['orderby'],
'ignore_sticky_posts' => $query_str['ignore_sticky_posts'],
);
// Get FINAL Query Object.
$final_query_obj = new WP_Query( $final_query_str );
return $final_query_obj;
}// End if().
}
}