Drupal: Edit email template from contact form - drupal

When submitting a message in my site-wide contact form in Drupal 6.x I get the following message along the top of every message:
[Name] sent a message using the contact form at [www.mysite.com/contact]
I would like to remove this message. Looking around, I've found it comes from the contact.module here:
$message['body'][] = t("!name sent a message using the contact form at !form.", array('!name' => $params['name'], '!form' => url($_GET['q'], array('absolute' => TRUE, 'language' => $language))), $language->language);
I've done a bit of research and it seems that I need to create a custom module with a hook_mail_alter() function to edit the contact.module. When it comes to this I get a bit lost. Could anyone kindly take me through the steps to accomplish the task?
Many thanks.

I did something like that recently. Here is a template you can use to get what you need. Most is from the contact module. The code below is from Drupal 7 but should work as is in Drupal 6.
/**
* Implementation of hook_mail_alter().
*/
function modulename_mail_alter(&$message) {
if ($message['id'] == 'contact_page_mail') {
$language = $message['language'];
$params = $message['params'];
$variables = array(
'!form-url' => url($_GET['q'], array('absolute' => TRUE, 'language' => $language)),
'!sender-name' => format_username($params['sender']),
'!sender-url' => $params['sender']->uid ? url('user/' . $params['sender']->uid, array('absolute' => TRUE, 'language' => $language)) : $params['sender']->mail,
);
$message['body'] = array();
$message['body'][] = t("Your custom message with variables", $variables, array('langcode' => $language->language));
$message['body'][] = $params['message']; // Append the user's message/
}
}

function theme_mail_alter(&$message) {
// only alter contact forms
if (!empty($message['id']) && $message['id'] == 'contact_page_mail') {
$contact_message = $message['params']['contact_message'];
$message['body'] = [];
$fields = $contact_message->getFields();
$new_body .= 'Message:' . PHP_EOL . $contact_message->get('message')->value . PHP_EOL . PHP_EOL;
foreach ($fields as $field_name => $field) {
if (get_class($field->getFieldDefinition()) == 'Drupal\field\Entity\FieldConfig') {
$new_body .= $field->getFieldDefinition()->label() . ':' . PHP_EOL;
if (isset($contact_message->get($field_name)->entity->uri->value)) {
$uri = $contact_message->get($field_name)->entity->uri->value;
$url = file_create_url($uri);
$new_body .= $url . PHP_EOL . PHP_EOL;
} else {
$new_body .= $contact_message->get($field_name)->value . PHP_EOL . PHP_EOL;
}
}
}
$message['body'][] = $new_body;
}
}

Related

How to generate zip file after woocommerce_email_attachments Woocommerce hook

