/var/www/html_uk/wp-content/plugins/automatewoo/includes/Actions/Send_SMS_Twilio.php


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
<?php
// phpcs:ignoreFile

namespace AutomateWoo;

if ( ! 
defined'ABSPATH' ) ) exit;

/**
 * @class Action_Send_SMS_Twilio
 */
class Action_Send_SMS_Twilio extends Action {


    function 
load_admin_details() {
        
$this->title __'Send SMS (Twilio)''automatewoo' );
        
$this->group __'SMS''automatewoo' );
        
$this->description __'It is recommended to include an unsubscribe link by using the variable {{ customer.unsubscribe_url }} in the SMS body.''automatewoo' );

        if ( 
AW()->options()->bitly_api && AW()->options()->bitly_shorten_sms_links ) {
            
/* translators: %1$s Bitly integration link start, %2$s Bitly integration link end. */
            
$bitly_text __'Links in the SMS body will be shortened with the %1$sBitly integration%2$s.''automatewoo' );
        } else {
            
/* translators: %1$s Bitly integration link start, %2$s Bitly integration link end. */
            
$bitly_text __'To shorten links in the SMS body the %1$sBitly integration%2$s must be enabled.''automatewoo' );
        }

        
$this->description .= sprintf(
            
' ' $bitly_text,
            
'<a href="' Admin::page_url'settings-bitly' ) . '" target="_blank">',
            
'</a>'
        
);
    }


    function 
load_fields() {
        
$sms_recipient = ( new Fields\Text() )
            ->
set_name'sms_recipient' )
            ->
set_title__'SMS recipients''automatewoo' ) )
            ->
set_description__'Multiple recipient numbers must be separated by commas. When using the {{ customer.phone }} variable the country code will be added automatically, if not already entered by the customer, by referencing the billing country.''automatewoo' ) )
            ->
set_variable_validation()
            ->
set_required();

        
$sms_body = ( new Fields\Text_Area() )
            ->
set_name'sms_body' )
            ->
set_title__'SMS body''automatewoo' ) )
            ->
set_rows(4)
            ->
set_variable_validation()
            ->
set_required();

        
$this->add_field$sms_recipient );
        
$this->add_field$sms_body );
    }


    
/**
     * @throws \Exception
     */
    
function run() {
        
$recipients Clean::comma_delimited_string$this->get_option'sms_recipient' ) );
        
$message $this->get_option'sms_body'true );

        if ( empty( 
$message ) ) {
            throw new 
\Exception__'Empty message body''automatewoo') );
        }

        
$message $this->process_urls_in_sms$message );

        
$valid_recipients_count 0;
        foreach ( 
$recipients as $recipient_string ) {
            
$recipient $this->workflow->variable_processor()->process_field$recipient_string );
            
// Do not send SMS for a variable that resolved to an empty number.
            
if( $recipient ) {
                
$this->send_sms$recipient$recipient_string$message );
                
$valid_recipients_count++;
            }
        }
        if ( 
$valid_recipients_count == ) {
            throw new 
\Exception__'No valid recipients''automatewoo') );
        }
    }


    
/**
     * Sends an SMS to one recipient.
     *
     * @since 4.3.2
     *
     * @param string $recipient_phone The phone number of the SMS recipient.
     * @param string $recipient_string Unprocessed recipient string.
     * @param string $message         The body of the SMS
     */
    
public function send_sms$recipient_phone$recipient_string$message ) {
        
$twilio Integrations::get_twilio();

        if ( ! 
$twilio ) {
            return;
        }

        
$is_sms_to_customer $this->is_recipient_the_primary_customer$recipient_string );

        
// check if this SMS is going to the workflow's primary customer
        
if ( $is_sms_to_customer ) {
            
$customer $this->workflow->data_layer()->get_customer();

            
// check if the customer is unsubscribed
            
if ( $this->workflow->is_customer_unsubscribed$customer ) ) {
                
$error = new \WP_Error'unsubscribed'__"The recipient is not opted-in to this workflow."'automatewoo' ) );
                
$this->workflow->log_action_email_error$error$this );
                return;
            }

            
// because the SMS is to the primary customer, use the customer's country to parse the phone number
            
$recipient_phone Phone_Numbers::parse$recipient_phone$customer->get_billing_country() );
        }
        else {
            
$recipient_phone Phone_Numbers::parse$recipient_phone );
        }

        
$request $twilio->send_sms$recipient_phone$message );

        if ( 
$request->is_successful() ) {
            
$this->workflow->log_action_note$this__'SMS successfully sent.''automatewoo' ) );
        }
        else {
            
// don't throw exception since the error is only for one recipient
            
$this->workflow->log_action_error$this$twilio->get_request_error_message$request ) );
        }
    }


    
/**
     * Determines if a recipient is the primary customer for the workflow.
     *
     * Must be used before the $recipient_phone has variables processed.
     *
     * @param string $recipient_field
     *
     * @return bool
     */
    
public function is_recipient_the_primary_customer$recipient_field ) {
        if ( ! 
$recipient_field ) {
            return 
false;
        }

        
$is_primary_customer false;

        if ( 
stristr$recipient_field'customer.phone' ) || stristr$recipient_field'order.billing_phone' ) ) {
            
$is_primary_customer true;
        }

        return 
apply_filters'automatewoo/sms/is_recipient_primary_customer'$is_primary_customer$this );
    }


    
/**
     * Process the URLs in an SMS body.
     * - Maybe converts URLs to trackable URLs
     * - Maybe shortens URL
     *
     * @since 4.3.2
     *
     * @param string $sms
     *
     * @return string
     */
    
public function process_urls_in_sms$sms ) {
        
$replacer = new Replace_Helper$sms, [ $this'callback_process_url' ], 'text_urls' );
        
$processed $replacer->process();
        return 
$processed;
    }


    
/**
     * Processes a single URL in the SMS body.
     *
     * @param string $url
     *
     * @return string
     */
    
public function callback_process_url$url ) {
        
$url html_entity_decode$url );

        
// make URL trackable if enabled
        
if ( $this->workflow->is_tracking_enabled() ) {
            
// don't track unsubscribe clicks
            
if ( ! strstr$url'aw-action=unsubscribe' ) ) {
                
$url $this->workflow->append_ga_tracking_to_url$url );
                
$url esc_url_rawTracking::get_click_tracking_url$this->workflow$url ) );
            }
        }

        
// shorten links if enabled
        
if ( AW()->options()->bitly_shorten_sms_links ) {
            
$bitly Integrations::get_bitly();

            if ( 
$bitly ) {
                
$short_url $bitly->shorten_url$url );

                
// Default to full url if bitly fails for any reason (e.g. exceeded rate limit).
                // https://github.com/woocommerce/automatewoo/issues/895
                
if ( $short_url ) {
                    
$url $short_url;
                }
            }
        }

        return 
$url;
    }


}