Wordpress Shortcode atts problems

I’m having a problem with using one of the atts array passed from a shortcode I’ve written. I want this function to get the email address passed by send_to in the atts array but it keep returning blank. The function then updates the form that’s included with a hidden field indicating where the form should be sent. Looking at the source HTML output it’s including everything bar the email address passed as send_to.

I’d really appreciate someone helping, or pointing out my glaring error.

The shortcode is [forms id=‘Question’ send_to=‘me@me.com’]


function forms_shortcode ($atts, $content=NULL) {
	
//shortcode functions  	
	function mail_to() {
		extract(shortcode_atts( array('send_to' => ''), $atts));
			$hidden_to = '<input name="to" type="hidden" value="';
			$hidden_to .= $send_to;
			$hidden_to .= '" />';
			return $hidden_to;
	}
	
	extract(shortcode_atts( array('id' => ''), $atts));
	$id = strtolower($id);
	if ($id == 'question') {
		ob_start();
		include 'question-form.php';
		$content = ob_get_clean();
		return $content;
		mail_to();
	}
}

add_shortcode('forms', 'forms_shortcode');

On the

shortcode_atts( array('send_to' => ''), $atts));

try setting send_to to null or a default address versus ‘’

Hi Ryan,

Thanks for the reply.

I tried changing the line to:

shortcode_atts( array('send_to' => NULL), $atts));

Which returns:

input name="to" type="hidden" value=""

and

shortcode_atts( array('send_to' => 'us@us.com'), $atts));

Which returns

input name="to" type="hidden" value="us@us.com"

Unfortunately neither version of the code picks up the send_to value from the shortcode.

that tells me that $send_to isn’t being populated. So let’s see your form code.

The code for the form is as follows:


               
                    <form action="<?php bloginfo('stylesheet_directory'); ?>/form-mail-handler.php" method="post" id="pros" >
                    <input name="from" type="hidden" value="<?php echo curPageURL(); ?>" />
 					<input name="type" type="hidden" value="Question" />
                	<?php 
				   	if (function_exists('mail_to')) {
    					echo mail_to();
				   	} 				   
				   	?>
                    <fieldset>
                    <legend>Ask us a question</legend>
                    <ol>
                    	<li>
                            <label for="name">Name:</label><br />
                            <input name="Name" type="text" id="name" />
                    	</li>
                        <li>
                        	<label for="email">email:</label><br />
                    		<input name="Email" type="text" id="email" />
                        </li>
                        <li>
                    		<label for "message">Question:</label><br />
                    		<textarea name="Message" cols="59" rows="7" id="message"></textarea>
						</li>
                        </ol>
                    </fieldset>
                    <fieldset class="submit">
                    <input name="submit" type="submit" value="Send Question" class="btn" />
                    </fieldset>
                    </form>


Once more thanks for your help.

Ok, a few things.It is a good idea to have names and id’s the same… Email != email. Also can I see form-mail-handler.php? Nothing in your code sets the form values to PHP variables.

The code for form-mail-handler is below.

I take your point about names and ID’s. They were the same (honest), but I changed them after I started writing the code below, but before I put the array_change_key_case function in.

My only defence is that I’m new to php so I’m kind of winging it.


<?php

$p = array_change_key_case($_POST, CASE_LOWER);


if (array_key_exists('to', $p)) {

    $to = $p['to'];
}
else {

	$to = 'us@us.com';
}


$subject = '';

if ($p['type']) {
	$subject .= $p['type'].' from ';
}

else {
	$subject .= 'Enquiry from ';
}


if ($p['name']) {
	$subject .= $p['name'];
}

else {
	$subject .= 'Unknown Sender';
}

if ($p['from']) {
	$subject .= ' via '.$p['from'];
}


$message = '';

foreach( $p as $key => $value){

	if (!$value) {
	}

	else {

		if ($key == 'submit' || $key == 'to' || $key == 'from' || $key == 'type') {	
		}

		else {

			$mail_item = ucfirst($key).': '.$value;

			$message .= $mail_item."\\r\
";
		}
	}
}




$headers = 'From: '. $p['email'] . "\\r\
";

$headers .= 'Reply-To: '. $p['email'] ."\\r\
";

$headers .= 'X-Mailer: PHP/' . phpversion();