What i want to do is create pdf (pdf's) on woocommerce_email_attachments hook, then create zip file with these pdf's, and then on thankyou page locate button to download this zip. To generate zip I used woocommerce_before_thankyou hook but this is too late. So I tried
woocommerce_order_status_on-hold,
woocommerce_order_status_processing
But these hooks seems not firing, maybe they work on transitions in admin order page. Also I tried woocommerce_payment_complete with test paypal account - not created zip also.
Or maybe these hooks fire before woocommerce_email_attachments and there is no pdf yet to create zip? So can you suggest hook after sending wc email but before woocommerce_before_thankyou ?
Code which I use to generate pdf's:
add_filter('woocommerce_email_attachments', 'attach_order_notice', 10, 3);
function attach_order_notice($attachments, $email_id, $order)
{
// check if all variables properly set
if (!is_object($order) || !isset($email_id)) {
return $attachments;
}
// Skip User emails
if (get_class($order) == 'WP_User') {
return $attachments;
}
// do not process low stock notifications, user emails etc!
if (in_array($email_id, array('no_stock', 'low_stock', 'backorder', 'customer_new_account', 'customer_reset_password'))) {
return $attachments;
}
// final check on order object
if (!($order instanceof \WC_Order || is_subclass_of($order, '\WC_Abstract_Order'))) {
return $attachments;
}
// if ($email_id == 'customer_on_hold_order') {
$order_items = $order->get_items(['line_item']);
$date = $order->get_date_created()->date('h-i-s,j-m-y');
foreach ($order_items as $product) {
$html = render_template(locate_template('pdf/certificate/certificate.php'), ['order' => $order, 'order_product' => $product]);
$html = utf8_decode(mb_convert_encoding($html, 'HTML-ENTITIES', 'UTF-8'));
$options = new Dompdf\Options([
'tempDir' => get_template_directory() . '/certificate',
'fontDir' => get_template_directory() . '/assets/fonts/',
'chroot' => get_template_directory(),
'defaultFont' => 'Montserrat',
'isRemoteEnabled' => true,
'isHtml5ParserEnabled' => true
]);
$dompdf = new Dompdf\Dompdf($options);
$dompdf->loadHtml($html);
$dompdf->setPaper('A4', 'portrait');
$dompdf->render();
$data = $dompdf->output();
$pdf_path = get_template_directory() . "/certificate/product-{$product->get_product_id()}({$date}).pdf";
file_put_contents($pdf_path, $data);
$attachments[] = $pdf_path;
}
// }
return $attachments;
}
Code which I use to create zip:
add_action('woocommerce_before_thankyou', 'custom_make_thank_page');
function custom_make_thank_page($order_id)
{
$order = wc_get_order($order_id);
$order_items = $order->get_items(['line_item']);
$date = $order->get_date_created()->date('h-i-s,j-m-y');
$total_quantity = array_sum(array_map(function ($product) {
return $product->get_quantity();
}, $order_items));
//Zip
$zip = new ZipArchive();
$file = TMP_PATH . '/pdf/zip/certificates-' . $order->get_id() . '.zip';
if ($zip->open($file, ZipArchive::CREATE) === TRUE) {
foreach ($order_items as $item) {
$file_pdf = get_template_directory() . "/certificate/product-{$item->get_product_id()}({$date}).pdf";
if (file_exists($file_pdf)) {
$zip->addFile($file_pdf, "/certificate/product-{$item->get_product_id()}({$date}).pdf");
}
}
$zip->close();
}
?>
<?php if (!$order->has_status('failed')) : ?>
<a href="<?php echo TMP_URL . '/pdf/zip/certificates-' . $order->get_id() . '.zip'; ?>" class="button button-thank-page"><span>Download certificate</span>
</a> // Here downloading not works, works only after reloading page
</div>
<?php endif; ?>
<?php
}

Wordpress: How to Search within a specific category by slug (category name)

How can I create a code which would search by slug(category name) but not by ID. How can I create a customized solution for my client for search within a specific category (without any plugins)?
Explain: I want the code of search to be customized in such a way that the client could search within a specific category without editing any code. Thanks!
is it's still actually, you should to check this tutorial where an author gives a very detailed explanation about the Search function customization.
One of the most interesting parts for a necessary your case:
// meta_query expects nested arrays even if you only have one query
$sm_query = new WP_Query( array( 'post_type' => 'accommodation', 'posts_per_page' => '-1', 'meta_query' => array( array( 'key' => '_sm_accommodation_city' ) ) ) );
// The Loop
if ( $sm_query->have_posts() ) {
$cities = array();
while ( $sm_query->have_posts() ) {
$sm_query->the_post();
$city = get_post_meta( get_the_ID(), '_sm_accommodation_city', true );
// populate an array of all occurrences (non duplicated)
if( !in_array( $city, $cities ) ){
$cities[] = $city;
}
}
}
} else{
echo 'No accommodations yet!';
return;
}
/* Restore original Post Data */
wp_reset_postdata();
if( count($cities) == 0){
return;
}
asort($cities);
$select_city = '<select name="city" style="width: 100%">';
$select_city .= '<option value="" selected="selected">' . __( 'Select city', 'smashing_plugin' ) . '</option>';
foreach ($cities as $city ) {
$select_city .= '<option value="' . $city . '">' . $city . '</option>';
}
$select_city .= '</select>' . "\n";
reset($cities);

