Plugin Directory

Changeset 3426934


Ignore:
Timestamp:
12/24/2025 03:37:45 PM (8 weeks ago)
Author:
combustiongroup
Message:

Release 1.2.9: implement bulk pull contacts

Location:
happy-texting/trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • happy-texting/trunk/core/class-happy-texting.php

    r3426328 r3426934  
    202202                    'permission_callback' => '__return_true'
    203203                ));
     204            });
     205
     206            add_action('rest_api_init', function () {
     207                register_rest_route('wc/v3', 'texting_webhook_bulk', [
     208                    'methods'  => 'POST',
     209                    'callback' => [$this, 'texting_webhook_bulk'],
     210                    'permission_callback' => function () {
     211                        if ( ! class_exists('WC_REST_Authentication') ) {
     212                            return false;
     213                        }
     214           
     215                        $auth = new WC_REST_Authentication();
     216                        $user_id = $auth->authenticate(false);
     217           
     218                        if ( ! $user_id ) {
     219                            return new WP_Error(
     220                                'woocommerce_rest_authentication_error',
     221                                'Invalid API credentials',
     222                                ['status' => 401]
     223                            );
     224                        }
     225           
     226                        return true;
     227                    }
     228                ]);
    204229            });
    205230
     
    14341459        function texting_webhook_auth_verify(){
    14351460            wp_send_json_success("Success", 200);
     1461        }
     1462
     1463        /**
     1464         * Process a single contact lookup and return customer data
     1465         *
     1466         * @param string $search_term Email or mobile number to search for
     1467         * @param bool $include_last_order Whether to include last_order object in response (default: true for backward compatibility)
     1468         * @return array|null Customer data array on success, null if customer not found
     1469         */
     1470        private function process_single_contact($search_term, $include_last_order = true) {
     1471            $customer_id = NULL;
     1472           
     1473            $orders = wc_order_search($search_term);
     1474            if (!$orders) {
     1475                return null;
     1476            }
     1477           
     1478            $last_order_id = intval(end($orders));
     1479            $order = wc_get_order($last_order_id);
     1480           
     1481            // Validate that order exists (WC_Order_Refund extends WC_Order, so checking WC_Order covers both)
     1482            if (!$order || !is_a($order, 'WC_Order')) {
     1483                return null;
     1484            }
     1485           
     1486            // Check if this is a refund order
     1487            if (is_a($order, 'WC_Order_Refund')) {
     1488                // For refund orders, get the parent order
     1489                $parent_id = $order->get_parent_id();
     1490                if ($parent_id) {
     1491                    $parent_order = wc_get_order($parent_id);
     1492                    if ($parent_order && is_a($parent_order, 'WC_Order')) {
     1493                        $customer_id = $parent_order->get_customer_id();
     1494                        // Use parent order for subsequent operations
     1495                        $order = $parent_order;
     1496                    } else {
     1497                        return null;
     1498                    }
     1499                } else {
     1500                    return null;
     1501                }
     1502            } else {
     1503                // Regular order
     1504                $customer_id = $order->get_customer_id();
     1505            }
     1506           
     1507            if (!$customer_id) {
     1508                return null;
     1509            }
     1510           
     1511            $customer = new WC_Customer($customer_id);
     1512            $last_order = $customer->get_last_order();
     1513           
     1514            $locations_label = '' != get_option('orddd_location_field_label') ? get_option('orddd_location_field_label') : 'Pickup Location';
     1515           
     1516            if ($last_order && $last_order->get_data()) {
     1517                $last_order_date = $last_order->get_data()['date_created'];
     1518                $last_order_object = $include_last_order ? $last_order->get_data() : null;
     1519                $shipping_method = $order->get_shipping_method();
     1520                $pickup_location = NULL;
     1521                if ($shipping_method == "Local pickup") {
     1522                    $pickup_location = $order->get_meta("$locations_label");
     1523                }
     1524            } else {
     1525                $last_order_date = [
     1526                    "date" => date("Y-m-d H:i:s"),
     1527                    "timezone_type" => 1,
     1528                    "timezone" => "+00:00"
     1529                ];
     1530                $last_order_object = null;
     1531                $pickup_location = NULL;
     1532                $shipping_method = NULL;
     1533            }
     1534           
     1535            $api_key = Happy_Texting_Settings::get(Happy_Texting_Settings::OPTION_API_KEY);
     1536            $textword_id = Happy_Texting_Settings::get(Happy_Texting_Settings::OPTION_TEXTWORD_ID);
     1537            $orders_count = $customer->get_order_count();
     1538            $total_spent = $customer->get_total_spent();
     1539           
     1540            global $wpdb;
     1541            $status = "no subscription";
     1542            $auto_query = "SELECT autoship_status FROM {$wpdb->prefix}wc_autoship_schedules WHERE customer_id=" . intval($customer_id);
     1543           
     1544            try {
     1545                $schedules = $wpdb->get_results($auto_query, 'ARRAY_A');
     1546               
     1547                if (!empty($schedules)) {
     1548                    $status = "paused subscription";
     1549                   
     1550                    foreach ($schedules as $schedule) {
     1551                        if ($schedule['autoship_status'] == 1) {
     1552                            $status = "active subscription";
     1553                            break;
     1554                        }
     1555                    }
     1556                }
     1557            } catch (Exception $e) {
     1558                // Continue with default status
     1559            }
     1560           
     1561            $result = [
     1562                'api_key' => $api_key,
     1563                'text_word' => $textword_id,
     1564                'first_name' => $order->get_billing_first_name(),
     1565                'last_name' => $order->get_billing_last_name(),
     1566                'email' => $order->get_billing_email(),
     1567                'phone' => $order->get_billing_phone(),
     1568                'event' => 'checkout',
     1569                'last_order_total' => $order->get_total(),
     1570                'orders_count' => $orders_count,
     1571                'total_spent' => $total_spent,
     1572                'last_order_date' => $last_order_date,
     1573                'shipping_method' => $shipping_method,
     1574                'pickup_location' => $pickup_location,
     1575                'location_label' => $locations_label,
     1576                'subscription_status' => $status,
     1577            ];
     1578           
     1579            if ($include_last_order) {
     1580                $result['last_order'] = $last_order_object;
     1581            }
     1582           
     1583            return $result;
     1584        }
     1585
     1586        /**
     1587         * Bulk webhook endpoint to process multiple contacts in a single request
     1588         *
     1589         * @param WP_REST_Request $request The REST request object
     1590         * @return WP_REST_Response|WP_Error
     1591         */
     1592        public function texting_webhook_bulk($request) {
     1593            // Get JSON body parameters
     1594            $params = $request->get_json_params();
     1595           
     1596            // Validate contacts array exists and is not empty
     1597            if (!isset($params['contacts']) || !is_array($params['contacts']) || empty($params['contacts'])) {
     1598                return new WP_Error(
     1599                    'missing_contacts',
     1600                    'contacts array is required and must not be empty',
     1601                    ['status' => 400]
     1602                );
     1603            }
     1604           
     1605            $contacts = $params['contacts'];
     1606           
     1607            // Validate maximum contacts limit (100)
     1608            if (count($contacts) > 100) {
     1609                return new WP_Error(
     1610                    'too_many_contacts',
     1611                    'Maximum 100 contacts allowed per request',
     1612                    ['status' => 400]
     1613                );
     1614            }
     1615           
     1616            // Validate each contact has at least mobile or email
     1617            foreach ($contacts as $index => $contact) {
     1618                if (!isset($contact['mobile']) && !isset($contact['email'])) {
     1619                    return new WP_Error(
     1620                        'invalid_contact',
     1621                        sprintf('Contact at index %d must have either mobile or email', $index),
     1622                        ['status' => 400]
     1623                    );
     1624                }
     1625            }
     1626           
     1627            // Process each contact
     1628            $results = [];
     1629           
     1630            foreach ($contacts as $contact) {
     1631                try {
     1632                    // Extract search term (email first, then mobile, same priority as existing endpoint)
     1633                    $search_term = '';
     1634                    if (isset($contact['email']) && !empty($contact['email'])) {
     1635                        $search_term = sanitize_text_field($contact['email']);
     1636                    } elseif (isset($contact['mobile']) && !empty($contact['mobile'])) {
     1637                        $search_term = sanitize_text_field($contact['mobile']);
     1638                    }
     1639                   
     1640                    // Process the contact
     1641                    $customer_data = $this->process_single_contact($search_term, false); // Don't include last_order
     1642                   
     1643                    if ($customer_data) {
     1644                        // Success - return customer data
     1645                        $results[] = array_merge(
     1646                            ['success' => true],
     1647                            $customer_data
     1648                        );
     1649                    } else {
     1650                        // Customer not found
     1651                        $results[] = [
     1652                            'success' => false,
     1653                            'error' => 'no customer for that search term',
     1654                            'mobile' => isset($contact['mobile']) ? $contact['mobile'] : null,
     1655                            'email' => isset($contact['email']) ? $contact['email'] : null,
     1656                        ];
     1657                    }
     1658                } catch (Exception $e) {
     1659                    // Handle any exceptions without stopping the batch
     1660                    $results[] = [
     1661                        'success' => false,
     1662                        'error' => 'Error processing contact: ' . $e->getMessage(),
     1663                        'mobile' => isset($contact['mobile']) ? $contact['mobile'] : null,
     1664                        'email' => isset($contact['email']) ? $contact['email'] : null,
     1665                    ];
     1666                }
     1667            }
     1668           
     1669            // Return response with success flag and results array
     1670            $response = [
     1671                'success' => true,
     1672                'results' => $results,
     1673            ];
     1674           
     1675            return rest_ensure_response($response);
    14361676        }
    14371677
  • happy-texting/trunk/happy-texting.php

    r3426328 r3426934  
    55 * @package       HAPPYTEXTI
    66 * @author        Happy Texting
    7  * @version       1.2.8
     7 * @version       1.2.9
    88 *
    99 * @wordpress-plugin
     
    1111 * Plugin URI:    https://hapytexting.com
    1212 * Description:   This plugin allows you to keep your customer list up to sync with www.happytexting.com
    13  * Version:       1.2.8
     13 * Version:       1.2.9
    1414 * Author:        Combustion Group
    1515 * Author URI:    https://combustiongroup.com
     
    2727
    2828// Plugin version
    29 define( 'HAPPYTEXTI_VERSION',       '1.2.8' );
     29define( 'HAPPYTEXTI_VERSION',       '1.2.9' );
    3030
    3131// Plugin Root File
  • happy-texting/trunk/readme.txt

    r3426328 r3426934  
    33License URI: https://www.gnu.org/licenses/gpl-2.0.html
    44Tested Up To: 6.6.1
    5 Stable tag: 1.2.8
     5Stable tag: 1.2.9
Note: See TracChangeset for help on using the changeset viewer.