$headers .= 'Content-Type: text/plain; ';


	
mail($to, $subject, $message, $headers);

if ($p['from'] && $p['type']) {
	$location_redirect = 'Location: '.$p['from'].'?submit=true&type='.$p['type'];
}

else if ($p['from']) {
	$location_redirect = 'Location: '.$p['from'].'?submit=true';
}

else {
	$location_redirect = "Location: $HTTP_REFERER";
}


header($location_redirect);
?>

Cheers,
Richard.

I didn’t test this but…
make the following change:


 (array_key_exists('to', $p)) {

    $to = $p['to'];
}
else {

	$to = $hidden_to;
}
 

Hi Ryan,

I don’t think that this will solve the problem. The else part of the code above is meant to default to the generic email address if there is no $to variable in the $_POST array. This file is only called when the form is submitted.

When I look at the source html code generated using the shortcode, if I use a default setting for send_to in the shortcode atts there will be the hidden “to” field with the value of the default email address I used.

For example, using the shortcode [forms id=‘question’ send_to=‘me@me.com’] this code:

	
            function mail_to() {
		extract(shortcode_atts( array('send_to' => 'us@us.com'), $atts));
			$hidden_to = '<input name="to" type="hidden" value="';
			$hidden_to .= $send_to;
			$hidden_to .= '" />';
			return $hidden_to;
	}

Outputs this:


<input name="to" type="hidden" value="us@us.com" />

and this code:

	
            function mail_to() {
		extract(shortcode_atts( array('send_to' => ''), $atts));
			$hidden_to = '<input name="to" type="hidden" value="';
			$hidden_to .= $send_to;
			$hidden_to .= '" />';
			return $hidden_to;
	}

Outputs this:


<input name="to" type="hidden" value="" />

The second example also outputs nothing in the value of the hidden “to” field if I change the default send_to to NULL.

So I think this is a problem in processing the $atts array and extracting the $send_to variable from it.

Cheers,
Richard.

Richard,
I cannot tell if you actually tried my suggestion or not. If I missed it, I am sorry, let me know, and relook at your code. However, it seems like you were just trying to show how I was wrong without even attempting it.

Sorry Ryan - I should have been clearer.

Yes I have tried it as you stated above. I tried the code you put above and the following:


if (array_key_exists('to', $p)) {
    $to = $p['to'];
}
else if ($send_to) {
	$to = $send_to;
}
else {
	$to = 'us@us.com';
}

With the version above, if there is no $send_to variable set by the shortcode the form is sent to us@us.com. When I set one using the shortcode and submit the form the mail function doesn’t work, but I think that this is because the default value for the shortcode variable $send_to is an empty string.

I really appreciate your help with this.

Cheers,
Richard.

If you did:


if (array_key_exists('to', $p)) {

    $to = $p['to'];
}
else {

    $to = $hidden_to;
}
if (array_key_exists('to', $p)) {
    $to = $p['to'];
}
else if ($send_to) {
	$to = $send_to;
}
else {
	$to = 'us@us.com';
}

My code gets overwritten… BTW did you try double quotes?

Sorry I’m not being clear again. I tried both:

if (array_key_exists('to', $p)) { 
  
    $to = $p['to']; 
} 
else { 
  
    $to = $send_to; 
}  

and


if (array_key_exists('to', $p)) {
    $to = $p['to'];
}
else if ($send_to) {
	$to = $send_to;
}
else {
	$to = 'us@us.com';
}

When you say double quotes do you mean in the extract argument, rather than single quotes, default or null value?

If so I’ve just tried this and it doesn’t work either.


extract(shortcode_atts( array('send_to' => ""), $atts));

Richard,
You didn’t try what I suggested in post #8, I suggested making $to = $hidden_to instead of $to = $send_to.

Sorry by double quotes, I meant: [forms id=‘Question’ send_to="me@me.com"]

I did try $hidden_to as well (I pasted the code into the function) but it doesn’t work becuase $hidden_to is a string that contains the hidden form field. So when I use the php mail function it would try to send the email to <input name=“to” type=“hidden” value=“” />.

I’ve just tried the double quotes as well but no joy.

My other guess would be to set up an array of good addresses, then use the keys to select the correct one.