Plugin Development - wp insert post not working

I am new to plugin development for WP. I have a problem with wp_insert_post from the plugin file, tested running this plugin php file, and all the code before the wp_insert_post is fine, but once it jumps on wp_insert_post nothing happens after, stuck at 'Test15'. Tested running the insert post part of the code from test page within the theme folder and it worked. Not sure what is the problem here. Please see the code below.
function db_importer_insert_properties($properties, $category, $user_id, $post_type) {
echo 'Test9<br>';
$result = true;
echo 'Test10<br>';
if($properties) {
echo 'Test11<br>';
if(count($properties) > 0) {
echo 'Test12<br/>';
print_r($properties);
echo '<br/>';
$count = 0;
foreach($properties as $property) {
echo 'Test13<br/>';
$address =$property['address'] ; //get title
$building=$address['streetNumber'];
$street=$address['street'];
$suburb=$address['suburb'];
$state=$address['state'];
$postcode=$address['postcode'];
$title=$building. ' ' .$street.', '.$suburb.', '.$postcode.', '.strtoupper($state);
//test post
$new_post = array(
'post_title' => 'My post10 ',
'post_content' => 'This is my post10 ',
'post_status' => 'publish',
'post_author' => 1,
'post_category' => 'uncategorized'
);
echo 'Test14<br/>';
print_r($new_post);
echo '<br/>';
echo 'Test15<br/>';
wp_insert_post($new_post);
echo 'Test16<br>';
if($post_id != 0) {
add_post_meta($post_id, "_bathrooms", esc_attr($property['features']['bathrooms']));
add_post_meta($post_id, "_bedrooms", esc_attr($property['features']['bedrooms']));
if(is_array($property['images'])) {
add_post_meta($post_id, "_images", esc_attr(implode("\n", $property['images'])));
}
else {
feedback("Post ID was 0");
}
feedback("added property $title with post_id $post_id");
$count++;
}
else {
feedback("post was failed to add");
}
}
feedback("Added $count properties");
}
else {
feedback("No properties to add.");
}
}
else {
feedback("No properties were selected");
$result = false;
}
return $result;
}
You forgot to declare your $post_id variable. Use the following:
$post_id = wp_insert_post( $new_post, true );
This will return the post ID on success or a WP error on failure.
Use print_r( $post_id ) to check the result.

Wordpress custom metabox input value with AJAX

