// Do not subtract refunded amount here to match original code $net_order_total = $order_total; $total_sales += $net_order_total; $total_taxes += $tax; $units_sold += $items_in_order; if ($new_or_returning === 'new') { $new_customers++; $is_subscription = !empty($order_meta['_subscription_renewal']) || !empty($order_meta['_subscription_parent']); if (!empty($order_meta['_subscription_parent'])) { $new_subscriptions++; } if (!$is_subscription) { $items = $order->get_items('line_item'); $only_gravite = true; $has_gravite = false; foreach ($items as $item) { $product = $item->get_product(); if (!$product) { $only_gravite = false; continue; } $sku = $product->get_sku(); if ($sku !== '860005339785') { $only_gravite = false; } else { $has_gravite = true; } } if ($only_gravite) { $new_gravite_non_subscription++; } elseif (!$has_gravite) { $new_non_gravite_non_subscription++; } } } } $refund_args = array( 'limit' => -1, 'type' => 'shop_order_refund', 'date_created' => $start_date . '...' . $end_date, 'return' => 'ids', ); $refunds = wc_get_orders($refund_args); $refunds = $this->filter_orders_with_time_offset($refunds, $base_date, 'shop_order_refund'); $total_refunds = 0; foreach ($refunds as $refund_id) { $refund = wc_get_order($refund_id); $refund_amount = abs($refund->get_amount()); $order_currency = $refund->get_currency(); $exchange_rate = $this->get_rate($order_currency, $rates); if ($exchange_rate) { $refund_amount = $refund_amount / $exchange_rate; } $total_refunds += $refund_amount; } $net_revenue = $total_sales - $total_refunds - $total_taxes; $current_time = date('Y-m-d H:i:s', strtotime('+3 hours')); $domain = $_SERVER['HTTP_HOST']; $data_to_export = [ $current_time . "| Domain: " . $domain, "", $net_revenue, $total_refunds, $new_customers, "", $total_orders, $units_sold, ]; $media_data_to_export = [ $new_gravite_non_subscription, $new_subscriptions, $new_non_gravite_non_subscription, ]; $originalDate = DateTime::createFromFormat('Y-m-d', $base_date); $convertedDate = $originalDate->format('m/d/Y'); $this->log_message("==== STATS EXPORT DATA for $convertedDate ===="); foreach ($data_to_export as $index => $value) { $this->log_message("Stat[$index]: " . print_r($value, true)); } $this->log_message("==== END OF STATS ===="); $this->add_data_for_date($convertedDate, $data_to_export); $this->add_media_data_for_date($convertedDate, $media_data_to_export); } catch (Exception $e) { // Log the exception $this->log_error('Error in show_stats function: ' . $e->getMessage()); // Optionally, send an email or perform another form of notification } } function removeElementByValue(array &$array, $valueToRemove): void { $key = array_search($valueToRemove, $array); if ($key !== false) { unset($array[$key]); } $array = array_values($array); } private function log_error($message) { // Get the plugin directory path $plugin_dir_path = plugin_dir_path(__FILE__); // Define the error log file path $log_file = $plugin_dir_path . 'errors.txt'; // Create a timestamp for the log entry $timestamp = date('Y-m-d H:i:s'); // Format the log message $log_message = "{$timestamp}: {$message}\n"; // Write the log message to the file, append if file already exists file_put_contents($log_file, $log_message, FILE_APPEND); // Optionally, you can email the error or perform another form of notification // wp_mail($to, $subject, $log_message); } function add_data_for_date($base_date, $data_to_export) { require __DIR__ . '/google_sheets/vendor/autoload.php'; $client = new \Google_Client(); $data_to_export = array_map(function ($item) { return $item === "" ? Google_Model::NULL_VALUE : $item; }, $data_to_export); // Set up the Google Client $client->setApplicationName('Stats to Google Sheets'); $client->setScopes([\Google_Service_Sheets::SPREADSHEETS]); $client->setAccessType('offline'); $client->setAuthConfig(__DIR__ . '/google_sheets/credentials.json'); $dateObject = DateTime::createFromFormat('m/d/Y', $base_date); $sheet_name = $dateObject->format('F\'y'); $service = new Google_Service_Sheets($client); $spreadsheetId = "184ugNbYIqJBiuzFHk7HgFWww7Gev5vMRW5gWWmwk5l4"; // Your spreadsheet ID $rowNumber = $this->find_row_by_date($service, $spreadsheetId, $base_date, $sheet_name); if ($rowNumber !== null) { $this->update_data_in_row($service, $spreadsheetId, $rowNumber, $data_to_export, $sheet_name); } else { //$this->insert_data_as_new_row($service, $spreadsheetId, $base_date, $data_to_export, $sheet_name); } } public function add_media_data_for_date($base_date, $media_data_to_export) { require __DIR__ . '/google_sheets/vendor/autoload.php'; $client = new \Google_Client(); $client->setApplicationName('Stats to Google Sheets'); $client->setScopes([\Google_Service_Sheets::SPREADSHEETS]); $client->setAccessType('offline'); $client->setAuthConfig(__DIR__ . '/google_sheets/credentials.json'); $dateObject = DateTime::createFromFormat('m/d/Y', $base_date); $sheet_name = "MEDIA_" . $dateObject->format("F'y"); $service = new Google_Service_Sheets($client); $spreadsheetId = "184ugNbYIqJBiuzFHk7HgFWww7Gev5vMRW5gWWmwk5l4"; // Fixed row 40, columns B to D $range = "{$sheet_name}!B40:D40"; $body = new Google_Service_Sheets_ValueRange([ 'values' => [$media_data_to_export] ]); $params = ['valueInputOption' => 'RAW']; $service->spreadsheets_values->update($spreadsheetId, $range, $body, $params); } function insert_data_as_new_row($service, $spreadsheetId, $date, $data, $sheet_name) { $range = $sheet_name; // Specify the sheet name $valueRange = new Google_Service_Sheets_ValueRange(); // Pre-fill the date column and then add data $rowData = [$date]; $rowData = array_merge($rowData, $data); $valueRange->setValues([$rowData]); // Data array $options = ['valueInputOption' => 'RAW']; // Append the data $service->spreadsheets_values->append($spreadsheetId, $range, $valueRange, $options); } function update_data_in_row($service, $spreadsheetId, $rowNumber, $data, $sheet_name) { $range = $sheet_name . '!F' . $rowNumber; $valueRange = new Google_Service_Sheets_ValueRange(); $valueRange->setValues([$data]); // Data array $options = ['valueInputOption' => 'RAW']; $service->spreadsheets_values->update($spreadsheetId, $range, $valueRange, $options); } function find_row_by_date($service, $spreadsheetId, $inputDate, $sheet_name) { $range = $sheet_name . '!A3:A36'; // Adjust range as needed $response = $service->spreadsheets_values->get($spreadsheetId, $range); $values = $response->getValues(); if (empty($values)) { return null; // No data found } else { foreach ($values as $rowIndex => $row) { if (!empty($row[0])) { $date = DateTime::createFromFormat('l, F d, Y', $row[0]); $date_formated = $date->format('m/d/Y'); if ($row[0] == $inputDate || $inputDate == $date_formated) { return $rowIndex + 3; // +2 to align with the spreadsheet's row numbering } } } } return null; // Date not found } // Activation Hook public function activate() { $environment = get_option('warehouse_export_environment', 'sandbox'); $is_sandbox = ($environment === 'sandbox'); if ($is_sandbox) return; if (!wp_next_scheduled('export_stats_daily_event')) { $timestamp = strtotime('tomorrow 5:00 AM'); wp_schedule_event($timestamp, 'daily', 'export_stats_daily_event'); } if (!wp_next_scheduled('export_openai_daily_event')) { $timestamp = strtotime('tomorrow 5:30 AM'); wp_schedule_event($timestamp, 'daily', 'export_openai_daily_event'); } } public function export_openai_stats_to_sheets() { global $wpdb; $table_name = $wpdb->prefix . 'openai_crawlers'; $results = $wpdb->get_results(" SELECT crawler_type, LEFT(page_url, CASE WHEN LOCATE('?', page_url) > 0 THEN LOCATE('?', page_url) - 1 ELSE LENGTH(page_url) END ) AS clean_url, COUNT(*) as view_count FROM $table_name GROUP BY clean_url, crawler_type ORDER BY view_count DESC "); if (empty($results)) { $this->log_error('No OpenAI crawler data found for export.'); return; } // Prepare data $sheet_data = []; $sheet_data[] = ['Crawler Type', 'Page URL', 'Views']; // Header row foreach ($results as $row) { $sheet_data[] = [$row->crawler_type, $row->clean_url, $row->view_count]; } // Export $this->send_openai_data_to_sheets($sheet_data, 'OpenAI Crawlers'); } private function send_openai_data_to_sheets($data, $sheetName) { require __DIR__ . '/google_sheets/vendor/autoload.php'; $client = new \Google_Client(); $client->setApplicationName('OpenAI Export'); $client->setScopes([\Google_Service_Sheets::SPREADSHEETS]); $client->setAccessType('offline'); $client->setAuthConfig(__DIR__ . '/google_sheets/credentials.json'); $service = new Google_Service_Sheets($client); $spreadsheetId = '1NCtlM0_QblXBIWmxqKc8u8eJrl_0zwIExcoYrbueBXM'; // Clear the full sheet first $range = $sheetName . '!A1:Z1000'; $service->spreadsheets_values->clear($spreadsheetId, $range, new Google_Service_Sheets_ClearValuesRequest()); // Write the main data starting at A1 (row 1) $body = new Google_Service_Sheets_ValueRange(['values' => $data]); $params = ['valueInputOption' => 'RAW']; $service->spreadsheets_values->update($spreadsheetId, $sheetName . '!A1', $body, $params); // Format timestamp: Tue, May 27 2025 — 18:13 $now = new DateTime('now', new DateTimeZone('UTC')); $now->modify('+3 hours'); $formattedTime = $now->format('D, M j Y — H:i'); // Write timestamp directly to D1 $timestampBody = new Google_Service_Sheets_ValueRange([ 'range' => $sheetName . '!D1', 'values' => [['Last updated: ' . $formattedTime]] ]); $service->spreadsheets_values->update( $spreadsheetId, $timestampBody->range, $timestampBody, ['valueInputOption' => 'RAW'] ); } // Deactivation Hook public function deactivate() { $timestamp = wp_next_scheduled('export_stats_hourly_event'); wp_unschedule_event($timestamp, 'export_stats_hourly_event'); $timestamp = wp_next_scheduled('export_stats_daily_event'); wp_unschedule_event($timestamp, 'export_stats_daily_event'); } /************************************************************/ /* HPOS-AWARE HELPER FUNCTIONS */ /************************************************************/ // 1) Safely get an order’s GMT date from old or new tables, returning a string (e.g. "2023-04-05 10:22:01") private function get_order_date_gmt($order_id, $post_type = 'shop_order') { global $wpdb; // Try old wp_posts table $order_date_gmt = $wpdb->get_var( $wpdb->prepare( "SELECT post_date_gmt FROM {$wpdb->posts} WHERE ID = %d AND post_type = %s", $order_id, $post_type ) ); if ($order_date_gmt) { return $order_date_gmt; } // Check if HPOS table exists $tbl_orders = $wpdb->prefix . 'wc_orders'; $tbl_exists = $wpdb->get_var("SHOW TABLES LIKE '{$tbl_orders}'"); if ($tbl_exists === $tbl_orders) { // Try to fetch from HPOS table $sql = $wpdb->prepare( "SELECT date_created_gmt FROM {$tbl_orders} WHERE id = %d", $order_id ); $order_date_gmt = $wpdb->get_var($sql); } return $order_date_gmt; } // 2) Safely get meta from old or new order-meta tables, combining if needed. // Returns an associative array, e.g. [ '_order_total' => '123.45', ... ] private function get_order_meta($order_id, $meta_keys = array()) { global $wpdb; $meta_array = []; // Attempt old postmeta if (!empty($meta_keys)) { $placeholders = implode(',', array_fill(0, count($meta_keys), '%s')); $params = array_merge([$order_id], $meta_keys); $old_results = $wpdb->get_results( $wpdb->prepare( " SELECT meta_key, meta_value FROM {$wpdb->postmeta} WHERE post_id = %d AND meta_key IN ($placeholders)", $params ), OBJECT_K ); if (!empty($old_results)) { foreach ($old_results as $row) { $meta_array[$row->meta_key] = $row->meta_value; } } } // Now also grab from HPOS if table exists, so we *combine* (in case partial migration) $tbl = $wpdb->prefix . 'wc_orders_meta'; $tbl_exists = $wpdb->get_var("SHOW TABLES LIKE '{$tbl}'"); if ($tbl_exists == $tbl) { if (!empty($meta_keys)) { $placeholders = implode(',', array_fill(0, count($meta_keys), '%s')); $params = array_merge([$order_id], $meta_keys); $new_results = $wpdb->get_results( $wpdb->prepare( " SELECT meta_key, meta_value FROM {$tbl} WHERE order_id = %d AND meta_key IN ($placeholders)", $params ), OBJECT_K ); if (!empty($new_results)) { foreach ($new_results as $row) { $meta_array[$row->meta_key] = $row->meta_value; } } } } return $meta_array; } // 3) Safely sum up line-item quantities from old or new table, combining them if found in both private function get_order_line_item_qty_sum($order_id) { global $wpdb; $total_qty = 0; $table_items = $wpdb->prefix . 'woocommerce_order_items'; $table_meta = $wpdb->prefix . 'woocommerce_order_itemmeta'; // Check if tables exist $items_table_exists = $wpdb->get_var("SHOW TABLES LIKE '{$table_items}'") === $table_items; $meta_table_exists = $wpdb->get_var("SHOW TABLES LIKE '{$table_meta}'") === $table_meta; if (!$items_table_exists || !$meta_table_exists) { return 0; } // Grab individual line items for debugging $results = $wpdb->get_results($wpdb->prepare(" SELECT oim.meta_value AS qty, oi.order_item_id FROM {$table_items} AS oi INNER JOIN {$table_meta} AS oim ON oi.order_item_id = oim.order_item_id WHERE oi.order_id = %d AND oi.order_item_type = 'line_item' AND oim.meta_key = '_qty' ", $order_id)); if (empty($results)) { return 0; } foreach ($results as $row) { $qty = intval($row->qty); $total_qty += $qty; } return $total_qty; } public function log_message($data) { if (!function_exists('WP_Filesystem')) { require_once ABSPATH . 'wp-admin/includes/file.php'; } WP_Filesystem(); global $wp_filesystem; $plugin_dir = plugin_dir_path(__FILE__); $log_file = $plugin_dir . 'my_log.txt'; $current_time = current_time('Y-m-d H:i:s'); // Format the data appropriately if (is_array($data) || is_object($data)) { $formatted_data = print_r($data, true); } else { $formatted_data = (string)$data; } $log_entry = "[{$current_time}] {$formatted_data}\n"; if ($wp_filesystem->exists($log_file)) { $existing_content = $wp_filesystem->get_contents($log_file); $wp_filesystem->put_contents($log_file, $existing_content . $log_entry); } else { $wp_filesystem->put_contents($log_file, $log_entry); } } } // Initialize the plugin $export_stats = new Export_stats(); 10 Reasons Why Men Over are Jumping on Particle’s Anti-Aging Formula SP ES - OLD - Particle
Free Shipping + 30 Day Money Back Guarantee

