Send all of a dropdown in Contact Form 7 - php

I need to send a full array of custom field to a mail (dynamicaly populate) with contact Form 7 to work it here before sending :
// define the wpcf7_posted_data callback
function action_wpcf7_posted_data($array)
{
$a = get_field('date')
//WORK HERE
$array['Nom & Prénom'] = $array['name'];
unset($array['name']);
$array['E-mail'] = $array['email'];
unset($array['email']);
$array['Téléphone'] = $array['tel'];
unset($array['tel']);
$array['Profession'] = $array['job'];
unset($array['job']);
$array['Session'] = $array['upcoming-gigs'];
unset($array['upcoming-gigs']);
unset($array['privacy']);
return $array;
}
add_filter('wpcf7_posted_data', 'action_wpcf7_posted_data', 10, 1);
Because it's before sending a mail I can't call anything to compare before sending.
So I want to send all the data in a hidden input next to compare it.
This the two input in contact Form 7 :
[select upcoming-gigs data:gigs id:date] [hidden select upcoming-gigs2 data:gigs2]
My goal here is to send all the data of the hidden select.
I don't find a way to send all input in the mail.
Is it possible ? There is a better way ?
Thx
EDIT :
My question mark2 :
The goal is to send a mail with the date of the session and the id of it.
I use ACF and I have :
And after a dynamic dropdown, it's look like this for the user :
The problem is I don't have the id of the session, only the date.
To know the id I need to compar to the array of all the custom field, I can't import it during wpcf7_posted_data.
I think if I send all the data of the array in a hidden field, I could remake the array and find the id of the session my user choose.
I hope I'm clearer.
(I can't make a request in php during wpcf7_posted_data. Can I make an ajax request ?)
EDIT2 :
This my hidden select with session and text
This is the html of contact form 7 the rest is div for CSS
[select upcoming-date data:date id:date] [hidden select upcoming-date2 data:date2]
EDIT3 :
Okay get it.
The custom fields I use to make the dropdown are in two part id and text. I have the text part I need the id.
If I send every text and id in the mail I can compare to the answer of the user et add to the mail the right id.
Here the generated html : http://www.sharemycode.fr/5ax
EDIT 4 :
That where I write the id and text of the dropdown :
That where I create the select :
add_filter('wpcf7_form_tag_data_option', function ($n, $options, $args) {
$ses = (array)get_field('date_new');
$sesCount = count($ses);
$gigs = [];
$gigs2 = [];
if (in_array('gigs', $options)) {
for ($i = 0; $i < $sesCount; $i++) {
if ($ses[$i]['date_start'] > date('d-m-Y', time())) {
$a = "A réaliser entre le " . $ses[$i]['date_start'] . " et le " . $ses[$i]['date_end'] ." | bla";
array_push($gigs, $a);
}
}
return $gigs;
}
}

It looks like this is supported by Contact Form 7 natively, it's just not very obvious on how to make it happen.
Here's a documentation page explaining the functionality: http://contactform7.com/selectable-recipient-with-pipes/
Basically all you have to do is put the values like so:
Visible Value|actual-form-value
What comes before the pipe "|" character will be shown in the form, and what comes after will be the actual value filled in for the form.
EDIT kanarpp :
I add my code here to separate the answer of HowardE.
This is how I dynamicaly create my select :
add_filter('wpcf7_form_tag_data_option', function ($n, $options, $args) {
$ses = (array)get_field('date');
$sesCount = count($ses);
$date= [];
if (in_array('date', $options)) {
for ($i = 0; $i < $sesCount; $i++) {
if ($ses[$i]['date_start'] > date('d-m-Y', time())) {
$a = "A réaliser entre le " . $ses[$i]['date_start'] . " et le " . $ses[$i]['date_end'] ." | bla";
array_push($date, $a);
}
}
return $date;
}
It's not working, I use Smart Grid-Layout Design for Contact Form 7 to create dynmicaly my select

I would create a custom form tag for the select. The following code will create a custom form tag called [gigs] which would be used like this:
[gigs upcoming-gigs]
I've also included ability to add the * and make it required.
My assumptions are how you're actually getting the ACF fields, which I can't actually do, since I don't have them, and you haven't completely shared how it's stored. You would add this to your functions.php.
add_action('wpcf7_init', function (){
wpcf7_add_form_tag( array('gigs', 'gigs*'), 'dd_cf7_upcoming_gigs' , array('name-attr' => true) );
});
function dd_cf7_upcoming_gigs($tag) {
if ( empty( $tag->name ) ) {
return '';
}
$validation_error = wpcf7_get_validation_error( $tag->name );
$class = wpcf7_form_controls_class( $tag->type );
if ( $validation_error ) {
$class .= ' wpcf7-not-valid';
}
$atts = array();
$atts['class'] = $tag->get_class_option( $class );
$atts['id'] = $tag->get_id_option();
$atts['tabindex'] = $tag->get_option( 'tabindex', 'signed_int', true );
if ( $tag->is_required() ) {
$atts['aria-required'] = 'true';
}
if ( $validation_error ) {
$atts['aria-invalid'] = 'true';
$atts['aria-describedby'] = wpcf7_get_validation_error_reference(
$tag->name
);
} else {
$atts['aria-invalid'] = 'false';
}
// Make first option unselected and please choose
$html = '<option value="">- - '. __('Please Choose', 'text-domain'). ' - -</option>';
// This part you may have to update with your custom fields
$ses = (array)get_field('date_new');
$sesCount = count($ses);
for ($i = 0; $i < $sesCount; $i++) {
if ($ses[$i]['date_start'] > date('d-m-Y', time())) {
$a = "A réaliser entre le " . $ses[$i]['date_start'] . " et le " . $ses[$i]['date_end'];
// if session ID is in fact $ses[$i]['session']
$html .= sprintf( '<option %1$s>%2$s</option>',
$ses[$i]['session'], $a );
}
}
foreach ($gigs as $key => $value){
$html .= sprintf( '<option %1$s>%2$s</option>',
$key, $value );
}
$atts['name'] = $tag->name;
$atts = wpcf7_format_atts( $atts );
$html = sprintf(
'<span class="wpcf7-form-control-wrap %1$s"><select %2$s>%3$s</select>%4$s</span>',
sanitize_html_class( $tag->name ), $atts, $html, $validation_error
);
return $html;
}
add_filter( 'wpcf7_validate_gigs', 'dd_validate_gigs_filter', 10, 2 );
add_filter( 'wpcf7_validate_gigs*', 'dd_validate_gigs_filter', 10, 2 );
function dd_validate_gigs_filter( $result, $tag ) {
$name = $tag->name;
$has_value = isset( $_POST[$name] ) && '' !== $_POST[$name];
if ( $has_value and $tag->has_option( 'multiple' ) ) {
$vals = array_filter( (array) $_POST[$name], function( $val ) {
return '' !== $val;
} );
$has_value = ! empty( $vals );
}
if ( $tag->is_required() and ! $has_value ) {
$result->invalidate( $tag, wpcf7_get_message( 'invalid_required' ) );
}
return $result;
}

Related

PHP: Accessing variables created with add_action()

I'm kinda learning php as I go along here (though I do have some experience in other languages), so I'm hoping someone can point me in the right direction.
I'm using an add_action() function in functions.php to access the form data from an Elementor form. Works fine from within add_action(), however I cannot return any of the variables to make them available elsewhere within functions.php (I've tried adding "return $fields").
There's probably an easy solution, but I've been wracking my brain all weekend, and haven't gotten anywhere. Any thoughts?
Side Note: I've read elsewhere that using filters may be a solution, but it doesn't seem to be as simple as changing "add_action()" to "add_filter()".
add_action( 'elementor_pro/forms/new_record', function( $record ) {
$form_name = $record->get_form_settings( 'form_name' );
if ( 'MyElementorForm' !== $form_name ) {
return;
}
$raw_fields = $record->get( 'fields' );
$fields = [];
foreach ( $raw_fields as $id => $field ) {
$fields[ $id ] = $field['value'];
}
$letter_type = $fields['LetterType'];
// Send Test Email //
if($letter_type === "1"){
$message = "Upload";
} elseif($letter_type === "0"){
$message = "PDF";
} else {
$message = "Fail " . gettype($letter_type) . " " . $letter_type;
}
mail(
"my#email_address.com",
"Test",
"Test Message " . $message
);}, 10, 2);

WordPress contact form 7 text value change

WordPress - Contact Form 7
I am trying to find out the filter to modify the cf7 field value when someone enter values in it.
when user type in textfield and submit data,
validate - I had done
should not goto thank you page if invalid entry - I had done
replace text field with new data - Not Done
Eg: 1
add_filter( 'wpcf7_validate_text*', 'your_validation_filter_func_tel', 100, 2 );
function your_validation_filter_func_tel( $result, $tag ) {
$Yourvalue = $_POST['your-number'];
if ( strlen( $Yourvalue ) == 2 ) {
$result->invalidate( 'your-number', "Please enter a valid number. " . );
// HERE I WANT TO REPLACE NEW DATA TO TEXT FIELD
$result->data( 'your-number', '1002' );
} else if ( strlen( $Yourvalue ) == 3 ) {
$result->invalidate( 'your-number', "Please enter a valid name." . );
// HERE I WANT TO REPLACE NEW DATA TO TEXT FIELD
$result->data( 'your-number', '1003' );
}
return $result;
}
Eg: 2
another working example
everything working except $result['tel'] = $tel_cleaned_final;
<?php
function custom_filter_wpcf7_is_tel( $result, $tel )
{
// Initialization and Clean Input
$tel_cleaned = strtr( $tel, array(' '=>'', '-'=>'', '.'=>''));
$tel_cleaned_trimmed = ltrim(strtr( $tel_cleaned, array('+'=>'')), '0');
/* Test Conditions.
I concluded 3 if conditions to 1 below bcaz the validation is working perfect
*/
if ('test conditions here')
$tel_cleaned_final = substr($tel_cleaned_trimmed, 2);
else
$tel_cleaned_final = $tel_cleaned_trimmed;
if (strlen($tel_cleaned_final) == 10)
{
$result = true;
//$result['tel'] = $tel_cleaned_final;
/*
Here i want to return new number to text box
for eg: +91 98989-89898 returns 9898989898
*/
}
else
{
$result = false;
}
return $result;
}
add_filter( 'wpcf7_is_tel', 'custom_filter_wpcf7_is_tel', 10, 2 );
?>
What you are trying to do cannot be done with only the validation filter. Because that just outputs true or false based on the validations performed. To do what you want, you have to use another filter ( 'wpcf7_posted_data' ) that has the value you want to filter. So we can break down our process into two steps.
Step 1: Do all the validation like you are currently doing.
Using your Example 2.
function custom_filter_wpcf7_is_tel( $result, $tel )
{
// Initialization and Clean Input
$tel_cleaned = strtr( $tel, array(' '=>'', '-'=>'', '.'=>''));
$tel_cleaned_trimmed = ltrim(strtr( $tel_cleaned, array('+'=>'')), '0');
/* Test Conditions.
I concluded 3 if conditions to 1 below bcaz the validation is working perfect
*/
if ('test conditions here')
$tel_cleaned_final = substr($tel_cleaned_trimmed, 2);
else
$tel_cleaned_final = $tel_cleaned_trimmed;
if (strlen($tel_cleaned_final) == 10)
{
$result = true;
} else
{
$result = false;
}
return $result;
}
add_filter( 'wpcf7_is_tel', 'custom_filter_wpcf7_is_tel', 10, 2 );
The above code will make sure that your points 1 and 2 are working.
Validate.
Stop submission if entry is invalid.
Step 2: Re-run your tests to get the desired value and update it.
function sr_change_updated_field_value( $posted_data )
{
// Initialization and Clean Input
$tel_cleaned = strtr( $tel, array(' '=>'', '-'=>'', '.'=>''));
$tel_cleaned_trimmed = ltrim(strtr( $tel_cleaned, array('+'=>'')), '0');
/* Test Conditions.
I concluded 3 if conditions to 1 below bcaz the validation is working perfect
*/
if ('test conditions here')
$tel_cleaned_final = substr($tel_cleaned_trimmed, 2);
else
$tel_cleaned_final = $tel_cleaned_trimmed;
// Use the name of your field in place of "tel"
$posted_data['tel'] = $tel_cleaned_final;
return $posted_data;
};
add_filter( 'wpcf7_posted_data', 'sr_change_updated_field_value', 10, 1 );
P.S. This will update the values sent in the email, or in the submissions if you store them. It will show the validation message, but it will not show the updated value in text field because that cannot be done with php in this scenario.
P.S. 2 This is all tested code. Happy Coding.
maybe this can help:
add_action( 'wpcf7_before_send_mail', 'some_function_name', 1 );
function some_function_name( $contact_form ) {
$wpcf7 = WPCF7_ContactForm::get_current();
$submission = WPCF7_Submission::get_instance();
if ($submission) {
$data = array();
$data['posted_data'] = $submission->get_posted_data();
$firstName = $data['posted_data']['first-name']; // just enter the field name here
$mail = $wpcf7->prop('mail');
if($firstName =''){
$mail['body'] = str_replace('[first-name]', $firstName . '-blah blah', $mail['body']);
}
$wpcf7->set_properties(array(
"mail" => $mail
));
return $wpcf7;
}
}
Hope it helps!
P.S. This is not tested, please let me know if it works :)

Check equals of tags in array

Good day!
I have archive page, that displays all posts tags in sidebar.
In Archive page i have loop:
global $b;
$i=1;
$b=0;
while( have_posts() ){
the_post();
global $arch_postID;
global $b;
if($i == $num_fetch && $sidebar == 'both-sidebar' ) {
echo '<div class="blog-item' . $item_index . ' gdl-divider ' . $item_class . ' mb30">';
$arch_postID[] = get_the_ID();
echo $i;
}elseif($i == $num_fetch) {
echo '<div class="blog-item' . $item_index . ' gdl-divider ' . $item_class . ' mb20">';
$arch_postID[] = get_the_ID();
echo $i;
}else{
echo '<div class="blog-item' . $item_index . ' gdl-divider ' . $item_class . ' mb50">';
$arch_postID[] = get_the_ID();
echo $i;
}
$b++;
$i++;
In function.php for sidebar i have:
global $arch_postID;
global $b;
global $archive_uri;
if ( !empty($arch_postID) && is_archive() ){
echo '<style>.archive-hide-side{display:none;}</style>';
for($i = 0; $i <= $b-1; $i++){
$array_keys = array_keys($arch_postID);
$terms_array = wp_get_post_terms($arch_postID[$i],'vip'); // Get terms for post_id in array( $arch_postID[0], $arch_postID[1] ... )
$terms_array_next = wp_get_post_terms($arch_postID[$i+1],'vip'); // Get terms for post_id in array( $arch_postID[1], $arch_postID[2] ... )
$terms_array_last = wp_get_post_terms($arch_postID[$b-1],'vip'); // Get terms for $arch_postID[$i = last]
$terms_array_first = wp_get_post_terms($arch_postID[0],'vip'); // Get terms for first post ID
for($a = 0; $a <= count($a)+1; $a++){
$name_array = $terms_array[$a]->name;
$name_array_next = $terms_array_next[$a]->name;
$name_array_last = $terms_array_last[$a]->name;
$name_array_first= $terms_array_first[$a]->name;
if( $name_array == $name_array_next or $name_array_next == $name_array_last or $name_array_last == $name_array_first ){ // check if next term->name is similar to previous of last, or first
$name_array_next = NULL; // assigned NULL to value of term->name
$name_array_last = NULL; // assigned NULL to value of term->name
$name_array_first = NULL; // assigned NULL to value of term->name
echo '<div style="color:black">'. $arch_postID[$i] .' || '. $name_array .'</div>'; // Display term->name values without next or previous term->name
}
}
}
}
This code works like - prntscr.com/7rrozc - displays all tags( on right side ) and post ID(on left side ) divided by "||" from current archive page posts.
End result:
I need to display only one tag, if it similar to another.
I have two posts, their tags: first post( "vip 1", "vip 2", "vip 3", "OTHER" ), second post( "vip 1", "vip 2", "OTHER 2").
In sidebar must be displayed "vip 1", "vip 2","vip 3","OTHER","OTHER 2".
I'm stuck on that question for two days, i have no solution in my mind... If someone knows how to do that, pls help me out. I would be happy for a little hint.
P.S. Thanks for you help and time!
I find solution, works great!
$Path=$_SERVER['REQUEST_URI'];
$Prev_path=$_SERVER['HTTP_REFERER'];
$URI='http://gradrich.tmweb.ru'.$Path;
global $arch_postID;
global $b;
global $archive_uri;
global $brr;
if ( !empty($arch_postID) && is_archive() ){
for($i = 0; $i <= $b-1; $i++){
$terms_array = wp_get_post_terms($arch_postID[$i],'super_vip');
for($a = 0; $a <= 100; $a++){//goes a 100 time from 0, to show all parameters from wp_get_post_terms array
$terms_name[] = $terms_array[$a]->name;// create array of terms->name
$terms_slug[] = $terms_array[$a]->slug;// create array of terms->slug
}
}
$result_name = array_unique($terms_name);// check name array for unique variables
$result_slug = array_unique($terms_slug);// check slug array for unique variables
for($f = 0, $s = 0; $f <= count($terms_name), $s <= count($terms_slug); $f++, $s++){// do loop for all unique variables
if(!empty($result_name[$f]) && !is_category() || !empty($result_slug[$s]) && !is_category()){//check if variables not empty than get proper name and slug from two arrays
echo '<div class="tagCloud-cover" id="cat-hide">' . $result_name[$f] . '<a href="'. $Prev_path .'" >-</a></div>';
} else{
}
}
}

Hide language WPML

I am using WPML language, and cant find solution for next thing:
On the Language switcher i want to hide language, lets say for example - "he", if current language is lets say for example "ar", so when we on arabic site we will not see on the selector the Hebrew, and same thing if we on Hebrew, the arabic will not display.
On shorten words: what i want is - if we on arabic site - the hebrew flag will be hidden.
What i tried:
function language_selector_flags(){
$languages = icl_get_languages('skip_missing=0');
if(!empty($languages)){
if(ICL_LANGUAGE_CODE=='en')
{
$order = array('ar'); //Specify your sort order here
}
elseif(ICL_LANGUAGE_CODE=='he')
{
$order = array('en', 'ar'); //Specify your sort order here
}
foreach ($order as $l) {
if (isset($languages[$l])) {
$l = $languages[$l]; //grab this language from the unsorted array that is returned by icl_get_languages()
//Display whatever way you want -- I'm just displaying flags in anchors (CSS: a {float:left; display:block;width:18px;height:12px;margin:0 2px;overflow:hidden;line-height:100px;})
if($l['active']) { $class = "active"; $url=""; } else { $class = ''; $url = 'href="'.$l['url'].'"'; }
echo '<a '.$url.' style="background:url('.$l['country_flag_url'].') no-repeat;" class="flag '.$class.'">';
echo $l['language_code'].'';
}
}
}
}
Its not affect at all the selector.
You can check out the plugin WPML Flag In Menu.
You could use the plugin_wpml_flag_in_menu() function from the plugin (see source code here) and replace:
// Exclude current viewing language
if( $l['language_code'] != ICL_LANGUAGE_CODE )
{
// ...
}
with
// Include only the current language
if( $l['language_code'] == ICL_LANGUAGE_CODE )
{
// ...
}
to show only the current language/flag, if I understand you correctly.
ps: If you need further assistance, you could for exampe show us the output of this debug function for the active language:
function debug_icl_active_language()
{
$languages = icl_get_languages( 'skip_missing=0' );
foreach( (array) $languages as $l )
{
if( $l['active'] )
{
printf( '<pre> Total languages: %d - Active: %s </pre>',
count( $languages ),
print_r( $l, TRUE ) );
}
}
}
i have some useful link for you, please go through it first:
http://wpml.org/forums/topic/hide-language-vs-display-hidden-languages-in-your-profile-not-working/
http://wpml.org/forums/topic/hide-one-language/
http://wpml.org/forums/topic/hiding-active-language-in-menu/
http://wpml.org/forums/topic/language-selector-how-to-hide-one-language/
thanks
function language_selector_flags(){
$languages = icl_get_languages('skip_missing=0');
if(!empty($languages)){
$filter = array();
$filter['ar'] = array( 'he' );
// set your other filters here
$active_language = null;
foreach ($languages as $l)
if($l['active']) {
$active_language = $l['language_code'];
break;
}
$filter = $active_language && isset( $filter[$active_language] ) ? $filter[$active_language] : array();
foreach ($languages as $l) {
//Display whatever way you want -- I'm just displaying flags in anchors (CSS: a {float:left; display:block;width:18px;height:12px;margin:0 2px;overflow:hidden;line-height:100px;})
if( in_array( $l['language_code'], $filter) )
continue;
if($l['active']) { $class = "active"; $url=""; } else { $class = ''; $url = 'href="'.$l['url'].'"'; }
echo '<a '.$url.' class="flag '.$class.'"><img src="', $l['country_flag_url'], '" alt="', esc_attr( $l['language_code'] ), '" /></a>';
}
}
}
EDIT: If I get this right, your client(I assume) doesn't want his customers (Israelis especiay) to know that he offer service also to the arabic speaking cusomers. If it so then you can parse the Accept-Language header and filter the language selector according the result.
I have a similar problem/issue:
On this website: https://neu.member-diving.com/
I have languages I not need in the switcher. I tried the code above, but it nothing changed so far.
So, what I would like to do is, When a client is on the one "german" page, the other german languages in the switcher should not need to be there, only the english one and the actual german one.
Where do I need to put code like
function language_selector_flags(){
$languages = icl_get_languages('skip_missing=0');
if(!empty($languages)){
$filter = array();
$filter['ar'] = array( 'he' );
// set your other filters here
$active_language = null;
foreach ($languages as $l)
if($l['active']) {
$active_language = $l['language_code'];
break;
}
$filter = $active_language && isset( $filter[$active_language] ) ? $filter[$active_language] : array();
foreach ($languages as $l) {
//Display whatever way you want -- I'm just displaying flags in anchors (CSS: a {float:left; display:block;width:18px;height:12px;margin:0 2px;overflow:hidden;line-height:100px;})
if( in_array( $l['language_code'], $filter) )
continue;
if($l['active']) { $class = "active"; $url=""; } else { $class = ''; $url = 'href="'.$l['url'].'"'; }
echo '<a '.$url.' class="flag '.$class.'"><img src="', $l['country_flag_url'], '" alt="', esc_attr( $l['language_code'] ), '" /></a>';
}
}
}

Entering multiple selections into database from <select multiple> box

I have the bit of code below and I would like uses to select multiple options in the "select multiple" box and for these all to be added into the database. At the moment only 1 of the values that is selected is entered. I am a noob with this sort of thing so an in need of help to progress with the project.
Thanks for any help!
function ProjectTheme_get_categories($taxo, $selected = "", $include_empty_option = "", $ccc = "")
{
$args = "orderby=name&order=ASC&hide_empty=0&parent=0";
$terms = get_terms( $taxo, $args );
$ret = '<select multiple size="20" name="'.$taxo.'_cat" class="'.$ccc.'" id="scrollselect '.$ccc.'">';
if(!empty($include_empty_option)) $ret .= "<option value=''>".$include_empty_option."</o ption>";
if(empty($selected)) $selected = -1;
foreach ( $terms as $term )
{
$id = $term->term_id;
$ret .= '<option '.($selected == $id ? "selected='selected'" : " " ).' value="'.$id.'">'.$term->name.'</option>';
$args = "orderby=name&order=ASC&hide_empty=0&parent=".$id;
$sub_terms = get_terms( $taxo, $args );
foreach ( $sub_terms as $sub_term )
{
$sub_id = $sub_term->term_id;
$ret .= '<option '.($selected == $sub_id ? "selected='selected'" : " " ).' value="'.$sub_id.'"> | '.$sub_term->name.'</option>';
$args2 = "orderby=name&order=ASC&hide_empty=0&parent=".$sub_id;
$sub_terms2 = get_terms( $taxo, $args2 );
foreach ( $sub_terms2 as $sub_term2 )
{
$sub_id2 = $sub_term2->term_id;
$ret .= '<option '.($selected == $sub_id2 ? "selected='selected'" : " " ).' value="'.$sub_id2.'"> |
'.$sub_term2->name.'</option>';
}
}
}
$ret .= '</select>';
return $ret;
}
Here is another section of the code where the user interacts with that form
<li><h2><?php echo __('Category', 'ProjectTheme'); ?>:</h2>
<p><?php echo ProjectTheme_get_categories("project_cat",
!isset($_POST['project_cat_cat']) ? (is_array($cat) ? $cat[0]->term_id : "") : $_POST['project_cat_cat']
, __("Select Category","ProjectTheme"), "do_input"); ?></p>
</li>
Additional code that handles the submit function of the form
do_action('ProjectTheme_post_new_post_post',$pid);
if(isset($_POST['project_submit1']))
{
$project_title = trim($_POST['project_title']);
$project_description = nl2br($_POST['project_description']);
$project_category = $_POST['project_cat_cat'];
$project_location = trim($_POST['project_location_cat']);
$project_tags = trim($_POST['project_tags']);
$price = trim($_POST['price']);
$project_location_addr = trim($_POST['project_location_addr']);
$end = trim($_POST['ending']);
update_post_meta($pid, 'finalised_posted', '0');
//--------------------------------
$projectOK = 1;
if(empty($project_title)) { $projectOK = 0; $MYerror['title'] = __('You cannot leave the project title blank!','ProjectTheme'); }
if(empty($project_category)) { $projectOK = 0; $MYerror['cate'] = __('You cannot leave the project category blank!','ProjectTheme'); }
if(empty($project_description)) { $projectOK = 0; $MYerror['description'] = __('You cannot leave the project description blank!','ProjectTheme'); }
//--------------------------------
$project_category2 = $project_category;
$my_post = array();
$my_post['post_title'] = $project_title;
$my_post['post_status'] = 'draft';
$my_post['ID'] = $pid;
$my_post['post_content'] = $project_description;
$term = get_term( $project_category, 'project_cat' );
$project_category = $term->slug;
$term = get_term( $project_location, 'project_location' );
$project_location = $term->slug;
wp_update_post( $my_post );
wp_set_object_terms($pid, array($project_category),'project_cat');
wp_set_object_terms($pid, array($project_location),'project_location');
wp_set_post_tags( $pid, $project_tags);
Append a [] to Select Tag's name like this <select name="taxo_cat[]" multiple> and in your php code you can access array of values by calling $_POST['taxo_cat']
First of all, to be able to save all selected options, you must send them as an array. For this, the name of the element must be
name="'.$taxo.'_cat[]"
After, on the server side you'll find all selected values in the request variable.
I'm not familiar with Wordpress, but what has changed in your code is
$project_category = $_POST['project_cat_cat'];
$project_location = trim($_POST['project_location_cat']);`
project_category and project_location are now array and not strings, this means you must propably change the way the function get_term() is called, and
wp_set_object_terms($pid, array($project_category),'project_cat');
wp_set_object_terms($pid, array($project_location),'project_location');
has to be changed to
wp_set_object_terms($pid, $project_category,'project_cat');
wp_set_object_terms($pid, $project_location,'project_location');

Categories