CF7 validate and store data - wordpress

I am trying to make custom validation to cf7 form and then store data in a custom post type if everything is valid. My problem is that even when form inputs are not valid form still sends email and store its data. Can you help me with that. Below is my code. What should I use to validate inputs first and only then store data.
Store posted data:
function save_posted_data_ios( $posted_data ) {
if( isset($posted_data['menu-377']) == "IOS" ){
$args2 = array(
'post_type' => 'np_coupon_code',
'post_status' => 'publish',
'posts_per_page' => 1,
'meta_query' => array(
array(
'key' => 'np_ccode__email',
'value' => 'null',
'compare' => 'NOT EXISTS'
),
array(
'key' => 'np_ccode__type',
'value' => 'IOS'
)
)
);
$posts_query2 = new WP_Query($args2);
$the_count_ios = $posts_query2->found_posts;
$query = new WP_Query($args2);
while ( $query->have_posts() ) : $query->the_post();
$id = get_the_ID();
$code = get_the_title();
endwhile;
if( isset($posted_data['your-email']) ){
update_post_meta($id, 'np_ccode__email', $posted_data['your-email']);
}
$to = $posted_data['your-email'];
$subject = 'Subject';
$body = $code;
$headers = array('Content-Type: text/html; charset=UTF-8');
wp_mail( $to, $subject, $body, $headers );
return $posted_data;
wp_reset_query();
}
}
add_filter( 'wpcf7_posted_data', 'save_posted_data_ios' );```
Custom error:
function my_wpcf7_validate_ios( $result_ios, $tag ) {
$type = $tag['type'];
$name = $tag['menu-377'];
$args2 = array(
'post_type' => 'np_coupon_code',
'post_status' => 'publish',
'posts_per_page' => 1,
'meta_query' => array(
array(
'key' => 'np_ccode__email',
'value' => 'null',
'compare' => 'NOT EXISTS'
),
array(
'key' => 'np_ccode__type',
'value' => 'IOS'
)
)
);
$posts_query2 = new WP_Query($args2);
$the_count_ios = $posts_query2->found_posts;
if ( $the_count_ios == 0 && $_POST['menu-377'] == "IOS"){
$result_ios->invalidate( $tag, wpcf7_get_message( 'invalid_ios' ) );
}
return $result_ios;
}
add_filter( 'wpcf7_validate_select*', 'my_wpcf7_validate_ios' , 10, 2 );
add_filter( 'wpcf7_messages', 'mywpcf7_ios_messages' );
function mywpcf7_ios_messages( $messages ) {
return array_merge( $messages, array(
'invalid_ios' => array(
'description' => __( "No IOS Coupons Left", 'contact-form-7' ),
'default' => __( 'No IOS Coupons Left.', 'contact-form-7' )
)
));
}

Related

Add woocommerce variation GTIN to structured data

If a webshop has variable products, in some cases the variations have unique GTINs. In our case, it is EAN.
How to add these different GTINS to the structured data? I made a function to insert multiple "offer" in "offers", but the GTIN is not recognized here.
This is the function:
//add structured data to the markup
function set_structured_data( $markup, $product ) {
if ($product->is_type('simple')){
$markup['brand'] = array('#type' => 'Brand', 'name' => get_post_meta( $product->get_id(), '_brand', true ) );
$markup['gtin8'] = get_post_meta( $product->get_id(), '_EAN', true );
}
if ($product->is_type('variable')){
$available_variations = $product->get_available_variations();
foreach ($available_variations as $variation) {
$variation_id = $variation['variation_id'];
$variproduct = wc_get_product($variation_id);
$i++;
$stock = $product->get_stock_status();
$offers[] = array(
'type' => 'Offer',
'price' => $variproduct->get_price(),
'priceValidUntil' => $priceuntil,
'priceSpecification' => array(
'price' => $variproduct->get_price(),
'priceCurrency' => get_woocommerce_currency(),
'valueAddedTaxIncluded' => 'http://schema.org/True'
),
'priceCurrency' => get_woocommerce_currency(),
'availability' => 'http://schema.org/'.$stock.'',
'url' => get_the_permalink(),
'seller' => array (
'type' => 'Organization',
'name' => 'HeatPerformance®',
'url' => get_the_permalink(),
));
}
$markup['offers'] = $offers;
$markup['brand'] = array('#type' => 'Brand', 'name' => get_post_meta( $product->get_id(), '_brand', true ) );
}
return $markup;
}
add_filter( 'woocommerce_structured_data_product', 'set_structured_data', 99, 2 );
Any ideas?
Ok after a couple of days puzzling i found the path to a solution here:
https://support.google.com/merchants/answer/6386198?hl=en
Result is that i corrected the standardized method from woocommerce and made each variation a unique product.
So first remove the markup in case of a variable product like this:
function set_structured_data( $markup, $product ) {
if ($product->is_type('variable')) {
$markup = array();
}
return $markup;
}
add_filter( 'woocommerce_structured_data_product', 'set_structured_data', 99, 2 );
And then build up the ld+json script again, but then the desired way:
function set_structured_data_variable() {
global $product;
if (isset($product)){
if ($product->is_type('variable') && !empty($product)){
$available_variations = $product->get_available_variations();
$date = date("Y-m-d",strtotime(" + 3months"));
$commenttext = '';
$commentauthor = '';
$commentdate = '';
$comments = get_comments(array( 'post_id' => $product->get_id(), 'number' => '1' ));
foreach($comments as $comment) {
$commenttext = $comment->comment_content;
$commentauthor = $comment->comment_author;
$commentdate = $comment->comment_date;
}
foreach ($available_variations as $variation) {
$variation_id = $variation['variation_id'];
$variproduct = wc_get_product($variation_id);
$i++;
$gtin = 0000000000001;
if (!empty(get_post_meta( $variation_id, '_EAN', true ))){
$gtin = get_post_meta( $variation_id, '_EAN', true );
}
$stock = $product->get_stock_status();
$arrays[$i] = array(
'#context' => 'https://schema.org/',
'#type' => 'Product',
'sku' => $variproduct->get_sku(),
'gtin13' => $gtin,
'image' => get_the_post_thumbnail_url($product->get_id()),
'name' => implode(" / ", $variproduct->get_variation_attributes()),
'description' => wp_strip_all_tags(get_the_excerpt($product->get_id())),
'brand' => array('#type' => 'Brand', 'name' => get_post_meta( $product->get_id(), '_brand', true ) ),
'review' => array(
'#type' => 'Review',
'reviewRating' => array (
'#type' => 'Rating',
'ratingValue' => $product->get_review_count(),
'bestRating' => '5',
'worstRating' => '1',
),
'author' => array(
'#type' => 'person',
'name' => $commentauthor,
'reviewBody' => $commenttext,
'datePublished' => $commentdate,
)),
'aggregateRating' => array (
'#type' => 'AggregateRating',
'ratingValue'=> $product->get_average_rating(),
'reviewCount' => $product->get_rating_count(),
),
'inProductGroupWithID' => $product->get_sku(),
'offers' => array(
'#type' => 'Offer',
'price' => $variproduct->get_price(),
'priceValidUntil' => $date,
'priceSpecification' => array(
'price' => $variproduct->get_price(),
'priceCurrency' => get_woocommerce_currency(),
'valueAddedTaxIncluded' => 'http://schema.org/True'
),
'priceCurrency' => get_woocommerce_currency(),
'availability' => 'http://schema.org/'.$stock.'',
'url' => get_the_permalink(),
'seller' => array (
'type' => 'Organization',
'name' => 'HeatPerformance®',
'url' => get_the_permalink(),
)));
}
echo '<script type="application/ld+json" class="buronoort">[';
$i = 0;
foreach ($arrays as $array){
$i++;
echo json_encode($array);
if ($i < array_key_last($arrays)){
echo ',';
}
}
echo ']</script>';
}
}
}
add_action('wp_head','set_structured_data_variable', 19);
Tested in the test tool for structured data and it is working.
A little concern is the product review however, i have to look into that what happens after multiple reviews.
Another concern is the EAN, i have set it standard to "0000000000001" as not all EANS are inputted yet. So this is a debatle solution, but if someone has a better idea, keep me posted.

Order posts by Title length in WP_QUERY

I am having problem ordering the posts based on the title length. Here is my code:
<?php
$terms = get_terms(array(
'taxonomy' => 'vendor_category',
'slug' => 'venues',
'hide_empty' => false
));
?>
<?php
foreach ($terms as $term) {
$eventargs = array(
'post_type' => 'vendor',
'posts_per_page' => -1,
'orderby' => 'title',
'order' => 'ASC',
'meta_key' => 'primary_category',
'meta_value' => $term->term_id,
);
$eventqry = new WP_Query($eventargs);
?>
How can i sort the posts based on the title length in ascending order.
You can save title length in post meta on save_post hook. and then you can retrieve post order by post meta value.
You can use save_post hook to save the post meta. put this code in your active theme.
//for existing vendors
add_action('admin_init', 'udpate_existing_vendor');
function udpate_existing_vendor(){
$existing_vendor_updated = get_option('existing_vendor_updated', 'no');
if( $existing_vendor_updated == 'no' ){
$vendor_args = array(
'post_type' => 'vendor',
'post_status' => 'publish',
'posts_per_page' => -1
);
$vendors = new WP_Query( $vendor_args );
if( $vendors->have_posts() ) {
while ( $vendors->have_posts() ) { $vendors->the_post();
$length = strlen( get_the_title() );
update_post_meta( get_the_ID(), 'title_length', $length );
} wp_reset_postdata();
}
update_option('existing_vendor_updated', 'yes');
}
}
// for new vendor
function save_vendor_title_length( $post_id ) {
$length = strlen( get_the_title( $post_id ) );
update_post_meta( $post_id, 'title_length', $length );
}
add_action( 'save_post_vendor', 'save_vendor_title_length');
Here your query will look like.
$terms = get_terms(array(
'taxonomy' => 'vendor_category',
'slug' => 'venues',
'hide_empty' => false
));
foreach ($terms as $term) {
$eventargs = array(
'post_type' => 'vendor',
'posts_per_page' => -1,
'orderby' => 'meta_value_num',
'order' => 'ASC',
'meta_key' => 'title_length'
);
$eventqry = new WP_Query( $eventargs );
}

Create a page with child pages and have each child have it's own page template

I have some code that creates pages with child pages in WordPress. What i would like to do is have each child have its own page template.
As you see below, i am creating child pages of Script and Assets. Currently the child page is created with one page_Full.php added to everything but i would like to have Script and Assets have their own page template. Ideas would be helpful.
Thanks in advance.
function CreatePage(){
$post_title = $_POST['ProjectName'];
$post_excerpt = $_POST['ProjectDiscript'];
$tags = $_POST['TypeOption'];
$pages = array(
array(
'name' => $post_title,
'title' => $post_title,
'child' => array(
'script' => $post_title.'_Script',
'assets' => $post_title.'_Assets'
)
)
);
$template = array(
'post_type' => 'page',
'post_status' => 'publish',
'post_author' => $user_id,
'post_excerpt' => $post_excerpt,
'tags_input' => array($tags),
);
foreach( $pages as $page ) {
$exists = get_page_by_title( $page['title'] );
$my_page = array(
'post_name' => $page['name'],
'post_title' => $page['title'],
'page_template' => 'page_Full.php'
);
$my_page = array_merge( $my_page, $template );
$id = ( $exists ? $exists->ID : wp_insert_post( $my_page ) );
if( isset( $page['child'] ) ) {
foreach( $page['child'] as $key => $value ) {
$child_id = get_page_by_title( $value );
$child_page = array(
'post_name' => $key,
'post_title' => $value,
'post_parent' => $id,
'page_template' => 'page_Full.php'
);
$child_page = array_merge( $child_page, $template );
if( !isset( $child_id ) ) wp_insert_post( $child_page );
}
}
}
wp_die();
}
add_action( 'wp_ajax_CreatePage','CreatePage' );
Had the idea to create an array for every child page - and it seams to work. Perhaps there is still a better way but for the time being - This does the trick!
$pages = array(
array(
'name' => $post_title,
'title' => $post_title,
'child' => array(
'script' => array(
'Pname' => $post_title.'_Script',
'Ptemplate' => 'page_Full_Script.php'
),
'assets' => array(
'Pname' => $post_title.'_Assets',
'Ptemplate' => 'page_Full_Assets.php'
),
'settings' => array(
'Pname' => $post_title.'_Settings',
'Ptemplate' => 'page_Full_Settings.php'
)
)
)
);
Here is the child with sub arrays.
if( isset( $page['child'] ) ) {
foreach( $page['child'] as $key[] => $value ) {
$child_id = get_page_by_title( $value );
$child_page = array(
'post_name' => $value['Pname'],
'post_title' => $value['Pname'],
'post_parent' => $id,
'page_template' => $value['Ptemplate'],
);
$child_page = array_merge( $child_page, $template );
if( !isset( $child_id ) ) wp_insert_post( $child_page );
}
}
And here is where the child array is set as var to be iterated through so that the info can be inserted into the child_page var to be merged and the post inserted.
Thanks to any who took the time to review.
Cheers

Issue with function and post ID

I am using the following function/shortcode in order to output an average global rating using ACF :
function get_average_rating($post_id) {
$rating_sum = 0;
$reviews_of_post = get_posts( array(
'post_type' => 'avis',
'posts_per_page' => -1,
'meta_query' => array(
array(
'key' => 'produit',
'value' => $post_id,
'compare' => '=',
),
),
) );
if ( empty( $reviews_of_post ) ) {
return 0;
}
foreach ( $reviews_of_post as $review ) {
$rating_sum += get_field( 'note_client', 'post_' . $review->ID);
}
return number_format((float)($rating_sum / count( $reviews_of_post )),1, ',', '');
}
add_shortcode( 'note-clients', 'get_average_rating');
It always return 0 except when I manually input the post ID like :
'meta_query' => array(
array(
'key' => 'produit',
'value' => 1234,
'compare' => '=',
),
),
How can I fix this ?
Thanks a lot !
Declare global $post; before your function.
Wordpress uses $post for many of its functions within the loop.
To avoid any conflicts later you should consider use of wp_reset_query
1 . Change key 'key' => 'produit' to 'key' => 'product',
2 .
foreach ( $reviews_of_post as $review ) {
$rating_sum += get_field( 'note_client', 'post_' . $review->ID);
}
**to**
foreach ( $reviews_of_post as $review ) {
$post_id = 'post_' . $review->ID ;
$rating_sum += get_field( 'note_client', $post_id );
}
Confirm ACF key (note_client) is correct
3 . Change this
add_shortcode( 'note-clients', 'get_average_rating');
to
add_shortcode( 'average_rating', 'get_average_rating');
Please try with your post static id:
$post_id = 9; //add here your static post id
$reviews_of_post = get_posts( array(
'post_type' => 'avis',
'posts_per_page' => -1,
'meta_query' => array(
array(
'key' => 'produit',
'value' => $post_id,
'compare' => '=',
),
),
) );

how to add another list parameter for meta_query

here is my wordpress new query loop $args
if (isset($_GET['list_shows'])) {
if ($_GET['list_shows'] == 'update') {
$orderby = 'modified';
$order = '';
} elseif ($_GET['list_shows'] == 'views') {
$orderby = 'meta_value_num';
$order = 'DESC';
} elseif ($_GET['list_shows'] == 'popularity') {
$orderby = 'comment_count';
$order = 'DESC';
}
} else {
$orderby = 'modified';
$order = '';
}
$argz=array(
'posts_per_page' => '-1',
'orderby'=>$orderby,
'order'=>$order,
'meta_query' => array(
array(
'key' => 'fragman',
'compare' => 'NOT EXISTS',
'posts_per_page' => '-1',
)
),
'date_query' => array(
array(
'column' => 'post_date_gmt',
'after' => '2 days ago',
),
'posts_per_page' => '-1',
),
);
the question is about ordering posts by meta_value_num , descending ?
my post views meta key = views, could we add this ordering parameter in this meta query ?
if it is, how can we do it. ?
Thanks.
You can pass like this
global $wp_query;
$args = array(
'meta_key' => 'views',
'orderby' => 'meta_value meta_value_num',
'order' => 'DESC'
);
query_posts( array_merge( $args , $wp_query->query ) );
I hope this will work for you.

Resources