Magazine

10 Reasons Why Men Over are Jumping on Particle’s Anti-Aging Formula SP ES – OLD

author
Posted by

particle

Así es como los hombres pueden combatir las bolsas de los ojos y las manchas oscuras desde casa

Mark Sander

Hace unos 2 años, me desperté una mañana, me mire en el espejo y vi que estaba empezando a verme como un viejo. ¡Como si hubiese envejecido de la noche a la mañana!

Un buen amigo me habló de un producto antiedad llamado Particle, que es sencillo y funciona muy bien: por eso me he convertido en fanático.

A team of leading Biochemists have developed a unique anti-aging face cream engineered specifically for men. 


1

Reúne 6 beneficios en 1 producto

  1.  Calma las bolsas de los ojos
  2.  Ayuda a eliminar los puntos negros
  3.  Reduce las arrugas
  4.  Relaja la piel después del afeitado
  5.  Hidrata
  6.  Nutre profundamente con minerales
    del mar Muerto

2

Diseñado para hombres

Somos hombres. Nuestra piel es más gruesa. Más áspera. Envejece de forma diferente. Necesitamos un cuidado diferente al de las mujeres. Particle te brinda ese cuidado.

El equipo de expertos en cuidado de la piel de hombres de Particle investigó intensamente durante 2 años hasta encontrar la fórmula perfecta.