I am using Wordpress 3.5, I have a custom post (sp_product) with a metabox and some input field. One of those input (sp_title).
I want to Search by the custom post title name by typing in my input (sp_title) field and when i press add button (that also in my custom meta box), It will find that post by that Title name and bring some post meta data into this Meta box and show into other field.
Here in this picture (Example)
Search
Click Button
Get some value by AJAX from a custom post.
Please give me a example code (just simple)
I will search a simple custom post Title,
Click a button
Get the Title of that post (that i search or match) with any other post meta value, By AJAX (jQuery-AJAX).
Please Help me.
I was able to find the lead because one of my plugins uses something similar to Re-attach images.
So, the relevant Javascript function is findPosts.open('action','find_posts').
It doesn't seem well documented, and I could only found two articles about it:
Find Posts Dialog Box
Using Built-in Post Finder in Plugins
Tried to implement both code samples, the modal window opens but dumps a -1 error. And that's because the Ajax call is not passing the check_ajax_referer in the function wp_ajax_find_posts.
So, the following works and it's based on the second article. But it has a security breach that has to be tackled, which is wp_nonce_field --> check_ajax_referer. It is indicated in the code comments.
To open the Post Selector, double click the text field.
The jQuery Select needs to be worked out.
Plugin file
add_action( 'load-post.php', 'enqueue_scripts_so_14416409' );
add_action( 'add_meta_boxes', 'add_custom_box_so_14416409' );
add_action( 'wp_ajax_find_posts', 'replace_default_ajax_so_14416409', 1 );
/* Scripts */
function enqueue_scripts_so_14416409() {
# Enqueue scripts
wp_enqueue_script( 'open-posts-scripts', plugins_url('open-posts.js', __FILE__), array('media', 'wp-ajax-response'), '0.1', true );
# Add the finder dialog box
add_action( 'admin_footer', 'find_posts_div', 99 );
}
/* Meta box create */
function add_custom_box_so_14416409()
{
add_meta_box(
'sectionid_so_14416409',
__( 'Select a Post' ),
'inner_custom_box_so_14416409',
'post'
);
}
/* Meta box content */
function inner_custom_box_so_14416409( $post )
{
?>
<form id="emc2pdc_form" method="post" action="">
<?php wp_nonce_field( 'find-posts', '_ajax_nonce', false); ?>
<input type="text" name="kc-find-post" id="kc-find-post" class="kc-find-post">
</form>
<?php
}
/* Ajax replacement - Verbatim copy from wp_ajax_find_posts() */
function replace_default_ajax_so_14416409()
{
global $wpdb;
// SECURITY BREACH
// check_ajax_referer( '_ajax_nonce' );
$post_types = get_post_types( array( 'public' => true ), 'objects' );
unset( $post_types['attachment'] );
$s = stripslashes( $_POST['ps'] );
$searchand = $search = '';
$args = array(
'post_type' => array_keys( $post_types ),
'post_status' => 'any',
'posts_per_page' => 50,
);
if ( '' !== $s )
$args['s'] = $s;
$posts = get_posts( $args );
if ( ! $posts )
wp_die( __('No items found.') );
$html = '<table class="widefat" cellspacing="0"><thead><tr><th class="found-radio"><br /></th><th>'.__('Title').'</th><th class="no-break">'.__('Type').'</th><th class="no-break">'.__('Date').'</th><th class="no-break">'.__('Status').'</th></tr></thead><tbody>';
foreach ( $posts as $post ) {
$title = trim( $post->post_title ) ? $post->post_title : __( '(no title)' );
switch ( $post->post_status ) {
case 'publish' :
case 'private' :
$stat = __('Published');
break;
case 'future' :
$stat = __('Scheduled');
break;
case 'pending' :
$stat = __('Pending Review');
break;
case 'draft' :
$stat = __('Draft');
break;
}
if ( '0000-00-00 00:00:00' == $post->post_date ) {
$time = '';
} else {
/* translators: date format in table columns, see http://php.net/date */
$time = mysql2date(__('Y/m/d'), $post->post_date);
}
$html .= '<tr class="found-posts"><td class="found-radio"><input type="radio" id="found-'.$post->ID.'" name="found_post_id" value="' . esc_attr($post->ID) . '"></td>';
$html .= '<td><label for="found-'.$post->ID.'">' . esc_html( $title ) . '</label></td><td class="no-break">' . esc_html( $post_types[$post->post_type]->labels->singular_name ) . '</td><td class="no-break">'.esc_html( $time ) . '</td><td class="no-break">' . esc_html( $stat ). ' </td></tr>' . "\n\n";
}
$html .= '</tbody></table>';
$x = new WP_Ajax_Response();
$x->add( array(
'data' => $html
));
$x->send();
}
Javascript file open-posts.js
jQuery(document).ready(function($) {
// Find posts
var $findBox = $('#find-posts'),
$found = $('#find-posts-response'),
$findBoxSubmit = $('#find-posts-submit');
// Open
$('input.kc-find-post').live('dblclick', function() {
$findBox.data('kcTarget', $(this));
findPosts.open();
});
// Insert
$findBoxSubmit.click(function(e) {
e.preventDefault();
// Be nice!
if ( !$findBox.data('kcTarget') )
return;
var $selected = $found.find('input:checked');
if ( !$selected.length )
return false;
var $target = $findBox.data('kcTarget'),
current = $target.val(),
current = current === '' ? [] : current.split(','),
newID = $selected.val();
if ( $.inArray(newID, current) < 0 ) {
current.push(newID);
$target.val( current.join(',') );
}
});
// Double click on the radios
$('input[name="found_post_id"]', $findBox).live('dblclick', function() {
$findBoxSubmit.trigger('click');
});
// Close
$( '#find-posts-close' ).click(function() {
$findBox.removeData('kcTarget');
});
});

