I am trying to get country name from country drop down, where I have used pipe symbol. like this in my form
[text* FullName id:fullname]
[select* country id:country include_blank "United States | a#gmail.com" "Canada | a#gmail.com" "Mexico | b#gmail.com" "United Kingdom | c#gmail.com"]
I have used different-2 email with country name because i need to sand email to company employee according to country name. In email template i have used [country] to get email and [_raw_country] to get country name that is working fine.
I am trying to get country name in function.php file to save it in database by this way.
function contactform7_before_send_mail( $form_to_DB ) {
//set your db details
$mydb = new wpdb('user','password','databasename','localhost');
$form_to_DB = WPCF7_Submission::get_instance();
if ( $form_to_DB )
$formData = $form_to_DB->get_posted_data();
$fullname = $formData['FullName'];
$country = $formData['country'];
$mydb->insert( 'mytable', array( 'fullname' =>$fullname,'country' =>$country), array( '%s' ) );
}
But it gives nothing. if i try to get like this
$country = $formData['country'][0];
it gives me only email id like a#gmail.com I have tryed $country = $formData['country'][1];
It give me nothing. I have also tryed $country = $formData['_raw_country']; But not get luck.
This is the reference document
https://contactform7.com/selectable-recipient-with-pipes/
you need something like this:
<?php
// Get the submitted data
$submission = WPCF7_Submission::get_instance();
if ( ! $submission
or ! $posted_data = $submission->get_posted_data() ) {
return;
}
// Get the contact form additional data
$contact_form = $submission->get_contact_form();
// get the tag used in the form
$mail_tags=$contact_form->scan_form_tags();
// search into tags for country
$key = array_search('country', array_column($mail_tags, 'name'));
// get the country pipes values
$pipes = new WPCF7_Pipes( $mail_tags[$key]->raw_values );
// get an array with the pipes
$pipes_array = $pipes->to_array();
// get the choosen value
$pipes_val = array_search( $posted_data['country'][0], array_column($pipes_array, 1));
// finally!
error_log(print_r($posted_data['country'],true));
error_log(print_r("in",true));
error_log(print_r($pipes_array[$pipes_val][0],true));
I posted this answer in your other question. This should work.
add_action( 'wpcf7_before_send_mail', 'cf7_pipes_so_67686211');
function cf7_pipes_so_67686211( $contact_form ) {
global $wpdb;
$mydb = new wpdb('user','password','database','localhost');
// Get Form Tags
$tags = $contact_form->scan_form_tags();
$pipe_array = array();
// Find the Values of the Pipes
foreach ($tags as $tag){
if ($tag->name === 'primarybusiness'){
$pipe_array = $tag->pipes->to_array();
}
}
// Get the form data
$form_to_DB = WPCF7_Submission::get_instance();
if ( $form_to_DB ) {
$formData = $form_to_DB->get_posted_data();
$fullname = $formData['FullName'];
foreach ($pipe_array as $value) {
// Compare and find the pipe value
if ( $posted_data['primarybusiness'][0] === $value[1] ){
$primarybusiness = $value[0];
}
}
$mydb->insert( 'mytable', array( 'fullname'=>$fullname,'primarybusiness'=>$primarybusiness), array( '%s' ) );
}
}
Related
I want to add a new custom filter in WordPress network admin
restrict_manage_users for network admin in the user panel
I want a custom filter option not a custom column, i just want to add one filter dropdown with roles
You will need to hook on the ‘restrict_manage_posts‘ filters to add your filter (dropdown) and to ‘parse_query‘ to alter the query according to the filter selection.
For example, if you want to add a filter to display a list of years for the user to select, add the following code in your functions.php file:
if (is_admin()){
//this hook will create a new filter on the admin area for the specified post type
add_action( 'restrict_manage_posts', function(){
global $wpdb, $table_prefix;
$post_type = (isset($_GET['post_type'])) ? quote_smart($_GET['post_type'], true) : 'post';
//only add filter to post type you want
if ($post_type == 'YOUR_POST_TYPE_HERE'){
//query database to get a list of years for the specific post type:
$values = array();
$query_years = $wpdb->get_results("SELECT year(post_date) as year from ".$table_prefix."posts
where post_type='".$post_type."'
group by year(post_date)
order by post_date");
foreach ($query_years as &$data){
$values[$data->year] = $data->year;
}
//give a unique name in the select field
?><select name="admin_filter_year">
<option value="">All years</option>
<?php
$current_v = isset($_GET['admin_filter_year'])? $_GET['admin_filter_year'] : '';
foreach ($values as $label => $value) {
printf(
'<option value="%s"%s>%s</option>',
$value,
$value == $current_v? ' selected="selected"':'',
$label
);
}
?>
</select>
<?php
}
});
//this hook will alter the main query according to the user's selection of the custom filter we created above:
add_filter( 'parse_query', function($query){
global $pagenow;
$post_type = (isset($_GET['post_type'])) ? quote_smart($_GET['post_type'], true) : 'post';
if ($post_type == 'YOUR_POST_TYPE_HERE' && $pagenow=='edit.php' && isset($_GET['admin_filter_year']) && !empty($_GET['admin_filter_year'])) {
$query->query_vars['year'] = $_GET['admin_filter_year'];
}
});
}
Using this technique you can actually add any filter you want.
I hope this will solve your problem.
add_filter( 'wpmu_users_columns', 'my_awesome_new_column' );
add_action( 'manage_users_custom_column', 'my_awesome_column_data', 10, 3 );
// Creates a new column in the network users table and puts it before a chosen column
function my_awesome_new_column( $columns ) {
return my_awesome_add_element_to_array( $columns, 'my-awesome-column', 'Awesome', 'registered' );
}
// Adds data to our new column
function my_awesome_column_data( $value, $column_name, $user_id ) {
// If this our column, we return our data
if ( 'my-awesome-column' == $column_name ) {
return 'Awesome user ID ' . intval( $user_id );
}
// If this is not any of our custom columns we just return the normal data
return $value;
}
// Adds a new element in an array on the exact place we want (if possible).
function my_awesome_add_element_to_array( $original_array, $add_element_key, $add_element_value, $add_before_key ) {
// This variable shows if we were able to add the element where we wanted
$added = 0;
// This will be the new array, it will include our element placed where we want
$new_array = array();
// We go through all the current elements and we add our new element on the place we want
foreach( $original_array as $key => $value ) {
// We put the element before the key we want
if ( $key == $add_before_key ) {
$new_array[ $add_element_key ] = $add_element_value;
// We were able to add the element where we wanted so no need to add it again later
$added = 1;
}
// All the normal elements remain and are added to the new array we made
$new_array[ $key ] = $value;
}
// If we failed to add the element earlier (because the key we tried to add it in front of is gone) we add it now to the end
if ( 0 == $added ) {
$new_array[ $add_element_key ] = $add_element_value;
}
// We return the new array we made
return $new_array;
}
Here is an example : https://wordpress.stackexchange.com/questions/299801/custom-column-under-all-users-multisite-network-admin
Goal:
I'm trying to accomplish 2 things.
Change the permalink structure of a custom post type
Output a list of linked posts (of that CPT) based on the post's parent-child relationship via shortcode
On the main page, list states
On the state pages, list cities of that state
On the city pages, list cities in the same state
What's working:
The correct permalink is displayed on the post's edit page.
The shortcode displays the proper items.
The issue: The list's links are wrong. The links were correct until I added the "post_type_link" modification.
The permalinks are created using the data of the current page. On the main page and state pages, the permalinks are clearly incorrect. On the city pages, all of the permalinks are for that specific page.
Example: On a page for Houston, TX, Dallas and Ft Worth are listed but their links are for Houston. Specifically, it should be "domain.com/company/texas/dallas" and "domain.com/company/texas/ft-worth", but I'm getting "domain.com/company/texas/houston" on the Houston page or an error on the Texas page.
How do I ensure the proper data is being used?
Code summary:
The filter
There are 3 patterns I want to use: "/company","/company/state", and "/company/state/city". Company is constant. State and city are stored as meta data. (States are an array with name and abbreviation.) The desired pattern should be easily identified by a taxonomy (page_groups).
The shortcode
It's pretty self-explanatory. The post structure is hierarchical. The company page's children are states. And the states' children are cities.
The list is generated via a query based on parent ID. The query returns an array of OBJs. The link is generated in a foreach loop using get_post_permalink().
I am using "global $post". The shortcode doesn't work without it. I'm guessing this is part of the issue. I could manually build the list item links, but that's a terrible long term solution.
EDIT: I updated the code to use get_the_ID and removed "global $post". No change to the shortcode output.
Code:
add_filter( 'post_type_link', 'company_tag_rewrite', 10, 2 );
function company_tag_rewrite( $permalink, $post ) {
if( $post->post_type == 'company-page' ) {
// main
if( has_term( 'company-main', 'page_groups', $post) ){
return get_home_url() ."/pest-control-service/company/";
}
// state
if( has_term( 'company-state', 'page_groups', $post) ){
$state = get_field('state');
if( $state && 'All' != $state['label'] ){
$label = strtolower($state['label']);
return get_home_url() ."/pest-control-service/company/$label";
}else{
return get_home_url() ."/pest-control-service/fix-the-state-data-city/";
}
}
// city
if( has_term( 'company-city', 'page_groups', $post) ){
$state = get_field('state');
$city = strtolower(get_field('city'));
if( !$state || 'All' == $state['label'] ){
return get_home_url() ."/pest-control-service/fix-the-state-data/";
}
if( $city ){
$label = strtolower($state['label']);
return get_home_url() ."/pest-control-service/company/$label/$city/";
}else{
return get_home_url() ."/pest-control-service/fix-the-city-data/";
}
}
return get_home_url() ."/pest-control-service/set_the_page_group/";
}else{
return $permalink;
}
}
function company_page_footer_fn($atts = array(), $content = null) {
ob_start();
// start output ----------
// determine mode and set query
global $post;
$ancestors = get_post_ancestors($post->ID);
$ancestor_count = count($ancestors);
$city = get_field('city'); //? do i need this?
$state_array = get_field('state');
$state = $state_array['label'];
// determine mode and set widget title and query
if (0 == $ancestor_count){
//main
$widget_title = "Top Locations";
$target = $post->ID;
}elseif(1 == $ancestor_count){
//state
$widget_title = "company has offices throughout $state including:";
$target = $post->ID;
}elseif(2 == $ancestor_count){
$widget_title = "company has offices throughout $state including:";
$target = wp_get_post_parent_id( );
//city
}else{
wp_reset_postdata();
return "<div style='background-color: white; color:red;font-weight: 700;padding: 1rem;'>You might want to check this post's data.</div>";
}
$post_kids = get_children(array(
// returns array of objects
"post_parent" => $target,
"post_status" => "publish",
),'OBJECT'
);
// get data
foreach($post_kids as $kid) {
$link = get_post_permalink($kid);
if (0 == $ancestor_count){
$state_array = get_field('state',$kid->ID);
$title = $state_array['label'];
}else{
$title = get_field('city',$kid->ID).", $state";
}
$data[] = array(
'title' => $title,
'link' => $link,
);
}
// sort
function cmp($a, $b)
{
return strcmp($a["title"], $b["title"]);
}
uasort($data, 'cmp');
// output
?><style>
</style><?php
echo "<div class='location-list-container'>";
echo "<H2>$widget_title</H2>";
echo "<div class='location-list'>";
foreach($data as $item){
$this_title = $item['title'];
$this_link = $item['link'];
echo "<h3><a href='$this_link'>$this_title</a></h3>";
}
echo "</div";
echo "</div";
//return output ----------
wp_reset_postdata();
$thisOutput = ob_get_clean();
return $thisOutput;
}
add_shortcode( 'company-page-footer', 'company_page_footer_fn' );
tldr:// how to clone an existing WC_Order_Item_Product to a new order?
I have looked through a lot of existing subscription plugins but didnt really get warm with them. So I decided to create something as a learning project. Its not for a customer, I dont expect it to be commercially successful product, but I guess its good to step up my game.
So I have created a custom table already that saves target dates and would like to create new orders from the existing WC_Order_Item_Product-Objects. By simply adding the original Object it will just move them from the old order, which is something I do not want to happen. I wonder how I could 'clone' the object and remove the protected [order_id] which would be overridden by WC_Order->add_item anyway without altering the original database entries. Maybe thats the wrong approach or a bad idea?
I have also tried to find some up2date hint on how to create a full custom WC_Order_Item_Product but was not really successful on that.
What I got atm:
function update ($reminder_id = null) {
global $woocommerce;
global $wpdb;
global $aboprodukt_table_name;
// TODO if reminder id
if ( ! $reminder_id) {
$neworders = [];
// get all reminders from db and loop through them
$aboprodukt_reminders = $wpdb->get_results( 'SELECT * FROM ' . $aboprodukt_table_name . ' ORDER BY ' . $aboprodukt_table_name . '.targetdate ASC');
foreach ($aboprodukt_reminders as $item ) {
// get original order item object to abstract
$order_item = new \WC_Order_Item_Product($item->orderitem);
// get order object
$order = $order_item->get_order();
// get customer id
$customer = $order->get_customer_id();
// TODO abstract order items
// assign user, adresses if not existing yet, copy from last order
if ( ! $neworders[$customer] ) {
// check all reminders
$customer_array = $order->get_data();
$args = array(
'customer_id' => $customer,
'created_via' => 'Aboprodukt',
'add_order_note' => __('Aboprodukt Custom Order', 'aboprodukt'),
);
$neworders[$customer] = \wc_create_order($args);
// TODO Shipping
}
// add order items
$neworders[$customer]->add_item($order_item);
$neworders[$customer]->calculate_totals();
$neworders[$customer]->save();
}
return print_r($neworders,true);}
Not sure if it helps so. but this is the way I've managed to do so.
For understanding: I got an extra "reminder"-table in the database that stores: date, order-item-id. It is removed after its used to create a new order.
function update ($reminder_id = null) {
global $woocommerce;
global $wpdb;
global $aboprodukt_table_name;
// TODO if order id
if ( ! $reminder_id) {
$neworders = [];
// get all reminders from db and loop through them
$aboprodukt_reminders = $wpdb->get_results( 'SELECT * FROM ' . $aboprodukt_table_name . ' ORDER BY ' . $aboprodukt_table_name . '.targetdate ASC');
foreach ($aboprodukt_reminders as $item ) {
// get original order item object to abstract
$order_item = new \WC_Order_Item_Product($item->orderitem);
$order = $order_item->get_order();
$customer = $order->get_customer_id();
// assign user, adresses if not existing yet, copy from last order
if ( ! $neworders[$customer] ) {
// check all reminders
$args = array(
'customer_id' => $customer,
'created_via' => 'Aboprodukt',
'add_order_note' => __('Aboprodukt Custom Order', 'aboprodukt'),
);
$neworders[$customer] = \wc_create_order($args);
// order
$customer_object = new \WC_Customer( $customer );
$types = array('billing','shipping');
foreach ($types as $type) {
foreach ( $customer_object->{"get_{$type}"}() as $key => $value) {
if ( ! empty($value) ) {
if ( is_callable( array( $neworders[$customer], "set_{$type}_{$key}" ) ) ) {
$neworders[$customer]->{"set_{$type}_{$key}"}( $value );
}
}
}
}
// Set Shipping
$shippingold = $order->get_shipping_methods();
$oldshippingitem = new \WC_Order_Item_Shipping( reset($shippingold) );
$newshippingitem = new \WC_Order_Item_Shipping();
$newshippingitem->set_method_id( $oldshippingitem->get_method_id() );
$newshippingitem->set_instance_id( $oldshippingitem->get_instance_id() );
$newshippingitem->set_method_title( $oldshippingitem->get_method_title() );
$newshippingitem->set_total( $oldshippingitem->get_total() );
$neworders[$customer]->add_item( $newshippingitem );
}
// if variation_id > 0 then is simple product, get product
$item_variation_id = $order_item->get_variation_id();
$item_id = $neworders[$customer]->add_product(
wc_get_product(isset( $item_variation_id ) && $item_variation_id > 0 ? $item_variation_id : $order_item->get_product_id() ),
$order_item->get_quantity()
);
// copy metadata for future use
$neworderitem = new \WC_Order_Item_Product($item_id);
$neworderitem->add_meta_data( '_aboprodukt_order', $order_item->get_meta('_aboprodukt_order'), true );
$neworderitem->add_meta_data( '_aboprodukt_timespan', $order_item->get_meta('_aboprodukt_timespan'), true );
$neworderitem->add_meta_data( '_aboprodukt_type', $order_item->get_meta('_aboprodukt_type'), true );
$neworderitem->save();
$neworders[$customer]->calculate_totals();
$neworders[$customer]->save();
$wpdb->query(
$wpdb->prepare(
"DELETE FROM $aboprodukt_table_name
WHERE id = %d",
$item->id
)
);
}
}
// send emails
foreach ( $neworders as $customers => $neworder ) {
$mailer = \WC()->mailer();
\WC()->mailer()->emails['WC_Email_Customer_Invoice']->trigger($neworder->get_id());
$neworder->add_order_note( sprintf( __('%s email notification manually sent.', 'woocommerce'), $mail->title), false, true);
}
return $neworders;
}
I want to calculate the inventory down to zero via storing the input of a number field.
So far i have the following:
add_action( 'wpcf7_before_send_mail',
function( $contact_form, $abort, $submission ) {
$post_id = get_the_id();
$voorraad = '';
if ($post_id === 5080){
$voorraad = get_post_meta(5080,'voorraad',true);
$newvoorraad = implode( ', ', (array) $submission->get_posted_data( 'number-435' ));
$stock = $voorraad - $newvoorraad;
update_post_meta($post_id, 'voorraad', $stock);
}
},10,3
);
However, this does not work.
The meta field voorraad exists and has value 450. However, the field is not updated after input. I cannot store the submitted data in the first place, even if i use an empty meta field with a different name and store a set string like 'example', only for testing purposes.
How can i store a user input in a meta field upon submission?
Any ideas?
The get_the_id() function won't retrieve the postID from the form. You have to get that from the $submission->get_meta('container_post_id)
add_action( 'wpcf7_before_send_mail',
function( $contact_form, $abort, $submission ) {
$post_id = $submission->get_meta('container_post_id');
$voorraad = '';
if ($post_id === 5080){
$voorraad = get_post_meta(5080,'voorraad',true);
$newvoorraad = implode( ', ', (array) $submission->get_posted_data( 'number-435' ));
$stock = $voorraad - $newvoorraad;
update_post_meta($post_id, 'voorraad', $stock);
}
},10,3
);
Method #2
Another Method would be to use the contact form ID as the trigger, and just place your post ID in the form.
add_action('wpcf7_before_send_mail',
function ($contact_form) {
if ($contact_form->id() === 123) { // Your Contact Form ID
$submission = WPCF7_Submission::get_instance();
$voorraad = '';
$voorraad = get_post_meta(5080, 'voorraad', true);
$newvoorraad = implode(', ', (array)$submission->get_posted_data('number-435'));
$stock = $voorraad - $newvoorraad;
update_post_meta(5080, 'voorraad', $stock);
}
}
);
I have an ACF repeater field field_5f71d4eaaf381 for email addresses and I want to output a comma separate list of the sub field values (measurement_extra_email_address) to create a $to for the WordPress mail function.
$values = $_POST['acf'];
$extra_recipients = $_POST['acf']['field_5f71d4eaaf381'];
if ( $extra_recipients ) {
$list = array();
foreach( $extra_recipients as $extra_recipient ) {
$list[] = $extra_recipient['measurement_extra_email_address'];
}
$to = implode(',', $list);
}
I thought above code should/would do it but no email is being send so I guess the code is incorrect..?
Just a note: When I remove above part of the code and just try $to = 'my#emailadress.com'; an e-mail is being send so the error should be in there...
Here's the code I was looking for:
$values = $_POST['acf'];
$measurement_mail_extra_recipients = $_POST['acf']['field_5f71d4eaaf381'];
if ( $measurement_mail_extra_recipients ) {
$list = array();
foreach( $measurement_mail_extra_recipients as $measurement_mail_extra_recipient ) {
$list[] = $measurement_mail_extra_recipient['field_5f71d55aaf382', $measurement_client];
}
$to = implode(',', $list);
}