I have a page where i'm using a button to generate a csv file from data being looped from an array, which when clicked is then automatically emailed to a user.

I also want the data to create a new wordpress post by using the wp_insert_post() function.

So far i've added this but i'm not sure where it should go in the code:

    wp_insert_post(array (
       'post_type' => 'saved-orders',
       'post_title' => 'Test',
       'post_content' => $allTheCarts(),
       'post_status' => 'publish',
       'comment_status' => 'closed',   // if you prefer
       'ping_status' => 'closed',      // if you prefer

Can anyone help me please?

function cart_items_array() { 

$carts2 = MultiCart\get_carts();

// All the products
$allTheCarts = array();

foreach ( $carts2 as $cart_id => $cart2 ) {

     // get array of items contained in a cart ...
    $items2 = MultiCart\get_cart( $cart_id );

    foreach ( $items2 as $item2_id => $item2 ) {
            $compProduct = array();

            $product_name = get_post($item2['product_id'])->post_title; 
            $familyterms = wp_get_post_terms( $item2['product_id'], 'pa_product-family'); 
            $cat_terms = wp_get_post_terms( $item2['product_id'], 'pa_product-category'); 
            $product_sku = get_post_meta( $item2['product_id'], '_sku', true );

            $compProduct[] = $product_sku; 

            foreach ($cat_terms as $cat_term) { $compProduct[] = $cat_term->name; };
            foreach ($familyterms as $family) { $compProduct[] = $family->name; }; 
            $compProduct[] = $product_name;
            $compProduct[] = $item2['quantity'];
            $compProduct[] = $cart2['name'];

            // Store the complete product info
            $allTheCarts[] = $compProduct;

return $allTheCarts;


// Create csv
function create_csv_string($data) {

  // Open temp file pointer
  if (!$fp = fopen('php://temp', 'w+')) return FALSE;

  // Loop data and write to file pointer
  foreach ($data as $line) fputcsv($fp, $line);

  $cartsdata = cart_items_array();

  foreach ($cartsdata as $cartrow) fputcsv($fp, $cartrow);

  // Place stream pointer at beginning

  // Return the data
  return stream_get_contents($fp);


 if ( isset( $_POST['submit'] ) ) {

function send_csv_mail ($csvData, $body, $to = 'email@email.co.uk', $subject = 'Test email with attachment', $from = 'webmaster@example.com') {

global $post;
$user_id = get_current_user_id();

  // This will provide plenty adequate entropy
  $multipartSep = '-----'.md5(time()).'-----';

  // Arrays are much more readable
  $headers = array(
    "From: $from",
    "Reply-To: $from",
    "Content-Type: multipart/mixed; boundary=\"$multipartSep\""

  // Make the attachment
  $attachment = chunk_split(base64_encode(create_csv_string($csvData))); 

  // Make the body of the message
  $body = "--$multipartSep\r\n"
        . "Content-Type: text/plain; charset=ISO-8859-1; format=flowed\r\n"
        . "Content-Transfer-Encoding: 7bit\r\n"
        . "\r\n"
        . "$body\r\n"
        . "--$multipartSep\r\n"
        . "Content-Type: text/csv\r\n"
        . "Content-Transfer-Encoding: base64\r\n"
        . "Content-Disposition: attachment; filename=\"".date('Y-m-d')."-".str_replace(' ', '-', strtolower(get_user_meta($user_id, "wpcf-branch-active", true)))."-file.csv\"\r\n"
        . "\r\n"
        . "$attachment\r\n"
        . "--$multipartSep--";

   // Send the email, return the result
   return @mail($to, $subject, $body, implode("\r\n", $headers)); 


$array = array(
                array("Code", "Product Category", "Product Family", "Description", "Quantity", "Bay"),          

send_csv_mail($array, "Hello World!!!\r\n This is simple text email message.");
if(!send_csv_mail) {
         echo "Error"; 
else {
    echo "<meta http-equiv=\"refresh\" content=\"0; url=./thank-you\" />";



There's a few options for where to put your wp_insert_post call; it all boils down to order of desired operations within the functionality as you've presented it.

  • If you want to create the post as soon as the array has been compiled/populated, and as some renderable markup:

    1. create a string variable and loop through the array to generate whatever html markup you want to represent the rows of data (table, list, etc)
    2. update your wp_insert_post function to set the post_content value to your string variable created above.
    3. insert the wp_insert_post function just before your return statement in the cart_items_array() function.
  • If you want to create the post as soon as the array has been compiled/populated into the comma separated text and want that csv text as the post content, you'll want to:

    1. update your wp_insert_post function to set the post_content value to stream_get_contents($fp);
    2. insert the wp_insert_post function just between your rewind() and return calls in the create_csv_string function
    3. after the wp_insert_post function you just inserted, and before the return call, add a call to rewind the file's stream pointer again.
  • If you don't want to insert the post until after the email has been sent:

    1. you'll probably want to change/break up your functionality so that it doesn't pipe from one function directly into another, as well as define variables representing each state of processing for the data. for example you might have the following variables outside of any functions, and after the function declarations:

      $rawCartDataArray = cart_items_array();

      $htmlRenderableCartData = your_new_format_array_data_into_markup_function($rawCartDataArray);

      $csvCartData = create_csv_with_header_row_function($csvDataHeaders, $rawCartDataArray);

    2. After breaking out the data like this, update $attachment variable definition to:

      $attachment = chunk_split(base64_encode($csvCartData));

    3. update your wp_insert_post function to set the post_content value to either the $htmlRenderableCartData or $csvCartData;

    4. Add a wp_insert_post() call either near the end of your send_csv_mail function, or outside in the main php after your call to send_csv_mail.

Another recommendation would be to move/rework your if/else at the end of the code as a try/catch in the send_csv_mail function itself.

  • Hi Anson, thanks for your help. I've split up the process like you said and have created the variables to store the information. One thing im not sure about is the function create_csv_with_header_row_function(). What should this be? – Shaun Oct 22 '17 at 10:56
  • That's just a renamed version of your create csv function since it takes the array of column headers you define in the send email function and the actual cart data. – Anson W Han Oct 22 '17 at 14:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.