PluginProbe
WANotifier for Forms and Actions / 0.1.1
WANotifier for Forms and Actions v0.1.1
3.1.0 3.0.4 2.7.10 2.7.11 2.7.12 2.7.13 2.7.2 2.7.3 2.7.4 2.7.5 2.7.6 2.7.7 2.7.8 2.7.9 3.0.0 3.0.1 3.0.2 3.0.3 trunk 0.1.0 0.1.1 1.0.0 1.0.1 1.0.2 1.0.3 All 66 releases
notifier / includes / class-notifier.php

class-notifier.php in WANotifier for Forms and Actions 0.1.1, at includes/class-notifier.php

403 lines 12.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * The core plugin class.
4 *
5 * @package Notifier
6 */
7 class Notifier {
8 /**
9 * The single instance of the class.
10 */
11 protected static $_instance = null;
12
13 /**
14 * Notifier Constructor.
15 */
16 public function __construct() {
17 $this->define_constants();
18 $this->includes();
19 $this->init_hooks();
20 }
21
22 /**
23 * Define Constants.
24 */
25 private function define_constants() {
26 $this->define( 'NOTIFIER_VERSION', '0.1.1' );
27 $this->define( 'NOTIFIER_NAME', 'notifier' );
28 $this->define( 'NOTIFIER_PREFIX', 'notifier_' );
29 $this->define( 'NOTIFIER_URL', trailingslashit( plugins_url( '', dirname(__FILE__) ) ) );
30 $this->define( 'NOTIFIER_WA_API_VERSION', 'v14.0' );
31 $this->define( 'NOTIFIER_WA_API_URL', 'https://graph.facebook.com/' . NOTIFIER_WA_API_VERSION . '/' );
32 }
33
34 /**
35 * Define constant if not already set.
36 *
37 * @param string $name Constant name.
38 * @param string|bool $value Constant value.
39 */
40 private function define( $name, $value ) {
41 if ( ! defined( $name ) ) {
42 define( $name, $value );
43 }
44 }
45
46 /**
47 * Main Notifier Instance.
48 *
49 * @return Notifier instance.
50 */
51 public static function get_instance() {
52 if ( is_null( self::$_instance ) ) {
53 self::$_instance = new self();
54 }
55 return self::$_instance;
56 }
57
58 /**
59 * Include required core files used in admin and on the frontend.
60 */
61 private function includes() {
62 // Libraries
63 require_once NOTIFIER_PATH . 'libraries/action-scheduler/action-scheduler.php';
64
65 // Functions
66 require_once NOTIFIER_PATH . 'includes/functions/functions-notifier-helpers.php';
67 require_once NOTIFIER_PATH . 'includes/functions/functions-notifier-meta-box-fields.php';
68
69 // Classes
70 require_once NOTIFIER_PATH . 'includes/classes/class-notifier-admin-notices.php';
71 require_once NOTIFIER_PATH . 'includes/classes/class-notifier-dashboard.php';
72 require_once NOTIFIER_PATH . 'includes/classes/class-notifier-message-templates.php';
73 require_once NOTIFIER_PATH . 'includes/classes/class-notifier-contacts.php';
74 require_once NOTIFIER_PATH . 'includes/classes/class-notifier-notifications.php';
75 require_once NOTIFIER_PATH . 'includes/classes/class-notifier-notification-triggers.php';
76 require_once NOTIFIER_PATH . 'includes/classes/class-notifier-settings.php';
77 }
78
79 /**
80 * Hook into actions and filters.
81 */
82 private function init_hooks() {
83 register_activation_hook ( NOTIFIER_FILE, array( $this, 'install') );
84
85 add_action( 'plugins_loaded', array( 'Notifier_Dashboard', 'init' ) );
86 add_action( 'plugins_loaded', array( 'Notifier_Message_Templates', 'init' ) );
87 add_action( 'plugins_loaded', array( 'Notifier_Contacts', 'init' ) );
88 add_action( 'plugins_loaded', array( 'Notifier_Notifications', 'init' ) );
89 add_action( 'plugins_loaded', array( 'Notifier_Notification_Triggers', 'init' ) );
90 add_action( 'plugins_loaded', array( 'Notifier_Settings', 'init' ) );
91 add_action( 'plugins_loaded', array( $this, 'maybe_include_woocoomerce_class' ) );
92
93 add_filter( 'init', array( $this , 'handle_webhook_requests') );
94
95 add_action( 'admin_enqueue_scripts', array( $this , 'admin_scripts') );
96 add_action( 'in_admin_header', array( $this , 'embed_page_header' ) );
97
98 add_action( 'removable_query_args', array( $this , 'remove_admin_query_args') );
99
100 add_action( 'admin_footer', array($this, 'add_admin_html_templates') );
101 }
102
103 /**
104 * Setup during plugin activation
105 */
106 public function install() {
107 $verify_token = get_option(NOTIFIER_PREFIX . 'verify_token');
108 if (!$verify_token) {
109 $bytes = random_bytes(20);
110 $verify_token = NOTIFIER_NAME . '-' . substr(bin2hex($bytes), 0, 10);
111 update_option(NOTIFIER_PREFIX . 'verify_token', $verify_token);
112 }
113 }
114
115 /**
116 * Check if plugin's page
117 */
118 public static function is_notifier_page() {
119 $current_screen = get_current_screen();
120 if ( strpos($current_screen->id, NOTIFIER_NAME) !== false) {
121 return true;
122 }
123
124 $plugin_ctps = array( 'wa_message_template', 'wa_contact', 'wa_notification' );
125 if ( '' !== $current_screen->post_type && in_array( $current_screen->post_type, $plugin_ctps ) ) {
126 return true;
127 }
128
129 return false;
130 }
131
132 /**
133 * Add admin scripts and styles
134 */
135 public function admin_scripts () {
136 if (!self::is_notifier_page()) {
137 return;
138 }
139
140 // Select2
141 wp_enqueue_script(
142 NOTIFIER_NAME . '-select2-js',
143 NOTIFIER_URL . 'assets/js/select2.min.js',
144 array('jquery'),
145 NOTIFIER_VERSION,
146 true
147 );
148
149 // Date / time picker
150 wp_enqueue_script( 'jquery-ui-datepicker' );
151 wp_enqueue_script(
152 NOTIFIER_NAME . '-timepicker-addon',
153 NOTIFIER_URL . 'assets/js/jquery-ui-timepicker-addon.min.js',
154 array( 'jquery-ui-datepicker' ),
155 NOTIFIER_VERSION,
156 true
157 );
158
159 // Admin JS file
160 wp_enqueue_script(
161 NOTIFIER_NAME . '-admin-js',
162 NOTIFIER_URL . 'assets/js/admin.js',
163 array('jquery'),
164 NOTIFIER_VERSION,
165 true
166 );
167 wp_localize_script(
168 NOTIFIER_NAME . '-admin-js',
169 'waNotifier',
170 apply_filters( 'notifier_js_variables', array('ajaxurl' => admin_url( 'admin-ajax.php' ) ) )
171 );
172
173 // Media upload library
174 wp_enqueue_media();
175
176 // Styles
177 wp_enqueue_style(
178 NOTIFIER_NAME . '-admin-css',
179 NOTIFIER_URL . 'assets/css/admin.css',
180 null,
181 NOTIFIER_VERSION
182 );
183 }
184
185 /**
186 * Set up a div for the header embed to render into.
187 * The initial contents here are meant as a place loader for when the PHP page initialy loads.
188 */
189 public static function embed_page_header() {
190 if (!self::is_notifier_page()) {
191 return;
192 }
193 $current_screen = get_current_screen();
194 $cpt = ( '' !== $current_screen->post_type) ? $current_screen->post_type : '';
195 $tax = ( '' !== $current_screen->taxonomy) ? $current_screen->taxonomy : '';
196 ?>
197 <div id="notifier-admin-header" data-post-type="<?php echo esc_attr($cpt); ?>">
198 <div class="notifier-admin-header-content">
199 <div class="header-page-title w-30">
200 <h2><?php echo esc_attr(get_admin_page_title()); ?></h2>
201 </div>
202 <div class="header-menu-items w-40 d-flex justify-content-center">
203 <?php
204 if ( 'wa_contact' == $cpt ) {
205 ?>
206 <ul>
207 <li>
208 <a class="<?php echo ('wa_contact_list' !== $tax && 'wa_contact_tag' !== $tax) ? 'active' : ''; ?>" href="<?php echo esc_url( admin_url('edit.php?post_type=wa_contact') ); ?>" class="">Contacts</a>
209 </li>
210 <li>
211 <a class="<?php echo ('wa_contact_list' == $tax) ? 'active' : ''; ?>" href="<?php echo esc_url( admin_url('edit-tags.php?taxonomy=wa_contact_list&post_type=wa_contact') ); ?>">Lists</a>
212 </li>
213 <li>
214 <a class="<?php echo ('wa_contact_tag' == $tax) ? 'active' : ''; ?>" href="<?php echo esc_url( admin_url('edit-tags.php?taxonomy=wa_contact_tag&post_type=wa_contact') ); ?>">Tags</a>
215 </li>
216 </ul>
217 <?php
218 }
219 ?>
220 </div>
221 <div class="header-action-links w-30 d-flex justify-content-end">
222 <span class="header-version">Version: <?php echo esc_html(NOTIFIER_VERSION); ?> (beta)</span>
223 <a href="mailto:ram@fantastech.co?subject=%5BWA%20Notifier%5D%20Help%20Needed%20on<?php echo esc_url(get_site_url()); ?>">Help</a>
224 <a href="admin.php?page=notifier&show=disclaimer">Disclaimer</a>
225 </div>
226 </div>
227 </div>
228 <?php
229 }
230
231 /**
232 * Handle response from Whatsapp
233 */
234 public static function handle_webhook_requests () {
235 if ( ! isset($_GET['notifier']) ) {
236 return;
237 }
238
239 if ( ! isset($_POST) ) {
240 return;
241 }
242
243 $hub_mode = isset($_GET['hub_mode']) ? sanitize_text_field( wp_unslash( $_GET['hub_mode'] ) ) : '';
244 $hub_verify_token = isset($_GET['hub_verify_token']) ? sanitize_text_field( wp_unslash( $_GET['hub_verify_token'] ) ) : '';
245 $hub_challenge = isset($_GET['hub_challenge']) ? sanitize_text_field( wp_unslash( $_GET['hub_challenge'] ) ) : '';
246
247 /* Validate WhastApp API webbook */
248 if ( 'subscribe' === $hub_mode ) {
249 $verify_token = get_option(NOTIFIER_PREFIX . 'verify_token');
250 if ($hub_verify_token == $verify_token) {
251 echo esc_html($hub_challenge);
252 }
253 }
254
255 exit;
256 }
257
258 /**
259 * For sending requests to Cloud API
260 */
261 public static function wa_cloud_api_request ( $endpoint, $args = array(), $method = 'POST', $headers = array() ) {
262 $phone_number_id = get_option('notifier_phone_number_id');
263 $request_url = NOTIFIER_WA_API_URL . $phone_number_id . '/' . untrailingslashit($endpoint);
264 return self::send_api_request($request_url, $args, $method, $headers);
265 }
266
267 /**
268 * For sending requests to WA Business API
269 */
270 public static function wa_business_api_request ( $endpoint, $args = array(), $method = 'POST', $headers = array() ) {
271 $business_account_id = get_option('notifier_business_account_id');
272 $request_url = NOTIFIER_WA_API_URL . $business_account_id . '/' . untrailingslashit($endpoint);
273 return self::send_api_request($request_url, $args, $method, $headers);
274 }
275
276 /**
277 * For sending graph api requests
278 */
279 public static function wa_graph_api_request ( $endpoint, $args = array(), $method = 'POST', $headers = array() ) {
280 $request_url = NOTIFIER_WA_API_URL . untrailingslashit($endpoint);
281 return self::send_api_request($request_url, $args, $method, $headers);
282 }
283
284 /**
285 * For sending API requests
286 */
287 private static function send_api_request ( $request_url, $args, $method, $headers ) {
288 $permanent_access_token = get_option('notifier_permanent_access_token');
289 $headers = wp_parse_args($headers, array(
290 'Authorization' => 'Bearer ' . $permanent_access_token
291 ));
292 $request_args = array(
293 'method' => $method,
294 'headers' => $headers,
295 'timeout' => 120,
296 'body' => $args
297 );
298 $response = wp_remote_request( $request_url, $request_args);
299 if ( is_wp_error( $response ) ) {
300 error_log( $response->get_error_message() );
301 return false;
302 } elseif (isset($response->error)) {
303 error_log($response->error_user_title . ' - ' . $response->eerror_user_msg);
304 return json_decode($response_body);
305 } else {
306 $response_body = wp_remote_retrieve_body( $response );
307 return json_decode($response_body);
308 }
309 }
310
311 /**
312 * For uploading media to WhatsApp
313 */
314 public static function wa_cloud_api_upload_media($attachment_id) {
315 $file_path = get_attached_file($attachment_id);
316 $file_size = filesize($file_path);
317
318 if (!$file_path) {
319 return;
320 }
321
322 $file_args = array (
323 'file_length' => $file_size,
324 'file_type' => get_post_mime_type($attachment_id)
325 );
326
327 $permanent_access_token = get_option('notifier_permanent_access_token');
328
329 // Create session ID for upload
330 $upload_session = self::wa_graph_api_request('app/uploads', $file_args);
331 if (!isset($upload_session->id)) {
332 error_log('Error creating WhatsApp image upload session: ' . $upload_session);
333 return false;
334 }
335
336 // Upload the file
337 $file = @fopen( $file_path, 'r' );
338 $file_data = fread( $file, $file_size );
339
340 $upload_headers = array(
341 'Authorization' => 'OAuth ' . $permanent_access_token,
342 'file_offset' => 0,
343 'Connection' => 'Close',
344 'Host' => 'graph.facebook.com',
345 'Content-Type' => 'multipart/form-data'
346 );
347
348 $upload_handle = self::wa_graph_api_request( $upload_session->id, $file_data, null, $upload_headers );
349 if (!isset($upload_handle->h)) {
350 error_log('Error while uploading profile image: ' . $upload_handle);
351 return false;
352 }
353
354 return $upload_handle->h;
355 }
356
357 /**
358 * Remove query args from WP backend
359 */
360 public static function remove_admin_query_args ($args) {
361 $remove_args = array('wa_import_count', 'wa_import_skipped', 'wa_contacts_import', 'import_contacts_from_users', 'refresh_status');
362 return array_merge($args, $remove_args);
363 }
364
365 /**
366 * Load Woocommerce class if it's present is activated
367 */
368 public static function maybe_include_woocoomerce_class () {
369 if ( class_exists( 'WooCommerce' ) ) {
370 require_once NOTIFIER_PATH . 'includes/classes/class-notifier-woocommerce.php';
371 Notifier_Woocommerce::init();
372 }
373 }
374
375 /**
376 * Add admin html templates to footer
377 */
378 public static function add_admin_html_templates () {
379 if (!self::is_notifier_page()) {
380 return;
381 }
382
383 $templates = apply_filters('notifier_admin_html_templates', array());
384
385 if (count($templates) == 0) {
386 return;
387 }
388
389 echo '<div class="notifier-templates">';
390 foreach ($templates as $template) {
391 $file_path = NOTIFIER_PATH . '/views/templates/admin-' . $template . '.php';
392 if ( ! file_exists($file_path) ) {
393 continue;
394 }
395 echo '<template id="notifier-template-' . esc_attr($template) . '">';
396 require_once $file_path;
397 echo '</template>';
398 }
399 echo '</div>';
400 }
401
402 }
403