performance – Generating two Woocommerce-based CSV files based on a URL request

I wrote this code about a year ago. I am looking to refactor it so that it is solid and secure because it is generated from a custom terminal. The script consists of reading the parameters of a query and generating custom CSV exports based on the categories, tags, and the date of completion of the command. These reports can be weekly, monthly, yearly or for all times. An email or a comma-separated list of emails can be passed as recipients.

The initial flow I had was like this:

  • Enable errors
  • Check if the query string set is correct
  • If no, go out, if not continue
  • Load WordPress / Woocommerce
  • Disinfect GET variables and define tweens, such as date ranges and string values.
  • Create a collectible table and browse all orders, except those that do not match the search parameters
  • Sort by category
  • If no order, leave
  • Otherwise, write in CSV format, send the file by e-mail and unassign the files

Some questions
– Do I have to convert this to OOP?
– Which design models can I use to make the logic more intuitive?

P. C is the cron URL

(wget -O- "https://site.com/wp-content/themes/theme/scripts/auto-export.php?export=GET&filter_units=all&period=month&filter_categories=product&filter_skus=all&email_list=email_list=dan@email.com" – no-check-certificate >> log.txt)

// Set INI values ​​for tests
ini_set (& # 39; display_errors & # 39 ;, 1);
ini_set (& # 39; display_startup_errors & # 39 ;, 1);
error_reporting (E_ALL);

// Exit if the export type is not defined (correctly)
if (! isset ($ _GET[ 'export' ]) || $ _GET['export'] ! == & 39; GET & # 39;)
exit;

// load WordPress
define (& # 39; WP_USE_THEMES & # 39 ;, false);
require ($ _ SERVER['DOCUMENT_ROOT'] . "/Wp-load.php");

// Sanititze GET data
$ search_data = sanitize_get ();

// Get sorted orders
$ orders = get_product_purchases ($ search_data);
$ orders = sort_orders_by (& # 39; category & # 39; DESC & # 39 ;, orders);


// output if no command
if (count ($ orders) == 0) {
echo "There were no orders given the settings";
exit;
}

write_to_csv_get ([
    'search_data' => $search_data,
    'orders'      => $orders,
])
echo "Export Successful";
exit;


/ **
* get_product_purchases
* Back order table
* /
function get_product_purchases ($ search_data) {
// destroy the search data
$ cat_data = $ search_data['categories'];
$ sku_data = $ search_data['skus'];
$ period = $ search_data['period'];
$ unit_data = $ search_data['units'];

// See the doc-block set_order_args () for more details
$ args = set_order_args ($ search_data);
$ WC_Orders = wc_get_orders ($ args);
$ results = [];

foreach ($ WC_Orders as $ WC_Order) {
if (empty ($ WC_Order)) continues;

$ order_data = $ WC_Order-> get_data ();

$ my_order[ 'order_id' ]          = $ WC_Order-> get_id ();
$ my_order['order_date']          = $ order_data['date_created']-> date (& # 39; Y-m-d & quot;);
$ my_order['shipping_first_name'] = $ order_data['shipping']['first_name'];
$ my_order['shipping_last_name']  = $ order_data['shipping']['last_name'];
$ my_order['shipping_address_1']  = $ order_data['shipping']['address_1'];
$ my_order['shipping_address_2']  = $ order_data['shipping']['address_2'];
$ my_order['shipping_city']       = $ order_data['shipping']['city'];
$ my_order['shipping_state']      = $ order_data['shipping']['state'];
$ my_order['shipping_postcode']   = $ order_data['shipping']['postcode'];

foreach ($ WC_Order-> get_items () as $ item_key => $ item_values) {
$ my_order_copy = $ my_order;

## Using methods WC_Order_Item ##
$ my_item['id'] = $ item_values-> get_id (); // the element ID is directly accessible from the $ item_key key of the foreach loop or

## Command access data properties (in an array of values) ##
$ item_data = $ item_values-> get_data ();

$ product_id = $ item_data['product_id'];
$ product['product_name']      = $ item_data['name'];
$ product['quantity']          = $ item_data['quantity'];

// Get the data from the WC_product object using methods (examples)
$ WC_Product = $ item_values-> get_product (); // the WC_Product object
if (empty ($ WC_Product)) {
Carry on;
};

$ item['item_name'] = preg_replace (& # 39; /[x00-x1Fx7F-xFF]/ & # 39;, & # 39; & # 39 ;, $ item_values-> get_name ()); // Product Name
$ product['sku']    = $ WC_Product-> get_sku ();
$ product['price']  = ($ WC_Product-> get_price ())
? sprintf (% .2f, $ WC_Product-> get_price ())
: & # 39;

// Tags = business units
$ product['tag']     = strtolower (get_tag_name ($ product_id));

// The term names are categories
$ terms = get_the_terms ($ product_id, & # 39; product_cat & # 39;);
$ cats [];

foreach ($ terms like $ term) {
array_push ($ cats, strtolower ($ term-> name));
}

$ product['category']    = $ cats[0];

/ *
Conduct a conditional check to push or not export

If a list of filters is set, check the property of the product against
the filter list and see if it matches. If it does not,
exclude it from CSV
* /
$ push = check_against_list ($ cat_data, $ product, & # 39; category);
if ($ push == 0) continues;

$ push = check_against_list ($ unit_data, $ product, & tag; tag & # 39;)
if ($ push == 0) continues;

$ push = check_against_list ($ sku_data, $ product, & sku & # 39; sku & # 39;)
if ($ push == 0) continues;

if ($ push == 1) {
$ row = array_merge ($ my_order_copy, $ product);
array_push ($ results, $ row);
}
}
}

returns $ results
}

/ **
* @param array $ params [search_data & orders]
 * @return [void]
 * /
write_to_csv_get function ($ params) {
// destruction settings
$ period = $ params['search_data']['period'];
$ orders = $ params['orders'];

$ date_summary = ($ period['all'] == 0)
? "from {$ period['range']['start_date']} at {$ period['range']['end_date']} "
: "From the beginning";

$ breakdown_file = "company - {$ period['type']} -order-details.csv ";
$ path = "/ tmp";
$ fp = fopen ("$ path / $ driver_file_name", & w;

if (fopen ("$ path / $ driver_file_name", "w +")) {
$ totals = []; // Sum of quantities
$ placed_header = false;

foreach ($ commands as $ index => $ row) {
$ totals = sum ($ row, $ total);

// Old code to write all order details
if (! $ placed_header)
{
fputcsv ($ fp, array_keys ($ row));
$ placed_header = true;
}

// If row, write it in CSV
if (count ($ row)! = 0)
fputcsv ($ fp, $ row);
}
} other {
fclose ($ fp);
unlink ("$ path / $ poverty_file_name");
error_log ("Automatic Report: CSV Breakdown - Failure to open the CSV file");
}

notify ($ driver_file_name, $ path, 'export download command details', 'detailed', $ parameters);

fclose ($ fp);
unlink ("$ path / $ filename");

$ totals_filename = "company - {$ period['type']} -orders-totals.csv ";
$ fp = fopen ("$ path / $ totals_filename", & w;

if (fopen ("$ path / $ totals_filename", "w +")) {
// Send the email totals
fputcsv ($ fp, [ "Orders - {$date_summary}"] )
fputcsv ($ fp, [ 'SKU', 'Name', 'Totals' ] )

// Displays the total of two columns (name | total)
foreach ($ totals as $ name => $ details) {
$ num = $ details[0];
$ sku = $ details[1];
/ *
Excel does not like some ASCII characters, use 7-bit ASCII code
https://stackoverflow.com/questions/1176904/php-how-to-remove-all-non-printable-characters-in-a-string
* /
fputcsv ($ fp, [ $sku, $name, $num ])
}

} other {
fclose ($ fp);
unlink ("$ path / $ totals_filename");
error_log ("Auto-report: Totals CSV - Can not open CSV file");
}

// Send CSV down
notify ($ totals_filename, $ path, 'Export total downloads',' totals for & # 39 ;, $ params);

fclose ($ fp);
unlink ("$ path / $ totals_filename");

return;
}

function sort_orders_by_date ($ results, $ order = & # 39;)
foreach ($ results as $ key => $ part) {
$ sort[$key] = strtotime ($ share['order_date'])
}

($ order == & # 39; DESC & # 39;)
? array_multisort ($ sort, SORT_DESC, $ results)
: array_multisort ($ sort, SORT_ASC, $ results);

returns $ results
}

function sort_orders_by (field $, $ order = & # 39; DESC & # 39 ;, results) {
if (count ($ results)> 0)
{
foreach ($ results as $ key => $ part) {
$ sort[$key] = $ part[ $field ];
}

($ order == & # 39; DESC & # 39;)
? array_multisort ($ sort, SORT_DESC, $ results)
: array_multisort ($ sort, SORT_ASC, $ results);
}

returns $ results
}

function sanitize_get () {
/ * ------------------------------------------------ -
Filter / sanitize dates
--------------------------------------------- * /
if (isset ($ _GET['period']))
{
$ period['all'] = 0;

switch ($ _GET['period'])
{
case ('week'):
$ period['type'] = & # 39; weekly & # 39 ;;
$ previous_week = strtotime ("- 1 week +1 day");

$ start_week = strtotime ("last Sunday", $ previous_week);
$ end_week = strtotime ("next Saturday", $ start_week);

$ period['range']['start_date']    = filter_var (date ("Y-m-d", $ start_week), FILTER_SANITIZE_STRING);
$ period['range']['end_date']            = filter_var (date ("Y-m-d", $ end_week), FILTER_SANITIZE_STRING);
Pause;
case ('month'):
$ period['type'] = & # 39; monthly & # 39 ;;

$ period['range']['start_date']    = date ('Y-m-d', strtotime ('first day of last month'));
$ period['range']['end_date']            = date ('Y-m-d', strtotime ('last day of last month'));
Pause;
case (& # 39; year & # 39;):
$ year = date (Y-1) - 1;

$ period['type'] = & # 39; annual & # 39 ;;
$ period['range']['start_date']    = "{$ year} -01-01";
$ period['range']['end_date']            = "{$ year} -12-31";
Pause;
case (& # 39; forever):
$ period['type'] = & # 39; full & # 39 ;;
$ period[ 'all' ] = 1;
Pause;
}
}
other
{
error_log ('Autoexport: no timeout has been allowed for automatic export');
exit;
}

/ * ------------------------------------------------ -
Filter / Disinfect Categories
--------------------------------------------- * /
if (isset ($ _GET['filter_categories']))
{
$ categories = [];
$ categories['all'] = 0;

if ($ _GET['filter_categories'] == & # 39; all & # 39;)
{
$ categories['all'] = 1;
}
other
{
$ categories['list'] = explode (& # 39 ;, & # 39 ;, $ _GET['filter_categories'])

foreach ($ categories['list'] like $ i => $ cat)
{
$ categories['list'][$i]    = str_replace (->, & # 39; -strtolower (filter_var ($ cat, FILTER_SANITIZE_STRING)));
}


if ($ categories['all'] === 0 && count ($ categories['list'] ) < 1 )
                 error_log( 'Empty value for categories was passed' );
         }
     }
     else
     {
         error_log( 'Autoexport: Empty value for categories was passed' );
         exit;
     }

     /*---------------------------------------------
             Filter / Sanitize Business Units
      ---------------------------------------------*/
     if ( isset( $_GET['filter_units']) )
     {
         if ( $_GET['filter_units'] == 'all' )
         {
             $units['all'] = 1;
         }
         else
         {
             $units = [];
             $units['list'] = explode( ',', $_GET['filter_units']);

             foreach( $units['list'] as $i => $ unit)
{
$ units['list'][$i]    = str_replace (& # 39; - & # 39; & # 39;; strtolower (filter_var ($ unit, FILTER_SANITIZE_STRING)));
}

if ($ units['all'] == 0 && count ($ units['list'] ) < 1 )
                 error_log( 'Empty value for business units was passed' );
         }
     }
     else
     {
         error_log( 'Autoexport: Empty value for business units was passed' );
         exit;
     }

     /*---------------------------------------------
             Filter / Sanitize Skus
      ---------------------------------------------*/
     if ( isset( $_GET['filter_skus']) )
     {
         $skus = [];

         if ( $_GET['filter_skus'] == 'all' )
         {
             $skus['all'] = 1;
         }
         else
         {
             $skus['list'] = explode( ',', $_GET['filter_skus'] );

             // Filter unit string and push it to the search list
             foreach( $skus['list'] as $i => $ sku)
{
$ skus['list'][$i]    = str_replace (& # 39; - & # 39; & # 39; & # 39;, filter_var ($ sku, FILTER_SANITIZE_STRING));
}

if ($ skus['all'] === 0 && count ($ skus['list'] ) < 1 )
                 error_log( 'Autoexport: Empty value for skus was passed' );
         }
     }
     else
     {
         error_log( 'Autoexport: Empty value for skus was passed' );
         exit;
     }

      /*---------------------------------------------
              Filter / Sanitize Emails
      --------------------------------------------- */
      // Optionally pass in string of double pipe separated emails to send to
      if ( isset( $_GET['email_list']))
      {
          $email_list = explode( ',', $_GET['email_list'] );

          foreach ( $email_list as $i => $ email)
{
$ email_list[ $i ] = filter_var ($ email, FILTER_SANITIZE_EMAIL);
}

$ email_list = implode (& # 39 ;, $ email_list);
}
other
{
error_log (& # 39; Autoexport: email given to automatic export & # 39;);
exit;
}

$ search_data = [
         'validated'  => 1,
         'period'     => $period,
         'categories' => $categories,
         'units'      => $units,
         'skus'       => $skus,
         'email_list' => $email_list,
     ];

if ($ search_data['validated'] ! = 1)
die (& # 39;) Sorry, the data you entered is invalid & # 39;);

return $ search_data;
}

/ *
More info on wc_order's arguments
https://github.com/woocommerce/woocommerce/wiki/wc_get_orders-and-WC_Order_Query
* /
function set_order_args ($ search_data) {
$ period = $ search_data['period'];

$ args = [
     // 'status' => [ 'completed' ],
& # 39; status & # 39; => & # 39; completed & # 39 ;,
& # 39; order_by & # 39; => & # 39; date,
& # 39; order & # 39; => & # 39; DESC & # 39;
];

if (isset ($ period['range'] )) {
if (isset ($ period['range']['start_date']) && isset ($ period['range']['end_date'])) {
$ args['date_before'] = $ period['range']['end_date'];
$ args['date_after']  = $ period['range']['start_date'];
// the old way of working worked
// WC date range format (2018-08-01 ... 2018-08-31)
// $ range = implode (& # 39 ;, $ period['range'] )
// $ args[ 'date_created'] = $ range;
}
}

returns $ args;
}

get_term_names () {function
$ tags = get_terms (array (& # 39; product_tag & # 39;), & quot; hide_empty = 1 & quot;);
$ tag_list = [];

if (! empty ($ tags) &&! is_wp_error ($ tags)) {
foreach ($ tags as $ tag) {
$ tag_list[] = $ tag-> name;
}
}

return $ tag_list;
}

/ *
Read more here:
https://stackoverflow.com/questions/21858431/woocommerce-get-a-list-for-all-sku-product
* /
function get_sku_list () {
$ skus = [];
$ args = array (& # 39; post_type = & # 39; product & # 39 ;, & # 39; posts_per_page & # 39; => -1);

query_posts ($ args);

if (have_posts ()):
while (have_posts ()): the_post ();
global $ post;
$ product = wc_get_product ($ post-> ID);
$ sku = $ product-> get_sku ();

if ($ sku! = & # 39;)
{
array_push ($ skus, $ sku);
}
waiting;
end if;

return $ skus;
}

function get_tag_name ($ product_id) {
$ tags = wp_get_post_terms ($ product_id, & # 39; product_tag & # 39;)

if (count ($ tags)> 0) {
foreach ($ tags as $ tag) {
return $ tag-> name;
}
} other {
return 'empty';
}
}

function check_against_list ($ data, $ product, $ property) {
$ push = (int) true;

if ($ data['all'] == 0) {
if (is_array ($ data['list'])) {
if (! in_array (htmlspecialchars_decode ($ product['tag']), $ data['list'] )) {
$ push = 0;
}
} other {
$ push = 0;
}
}

return $ push;
}

sum function ($ row, $ totals) {
(empty (total $[$row['product_name' ]]))
? $ total[$row['product_name' ]]=[(Int)1$row[(Int)1$row[(int)1$row[(int)1$row['sku']]: $ totals[$row['product_name' ]][0]++;

return totals $;
}

function check_in_range ($ start_date, end_date, $ date_order) {
// Convert to timestamp
$ start_ts = strtotime ($ start_date);
$ end_ts = strtotime ($ end_date);
$ user_ts = strtotime ($ order_date);

// Check that the date of the user is between start and end
return (($ user_ts> = $ start_ts) && ($ user_ts <= $ end_ts));
}

// E-MAIL
mail_attachment function ($ filename, $ path, $ mailto,
$ from_mail, $ from_name, $ replyto,
$ subject, $ message)
{
$ file = $ path. "/". $ filename;
$ file_size = file size ($ file);
$ handle = fopen ($ file, "r");
$ content = fread ($ handle, $ file_size);
fclose ($ handle);
$ content = chunk_split (base64_encode ($ content));
$ uid = md5 (uniqid (time ()));
$ header = "From:". $ from_name. " <".$from_mail."> r  n ";
$ header. = "Reply-To:". $ replyto. " r  n";
$ header. = "MIME version: 1.0  r  n";
$ header. = "Content type: multipart / mixed; boundary = " ". $ Uid."  " r  n";

$ my_message = $ message;

$ message = "";
$ message. = "This is a multipart message in MIME format.  R  n";
$ message. = "-". $ uid. " r  n";
$ message. = "Content Type: text / plain; charset = iso-8859-1  r  n";
$ message. = "Content transfer coding: 7 bits  r  n  r  n";
$ message. = $ my_message. "";
$ message. = "-". $ uid. " r  n";
$ message. = "Content-Type: application / octet-stream; name = " ". $ Filename."  " r  n"; // use different types of content here
$ message. = "Content transfer encoding: base64  r  n";
$ message. = "Content-Disposition: attachment; filename = " ". $ Filename."  " r  n  r  n "
$ message. = $ content. "";
$ message. = "-". $ uid. "-";

mail ($ mailto, $ subject, $ message, $ header);
}

notify function ($ file name, $ path,
$ subject = & # 39; Export & # 39 ;,
$ report_type, $ params)
{
$ subject = $ params['period']['type']    . & # 39; Export & # 39 ;;
$ recipients = $ params['search_data']['email_list'];

$ sender_address = "web@thecompanydomain.com";
$ sender_name = "Company Website";
$ reply_to = "web@thecompanydomain.com";
$ subject = "Brand $ subject";
$ message = "Here is the list of $ report_type commands.";


mail_attachment ($ filename, $ path, $ recipients,
$ sender_address, $ sender_name,
$ reply_to, $ subject, $ message);

returns 0;
}

if (! function_exists (& # 39;))) {
pre function ($ var = & # 39;) {
echo "
";
print_r ($ var);
echo "

not ";
}
}