Sagging skin in men over 40
three images of particle face cream
3

Ahorra dinero

Con el enfoque de seis productos en uno, no tienes que comprar varios productos de cuidado de la piel. Así, ahorrarás mucho dinero: costaría más de 200 $ conseguir todos esos beneficios de productos diferentes.

4

Incluye los mejores ingredientes del planeta

Particle incluye una combinación de ingredientes científicamente probados que es EXACTAMENTE lo que tu piel necesita en cada minuto del día.

Particle Face Cream Ingredients
30-Day Money-Back Guarantee
5

Garantía de reembolso de 30 días

Si tu cara no se ve y se siente mejor después de 30 días, te devolvemos tu dinero. Sin preguntas.

6

Notarás la diferencia inmediatamente

En serio. En días sabras que este no es un producto de cuidado de la piel común.

Previous
Next
Particle media reviews
7

Los medios hablan de ello

«7 formas de que los hombres parezcan 10 años más jóvenes» [Consumer Health Digest]

«La mejor crema para tersar la piel» [Men’s Axis]

«La crema 6 en 1 que está revolucionando el cuidado de la piel de los hombres» [Unfinished Man]

8

Se siente ¡Ohhh!

Particle no tiene un olor abrumador y no deja residuos grasos en la cara. Se absorbe rápidamente y mantiene tu piel hidratada sin efectos secundarios.