Adding attribute to option element using forms api : drupal 7

I want to add title="icons/icon_cart.gif" for each of the below options in my select list which is rendered using views.
After trying and reading many articles I can't seem to find the way to add this html into my form.
Below is my code.
function customchatter_form_alter(&$form, &$form_state, $form_id) {
$form["tid"]["#options"][1]=t("nooo chatter");
// this works to change the label of the option but how do I add title="icons/icon-
cart.gif" ?
}
My html code:
<select id="edit-tid" name="tid" class="form-select">
<option value="All">- Any -</option>
<option value="1">nooo chatter</option>
<option value="2">Complaints Complaints</option>
<option value="3">Gear & Gadgets</option>
</select>
Cheers,
Vishal
UPDATE
I tried to update the code as per Clive's advice but the values are still not coming up right. Below is my story.
So below is the html output I am able to achieve but the title always seems to be the number 1.
<select id="edit-select" class="form-select" name="select">
<option value="1" title="1">One</option>
<option value="2" title="1">Two</option>
</select>
As you can see title is there but the value is wrong. Below is my form and the functions which I wrote.
My form:
$form['select'] = array(
'#type' => 'select',
'#options' => array(1 => 'One', 2 => 'Two'),
'#title' => array(1 => 'One', 2 => 'Two')
// I tried many combinations but nothing seems to work.
);
My Theme functions.
function kt_vusers_select($variables) {
$element = $variables['element'];
element_set_attributes($element, array('id', 'name', 'size'));
_form_set_class($element, array('form-select'));
return '<select' . drupal_attributes($element['#attributes']) . '>' .
kt_vusers_form_select_options($element) . '</select>';
}
function kt_vusers_form_select_options($element, $choices = NULL) {
if (!isset($choices)) {
$choices = $element['#options'];
}
// array_key_exists() accommodates the rare event where $element['#value'] is NULL.
// isset() fails in this situation.
$value_valid = isset($element['#value']) || array_key_exists('#value', $element);
// #vishal so there I have declared the variable to accept the values.
$vtitle = isset($element['#title']) || array_key_exists('#title', $element);
$value_is_array = $value_valid && is_array($element['#value']);
$options = '';
foreach ($choices as $key => $choice) {
if (is_array($choice)) {
$options .= '<optgroup label="' . $key . '">';
$options .= form_select_options($element, $choice);
$options .= '</optgroup>';
}
elseif (is_object($choice)) {
$options .= form_select_options($element, $choice->option);
}
else {
$key = (string) $key;
if ($value_valid && (!$value_is_array && (string) $element['#value'] === $key ||
($value_is_array && in_array($key, $element['#value'])))) {
$selected = ' selected="selected"';
}
else {
$selected = '';
}
// #vishal this is where the variable is being used.
$options .= '<option title="'.$vtitle.'" value="' . check_plain($key) . '"' . $selected .
'>' . check_plain($choice) . '</option>';
}
}
return $options;
}
below is the correct code for the last theme function
function kt_vusers_form_select_options($element, $choices = NULL, $vtitles=NULL) {
// Build up your own version of form_select_options here
// that takes into account your extra attribute needs.
// This will probably involve inspecting your custom FAPI property,
// which we'll call #extra_option_attributes
if (!isset($choices)) {
$choices = $element['#options'];
$vtitles = array();
$vtitles = $element['#title'];
}
// array_key_exists() accommodates the rare event where $element['#value'] is NULL.
// isset() fails in this situation.
$value_valid = isset($element['#value']) || array_key_exists('#value', $element);
$value_is_array = $value_valid && is_array($element['#value']);
$options = '';
// print_r($vtitles);
while
(
(list($key, $choice) = each($choices))
&& (list($keytwo, $vtitle) = each($vtitles))
)
{
// printf("%s => %s, %s => %s \n", $key1, $value1, $key2, $value2);
if (is_array($choice)) {
$options .= '<optgroup label="' . $key . '">';
$options .= kt_vusers_form_select_options($element, $choice);
$i++;
// $options .= form_select_options($element, $vtitle);
$options .= '</optgroup>';
} // end if if is_array
elseif(is_object($choice)) {
$options .= form_select_options($element, $choice->option);
} // end of else if
else {
$key = (string) $key;
if ($value_valid && (!$value_is_array && (string) $element['#value'] === $key ||
($value_is_array && in_array($key, $element['#value'])))) {
$selected = ' selected="selected"';
}
else {
$selected = '';
}
// $options .= '<option title="'.$vtitle.'" value="' . check_plain($key) . '"' .
$selected . '>' . check_plain($choice) . '</option>';
}
$options .= '<option value="'. check_plain($key) .'" title="' . $vtitle . '"' . $selected
.'>'. check_plain($choice) .'</option>';
} // end of choice
return $options;
} // end of function
I'm afraid you're going to have to dig quite far down to do this, the #options array is flattened in form_select_options() and it doesn't currently include any way of adding attributes. This is the code:
$options .= '<option value="' . check_plain($key) . '"' . $selected . '>' . check_plain($choice) . '</option>';
As you can see there's simply no scope for attributes in there. You will be able to override this though, but it will involve implementing your own version of theme_select() and your own FAPI property.
I haven't got time to flesh the entire thing out but in your theme file you would be doing something like this:
function MYTHEME_select($variables) {
$element = $variables['element'];
element_set_attributes($element, array('id', 'name', 'size'));
_form_set_class($element, array('form-select'));
return '<select' . drupal_attributes($element['#attributes']) . '>' . MYTHEME_form_select_options($element) . '</select>';
}
function MYTHEME_form_select_options($element) {
// Build up your own version of form_select_options here
// that takes into account your extra attribute needs.
// This will probably involve inspecting your custom FAPI property,
// which we'll call #extra_option_attributes
}
Refer to form_select_options for constructing MYTHEME_form_select_options
And your code in the form would be something like:
$form['select'] = array(
'#type' => 'select',
'#options' => array(1 => 'One', 2 => 'Two'),
'#extra_option_attributes' => array(
1 => array('title' => 'Test title'), // Attributes for option with key "1",
2 => array('title' => 'Test title'), // Attributes for option with key "2",
)
);
In MYTHEME_form_select_options() you can then inspect the element's #extra_option_attributes key (if one exists) to see if you need to physically add any more attributes in the HTML you create.
Hope that helps, I know it seems like a crazily long-winded way of doing what you need to but as far as I know it's the only way.
Tested
Try:
$form["tid"][1]['#attributes'] = array('title' => t('nooo chatter'));
instead of:
$form["tid"]['#options'][1]['#attributes'] = array('title' => t('nooo chatter'));
It is possible to add arbitrary attributes to elements this way. I discovered this after performing some tests based on this answer.
Also mentioned here and here.
Untested, but have you tried:
$form["tid"]["#options"][1]['#attributes'] = array('title' => t('YOUR NEW TITLE'));
You might need to mess around with the name of the element etc but the #attributes tag should work.
EDIT: As pointed out in Clive's answer, this won't work but I'll leave it up in case anyone wants to know how to add attributes to other fields (textboxes etc).

Resources