I developed a small one-file plugin for a wordpress site. It's just adds an upload form for a file that POSTs to itself and then does some stuff with the file's contents once submitted.
It works fine on the staging environment, but on the live server there is a strange problem. Once I submit the form with the file the server does not bring me back to the same page but instead returns the following JSON:
{"success":false,"message":"Please enter a message."}
I am at loss what could be causing this. Has anybody come across such a problem?
The (simplified plugin):
function show_upload_form() {
if ($_FILES['userfile']) {
echo "<p>file received</p>";
$file = fopen($_FILES['userfile']['tmp_name'], "r");
$data = [];
while (!feof($file)) {
$data[] = fgetcsv($file,null,';');
}
foreach ($data as $line) {
$pid = $line[0];
if (isset($line[1])) {
$price = trim(str_replace(',', '.', $line[1]));
} else {
$price = "";
}
if (isset($line[2])) {
$title = trim(iconv("ISO-8859-1", "UTF-8", $line[2]));
} else {
$title = "";
}
global $wpdb;
$product_ids = $wpdb->get_results($wpdb->prepare( "SELECT post_id FROM $wpdb->postmeta WHERE meta_key='_sku' AND meta_value='%s'", $pid));
foreach ($product_ids as $product_id) {
$elem = $product_id->post_id;
if ($price != "") {
update_post_meta($elem, '_price', $price);
update_post_meta($elem, '_sale_price', $price);
update_post_meta($elem, '_regular_price', $price);
}
if ($title != "") {
wp_update_post(array(
'ID' => $elem,
'post_title' => $title,
));
}
}
echo "<p>Produkt #".$pid;
if ($price != "") {
echo " - new price: ".$price."€";
}
if ($title != "") {
echo "- new title: ".$title;
}
}
} else {
echo "<form method=\"post\" enctype=\"multipart/form-data\">";
echo "<label for=\"file\">Select a file:</label>";
echo "<input type=\"file\" name=\"userfile\" id=\"file\">";
echo "<br /><br />";
echo "<button>Upload File</button>";
echo "<form>";
}
}
I appreciate any input.
Try something like this
<form action="<?=admin_url( 'admin-post.php' ) ?>" method="POST">
<input type="hidden" name="action" value="my_custom_plugin_action"/>
<input type="submit" value="SEND"/>
</form>
add_action( 'admin_post_nopriv_my_custom_plugin_action',array( "class_that_owns_that_function", 'show_upload_form' ) );
public function show_upload_form()
{
//Here write your code
}
Problem disappeared after deactivating and individually reactivating all the plugins for the second or third time. Guess this one will remain a mystery ...
Related
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
}
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.
I have created one plugin import.php
<?php
function fileupload_process() {
ini_set('memory_limit', '64M');
set_time_limit(0);
$uploadfiles = $_FILES['uploadfiles'];
//echo 'ddd';
// exit;
if (is_array($uploadfiles)) {
//echo 'ram';
//print_r($uploadfiles);
echo $uploadfiles['name'];
// foreach ($uploadfiles as $key => $value) {
foreach ($uploadfiles['name'] as $key => $value) {
// look only for uploaded files
if ($uploadfiles['error'][$key] == 0) {
$filetmp = $uploadfiles['tmp_name'][$key];
if (($handle = fopen($filetmp, "r")) !== FALSE) {
$flag = true;
$songs = explode("\n",file_get_contents($filetmp));
$count = count( $songs );
unset($songs);
echo "Total item count: " . $count . "<BR />";
// typical entry: If You Have To Ask,Red Hot Chili Peppers,0:03:37, Rock & Alternative,1991,on
// using a generous 1000 length - will lowering this actually impact performance in terms of memory allocation?
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
// Skip the first entry in the csv containing colmn info
if($flag) {
$flag = false;
echo "<BR />";
$count--;
continue;
}
// insert the current post and relevant info into the database
$currently_processed = process_custom_post($data);
$count--;
}
echo "Done!";
fclose($handle);
}
unlink($filetmp); // delete the temp csv file
}
}
}
} // END: file_upload_process()
function process_custom_post($song) {
global $wpdb;
// Prepare and insert the custom post
$track = (array_key_exists(0, $song) && $song[0] != "" ? $song[0] : 'N/A');
$custom_post = array();
$custom_post['post_type'] = 'songs';
$custom_post['post_status'] = 'publish';
$custom_post['post_title'] = $track;
$post_id = wp_insert_post( $custom_post );
// Prepare and insert the custom post meta
$meta_keys = array();
$meta_keys['artist_name'] = (array_key_exists(1, $song) && $song[1] != "" ? $song[1] : 'N/A');
$meta_keys['song_length'] = (array_key_exists(2, $song) && $song[2] != "" ? $song[2] : 'N/A');
$meta_keys['song_genre'] = (array_key_exists(3, $song) && $song[3] != "" ? $song[3] : 'N/A');
$meta_keys['song_year'] = (array_key_exists(4, $song) && $song[4] != "" ? $song[4] : 'N/A');
$meta_keys['song_month'] = (array_key_exists(5, $song) && $song[5] != "" ? $song[5] : 'N/A');
$meta_keys['sample_playlist'] = (array_key_exists(6, $song) && $song[6] != "" ? $song[6] : '');
$custom_fields = array();
$place_holders = array();
$query_string = "INSERT INTO $wpdb->postmeta ( post_id, meta_key, meta_value) VALUES ";
foreach($meta_keys as $key => $value) {
array_push($custom_fields, $post_id, $key, $value);
$place_holders[] = "('%d', '%s', '%s')";
}
$query_string .= implode(', ', $place_holders);
$wpdb->query( $wpdb->prepare("$query_string ", $custom_fields));
return true;
}// END: process_custom_post()
function import_page () {
//HTML for the import page + the file upload form
if (isset($_POST['uploadfile'])) {
fileupload_process();
}
}
In main.php I do customize the code:
<?php
/*
Plugin Name: csv ram
Plugin URI: http://www.newdreamdatasystems.com
Description: csv ram
Version: 2.0
Author: RAM KUMAR
Author URI: http://www.newdreamdatasystems.com
*/
define('SAVEQUERIES', true);
define( 'MY_PLUGIN_ROOT' , dirname(__FILE__) );
include_once( MY_PLUGIN_ROOT . '/import.php');
$ram = import_page();
add_action('admin_menu', 'register_my_custom_submenu_page');
function register_my_custom_submenu_page() {
add_submenu_page( 'tools.php', 'My Custom Submenu Page', 'My Custom Submenu Page', 'manage_options', 'my-custom-submenu-page', 'my_custom_submenu_page_callback' );
}
function my_custom_submenu_page_callback() {
$html= <<<RAM
<form action="{$ram}" method="post" enctype="multipart/form-data" name="form1" id="form1" onSubmit="">
<label>upload file<input type="file" name="uploadfiles" id="uploadfiles" /></label>
<label><input type="submit" name="uploadfile" id="uploadfile" value="Submit" /></label>
</form>
RAM;
echo $html;
}
But I have one error:
Warning: Invalid argument supplied for foreach() in C:\xampp\htdocs\wordpress\wp-content\plugins\try\import.php on line 13..?
How to fix this?
Three main problems:
The function import_page() should be run inside the callback:
function my_custom_submenu_page_callback() {
import_page();
/* etc */
}
Action <form action=""> should be empty, so it goes back to the same plugin page, /wp-admin/tools.php?page=my-custom-submenu-page.
The file field should allow for multiple uploads so this will work foreach ($uploadfiles as $key => $value) and remove the error you're seeing.
<input type="file" name="uploadfiles[]" id="uploadfiles" multiple />
Thinking better, you may not need the multiple attribute, but then adjust the rest of the logic.
But after this adjustments, there are still a bunch of notices and warnings, like Array to string conversion, Undefined index: name and fopen(): Filename cannot be empty.
All this is easily fixed with careful debugging, this is how I found the 3 problems above:
Add printf( '<pre>%s</pre>', print_r( $INSPECT_VAR, true ) ); to go inspecting the problematic variables.
I'm going to break my brain..
I've created a new metabox for my custom post type "book".
I'm using a lot of different type of fields like input text, checkbox, select, textarea, taxonomy select and repeatable and everything work great!
But now I'd like to do a more difficult step..
Is it possible to do a repeatable field with 2 fields inside it?
I would like have a select and an input text near it.. inside the select admin can choose the shop (es. Ibs or Amazon) and in the input field he can write the url for sell the book.
This is my code:
/* META Book */
function add_mycustom_meta_box() {
add_meta_box(
'custom_meta_box',
'Info book',
'show_custom_meta_box', // $callback
'product',
'normal',
'high');
}
// Field Array
$prefix = 'custom_';
$custom_meta_fields = array(
array(
'label' => 'Link vendita',
'desc' => 'Inserisci l url dei siti esterni',
'id' => $prefix.'repeatable',
'type' => 'repeatable',
'options' => array(
'amazon' => array(
'label' => 'Amazon',
'value' => 'amazon'
),
'ibs' => array(
'label' => 'Ibs',
'value' => 'ibs'
)
)
)
);
// Callback
function show_custom_meta_box() {
global $custom_meta_fields, $post;
// Use nonce for verification
echo '<input type="hidden" name="custom_meta_box_nonce" value="'.wp_create_nonce(basename(__FILE__)).'" />';
// Build metabox
echo '<table class="form-table">';
foreach ($custom_meta_fields as $field) {
// get value of this field if it exists for this post
$meta = get_post_meta($post->ID, $field['id'], true);
// begin a table row with
echo '<tr>
<th><label for="'.$field['id'].'">'.$field['label'].'</label></th>
<td>';
switch($field['type']) {
// if repeatable
case 'repeatable':
echo '<a class="repeatable-add button" href="#">+</a>
<ul id="'.$field['id'].'-repeatable" class="custom_repeatable">';
$i = 0;
if ($meta) {
foreach($meta as $row) {
echo '<li><span class="sort hndle">|||</span>';
// Select ibis or amazon
echo '<select name="'.$field['id'].'" id="'.$field['id'].'">';
foreach ($field['options'] as $option) {
echo '<option', $row == $option['value'] ? ' selected="selected"' : '', ' value="'.$option['value'].'">'.$option['label'].'</option>';
}
echo '</select>';
// end select
echo '<input type="text" name="'.$field['id'].'['.$i.']" id="'.$field['id'].'" value="'.$row.'" size="30" data-shop="'.$option.'" />
<a class="repeatable-remove button" href="#">-</a></li>';
$i++;
}
} else {
echo '<li><span class="sort hndle">|||</span>';
// Select ibis o amazon
echo '<select name="'.$field['id'].'" id="'.$field['id'].'">';
foreach ($field['options'] as $option) {
echo '<option', $row == $option['value'] ? ' selected="selected"' : '', ' value="'.$option['value'].'">'.$option['label'].'</option>';
}
echo '</select>';
// Fine select
echo '<input type="text" name="'.$field['id'].'['.$i.']" id="'.$field['id'].'" value="" size="30" />
<a class="repeatable-remove button" href="#">-</a></li>';
}
echo '</ul>
<span class="description">'.$field['desc'].'</span>';
break;
} //end switch
echo '</td></tr>';
} // end foreach
echo '</table>';
}
// Save the Data
function save_custom_meta($post_id) {
global $custom_meta_fields;
// verify nonce
if (!wp_verify_nonce($_POST['custom_meta_box_nonce'], basename(__FILE__)))
return $post_id;
// check autosave
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE)
return $post_id;
// check permissions
if ('page' == $_POST['post_type']) {
if (!current_user_can('edit_page', $post_id))
return $post_id;
} elseif (!current_user_can('edit_post', $post_id)) {
return $post_id;
}
// loop through fields and save the data
foreach ($custom_meta_fields as $field) {
$old = get_post_meta($post_id, $field['id'], true);
$new = $_POST[$field['id']];
if ($new && $new != $old) {
update_post_meta($post_id, $field['id'], $new);
} elseif ('' == $new && $old) {
delete_post_meta($post_id, $field['id'], $old);
}
} // end foreach
}
add_action('save_post', 'save_custom_meta');
The repeatable field generate an array and it is ok, but what I can do to store the select value also?
Hope someone can help me
Thanks
I'm sure you can put in dynamic fields into custom Metaboxes inside the edit screen of any post type.
I build this for the Language Field Plugin into the admin page on http://wordpress.org/plugins/language-field/
I was relying on this example
http://www.mustbebuilt.co.uk/2012/07/27/adding-form-fields-dynamically-with-jquery/
Generally take these steps
Add custom Meta box with this example
http://codex.wordpress.org/Function_Reference/add_meta_box#Examples
when it comes to these lines
$mydata = sanitize_text_field( $_POST['myplugin_new_field'] );
// Update the meta field in the database.
update_post_meta( $post_id, '_my_meta_value_key', $mydata );
loop thru the fields created with example above.
I am using a script found at http://wpdevsnippets.com/add-category-tag-taxonomy-picture/. However, I cannot get the writer to answer a usage question, so here it is:
How do I use this script with a custom taxonomy on a page.php or archive.php template?
add_action('admin_head', 'wpds_admin_head');
add_action('edit_term', 'wpds_save_tax_pic');
add_action('create_term', 'wpds_save_tax_pic');
function wpds_admin_head() {
$taxonomies = get_taxonomies();
//$taxonomies = array('category'); // uncomment and specify particular taxonomies you want to add image feature.
if (is_array($taxonomies)) {
foreach ($taxonomies as $z_taxonomy) {
add_action($z_taxonomy . '_add_form_fields', 'wpds_tax_field');
add_action($z_taxonomy . '_edit_form_fields', 'wpds_tax_field');
}
}
}
// add image field in add form
function wpds_tax_field($taxonomy) {
wp_enqueue_style('thickbox');
wp_enqueue_script('thickbox');
if(empty($taxonomy)) {
echo '<div class="form-field">
<label for="wpds_tax_pic">Picture</label>
<input type="text" name="wpds_tax_pic" id="wpds_tax_pic" value="" />
</div>';
}
else{
$wpds_tax_pic_url = get_option('wpds_tax_pic' . $taxonomy->term_id);
echo '<tr class="form-field">
<th scope="row" valign="top"><label for="wpds_tax_pic">Picture</label></th>
<td><input type="text" name="wpds_tax_pic" id="wpds_tax_pic" value="' . $wpds_tax_pic_url . '" /><br />';
if(!empty($wpds_tax_pic_url))
echo '<img src="'.$wpds_tax_pic_url.'" style="max-width:200px;border: 1px solid #ccc;padding: 5px;box-shadow: 5px 5px 10px #ccc;margin-top: 10px;" >';
echo '</td></tr>';
}
echo '<script type="text/javascript">
jQuery(document).ready(function() {
jQuery("#wpds_tax_pic").click(function() {
tb_show("", "media-upload.php?type=image&TB_iframe=true");
return false;
});
window.send_to_editor = function(html) {
jQuery("#wpds_tax_pic").val( jQuery("img",html).attr("src") );
tb_remove();
}
});
</script>';
}
// save our taxonomy image while edit or save term
function wpds_save_tax_pic($term_id) {
if (isset($_POST['wpds_tax_pic']))
update_option('wpds_tax_pic' . $term_id, $_POST['wpds_tax_pic']);
}
// output taxonomy image url for the given term_id (NULL by default)
function wpds_tax_pic_url($term_id = NULL) {
if ($term_id)
return get_option('wpds_tax_pic' . $term_id);
elseif (is_category())
return get_option('wpds_tax_pic' . get_query_var('cat')) ;
elseif (is_tax()) {
$current_term = get_term_by('slug', get_query_var('term'), get_query_var('taxonomy'));
return get_option('wpds_tax_pic' . $current_term->term_id);
}
}
And here is the function that is used to call this:
wpds_tax_pic_url();
or
wpds_tax_pic_url($category->cat_ID);
How do I use this script with a custom taxonomy on a page.php or archive.php template?
On archive.php, you can use the wpds_tax_pic_url(); without any parameters it should display the URL of the attached image.
if(wpds_tax_pic_url()){
echo '<img src="'.wpds_tax_pic_url().'" />';
}else{
// other image or nothing.
}
On page.php or post.php, something following would work
$terms = wp_get_post_terms($post_id, 'custom_taxonomy');
foreach ($terms as $t) {
if(wpds_tax_pic_url($t->term_id))
echo '<img src="'.wpds_tax_pic_url($t->term_id).'" />';
}