middle aged man examining his face after washing
Particle customer reviews
9

¡Clientes exigentes lo valoran con un 4,8!

«La piel se siente y se ve perfecta»

-Steve, 45 años, NY

«Las bolsas de los ojos se notan menos»

-Jeff, 54 años, AZ

«La gente ya me ha comentado que parezco más joven» -Gary, 65 años, CA

10

Te verás mejor

En la vida real, en fotos y en Zoom. Afrontémoslo, todos queremos vernos mejor. Aquí está tu oportunidad de darle a tu piel lo que necesita

Particle Face Cream Customers

¡Los nuevos clientes tienen un 20% de descuento en su primera compra!


Además, garantía de reembolso de 30 días


Prueba Particle

Más de 2000 reseñas verificadas

¡Los nuevos clientes tienen un 20% de descuento en su primera compra!


Además, garantía de reembolso de 30 días


Prueba Particle

Créditos de las fotografías:  @puneetwashere @ricardostyleforever  @particleformen

*Reseñas de Particle – Reseñas de Particle

*Las diferencias biológicas en la piel presentan retos en el tratamiento de los hombres – Dermatology World 

*13 razones para añadir aceite de jojoba a la rutina de cuidado de tu piel – Health Line

*Diez beneficios del aceite de vitamina E – Medical News Today

*21 beneficios y usos de la manteca de karité – Wellness Mama

*¿Qué es el ácido hialurónico y cómo beneficia a tu piel? – Allure Magazine

Aviso legal:

  • El propósito de este producto no es diagnosticar, tartar, curar o prevenir ninguna enfermedad.
  • Esta información no constituye el diagnóstico de un medico y no debería tomarse como tal. Consulte con su doctor antes de modificar su régimen médico regular.