OneSignal – Free Web Push Notifications - Version 1.17.6

Version Description

  • Fixed bug where scheduled posts would send notifications immediately, added Gutenberg support for scheduled notifications
Download this release

Release Info

Developer OneSignal
Plugin Icon 128x128 OneSignal – Free Web Push Notifications
Version 1.17.6
Comparing to
See all releases

Code changes from version 1.17.5 to 1.17.6

Files changed (4) hide show
  1. notice.js +19 -11
  2. onesignal-admin.php +811 -717
  3. onesignal.php +2 -2
  4. readme.txt +8 -4
notice.js CHANGED
@@ -5,7 +5,8 @@ var state = {
5
  first_modified : undefined, // when the post was first modified
6
  started : false, // post notification requests started
7
  interval: undefined, // global interval for reattempting requests
8
- interval_count : 0 // how many times has the request been attempted
 
9
  }
10
 
11
  function notice() {
@@ -40,6 +41,7 @@ function notice() {
40
 
41
  // latest modified date, status of the post
42
  const { modified, status } = post;
 
43
 
44
  // is checked
45
  const send_os_notif = jQuery("[name=send_onesignal_notification]").attr(
@@ -50,9 +52,10 @@ function notice() {
50
  const post_modified = modified !== state.first_modified;
51
 
52
  const is_published = status === "publish";
 
53
 
54
  // if hasn't started, change detected, box checked, and the status is 'publish'
55
- if (!state.started && post_modified && send_os_notif && is_published) {
56
  state.interval = setInterval(get_metadata, 3000); // starts requests
57
  state.started = true;
58
  }
@@ -70,7 +73,7 @@ function notice() {
70
 
71
  jQuery.get(ajax_object.ajax_url, data, function(response) {
72
  response = JSON.parse(response);
73
- const { recipients, status_code, error_message } = response;
74
 
75
  if(window.DEBUG_MODE){
76
  console.log(response);
@@ -82,21 +85,21 @@ function notice() {
82
  if(!is_status_empty && !is_recipients_empty){
83
  // status 0: HTTP request failed
84
  if (status_code === "0") {
85
- error_notice("OneSignal Push: request failed with status code 0. "+error_message);
86
  reset_state();
87
  return;
88
  }
89
 
90
  // 400 & 500 level errors
91
  if (status_code >= 400) {
92
- if (!error_message) {
93
  error_notice(
94
  "OneSignal Push: there was a " +
95
  status_code +
96
  " error sending your notification"
97
  );
98
  } else {
99
- error_notice("OneSignal Push: there was a " + status_code + " error sending your notification: " + error_message);
100
  }
101
 
102
  reset_state();
@@ -105,7 +108,7 @@ function notice() {
105
 
106
  if (recipients === "0") {
107
  error_notice(
108
- "OneSignal Push: there were no recipients. You either 1) have no subscribers yet or 2) you hit the rate-limit. Please try again in three minutes. Learn more: https://bit.ly/2UDplAS"
109
  );
110
  reset_state();
111
 
@@ -132,11 +135,18 @@ function notice() {
132
  */
133
  const show_notice = recipients => {
134
  const plural = recipients == 1 ? "" : "s";
 
 
 
 
 
 
 
135
  wp.data
136
  .dispatch("core/notices")
137
  .createNotice(
138
  "info",
139
- "OneSignal Push: Successfully sent a notification to " +
140
  recipients +
141
  " recipient" +
142
  plural,
@@ -190,10 +200,8 @@ const isWpCoreEditorDefined = () => {
190
  * returns an object in the format
191
  * { status : "200",
192
  * recipients : "1374",
193
- * error_message : []
194
  * }
195
- *
196
- * - if the recipient number is "0", the error_message will contain the entire HTTP response as JSON
197
  */
198
  window.OneSignal = {
199
  debug : () => {
5
  first_modified : undefined, // when the post was first modified
6
  started : false, // post notification requests started
7
  interval: undefined, // global interval for reattempting requests
8
+ interval_count : 0, // how many times has the request been attempted
9
+ status : undefined // whether the post is scheduled or published
10
  }
11
 
12
  function notice() {
41
 
42
  // latest modified date, status of the post
43
  const { modified, status } = post;
44
+ state.status = status;
45
 
46
  // is checked
47
  const send_os_notif = jQuery("[name=send_onesignal_notification]").attr(
52
  const post_modified = modified !== state.first_modified;
53
 
54
  const is_published = status === "publish";
55
+ const is_scheduled = status === "future";
56
 
57
  // if hasn't started, change detected, box checked, and the status is 'publish'
58
+ if (!state.started && post_modified && send_os_notif && (is_published || is_scheduled)) {
59
  state.interval = setInterval(get_metadata, 3000); // starts requests
60
  state.started = true;
61
  }
73
 
74
  jQuery.get(ajax_object.ajax_url, data, function(response) {
75
  response = JSON.parse(response);
76
+ const { recipients, status_code, response_body } = response;
77
 
78
  if(window.DEBUG_MODE){
79
  console.log(response);
85
  if(!is_status_empty && !is_recipients_empty){
86
  // status 0: HTTP request failed
87
  if (status_code === "0") {
88
+ error_notice("OneSignal Push: request failed with status code 0. "+response_body);
89
  reset_state();
90
  return;
91
  }
92
 
93
  // 400 & 500 level errors
94
  if (status_code >= 400) {
95
+ if (!response_body) {
96
  error_notice(
97
  "OneSignal Push: there was a " +
98
  status_code +
99
  " error sending your notification"
100
  );
101
  } else {
102
+ error_notice("OneSignal Push: there was a " + status_code + " error sending your notification: " + response_body);
103
  }
104
 
105
  reset_state();
108
 
109
  if (recipients === "0") {
110
  error_notice(
111
+ "OneSignal Push: there were no recipients."
112
  );
113
  reset_state();
114
 
135
  */
136
  const show_notice = recipients => {
137
  const plural = recipients == 1 ? "" : "s";
138
+
139
+ if (state.status === "publish") {
140
+ var notice_text = "OneSignal Push: Successfully sent a notification to ";
141
+ } else if (state.status === "future"){
142
+ var notice_text = "OneSignal Push: Successfully scheduled a notification for ";
143
+ }
144
+
145
  wp.data
146
  .dispatch("core/notices")
147
  .createNotice(
148
  "info",
149
+ notice_text +
150
  recipients +
151
  " recipient" +
152
  plural,
200
  * returns an object in the format
201
  * { status : "200",
202
  * recipients : "1374",
203
+ * response_body : []
204
  * }
 
 
205
  */
206
  window.OneSignal = {
207
  debug : () => {
onesignal-admin.php CHANGED
@@ -1,343 +1,362 @@
1
  <?php
2
 
3
- defined( 'ABSPATH' ) or die('This page may not be accessed directly.');
4
 
5
- function onesignal_change_footer_admin() {
6
- return '';
 
7
  }
8
  /*
9
  * Loads js script that includes ajax call with post id
10
  */
11
 
12
  add_action('admin_enqueue_scripts', 'load_javascript');
13
- function load_javascript() {
14
- global $post;
15
- if($post){
 
16
  wp_register_script('notice_script', plugins_url('notice.js', __FILE__), array('jquery'), '1.1', true);
17
  wp_enqueue_script('notice_script');
18
- wp_localize_script('notice_script', 'ajax_object', array('ajax_url' => admin_url("admin-ajax.php"), 'post_id' => $post->ID));
19
  }
20
  }
21
 
22
- add_action( 'wp_ajax_has_metadata', 'has_metadata' );
23
- function has_metadata() {
24
- $post_id = $_GET['post_id'];
25
-
26
- if(is_null($post_id)){
27
- error_log("OneSignal: could not get post_id");
28
- $data = array('error' => "could not get post id");
29
- }else{
30
- $recipients = get_post_meta($post_id, "recipients");
31
- if($recipients && is_array($recipients)){
32
- $recipients = $recipients[0];
33
- }
34
-
35
- $status = get_post_meta($post_id, "status");
36
- if($status && is_array($status)){
37
- $status = $status[0];
38
- }
39
-
40
- $error_message = get_post_meta($post_id, "error_message");
41
- if($error_message && is_array($error_message)){
42
- $error_message = $error_message[0];
43
- }
44
-
45
- // reset meta
46
- delete_post_meta($post_id, "status");
47
- delete_post_meta($post_id, "recipients");
48
- delete_post_meta($post_id, "error_message");
49
-
50
- $data = array('recipients' => $recipients, 'status_code' => $status, 'error_message' => $error_message);
51
- }
52
 
53
- echo json_encode($data);
 
 
 
54
 
55
- exit;
 
 
 
56
 
57
- }
 
 
 
58
 
59
- class OneSignal_Admin {
60
- /**
61
- * Increment $RESOURCES_VERSION any time the CSS or JavaScript changes to view the latest changes.
62
- */
63
- private static $RESOURCES_VERSION = '42';
64
- private static $SAVE_POST_NONCE_KEY = 'onesignal_meta_box_nonce';
65
- private static $SAVE_POST_NONCE_ACTION = 'onesignal_meta_box';
66
- public static $SAVE_CONFIG_NONCE_KEY = 'onesignal_config_page_nonce';
67
- public static $SAVE_CONFIG_NONCE_ACTION = 'onesignal_config_page';
68
-
69
- public function __construct() {
70
- }
71
-
72
- public static function init() {
73
- $onesignal = new self();
74
-
75
- if (class_exists('WDS_Log_Post')) {
76
- function exception_error_handler($errno, $errstr, $errfile, $errline) {
77
- try {
78
- switch ($errno) {
79
- case E_USER_ERROR:
80
- onesignal_debug('[ERROR]', $errstr . ' @ ' . $errfile . ':' . $errline);
81
- exit(1);
82
- break;
83
-
84
- case E_USER_WARNING:
85
- onesignal_debug('[WARNING]', $errstr . ' @ ' . $errfile . ':' . $errline);
86
- break;
87
-
88
- case E_USER_NOTICE || E_NOTICE:
89
- //onesignal_debug('NOTICE: ' . $errstr . ' @ ' . $errfile . ':' . $errline);
90
- break;
91
-
92
- case E_STRICT:
93
- //onesignal_debug('DEPRECATED: ' . $errstr . ' @ ' . $errfile . ':' . $errline);
94
- break;
95
-
96
- default:
97
- onesignal_debug('[UNKNOWN ERROR]', '(' . $errno . '): ' . $errstr . ' @ ' . $errfile . ':' . $errline);
98
- break;
99
- }
100
-
101
- return true;
102
- } catch (Exception $ex) {
103
- return true;
104
- }
105
- }
106
-
107
- set_error_handler("exception_error_handler");
108
-
109
- function fatal_exception_error_handler() {
110
- $error = error_get_last();
111
- try {
112
- switch ($error['type']) {
113
- case E_ERROR:
114
- case E_CORE_ERROR:
115
- case E_COMPILE_ERROR:
116
- case E_USER_ERROR:
117
- case E_RECOVERABLE_ERROR:
118
- case E_CORE_WARNING:
119
- case E_COMPILE_WARNING:
120
- case E_PARSE:
121
- onesignal_debug('[CRITICAL ERROR]', '(' . $error['type'] . ') ' . $error['message'] . ' @ ' . $error['file'] . ':' . $error['line']);
122
- }
123
- } catch (Exception $ex) {
124
- return true;
125
- }
126
- }
127
-
128
- register_shutdown_function('fatal_exception_error_handler');
129
- }
130
-
131
- if (OneSignalUtils::can_modify_plugin_settings()) {
132
- add_action( 'admin_menu', array(__CLASS__, 'add_admin_page') );
133
- }
134
- if (OneSignalUtils::can_send_notifications()) {
135
- add_action('admin_init', array( __CLASS__, 'add_onesignal_post_options' ));
136
  }
137
 
138
- add_action( 'save_post', array(__CLASS__, 'on_save_post'), 1, 3 );
139
- add_action( 'transition_post_status', array( __CLASS__, 'on_transition_post_status' ), 10, 3 );
140
- add_action( 'admin_enqueue_scripts', array( __CLASS__, 'admin_styles' ) );
141
- return $onesignal;
142
- }
143
-
144
- public static function admin_styles() {
145
- wp_enqueue_style( 'onesignal-admin-styles', plugin_dir_url( __FILE__ ) . 'views/css/onesignal-menu-styles.css', false, OneSignal_Admin::$RESOURCES_VERSION);
146
- }
147
-
148
- /**
149
- * Save the meta when the post is saved.
150
- * @param int $post_id The ID of the post being saved.
151
- */
152
- public static function on_save_post($post_id, $post, $updated) {
153
- if ($post->post_type == 'wdslp-wds-log') {
154
- // Prevent recursive post logging
155
- return;
156
- }
157
- /*
158
- * We need to verify this came from the our screen and with proper authorization,
159
- * because save_post can be triggered at other times.
160
- */
161
- // Check if our nonce is set.
162
- if (!isset( $_POST[OneSignal_Admin::$SAVE_POST_NONCE_KEY] ) ) {
163
- // This is called on every new post ... not necessary to log it.
164
- // onesignal_debug('Nonce is not set for post ' . $post->post_title . ' (ID ' . $post_id . ')');
165
- return $post_id;
166
  }
167
 
168
- $nonce = $_POST[OneSignal_Admin::$SAVE_POST_NONCE_KEY];
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
169
 
170
- // Verify that the nonce is valid.
171
- if (!wp_verify_nonce($nonce, OneSignal_Admin::$SAVE_POST_NONCE_ACTION)) {
172
- onesignal_debug('Nonce is not valid for ' . $post->post_title . ' (ID ' . $post_id . ')');
173
- return $post_id;
174
  }
175
 
176
- /*
177
- * If this is an autosave, our form has not been submitted,
178
- * so we don't want to do anything.
179
- */
180
- if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
181
- return $post_id;
182
  }
183
 
184
- /* OK, it's safe for us to save the data now. */
185
-
186
- /* Some WordPress environments seem to be inconsistent about whether on_save_post is called before transition_post_status
187
- * Check flag in case we just sent a notification for this post (this on_save_post is called after a successful send)
188
- */
189
- $just_sent_notification = (get_post_meta($post_id, 'onesignal_notification_already_sent', true) == true);
190
-
191
- if ($just_sent_notification) {
192
- // Reset our flag
193
- update_post_meta($post_id, 'onesignal_notification_already_sent', false);
194
- onesignal_debug('A notification was just sent, so ignoring on_save_post. Resetting check flag.');
195
- return;
196
- }
197
-
198
- if (array_key_exists('onesignal_meta_box_present', $_POST)) {
199
- update_post_meta($post_id, 'onesignal_meta_box_present', true);
200
- onesignal_debug('Set post metadata "onesignal_meta_box_present" to true.');
201
- } else {
202
- update_post_meta($post_id, 'onesignal_meta_box_present', false);
203
- onesignal_debug('Set post metadata "onesignal_meta_box_present" to false.');
204
- }
205
-
206
- /* Even though the meta box always contains the checkbox, if an HTML checkbox is not checked, it is not POSTed to the server */
207
- if (array_key_exists('send_onesignal_notification', $_POST)) {
208
- update_post_meta($post_id, 'onesignal_send_notification', true);
209
- onesignal_debug('Set post metadata "onesignal_send_notification" to true.');
210
- } else {
211
- update_post_meta($post_id, 'onesignal_send_notification', false);
212
- onesignal_debug('Set post metadata "onesignal_send_notification" to false.');
213
- }
214
- }
215
-
216
- public static function add_onesignal_post_options() {
217
- // If there is an error or success message we should display, display it now
218
- function admin_notice_error() {
219
- $onesignal_transient_error = get_transient('onesignal_transient_error');
220
- if ( !empty($onesignal_transient_error) ) {
221
- delete_transient( 'onesignal_transient_error' );
222
- echo $onesignal_transient_error;
223
- }
224
-
225
- $onesignal_transient_success = get_transient('onesignal_transient_success');
226
- if ( !empty($onesignal_transient_success) ) {
227
- delete_transient( 'onesignal_transient_success' );
228
- echo $onesignal_transient_success;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
229
  }
230
  }
231
- add_action( 'admin_notices', 'admin_notice_error');
232
 
233
- // Add our meta box for the "post" post type (default)
234
- add_meta_box('onesignal_notif_on_post',
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
235
  'OneSignal Push Notifications',
236
- array( __CLASS__, 'onesignal_notif_on_post_html_view' ),
237
  'post',
238
  'side',
239
  'high');
240
 
241
- // Then add our meta box for all other post types that are public but not built in to WordPress
242
- $args = array(
243
- 'public' => true,
244
- '_builtin' => false
245
  );
246
- $output = 'names';
247
- $operator = 'and';
248
- $post_types = get_post_types( $args, $output, $operator );
249
- foreach ( $post_types as $post_type ) {
250
- add_meta_box(
251
  'onesignal_notif_on_post',
252
  'OneSignal Push Notifications',
253
- array( __CLASS__, 'onesignal_notif_on_post_html_view' ),
254
  $post_type,
255
  'side',
256
  'high'
257
  );
 
258
  }
259
- }
260
-
261
 
262
- /**
263
- * Render Meta Box content.
264
- * @param WP_Post $post The post object.
265
- */
266
- public static function onesignal_notif_on_post_html_view($post) {
267
- $post_type = $post->post_type;
268
- $onesignal_wp_settings = OneSignal::get_onesignal_settings();
 
 
269
 
270
- // Add an nonce field so we can check for it later.
271
- wp_nonce_field(OneSignal_Admin::$SAVE_POST_NONCE_ACTION, OneSignal_Admin::$SAVE_POST_NONCE_KEY, true);
272
 
273
- // Our plugin config setting "Automatically send a push notification when I publish a post from the WordPress editor"
274
- $settings_send_notification_on_wp_editor_post = $onesignal_wp_settings['notification_on_post'];
275
 
276
- /* This is a scheduled post and the user checked "Send a notification on post publish/update". */
277
- $post_metadata_was_send_notification_checked = (get_post_meta($post->ID, 'onesignal_send_notification', true) == true);
278
 
279
- // We check the checkbox if: setting is enabled on Config page, post type is ONLY "post", and the post has not been published (new posts are status "auto-draft")
280
  $meta_box_checkbox_send_notification = ($settings_send_notification_on_wp_editor_post && // If setting is enabled
281
- $post->post_type == "post" && // Post type must be type post for checkbox to be auto-checked
282
- in_array($post->post_status, array("future", "draft", "auto-draft", "pending"))) || // Post is scheduled, incomplete, being edited, or is awaiting publication
283
  ($post_metadata_was_send_notification_checked);
284
 
285
- if (has_filter('onesignal_meta_box_send_notification_checkbox_state')) {
286
- $meta_box_checkbox_send_notification = apply_filters('onesignal_meta_box_send_notification_checkbox_state', $post, $onesignal_wp_settings);
287
- }
288
- onesignal_debug('$meta_box_checkbox_send_notification:', $meta_box_checkbox_send_notification);
289
- onesignal_debug(' [$meta_box_checkbox_send_notification]', 'has_filter(onesignal_meta_box_send_notification_checkbox_state):', has_filter('onesignal_meta_box_send_notification_checkbox_state'));
290
- onesignal_debug(' [$meta_box_checkbox_send_notification]', 'onesignal_meta_box_send_notification_checkbox_state filter result:', apply_filters('onesignal_meta_box_send_notification_checkbox_state', $post, $onesignal_wp_settings));
291
- onesignal_debug(' [$meta_box_checkbox_send_notification]', '$settings_send_notification_on_wp_editor_post:', $settings_send_notification_on_wp_editor_post);
292
- onesignal_debug(' [$meta_box_checkbox_send_notification]', '$settings_send_notification_on_wp_editor_post:', $settings_send_notification_on_wp_editor_post);
293
- onesignal_debug(' [$meta_box_checkbox_send_notification]', '$post->post_type == "post":', $post->post_type == "post", '(' . $post->post_type . ')');
294
- onesignal_debug(' [$meta_box_checkbox_send_notification]', 'in_array($post->post_status, array("future", "draft", "auto-draft", "pending"):', in_array($post->post_status, array("future", "draft", "auto-draft", "pending")), '(' . $post->post_status . ')');
295
-
296
- ?>
297
 
298
  <input type="hidden" name="onesignal_meta_box_present" value="true"></input>
299
- <input type="checkbox" name="send_onesignal_notification" value="true" <?php if ($meta_box_checkbox_send_notification) { echo "checked"; } ?>></input>
 
 
300
  <label>
301
- <?php if ($post->post_status == "publish") {
302
- echo "Send notification on " . $post_type . " update";
303
  } else {
304
- echo "Send notification on " . $post_type . " publish";
305
  } ?>
306
  </label>
307
  <?php
308
- }
309
 
310
- public static function save_config_page($config) {
311
- if (!OneSignalUtils::can_modify_plugin_settings()) {
312
- onesignal_debug('Not saving plugin settings because the current user is not an administrator.');
313
- set_transient( 'onesignal_transient_error', '<div class="error notice onesignal-error-notice">
 
314
  <p><strong>OneSignal Push:</strong><em> Only administrators are allowed to save plugin settings.</em></p>
315
- </div>', 86400 );
316
- return;
317
- }
318
 
319
- $sdk_dir = plugin_dir_path( __FILE__ ) . 'sdk_files/';
320
- $onesignal_wp_settings = OneSignal::get_onesignal_settings();
321
- $new_app_id = $config['app_id'];
322
 
323
- // Validate the UUID
324
- if( preg_match('/([a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12})/', $new_app_id, $m))
325
- $onesignal_wp_settings['app_id'] = trim($new_app_id);
326
 
327
- if (array_key_exists('gcm_sender_id', $config) && (is_numeric($config['gcm_sender_id']) || $config['gcm_sender_id'] === '')) {
328
- $onesignal_wp_settings['gcm_sender_id'] = trim($config['gcm_sender_id']);
329
- }
 
330
 
331
- if (array_key_exists('subdomain', $config)) {
332
- $onesignal_wp_settings['subdomain'] = str_replace(' ', '', $config['subdomain']);
333
- } else {
334
- $onesignal_wp_settings['subdomain'] = "";
335
- }
336
- $onesignal_wp_settings['subdomain'] = trim($onesignal_wp_settings['subdomain']);
 
 
 
 
337
 
338
- $onesignal_wp_settings['is_site_https_firsttime'] = 'set';
339
 
340
- $booleanSettings = array(
341
  'is_site_https',
342
  'prompt_auto_register',
343
  'use_modal_prompt',
@@ -362,11 +381,11 @@ class OneSignal_Admin {
362
  'show_notification_send_status_message',
363
  'use_http_permission_request',
364
  'customize_http_permission_request',
365
- 'use_slidedown_permission_message_for_https'
366
  );
367
- OneSignal_Admin::saveBooleanSettings($onesignal_wp_settings, $config, $booleanSettings);
368
 
369
- $stringSettings = array(
370
  'app_rest_api_key',
371
  'safari_web_id',
372
  'prompt_action_message',
@@ -417,70 +436,78 @@ class OneSignal_Admin {
417
  'http_permission_request_modal_title',
418
  'http_permission_request_modal_message',
419
  'http_permission_request_modal_button_text',
420
- 'persist_notifications'
421
  );
422
- OneSignal_Admin::saveStringSettings($onesignal_wp_settings, $config, $stringSettings);
423
-
424
- OneSignal::save_onesignal_settings($onesignal_wp_settings);
425
- return $onesignal_wp_settings;
426
- }
427
-
428
- public static function saveBooleanSettings(&$onesignal_wp_settings, &$config, $settings) {
429
- foreach ($settings as $setting) {
430
- if (array_key_exists($setting, $config)) {
431
- $onesignal_wp_settings[$setting] = true;
432
- } else {
433
- $onesignal_wp_settings[$setting] = false;
434
- }
435
  }
436
- }
437
-
438
- public static function saveStringSettings(&$onesignal_wp_settings, &$config, $settings) {
439
- foreach ($settings as $setting) {
440
- if (array_key_exists($setting, $config)) {
441
- $value = $config[$setting];
442
- $value = OneSignalUtils::normalize($value);
443
- $onesignal_wp_settings[$setting] = $value;
444
- }
 
 
 
 
 
 
 
 
 
 
 
 
445
  }
446
- }
447
 
448
- public static function add_admin_page() {
449
- $OneSignal_menu = add_menu_page('OneSignal Push',
 
450
  'OneSignal Push',
451
  'manage_options',
452
  'onesignal-push',
453
  array(__CLASS__, 'admin_menu')
454
  );
455
 
456
- OneSignal_Admin::save_config_settings_form();
457
 
458
- add_action( 'load-' . $OneSignal_menu, array(__CLASS__, 'admin_custom_load') );
459
- }
460
 
461
- public static function save_config_settings_form() {
462
- // If the user is trying to save the form, require a valid nonce or die
463
- if (array_key_exists('app_id', $_POST)) {
464
- // check_admin_referer dies if not valid; no if statement necessary
465
- check_admin_referer(OneSignal_Admin::$SAVE_CONFIG_NONCE_ACTION, OneSignal_Admin::$SAVE_CONFIG_NONCE_KEY);
466
- $onesignal_wp_settings = OneSignal_Admin::save_config_page($_POST);
 
 
467
  }
468
- }
469
-
470
- public static function admin_menu() {
471
- require_once( plugin_dir_path( __FILE__ ) . '/views/config.php' );
472
- }
473
-
474
- public static function admin_custom_load() {
475
- add_action('admin_enqueue_scripts', array(__CLASS__, 'admin_custom_scripts'));
476
-
477
- $onesignal_wp_settings = OneSignal::get_onesignal_settings();
478
- if (
479
- $onesignal_wp_settings['app_id'] == '' ||
480
- $onesignal_wp_settings['app_rest_api_key'] == ''
481
- ) {
482
- function admin_notice_setup_not_complete() {
483
- ?>
 
 
484
  <script>
485
  document.addEventListener('DOMContentLoaded', function() {
486
  activateSetupTab('setup/0');
@@ -490,446 +517,513 @@ class OneSignal_Admin {
490
  <p><strong>OneSignal Push:</strong> <em>Your setup is not complete. Please follow the Setup guide to set up web push notifications. Both the App ID and REST API Key fields are required.</em></p>
491
  </div>
492
  <?php
493
- }
494
 
495
- add_action('admin_notices', 'admin_notice_setup_not_complete');
496
- }
497
 
498
- if (!function_exists('curl_init')) {
499
- function admin_notice_curl_not_installed() {
500
- ?>
 
501
  <div class="error notice onesignal-error-notice">
502
  <p><strong>OneSignal Push:</strong> <em>cURL is not installed on this server. cURL is required to send notifications. Please make sure cURL is installed on your server before continuing.</em></p>
503
  </div>
504
  <?php
505
- }
506
- add_action( 'admin_notices', 'admin_notice_curl_not_installed');
507
- }
508
- }
509
-
510
- public static function admin_custom_scripts() {
511
- add_filter('admin_footer_text', 'onesignal_change_footer_admin', 9999); // 9999 means priority, execute after the original fn executes
512
-
513
- wp_enqueue_style( 'icons', plugin_dir_url( __FILE__ ) . 'views/css/icons.css', false, OneSignal_Admin::$RESOURCES_VERSION);
514
- wp_enqueue_style( 'semantic-ui', plugin_dir_url( __FILE__ ) . 'views/css/semantic-ui.css', false, OneSignal_Admin::$RESOURCES_VERSION);
515
- wp_enqueue_style( 'site', plugin_dir_url( __FILE__ ) . 'views/css/site.css', false, OneSignal_Admin::$RESOURCES_VERSION);
516
-
517
- wp_enqueue_script( 'jquery.min', plugin_dir_url( __FILE__ ) . 'views/javascript/jquery.min.js', false, OneSignal_Admin::$RESOURCES_VERSION);
518
- wp_enqueue_script( 'semantic-ui', plugin_dir_url( __FILE__ ) . 'views/javascript/semantic-ui.js', false, OneSignal_Admin::$RESOURCES_VERSION);
519
- wp_enqueue_script( 'jquery.cookie', plugin_dir_url( __FILE__ ) . 'views/javascript/jquery.cookie.js', false, OneSignal_Admin::$RESOURCES_VERSION);
520
- wp_enqueue_script( 'site', plugin_dir_url( __FILE__ ) . 'views/javascript/site-admin.js', false, OneSignal_Admin::$RESOURCES_VERSION);
521
- }
522
-
523
- /**
524
- * Returns true if more than one notification has been sent in the last minute.
525
- */
526
- public static function get_sending_rate_limit_wait_time() {
527
- onesignal_debug('Called is_over_sending_rate_limit()');
528
- $last_send_time = get_option('onesignal.last_send_time');
529
- onesignal_debug(' [is_over_sending_rate_limit] Last send time:', $last_send_time);
530
- if ($last_send_time) {
531
- $time_elapsed_since_last_send = ONESIGNAL_API_RATE_LIMIT_SECONDS - (current_time('timestamp') - intval($last_send_time));
532
- if ($time_elapsed_since_last_send > 0) {
533
- onesignal_debug(' [is_over_sending_rate_limit] Current send time (' . current_time('timestamp') . ') is less than rate limit time after the last send time.');
534
- return $time_elapsed_since_last_send;
535
  }
536
  }
537
- return false;
538
- }
539
-
540
- /**
541
- * Updates the last sent timestamp, used in rate limiting notifications sent more than 1 per minute.
542
- */
543
- public static function update_last_sent_timestamp() {
544
- update_option('onesignal.last_send_time', current_time('timestamp'));
545
- }
546
-
547
-
548
- /**
549
- * hashes notification-title+timestamp and converts it into a uuid
550
- * meant to prevent duplicate notification issue started with wp5.0.0
551
- * @title - title of post
552
- * return - uuid of sha1 hash of post title + post timestamp
553
- */
554
- public static function uuid($title) {
555
- $now = explode(':', date("z:H:i"));
556
- $now_minutes = $now[0] * 60 * 24 + $now[1] * 60 + $now[2];
557
- $prev_minutes = get_option('TimeLastUpdated');
558
- $prehash = (string)$title;
559
-
560
- if ($prev_minutes !== false && ($now_minutes - $prev_minutes) > 2) {
561
- update_option('TimeLastUpdated', $now_minutes);
562
- $timestamp = $now_minutes;
563
- } else if ($prev_minutes == false) {
564
- add_option('TimeLastUpdated', $now_minutes);
565
- $timestamp = $now_minutes;
566
- } else {
567
- $timestamp = $prev_minutes;
568
- }
569
-
570
- $prehash = $prehash . $timestamp;
571
-
572
- $sha1 = substr(sha1($prehash), 0, 32);
573
- return substr($sha1, 0, 8) . '-' . substr($sha1, 8, 4) . '-' . substr($sha1, 12, 4) . '-' . substr($sha1, 16, 4) . '-' . substr($sha1, 20, 12);
574
- }
575
 
576
- /**
577
- * The main function that actually sends a notification to OneSignal.
578
- */
579
- public static function send_notification_on_wp_post($new_status, $old_status, $post) {
580
- try {
581
- if (!function_exists('curl_init')) {
582
- onesignal_debug('Canceling send_notification_on_wp_post because curl_init() is not a defined function.');
583
- return;
584
- }
585
-
586
- $time_to_wait = self::get_sending_rate_limit_wait_time();
587
- if ($time_to_wait > 0) {
588
- set_transient('onesignal_transient_error', '<div class="error notice onesignal-error-notice">
589
- <p><strong>OneSignal Push:</strong><em> Please try again in ' . $time_to_wait . ' seconds. Only one notification can be sent every ' . ONESIGNAL_API_RATE_LIMIT_SECONDS . ' seconds.</em></p>
590
- </div>', 86400);
591
- return;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
592
  }
593
 
594
- $onesignal_wp_settings = OneSignal::get_onesignal_settings();
595
 
596
- /* Looks like on_save_post is called after transition_post_status so we'll have to check POST data in addition to post meta data */
597
 
598
- /* Settings related to creating a post involving the WordPress editor displaying the OneSignal meta box
599
- **********************************************************************************************************/
600
 
601
- /* Returns true if there is POST data */
602
- $was_posted = !empty($_POST);
 
 
 
 
 
 
603
 
604
- /* When this post was created or updated, the OneSignal meta box in the WordPress post editor screen was visible */
605
- $onesignal_meta_box_present = $was_posted && array_key_exists('onesignal_meta_box_present', $_POST) && $_POST['onesignal_meta_box_present'] == 'true';
606
- /* The checkbox "Send notification on post publish/update" on the OneSignal meta box is checked */
607
- $onesignal_meta_box_send_notification_checked = $was_posted && array_key_exists('send_onesignal_notification', $_POST) && $_POST['send_onesignal_notification'] == 'true';
608
 
609
- /* This is a scheduled post and the OneSignal meta box was present. */
610
- $post_metadata_was_onesignal_meta_box_present = (get_post_meta($post->ID, 'onesignal_meta_box_present', true) == true);
611
- /* This is a scheduled post and the user checked "Send a notification on post publish/update". */
612
- $post_metadata_was_send_notification_checked = (get_post_meta($post->ID, 'onesignal_send_notification', true) == true);
 
 
 
 
613
 
614
- /* Either we were just posted from the WordPress post editor form, or this is a scheduled notification and it was previously submitted from the post editor form */
615
- $posted_from_wordpress_editor = $onesignal_meta_box_present || $post_metadata_was_onesignal_meta_box_present;
616
- /* ********************************************************************************************************* */
617
-
618
-
619
- /* Settings related to creating a post outside of the WordPress editor NOT displaying the OneSignal meta box
620
- ************************************************************************************************************/
621
-
622
- /* OneSignal plugin setting "Automatically send a push notification when I create a post from 3rd party plugins"
623
- * If set to true, send only if *publishing* a post type *post* from *something other than the default WordPress editor*.
624
- * The filter hooks "onesignal_exclude_post" and "onesignal_include_post" can override this behavior as long as the option to automatically send from 3rd party plugins is set.
625
- */
626
- $settings_send_notification_on_non_editor_post_publish = $onesignal_wp_settings['notification_on_post_from_plugin'];
627
- $additional_custom_post_types_string = str_replace(' ', '', $onesignal_wp_settings['allowed_custom_post_types']);
628
- $additional_custom_post_types_array = array_filter(explode(',', $additional_custom_post_types_string));
629
- onesignal_debug('Additional allowed custom post types:', $additional_custom_post_types_string);
630
- $non_editor_post_publish_do_send_notification = $settings_send_notification_on_non_editor_post_publish &&
631
- ($post->post_type == "post" || in_array($post->post_type, $additional_custom_post_types_array)) &&
632
- $old_status !== "publish";
633
- /* ********************************************************************************************************* */
634
-
635
-
636
- if ($posted_from_wordpress_editor) {
637
- // Decide to send based on whether the checkbox "Send notification on post publish/update" is checked
638
- // This post may be scheduled or just submitted from the WordPress editor
639
- // Metadata may not be saved into post yet, so use $_POST form data if metadata not available
640
- $do_send_notification = ($was_posted && $onesignal_meta_box_send_notification_checked) ||
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
641
  (!$was_posted && $post_metadata_was_send_notification_checked);
642
- } else {
643
- // This was definitely not submitted via the WordPress editor
644
- // Decide to send based on whether the 3rd-party plugins setting is checked
645
- $do_send_notification = $non_editor_post_publish_do_send_notification;
646
- }
647
 
648
- if (has_filter('onesignal_include_post')) {
649
- if (apply_filters('onesignal_include_post', $new_status, $old_status, $post)) {
650
- onesignal_debug('Will actually send a notification for this post because the filter opted to include the post.');
651
- $do_send_notification = true;
 
652
  }
653
- }
654
 
655
- onesignal_debug('Post Status:', $old_status, '-->', $new_status);
656
- onesignal_debug_post($post);
657
- onesignal_debug('Has onesignal_include_post filter:', has_filter('onesignal_include_post'));
658
- onesignal_debug(' [onesignal_include_post Filter]', 'Filter Result:' , apply_filters('onesignal_include_post', $new_status, $old_status, $post));
659
- onesignal_debug('Has onesignal_exclude_post filter:', has_filter('onesignal_exclude_post'));
660
- onesignal_debug(' [onesignal_exclude_post Filter]', 'Filter Result:' , apply_filters('onesignal_exclude_post', $new_status, $old_status, $post));
661
- onesignal_debug('Posted from WordPress editor:', $posted_from_wordpress_editor);
662
- onesignal_debug(' [Posted from WordPress editor]', 'Just Posted Meta Box Present:', $onesignal_meta_box_present);
663
- onesignal_debug(' [Posted from WordPress editor]', 'Was Meta Box Ever Present:', $post_metadata_was_onesignal_meta_box_present);
664
- onesignal_debug('Editor Post Send:', $posted_from_wordpress_editor && $do_send_notification);
665
- onesignal_debug(' [Editor Post Send]', 'Meta Box Send Notification Just Checked:', $onesignal_meta_box_send_notification_checked);
666
- onesignal_debug(' [Editor Post Send]', 'Meta Box Send Notification Previously Checked:', $post_metadata_was_send_notification_checked);
667
- onesignal_debug('Non-Editor Post Send:', $non_editor_post_publish_do_send_notification);
668
- onesignal_debug(' [Non-Editor Post Send]', 'Auto Send Config Setting:', $settings_send_notification_on_non_editor_post_publish);
669
- onesignal_debug(' [Non-Editor Post Send]', 'Post Type:', ($post->post_type == "post" || in_array($post->post_type, $additional_custom_post_types_array)), '(' . $post->post_type . ')');
670
- onesignal_debug(' [Non-Editor Post Send]', 'Old Post Status:' , ($old_status !== "publish"), '(' . $old_status . ')');
671
- onesignal_debug('Actually Sending Notification:', $do_send_notification);
672
-
673
- if ($do_send_notification) {
674
-
675
- /* Now that all settings are retrieved, and we are actually sending the notification, reset the post's metadata
676
- * If this post is sent through a plugin in the future, existing metadata will interfere with the send condition logic
677
- * If this post is re-sent through the WordPress editor, the metadata will be added back automatically
678
- */
679
- update_post_meta($post->ID, 'onesignal_meta_box_present', false);
680
- update_post_meta($post->ID, 'onesignal_send_notification', false);
681
- onesignal_debug('Removed OneSignal metadata from post.');
682
-
683
- /* Some WordPress environments seem to be inconsistent about whether on_save_post is called before transition_post_status
684
- * This sets the metadata back to true, and will cause a post to be sent even if the checkbox is not checked the next time
685
- * We remove all related $_POST data to prevent this
686
- */
687
- if ($was_posted) {
688
- if (array_key_exists('onesignal_meta_box_present', $_POST)) {
689
- unset($_POST['onesignal_meta_box_present']);
690
- onesignal_debug('Unset $_POST[\'onesignal_meta_box_present\']');
691
- }
692
- if (array_key_exists('send_onesignal_notification', $_POST)) {
693
- unset($_POST['send_onesignal_notification']);
694
- onesignal_debug('Unset $_POST[\'send_onesignal_notification\']');
695
- }
696
- }
697
-
698
-
699
- $notif_content = OneSignalUtils::decode_entities(get_the_title($post->ID));
700
-
701
- $site_title = "";
702
- if ($onesignal_wp_settings['notification_title'] != "") {
703
- $site_title = OneSignalUtils::decode_entities($onesignal_wp_settings['notification_title']);
704
- } else {
705
- $site_title = OneSignalUtils::decode_entities(get_bloginfo('name'));
706
- }
707
-
708
- if (function_exists('qtrans_getLanguage')) {
709
- try {
710
- $qtransLang = qtrans_getLanguage();
711
- $site_title = qtrans_use($qtransLang, $site_title, false);
712
- $notif_content = qtrans_use($qtransLang, $notif_content, false);
713
- } catch (Exception $e) {
714
- onesignal_debug('Caught qTrans exception:', $e->getMessage());
715
- }
716
- }
717
-
718
- $fields = array(
719
- "external_id" => self::uuid($notif_content),
720
- "app_id" => $onesignal_wp_settings["app_id"],
721
- "headings" => array("en" => $site_title),
722
- "included_segments" => array("All"),
723
- "isAnyWeb" => true,
724
- "url" => get_permalink($post->ID),
725
- "contents" => array("en" => $notif_content)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
726
  );
727
 
728
- $send_to_mobile_platforms = $onesignal_wp_settings['send_to_mobile_platforms'];
729
- if ($send_to_mobile_platforms == true) {
730
- $fields["isIos"] = true;
731
- $fields["isAndroid"] = true;
732
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
733
 
734
- $config_utm_additional_url_params = $onesignal_wp_settings["utm_additional_url_params"];
735
- if (!empty($config_utm_additional_url_params)) {
736
- $fields["url"] .= '?' . $config_utm_additional_url_params;
737
- }
738
 
739
- if (has_post_thumbnail($post->ID)) {
740
- onesignal_debug('Post has featured image.');
 
 
741
 
742
- $post_thumbnail_id = get_post_thumbnail_id($post->ID);
743
- // Higher resolution (2x retina, + a little more) for the notification small icon
744
- $thumbnail_sized_images_array = wp_get_attachment_image_src($post_thumbnail_id, array(192, 192), true);
745
- // Much higher resolution for the notification large image
746
- $large_sized_images_array = wp_get_attachment_image_src($post_thumbnail_id, 'large', true);
747
 
748
- $config_use_featured_image_as_icon = $onesignal_wp_settings['showNotificationIconFromPostThumbnail'] == "1";
749
- onesignal_debug('Post should use featured image for notification icon (small):', $config_use_featured_image_as_icon);
750
- $config_use_featured_image_as_image = $onesignal_wp_settings['showNotificationImageFromPostThumbnail'] == "1";
751
- onesignal_debug('Post should use featured image for notification image (large):', $config_use_featured_image_as_image);
752
 
753
- // get the icon image from wordpress if it exists
754
- if ($config_use_featured_image_as_icon) {
755
- onesignal_debug('Featured post image thumbnail-sized array:', $thumbnail_sized_images_array);
756
- $thumbnail_image = $thumbnail_sized_images_array[0];
757
- // set the icon image for both chrome and firefox-1
758
- $fields['chrome_web_icon'] = $thumbnail_image;
759
- $fields['firefox_icon'] = $thumbnail_image;
760
- onesignal_debug('Setting Chrome and Firefox notification icon to:', $thumbnail_image);
761
- }
762
- if ($config_use_featured_image_as_image) {
763
- onesignal_debug('Featured post image large-sized array:', $large_sized_images_array);
764
- $large_image = $large_sized_images_array[0];
765
- $fields['chrome_web_image'] = $large_image;
766
- onesignal_debug('Setting Chrome notification large image to:', $large_image);
767
- }
768
- }
769
 
770
- if (has_filter('onesignal_send_notification')) {
771
- onesignal_debug('Applying onesignal_send_notification filter.');
772
- $fields = apply_filters('onesignal_send_notification', $fields, $new_status, $old_status, $post);
773
- onesignal_debug('onesignal_send_notification filter $fields result:', $fields);
774
 
775
- // If the filter adds "do_send_notification: false", do not send a notification
776
- if (array_key_exists('do_send_notification', $fields) && $fields['do_send_notification'] == false) {
777
- return;
778
- }
779
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
780
 
781
- if (defined('ONESIGNAL_DEBUG') || class_exists('WDS_Log_Post')) {
782
- // http://blog.kettle.io/debugging-curl-requests-in-php/
783
- ob_start();
784
- $out = fopen('php://output', 'w');
785
- }
786
 
787
- $onesignal_post_url = "https://onesignal.com/api/v1/notifications";
788
 
789
- if (defined('ONESIGNAL_DEBUG') && defined('ONESIGNAL_LOCAL')) {
790
- $onesignal_post_url = "https://localhost:3001/api/v1/notifications";
 
 
791
  }
 
792
 
 
 
 
 
 
 
 
 
 
 
 
793
  $onesignal_auth_key = $onesignal_wp_settings['app_rest_api_key'];
794
 
 
 
 
 
 
 
 
 
795
 
796
- $request = array(
797
- "headers" => array(
798
- "content-type" => "application/json;charset=utf-8",
799
- "Authorization" => "Basic " . $onesignal_auth_key
800
- ),
801
- "body" => json_encode($fields),
802
- "timeout" => 60
803
- );
804
-
805
- $response = wp_remote_post($onesignal_post_url, $request);
806
-
807
- if ( is_wp_error($response) || !is_array( $response ) || !isset( $response['body']) ) {
808
- $status = $response->get_error_code(); // custom code for WP_ERROR
809
- $error_message = $response->get_error_message();
810
- error_log("There was a ".$status." error returned from OneSignal: ".$error_message);
811
- update_post_meta($post->ID, "error_message", $error_message);
812
- return;
813
- }
814
-
815
- if ( isset( $response['body'] ) ) {
816
- $response_body = json_decode($response["body"], true);
817
- }
818
-
819
- if ( isset( $response_body["errors"] ) ) {
820
- update_post_meta($post->ID, "error_message", $response_body["errors"][0]);
821
- }
822
 
823
- if ( isset( $response['response'] ) ) {
824
- $status = $response['response']['code'];
825
- }
 
826
 
827
- if ($response_body['recipients'] == "0") {
828
- update_post_meta($post->ID, "error_message", json_encode($response_body));
829
  }
830
 
831
- update_post_meta($post->ID, "status", $status);
832
-
833
- if ($status != 200) {
834
- error_log("There was a ".$status." error sending your notification.");
835
- error_log("Response from OneSignal:", json_encode($response));
836
- if ($status != 0) {
837
- set_transient( 'onesignal_transient_error', '<div class="error notice onesignal-error-notice">
838
- <p><strong>OneSignal Push:</strong><em> There was a ' . $status . ' error sending your notification.</em></p>
839
- </div>', 86400 );
840
- } else {
841
- // A 0 HTTP status code means the connection couldn't be established
842
- set_transient( 'onesignal_transient_error', '<div class="error notice onesignal-error-notice">
843
- <p><strong>OneSignal Push:</strong><em> There was an error establishing a network connection. Please make sure outgoing network connections from cURL are allowed.</em></p>
844
- </div>', 86400 );
845
- }
846
- } else {
847
- if (!empty($response)) {
848
- onesignal_debug('OneSignal API Raw Response:', $response);
849
-
850
- // API can send a 200 OK even if the notification failed to send
851
- if ( isset( $response["body"]) ) {
852
- $response_body = json_decode($response["body"], true);
853
- if ( isset ( $response_body["recipients"] ) ) {
854
- $recipient_count = $response_body["recipients"];
855
- } else {
856
- error_log("OneSignal: recipients not set in response body");
857
- }
858
- } else {
859
- error_log("OneSignal: body not set in HTTP response");
860
- }
861
-
862
- // updates meta so that recipient count is available for GET request from client
863
- update_post_meta($post->ID, "recipients", $recipient_count);
864
-
865
- $sent_or_scheduled = array_key_exists('send_after', $fields) ? 'scheduled' : 'sent';
866
- $config_show_notification_send_status_message = $onesignal_wp_settings['show_notification_send_status_message'] == "1";
867
-
868
- if ($config_show_notification_send_status_message) {
869
- if ($recipient_count != 0) {
870
- set_transient('onesignal_transient_success', '<div class="components-notice is-success is-dismissible">
871
- <div class="components-notice__content">
872
- <p><strong>OneSignal Push:</strong><em> Successfully ' . $sent_or_scheduled . ' a notification to ' . $recipient_count . ' recipients.</em></p>
873
- </div>
874
- </div>', 86400);
875
- } else {
876
- set_transient('onesignal_transient_success', '<div class="updated notice notice-success is-dismissible">
877
- <p><strong>OneSignal Push:</strong><em>There were no recipients. You either 1) have no subscribers yet or 2) you hit the rate-limit. Please try again in an hour.</em></p>
878
- </div>', 86400);
879
- }
880
- }
881
- }
882
  }
883
 
884
- if (defined('ONESIGNAL_DEBUG') || class_exists('WDS_Log_Post')) {
885
- fclose($out);
886
- $debug_output = ob_get_clean();
887
 
 
888
  }
889
 
890
- self::update_last_sent_timestamp();
 
 
 
 
 
891
 
892
- return $response;
893
- }
894
- }
895
- catch (Exception $e) {
896
- onesignal_debug('Caught Exception:', $e->getMessage());
897
- }
898
- }
899
 
900
- public static function was_post_restored_from_trash($old_status, $new_status) {
901
- return $old_status === 'trash' && $new_status === 'publish';
902
- }
 
 
903
 
904
- public static function on_transition_post_status( $new_status, $old_status, $post ) {
905
- if ($post->post_type == 'wdslp-wds-log' ||
906
- self::was_post_restored_from_trash($old_status, $new_status)) {
907
- // It's important not to call onesignal_debug() on posts of type wdslp-wds-log, otherwise each post will recursively generate 4 more posts
908
- return;
909
- }
910
- if (has_filter('onesignal_include_post')) {
911
- onesignal_debug('Applying onesignal_include_post filter.');
912
- if (apply_filters('onesignal_include_post', $new_status, $old_status, $post)) {
913
- // If the filter returns "$do_include_post: true", always process this post
914
- onesignal_debug('Processing post because the filter opted to include the post.');
915
- self::send_notification_on_wp_post($new_status, $old_status, $post);
916
- return;
917
- }
918
- }
919
- if (has_filter('onesignal_exclude_post')) {
920
- onesignal_debug('Applying onesignal_exclude_post filter.');
921
- if (apply_filters('onesignal_exclude_post', $new_status, $old_status, $post)) {
922
- // If the filter returns "$do_exclude_post: false", do not process this post at all
923
- onesignal_debug('Not processing post because the filter opted to exclude the post.');
924
- return;
925
- }
926
- }
927
- if (!(empty($post) ||
928
- $new_status !== "publish" ||
929
  $post->post_type == 'page')) {
930
- self::send_notification_on_wp_post($new_status, $old_status, $post);
 
931
  }
932
- }
933
  }
934
 
935
- ?>
1
  <?php
2
 
3
+ defined('ABSPATH') or die('This page may not be accessed directly.');
4
 
5
+ function onesignal_change_footer_admin()
6
+ {
7
+ return '';
8
  }
9
  /*
10
  * Loads js script that includes ajax call with post id
11
  */
12
 
13
  add_action('admin_enqueue_scripts', 'load_javascript');
14
+ function load_javascript()
15
+ {
16
+ global $post;
17
+ if ($post) {
18
  wp_register_script('notice_script', plugins_url('notice.js', __FILE__), array('jquery'), '1.1', true);
19
  wp_enqueue_script('notice_script');
20
+ wp_localize_script('notice_script', 'ajax_object', array('ajax_url' => admin_url('admin-ajax.php'), 'post_id' => $post->ID));
21
  }
22
  }
23
 
24
+ add_action('wp_ajax_has_metadata', 'has_metadata');
25
+ function has_metadata()
26
+ {
27
+ $post_id = $_GET['post_id'];
28
+
29
+ if (is_null($post_id)) {
30
+ error_log('OneSignal: could not get post_id');
31
+ $data = array('error' => 'could not get post id');
32
+ } else {
33
+ $recipients = get_post_meta($post_id, 'recipients');
34
+ if ($recipients && is_array($recipients)) {
35
+ $recipients = $recipients[0];
36
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
37
 
38
+ $status = get_post_meta($post_id, 'status');
39
+ if ($status && is_array($status)) {
40
+ $status = $status[0];
41
+ }
42
 
43
+ $response_body = get_post_meta($post_id, 'response_body');
44
+ if ($response_body && is_array($response_body)) {
45
+ $response_body = $response_body[0];
46
+ }
47
 
48
+ // reset meta
49
+ delete_post_meta($post_id, 'status');
50
+ delete_post_meta($post_id, 'recipients');
51
+ delete_post_meta($post_id, 'response_body');
52
 
53
+ $data = array('recipients' => $recipients, 'status_code' => $status, 'response_body' => $response_body);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
54
  }
55
 
56
+ echo json_encode($data);
57
+
58
+ exit;
59
+ }
60
+
61
+ class OneSignal_Admin
62
+ {
63
+ /**
64
+ * Increment $RESOURCES_VERSION any time the CSS or JavaScript changes to view the latest changes.
65
+ */
66
+ private static $RESOURCES_VERSION = '42';
67
+ private static $SAVE_POST_NONCE_KEY = 'onesignal_meta_box_nonce';
68
+ private static $SAVE_POST_NONCE_ACTION = 'onesignal_meta_box';
69
+ public static $SAVE_CONFIG_NONCE_KEY = 'onesignal_config_page_nonce';
70
+ public static $SAVE_CONFIG_NONCE_ACTION = 'onesignal_config_page';
71
+
72
+ public function __construct()
73
+ {
 
 
 
 
 
 
 
 
 
 
74
  }
75
 
76
+ public static function init()
77
+ {
78
+ $onesignal = new self();
79
+
80
+ if (class_exists('WDS_Log_Post')) {
81
+ function exception_error_handler($errno, $errstr, $errfile, $errline)
82
+ {
83
+ try {
84
+ switch ($errno) {
85
+ case E_USER_ERROR:
86
+ onesignal_debug('[ERROR]', $errstr.' @ '.$errfile.':'.$errline);
87
+ exit(1);
88
+ break;
89
+
90
+ case E_USER_WARNING:
91
+ onesignal_debug('[WARNING]', $errstr.' @ '.$errfile.':'.$errline);
92
+ break;
93
+
94
+ case E_USER_NOTICE || E_NOTICE:
95
+ //onesignal_debug('NOTICE: ' . $errstr . ' @ ' . $errfile . ':' . $errline);
96
+ break;
97
+
98
+ case E_STRICT:
99
+ //onesignal_debug('DEPRECATED: ' . $errstr . ' @ ' . $errfile . ':' . $errline);
100
+ break;
101
+
102
+ default:
103
+ onesignal_debug('[UNKNOWN ERROR]', '('.$errno.'): '.$errstr.' @ '.$errfile.':'.$errline);
104
+ break;
105
+ }
106
+
107
+ return true;
108
+ } catch (Exception $ex) {
109
+ return true;
110
+ }
111
+ }
112
+
113
+ set_error_handler('exception_error_handler');
114
+
115
+ function fatal_exception_error_handler()
116
+ {
117
+ $error = error_get_last();
118
+ try {
119
+ switch ($error['type']) {
120
+ case E_ERROR:
121
+ case E_CORE_ERROR:
122
+ case E_COMPILE_ERROR:
123
+ case E_USER_ERROR:
124
+ case E_RECOVERABLE_ERROR:
125
+ case E_CORE_WARNING:
126
+ case E_COMPILE_WARNING:
127
+ case E_PARSE:
128
+ onesignal_debug('[CRITICAL ERROR]', '('.$error['type'].') '.$error['message'].' @ '.$error['file'].':'.$error['line']);
129
+ }
130
+ } catch (Exception $ex) {
131
+ return true;
132
+ }
133
+ }
134
+
135
+ register_shutdown_function('fatal_exception_error_handler');
136
+ }
137
+
138
+ if (OneSignalUtils::can_modify_plugin_settings()) {
139
+ add_action('admin_menu', array(__CLASS__, 'add_admin_page'));
140
+ }
141
+ if (OneSignalUtils::can_send_notifications()) {
142
+ add_action('admin_init', array(__CLASS__, 'add_onesignal_post_options'));
143
+ }
144
+
145
+ add_action('save_post', array(__CLASS__, 'on_save_post'), 1, 3);
146
+ add_action('transition_post_status', array(__CLASS__, 'on_transition_post_status'), 10, 3);
147
+ add_action('admin_enqueue_scripts', array(__CLASS__, 'admin_styles'));
148
 
149
+ return $onesignal;
 
 
 
150
  }
151
 
152
+ public static function admin_styles()
153
+ {
154
+ wp_enqueue_style('onesignal-admin-styles', plugin_dir_url(__FILE__).'views/css/onesignal-menu-styles.css', false, OneSignal_Admin::$RESOURCES_VERSION);
 
 
 
155
  }
156
 
157
+ /**
158
+ * Save the meta when the post is saved.
159
+ *
160
+ * @param int $post_id the ID of the post being saved
161
+ */
162
+ public static function on_save_post($post_id, $post, $updated)
163
+ {
164
+ if ($post->post_type == 'wdslp-wds-log') {
165
+ // Prevent recursive post logging
166
+ return;
167
+ }
168
+ /*
169
+ * We need to verify this came from the our screen and with proper authorization,
170
+ * because save_post can be triggered at other times.
171
+ */
172
+ // Check if our nonce is set.
173
+ if (!isset($_POST[OneSignal_Admin::$SAVE_POST_NONCE_KEY])) {
174
+ // This is called on every new post ... not necessary to log it.
175
+ // onesignal_debug('Nonce is not set for post ' . $post->post_title . ' (ID ' . $post_id . ')');
176
+ return $post_id;
177
+ }
178
+
179
+ $nonce = $_POST[OneSignal_Admin::$SAVE_POST_NONCE_KEY];
180
+
181
+ // Verify that the nonce is valid.
182
+ if (!wp_verify_nonce($nonce, OneSignal_Admin::$SAVE_POST_NONCE_ACTION)) {
183
+ onesignal_debug('Nonce is not valid for '.$post->post_title.' (ID '.$post_id.')');
184
+
185
+ return $post_id;
186
+ }
187
+
188
+ /*
189
+ * If this is an autosave, our form has not been submitted,
190
+ * so we don't want to do anything.
191
+ */
192
+ if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
193
+ return $post_id;
194
+ }
195
+
196
+ /* OK, it's safe for us to save the data now. */
197
+
198
+ /* Some WordPress environments seem to be inconsistent about whether on_save_post is called before transition_post_status
199
+ * Check flag in case we just sent a notification for this post (this on_save_post is called after a successful send)
200
+ */
201
+ $just_sent_notification = (get_post_meta($post_id, 'onesignal_notification_already_sent', true) == true);
202
+
203
+ if ($just_sent_notification) {
204
+ // Reset our flag
205
+ update_post_meta($post_id, 'onesignal_notification_already_sent', false);
206
+ onesignal_debug('A notification was just sent, so ignoring on_save_post. Resetting check flag.');
207
+
208
+ return;
209
+ }
210
+
211
+ if (array_key_exists('onesignal_meta_box_present', $_POST)) {
212
+ update_post_meta($post_id, 'onesignal_meta_box_present', true);
213
+ onesignal_debug('Set post metadata "onesignal_meta_box_present" to true.');
214
+ } else {
215
+ update_post_meta($post_id, 'onesignal_meta_box_present', false);
216
+ onesignal_debug('Set post metadata "onesignal_meta_box_present" to false.');
217
+ }
218
+
219
+ /* Even though the meta box always contains the checkbox, if an HTML checkbox is not checked, it is not POSTed to the server */
220
+ if (array_key_exists('send_onesignal_notification', $_POST)) {
221
+ update_post_meta($post_id, 'onesignal_send_notification', true);
222
+ onesignal_debug('Set post metadata "onesignal_send_notification" to true.');
223
+ } else {
224
+ update_post_meta($post_id, 'onesignal_send_notification', false);
225
+ onesignal_debug('Set post metadata "onesignal_send_notification" to false.');
226
  }
227
  }
 
228
 
229
+ public static function add_onesignal_post_options()
230
+ {
231
+ // If there is an error or success message we should display, display it now
232
+ function admin_notice_error()
233
+ {
234
+ $onesignal_transient_error = get_transient('onesignal_transient_error');
235
+ if (!empty($onesignal_transient_error)) {
236
+ delete_transient('onesignal_transient_error');
237
+ echo $onesignal_transient_error;
238
+ }
239
+
240
+ $onesignal_transient_success = get_transient('onesignal_transient_success');
241
+ if (!empty($onesignal_transient_success)) {
242
+ delete_transient('onesignal_transient_success');
243
+ echo $onesignal_transient_success;
244
+ }
245
+ }
246
+ add_action('admin_notices', 'admin_notice_error');
247
+
248
+ // Add our meta box for the "post" post type (default)
249
+ add_meta_box('onesignal_notif_on_post',
250
  'OneSignal Push Notifications',
251
+ array(__CLASS__, 'onesignal_notif_on_post_html_view'),
252
  'post',
253
  'side',
254
  'high');
255
 
256
+ // Then add our meta box for all other post types that are public but not built in to WordPress
257
+ $args = array(
258
+ 'public' => true,
259
+ '_builtin' => false,
260
  );
261
+ $output = 'names';
262
+ $operator = 'and';
263
+ $post_types = get_post_types($args, $output, $operator);
264
+ foreach ($post_types as $post_type) {
265
+ add_meta_box(
266
  'onesignal_notif_on_post',
267
  'OneSignal Push Notifications',
268
+ array(__CLASS__, 'onesignal_notif_on_post_html_view'),
269
  $post_type,
270
  'side',
271
  'high'
272
  );
273
+ }
274
  }
 
 
275
 
276
+ /**
277
+ * Render Meta Box content.
278
+ *
279
+ * @param WP_Post $post the post object
280
+ */
281
+ public static function onesignal_notif_on_post_html_view($post)
282
+ {
283
+ $post_type = $post->post_type;
284
+ $onesignal_wp_settings = OneSignal::get_onesignal_settings();
285
 
286
+ // Add an nonce field so we can check for it later.
287
+ wp_nonce_field(OneSignal_Admin::$SAVE_POST_NONCE_ACTION, OneSignal_Admin::$SAVE_POST_NONCE_KEY, true);
288
 
289
+ // Our plugin config setting "Automatically send a push notification when I publish a post from the WordPress editor"
290
+ $settings_send_notification_on_wp_editor_post = $onesignal_wp_settings['notification_on_post'];
291
 
292
+ /* This is a scheduled post and the user checked "Send a notification on post publish/update". */
293
+ $post_metadata_was_send_notification_checked = (get_post_meta($post->ID, 'onesignal_send_notification', true) == true);
294
 
295
+ // We check the checkbox if: setting is enabled on Config page, post type is ONLY "post", and the post has not been published (new posts are status "auto-draft")
296
  $meta_box_checkbox_send_notification = ($settings_send_notification_on_wp_editor_post && // If setting is enabled
297
+ $post->post_type == 'post' && // Post type must be type post for checkbox to be auto-checked
298
+ in_array($post->post_status, array('future', 'draft', 'auto-draft', 'pending'))) || // Post is scheduled, incomplete, being edited, or is awaiting publication
299
  ($post_metadata_was_send_notification_checked);
300
 
301
+ if (has_filter('onesignal_meta_box_send_notification_checkbox_state')) {
302
+ $meta_box_checkbox_send_notification = apply_filters('onesignal_meta_box_send_notification_checkbox_state', $post, $onesignal_wp_settings);
303
+ }
304
+ onesignal_debug('$meta_box_checkbox_send_notification:', $meta_box_checkbox_send_notification);
305
+ onesignal_debug(' [$meta_box_checkbox_send_notification]', 'has_filter(onesignal_meta_box_send_notification_checkbox_state):', has_filter('onesignal_meta_box_send_notification_checkbox_state'));
306
+ onesignal_debug(' [$meta_box_checkbox_send_notification]', 'onesignal_meta_box_send_notification_checkbox_state filter result:', apply_filters('onesignal_meta_box_send_notification_checkbox_state', $post, $onesignal_wp_settings));
307
+ onesignal_debug(' [$meta_box_checkbox_send_notification]', '$settings_send_notification_on_wp_editor_post:', $settings_send_notification_on_wp_editor_post);
308
+ onesignal_debug(' [$meta_box_checkbox_send_notification]', '$settings_send_notification_on_wp_editor_post:', $settings_send_notification_on_wp_editor_post);
309
+ onesignal_debug(' [$meta_box_checkbox_send_notification]', '$post->post_type == "post":', $post->post_type == 'post', '('.$post->post_type.')');
310
+ onesignal_debug(' [$meta_box_checkbox_send_notification]', 'in_array($post->post_status, array("future", "draft", "auto-draft", "pending"):', in_array($post->post_status, array('future', 'draft', 'auto-draft', 'pending')), '('.$post->post_status.')'); ?>
 
 
311
 
312
  <input type="hidden" name="onesignal_meta_box_present" value="true"></input>
313
+ <input type="checkbox" name="send_onesignal_notification" value="true" <?php if ($meta_box_checkbox_send_notification) {
314
+ echo 'checked';
315
+ } ?>></input>
316
  <label>
317
+ <?php if ($post->post_status == 'publish') {
318
+ echo 'Send notification on '.$post_type.' update';
319
  } else {
320
+ echo 'Send notification on '.$post_type.' publish';
321
  } ?>
322
  </label>
323
  <?php
324
+ }
325
 
326
+ public static function save_config_page($config)
327
+ {
328
+ if (!OneSignalUtils::can_modify_plugin_settings()) {
329
+ onesignal_debug('Not saving plugin settings because the current user is not an administrator.');
330
+ set_transient('onesignal_transient_error', '<div class="error notice onesignal-error-notice">
331
  <p><strong>OneSignal Push:</strong><em> Only administrators are allowed to save plugin settings.</em></p>
332
+ </div>', 86400);
 
 
333
 
334
+ return;
335
+ }
 
336
 
337
+ $sdk_dir = plugin_dir_path(__FILE__).'sdk_files/';
338
+ $onesignal_wp_settings = OneSignal::get_onesignal_settings();
339
+ $new_app_id = $config['app_id'];
340
 
341
+ // Validate the UUID
342
+ if (preg_match('/([a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12})/', $new_app_id, $m)) {
343
+ $onesignal_wp_settings['app_id'] = trim($new_app_id);
344
+ }
345
 
346
+ if (array_key_exists('gcm_sender_id', $config) && (is_numeric($config['gcm_sender_id']) || $config['gcm_sender_id'] === '')) {
347
+ $onesignal_wp_settings['gcm_sender_id'] = trim($config['gcm_sender_id']);
348
+ }
349
+
350
+ if (array_key_exists('subdomain', $config)) {
351
+ $onesignal_wp_settings['subdomain'] = str_replace(' ', '', $config['subdomain']);
352
+ } else {
353
+ $onesignal_wp_settings['subdomain'] = '';
354
+ }
355
+ $onesignal_wp_settings['subdomain'] = trim($onesignal_wp_settings['subdomain']);
356
 
357
+ $onesignal_wp_settings['is_site_https_firsttime'] = 'set';
358
 
359
+ $booleanSettings = array(
360
  'is_site_https',
361
  'prompt_auto_register',
362
  'use_modal_prompt',
381
  'show_notification_send_status_message',
382
  'use_http_permission_request',
383
  'customize_http_permission_request',
384
+ 'use_slidedown_permission_message_for_https',
385
  );
386
+ OneSignal_Admin::saveBooleanSettings($onesignal_wp_settings, $config, $booleanSettings);
387
 
388
+ $stringSettings = array(
389
  'app_rest_api_key',
390
  'safari_web_id',
391
  'prompt_action_message',
436
  'http_permission_request_modal_title',
437
  'http_permission_request_modal_message',
438
  'http_permission_request_modal_button_text',
439
+ 'persist_notifications',
440
  );
441
+ OneSignal_Admin::saveStringSettings($onesignal_wp_settings, $config, $stringSettings);
442
+
443
+ OneSignal::save_onesignal_settings($onesignal_wp_settings);
444
+
445
+ return $onesignal_wp_settings;
 
 
 
 
 
 
 
 
446
  }
447
+
448
+ public static function saveBooleanSettings(&$onesignal_wp_settings, &$config, $settings)
449
+ {
450
+ foreach ($settings as $setting) {
451
+ if (array_key_exists($setting, $config)) {
452
+ $onesignal_wp_settings[$setting] = true;
453
+ } else {
454
+ $onesignal_wp_settings[$setting] = false;
455
+ }
456
+ }
457
+ }
458
+
459
+ public static function saveStringSettings(&$onesignal_wp_settings, &$config, $settings)
460
+ {
461
+ foreach ($settings as $setting) {
462
+ if (array_key_exists($setting, $config)) {
463
+ $value = $config[$setting];
464
+ $value = OneSignalUtils::normalize($value);
465
+ $onesignal_wp_settings[$setting] = $value;
466
+ }
467
+ }
468
  }
 
469
 
470
+ public static function add_admin_page()
471
+ {
472
+ $OneSignal_menu = add_menu_page('OneSignal Push',
473
  'OneSignal Push',
474
  'manage_options',
475
  'onesignal-push',
476
  array(__CLASS__, 'admin_menu')
477
  );
478
 
479
+ OneSignal_Admin::save_config_settings_form();
480
 
481
+ add_action('load-'.$OneSignal_menu, array(__CLASS__, 'admin_custom_load'));
482
+ }
483
 
484
+ public static function save_config_settings_form()
485
+ {
486
+ // If the user is trying to save the form, require a valid nonce or die
487
+ if (array_key_exists('app_id', $_POST)) {
488
+ // check_admin_referer dies if not valid; no if statement necessary
489
+ check_admin_referer(OneSignal_Admin::$SAVE_CONFIG_NONCE_ACTION, OneSignal_Admin::$SAVE_CONFIG_NONCE_KEY);
490
+ $onesignal_wp_settings = OneSignal_Admin::save_config_page($_POST);
491
+ }
492
  }
493
+
494
+ public static function admin_menu()
495
+ {
496
+ require_once plugin_dir_path(__FILE__).'/views/config.php';
497
+ }
498
+
499
+ public static function admin_custom_load()
500
+ {
501
+ add_action('admin_enqueue_scripts', array(__CLASS__, 'admin_custom_scripts'));
502
+
503
+ $onesignal_wp_settings = OneSignal::get_onesignal_settings();
504
+ if (
505
+ $onesignal_wp_settings['app_id'] == '' ||
506
+ $onesignal_wp_settings['app_rest_api_key'] == ''
507
+ ) {
508
+ function admin_notice_setup_not_complete()
509
+ {
510
+ ?>
511
  <script>
512
  document.addEventListener('DOMContentLoaded', function() {
513
  activateSetupTab('setup/0');
517
  <p><strong>OneSignal Push:</strong> <em>Your setup is not complete. Please follow the Setup guide to set up web push notifications. Both the App ID and REST API Key fields are required.</em></p>
518
  </div>
519
  <?php
520
+ }
521
 
522
+ add_action('admin_notices', 'admin_notice_setup_not_complete');
523
+ }
524
 
525
+ if (!function_exists('curl_init')) {
526
+ function admin_notice_curl_not_installed()
527
+ {
528
+ ?>
529
  <div class="error notice onesignal-error-notice">
530
  <p><strong>OneSignal Push:</strong> <em>cURL is not installed on this server. cURL is required to send notifications. Please make sure cURL is installed on your server before continuing.</em></p>
531
  </div>
532
  <?php
533
+ }
534
+ add_action('admin_notices', 'admin_notice_curl_not_installed');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
535
  }
536
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
537
 
538
+ public static function admin_custom_scripts()
539
+ {
540
+ add_filter('admin_footer_text', 'onesignal_change_footer_admin', 9999); // 9999 means priority, execute after the original fn executes
541
+
542
+ wp_enqueue_style('icons', plugin_dir_url(__FILE__).'views/css/icons.css', false, OneSignal_Admin::$RESOURCES_VERSION);
543
+ wp_enqueue_style('semantic-ui', plugin_dir_url(__FILE__).'views/css/semantic-ui.css', false, OneSignal_Admin::$RESOURCES_VERSION);
544
+ wp_enqueue_style('site', plugin_dir_url(__FILE__).'views/css/site.css', false, OneSignal_Admin::$RESOURCES_VERSION);
545
+
546
+ wp_enqueue_script('jquery.min', plugin_dir_url(__FILE__).'views/javascript/jquery.min.js', false, OneSignal_Admin::$RESOURCES_VERSION);
547
+ wp_enqueue_script('semantic-ui', plugin_dir_url(__FILE__).'views/javascript/semantic-ui.js', false, OneSignal_Admin::$RESOURCES_VERSION);
548
+ wp_enqueue_script('jquery.cookie', plugin_dir_url(__FILE__).'views/javascript/jquery.cookie.js', false, OneSignal_Admin::$RESOURCES_VERSION);
549
+ wp_enqueue_script('site', plugin_dir_url(__FILE__).'views/javascript/site-admin.js', false, OneSignal_Admin::$RESOURCES_VERSION);
550
+ }
551
+
552
+ /**
553
+ * Returns true if more than one notification has been sent in the last minute.
554
+ */
555
+ public static function get_sending_rate_limit_wait_time()
556
+ {
557
+ onesignal_debug('Called is_over_sending_rate_limit()');
558
+ $last_send_time = get_option('onesignal.last_send_time');
559
+ onesignal_debug(' [is_over_sending_rate_limit] Last send time:', $last_send_time);
560
+ if ($last_send_time) {
561
+ $time_elapsed_since_last_send = ONESIGNAL_API_RATE_LIMIT_SECONDS - (current_time('timestamp') - intval($last_send_time));
562
+ if ($time_elapsed_since_last_send > 0) {
563
+ onesignal_debug(' [is_over_sending_rate_limit] Current send time ('.current_time('timestamp').') is less than rate limit time after the last send time.');
564
+
565
+ return $time_elapsed_since_last_send;
566
+ }
567
+ }
568
+
569
+ return false;
570
+ }
571
+
572
+ /**
573
+ * Updates the last sent timestamp, used in rate limiting notifications sent more than 1 per minute.
574
+ */
575
+ public static function update_last_sent_timestamp()
576
+ {
577
+ update_option('onesignal.last_send_time', current_time('timestamp'));
578
+ }
579
+
580
+ /**
581
+ * hashes notification-title+timestamp and converts it into a uuid
582
+ * meant to prevent duplicate notification issue started with wp5.0.0.
583
+ *
584
+ * @title - title of post
585
+ * return - uuid of sha1 hash of post title + post timestamp
586
+ */
587
+ public static function uuid($title)
588
+ {
589
+ $now = explode(':', date('z:H:i'));
590
+ $now_minutes = $now[0] * 60 * 24 + $now[1] * 60 + $now[2];
591
+ $prev_minutes = get_option('TimeLastUpdated');
592
+ $prehash = (string) $title;
593
+
594
+ if ($prev_minutes !== false && ($now_minutes - $prev_minutes) > 0) {
595
+ update_option('TimeLastUpdated', $now_minutes);
596
+ $timestamp = $now_minutes;
597
+ } elseif ($prev_minutes == false) {
598
+ add_option('TimeLastUpdated', $now_minutes);
599
+ $timestamp = $now_minutes;
600
+ } else {
601
+ $timestamp = $prev_minutes;
602
  }
603
 
604
+ $prehash = $prehash.$timestamp;
605
 
606
+ $sha1 = substr(sha1($prehash), 0, 32);
607
 
608
+ return substr($sha1, 0, 8).'-'.substr($sha1, 8, 4).'-'.substr($sha1, 12, 4).'-'.substr($sha1, 16, 4).'-'.substr($sha1, 20, 12);
609
+ }
610
 
611
+ /**
612
+ * The main function that actually sends a notification to OneSignal.
613
+ */
614
+ public static function send_notification_on_wp_post($new_status, $old_status, $post)
615
+ {
616
+ try {
617
+ if (!function_exists('curl_init')) {
618
+ onesignal_debug('Canceling send_notification_on_wp_post because curl_init() is not a defined function.');
619
 
620
+ return;
621
+ }
 
 
622
 
623
+ $time_to_wait = self::get_sending_rate_limit_wait_time();
624
+ if ($time_to_wait > 0) {
625
+ set_transient('onesignal_transient_error', '<div class="error notice onesignal-error-notice">
626
+ <p><strong>OneSignal Push:</strong><em> Please try again in '.$time_to_wait.' seconds. Only one notification can be sent every '.ONESIGNAL_API_RATE_LIMIT_SECONDS.' seconds.</em></p>
627
+ </div>', 86400);
628
+
629
+ return;
630
+ }
631
 
632
+ $onesignal_wp_settings = OneSignal::get_onesignal_settings();
633
+
634
+ /* Looks like on_save_post is called after transition_post_status so we'll have to check POST data in addition to post meta data */
635
+
636
+ /* Settings related to creating a post involving the WordPress editor displaying the OneSignal meta box
637
+ **********************************************************************************************************/
638
+
639
+ /* Returns true if there is POST data */
640
+ $was_posted = !empty($_POST);
641
+
642
+ /* When this post was created or updated, the OneSignal meta box in the WordPress post editor screen was visible */
643
+ $onesignal_meta_box_present = $was_posted && array_key_exists('onesignal_meta_box_present', $_POST) && $_POST['onesignal_meta_box_present'] == 'true';
644
+ /* The checkbox "Send notification on post publish/update" on the OneSignal meta box is checked */
645
+ $onesignal_meta_box_send_notification_checked = $was_posted && array_key_exists('send_onesignal_notification', $_POST) && $_POST['send_onesignal_notification'] == 'true';
646
+
647
+ /* This is a scheduled post and the OneSignal meta box was present. */
648
+ $post_metadata_was_onesignal_meta_box_present = (get_post_meta($post->ID, 'onesignal_meta_box_present', true) == true);
649
+ /* This is a scheduled post and the user checked "Send a notification on post publish/update". */
650
+ $post_metadata_was_send_notification_checked = (get_post_meta($post->ID, 'onesignal_send_notification', true) == true);
651
+
652
+ /* Either we were just posted from the WordPress post editor form, or this is a scheduled notification and it was previously submitted from the post editor form */
653
+ $posted_from_wordpress_editor = $onesignal_meta_box_present || $post_metadata_was_onesignal_meta_box_present;
654
+ /* ********************************************************************************************************* */
655
+
656
+ /* Settings related to creating a post outside of the WordPress editor NOT displaying the OneSignal meta box
657
+ ************************************************************************************************************/
658
+
659
+ /* OneSignal plugin setting "Automatically send a push notification when I create a post from 3rd party plugins"
660
+ * If set to true, send only if *publishing* a post type *post* from *something other than the default WordPress editor*.
661
+ * The filter hooks "onesignal_exclude_post" and "onesignal_include_post" can override this behavior as long as the option to automatically send from 3rd party plugins is set.
662
+ */
663
+ $settings_send_notification_on_non_editor_post_publish = $onesignal_wp_settings['notification_on_post_from_plugin'];
664
+ $additional_custom_post_types_string = str_replace(' ', '', $onesignal_wp_settings['allowed_custom_post_types']);
665
+ $additional_custom_post_types_array = array_filter(explode(',', $additional_custom_post_types_string));
666
+ onesignal_debug('Additional allowed custom post types:', $additional_custom_post_types_string);
667
+ $non_editor_post_publish_do_send_notification = $settings_send_notification_on_non_editor_post_publish &&
668
+ ($post->post_type == 'post' || in_array($post->post_type, $additional_custom_post_types_array)) &&
669
+ $old_status !== 'publish';
670
+ /* ********************************************************************************************************* */
671
+
672
+ if ($posted_from_wordpress_editor) {
673
+ // Decide to send based on whether the checkbox "Send notification on post publish/update" is checked
674
+ // This post may be scheduled or just submitted from the WordPress editor
675
+ // Metadata may not be saved into post yet, so use $_POST form data if metadata not available
676
+ $do_send_notification = ($was_posted && $onesignal_meta_box_send_notification_checked) ||
677
  (!$was_posted && $post_metadata_was_send_notification_checked);
678
+ } else {
679
+ // This was definitely not submitted via the WordPress editor
680
+ // Decide to send based on whether the 3rd-party plugins setting is checked
681
+ $do_send_notification = $non_editor_post_publish_do_send_notification;
682
+ }
683
 
684
+ if (has_filter('onesignal_include_post')) {
685
+ if (apply_filters('onesignal_include_post', $new_status, $old_status, $post)) {
686
+ onesignal_debug('Will actually send a notification for this post because the filter opted to include the post.');
687
+ $do_send_notification = true;
688
+ }
689
  }
 
690
 
691
+ onesignal_debug('Post Status:', $old_status, '-->', $new_status);
692
+ onesignal_debug_post($post);
693
+ onesignal_debug('Has onesignal_include_post filter:', has_filter('onesignal_include_post'));
694
+ onesignal_debug(' [onesignal_include_post Filter]', 'Filter Result:', apply_filters('onesignal_include_post', $new_status, $old_status, $post));
695
+ onesignal_debug('Has onesignal_exclude_post filter:', has_filter('onesignal_exclude_post'));
696
+ onesignal_debug(' [onesignal_exclude_post Filter]', 'Filter Result:', apply_filters('onesignal_exclude_post', $new_status, $old_status, $post));
697
+ onesignal_debug('Posted from WordPress editor:', $posted_from_wordpress_editor);
698
+ onesignal_debug(' [Posted from WordPress editor]', 'Just Posted Meta Box Present:', $onesignal_meta_box_present);
699
+ onesignal_debug(' [Posted from WordPress editor]', 'Was Meta Box Ever Present:', $post_metadata_was_onesignal_meta_box_present);
700
+ onesignal_debug('Editor Post Send:', $posted_from_wordpress_editor && $do_send_notification);
701
+ onesignal_debug(' [Editor Post Send]', 'Meta Box Send Notification Just Checked:', $onesignal_meta_box_send_notification_checked);
702
+ onesignal_debug(' [Editor Post Send]', 'Meta Box Send Notification Previously Checked:', $post_metadata_was_send_notification_checked);
703
+ onesignal_debug('Non-Editor Post Send:', $non_editor_post_publish_do_send_notification);
704
+ onesignal_debug(' [Non-Editor Post Send]', 'Auto Send Config Setting:', $settings_send_notification_on_non_editor_post_publish);
705
+ onesignal_debug(' [Non-Editor Post Send]', 'Post Type:', ($post->post_type == 'post' || in_array($post->post_type, $additional_custom_post_types_array)), '('.$post->post_type.')');
706
+ onesignal_debug(' [Non-Editor Post Send]', 'Old Post Status:', ($old_status !== 'publish'), '('.$old_status.')');
707
+ onesignal_debug('Actually Sending Notification:', $do_send_notification);
708
+
709
+ if ($do_send_notification) {
710
+ /* Now that all settings are retrieved, and we are actually sending the notification, reset the post's metadata
711
+ * If this post is sent through a plugin in the future, existing metadata will interfere with the send condition logic
712
+ * If this post is re-sent through the WordPress editor, the metadata will be added back automatically
713
+ */
714
+ update_post_meta($post->ID, 'onesignal_meta_box_present', false);
715
+ update_post_meta($post->ID, 'onesignal_send_notification', false);
716
+ onesignal_debug('Removed OneSignal metadata from post.');
717
+
718
+ /* Some WordPress environments seem to be inconsistent about whether on_save_post is called before transition_post_status
719
+ * This sets the metadata back to true, and will cause a post to be sent even if the checkbox is not checked the next time
720
+ * We remove all related $_POST data to prevent this
721
+ */
722
+ if ($was_posted) {
723
+ if (array_key_exists('onesignal_meta_box_present', $_POST)) {
724
+ unset($_POST['onesignal_meta_box_present']);
725
+ onesignal_debug('Unset $_POST[\'onesignal_meta_box_present\']');
726
+ }
727
+ if (array_key_exists('send_onesignal_notification', $_POST)) {
728
+ unset($_POST['send_onesignal_notification']);
729
+ onesignal_debug('Unset $_POST[\'send_onesignal_notification\']');
730
+ }
731
+ }
732
+
733
+ $notif_content = OneSignalUtils::decode_entities(get_the_title($post->ID));
734
+
735
+ $site_title = '';
736
+ if ($onesignal_wp_settings['notification_title'] != '') {
737
+ $site_title = OneSignalUtils::decode_entities($onesignal_wp_settings['notification_title']);
738
+ } else {
739
+ $site_title = OneSignalUtils::decode_entities(get_bloginfo('name'));
740
+ }
741
+
742
+ if (function_exists('qtrans_getLanguage')) {
743
+ try {
744
+ $qtransLang = qtrans_getLanguage();
745
+ $site_title = qtrans_use($qtransLang, $site_title, false);
746
+ $notif_content = qtrans_use($qtransLang, $notif_content, false);
747
+ } catch (Exception $e) {
748
+ onesignal_debug('Caught qTrans exception:', $e->getMessage());
749
+ }
750
+ }
751
+
752
+ $post_time = get_post_time('D M d Y G:i:', true, $post);
753
+
754
+ if (!$post_time) {
755
+ error_log("OneSignal: Couldn't get post_time");
756
+
757
+ return;
758
+ } else {
759
+ $post_time = $post_time.'00 GMT-0:00';
760
+ }
761
+
762
+ $old_uuid_array = get_post_meta($post->ID, 'uuid');
763
+ $uuid = self::uuid($notif_content);
764
+ update_post_meta($post->ID, 'uuid', $uuid);
765
+
766
+ if ($new_status == 'future' && $old_uuid_array) {
767
+ if ($old_uuid_array[0] != $uuid) {
768
+ self::cancel_scheduled_notification($post);
769
+ }
770
+ }
771
+
772
+ $fields = array(
773
+ 'external_id' => $uuid,
774
+ 'app_id' => $onesignal_wp_settings['app_id'],
775
+ 'headings' => array('en' => $site_title),
776
+ 'included_segments' => array('All'),
777
+ 'isAnyWeb' => true,
778
+ 'url' => get_permalink($post->ID),
779
+ 'contents' => array('en' => $notif_content),
780
+ 'send_after' => $post_time,
781
  );
782
 
783
+ $send_to_mobile_platforms = $onesignal_wp_settings['send_to_mobile_platforms'];
784
+ if ($send_to_mobile_platforms == true) {
785
+ $fields['isIos'] = true;
786
+ $fields['isAndroid'] = true;
787
+ }
788
+
789
+ $config_utm_additional_url_params = $onesignal_wp_settings['utm_additional_url_params'];
790
+ if (!empty($config_utm_additional_url_params)) {
791
+ $fields['url'] .= '?'.$config_utm_additional_url_params;
792
+ }
793
+
794
+ if (has_post_thumbnail($post->ID)) {
795
+ onesignal_debug('Post has featured image.');
796
+
797
+ $post_thumbnail_id = get_post_thumbnail_id($post->ID);
798
+ // Higher resolution (2x retina, + a little more) for the notification small icon
799
+ $thumbnail_sized_images_array = wp_get_attachment_image_src($post_thumbnail_id, array(192, 192), true);
800
+ // Much higher resolution for the notification large image
801
+ $large_sized_images_array = wp_get_attachment_image_src($post_thumbnail_id, 'large', true);
802
+
803
+ $config_use_featured_image_as_icon = $onesignal_wp_settings['showNotificationIconFromPostThumbnail'] == '1';
804
+ onesignal_debug('Post should use featured image for notification icon (small):', $config_use_featured_image_as_icon);
805
+ $config_use_featured_image_as_image = $onesignal_wp_settings['showNotificationImageFromPostThumbnail'] == '1';
806
+ onesignal_debug('Post should use featured image for notification image (large):', $config_use_featured_image_as_image);
807
+
808
+ // get the icon image from wordpress if it exists
809
+ if ($config_use_featured_image_as_icon) {
810
+ onesignal_debug('Featured post image thumbnail-sized array:', $thumbnail_sized_images_array);
811
+ $thumbnail_image = $thumbnail_sized_images_array[0];
812
+ // set the icon image for both chrome and firefox-1
813
+ $fields['chrome_web_icon'] = $thumbnail_image;
814
+ $fields['firefox_icon'] = $thumbnail_image;
815
+ onesignal_debug('Setting Chrome and Firefox notification icon to:', $thumbnail_image);
816
+ }
817
+ if ($config_use_featured_image_as_image) {
818
+ onesignal_debug('Featured post image large-sized array:', $large_sized_images_array);
819
+ $large_image = $large_sized_images_array[0];
820
+ $fields['chrome_web_image'] = $large_image;
821
+ onesignal_debug('Setting Chrome notification large image to:', $large_image);
822
+ }
823
+ }
824
+
825
+ if (has_filter('onesignal_send_notification')) {
826
+ onesignal_debug('Applying onesignal_send_notification filter.');
827
+ $fields = apply_filters('onesignal_send_notification', $fields, $new_status, $old_status, $post);
828
+ onesignal_debug('onesignal_send_notification filter $fields result:', $fields);
829
+
830
+ // If the filter adds "do_send_notification: false", do not send a notification
831
+ if (array_key_exists('do_send_notification', $fields) && $fields['do_send_notification'] == false) {
832
+ return;
833
+ }
834
+ }
835
+
836
+ if (defined('ONESIGNAL_DEBUG') || class_exists('WDS_Log_Post')) {
837
+ // http://blog.kettle.io/debugging-curl-requests-in-php/
838
+ ob_start();
839
+ $out = fopen('php://output', 'w');
840
+ }
841
+
842
+ $onesignal_post_url = 'https://onesignal.com/api/v1/notifications';
843
+
844
+ if (defined('ONESIGNAL_DEBUG') && defined('ONESIGNAL_LOCAL')) {
845
+ $onesignal_post_url = 'https://localhost:3001/api/v1/notifications';
846
+ }
847
+
848
+ $onesignal_auth_key = $onesignal_wp_settings['app_rest_api_key'];
849
+
850
+ $request = array(
851
+ 'headers' => array(
852
+ 'content-type' => 'application/json;charset=utf-8',
853
+ 'Authorization' => 'Basic '.$onesignal_auth_key,
854
+ ),
855
+ 'body' => json_encode($fields),
856
+ 'timeout' => 60,
857
+ );
858
 
859
+ $response = wp_remote_post($onesignal_post_url, $request);
 
 
 
860
 
861
+ if (is_wp_error($response) || !is_array($response) || !isset($response['body'])) {
862
+ $status = $response->get_error_code(); // custom code for WP_ERROR
863
+ $error_message = $response->get_error_message();
864
+ error_log('There was a '.$status.' error returned from OneSignal: '.$error_message);
865
 
866
+ return;
867
+ }
 
 
 
868
 
869
+ if (isset($response['body'])) {
870
+ $response_body = json_decode($response['body'], true);
871
+ }
 
872
 
873
+ if (isset($response['response'])) {
874
+ $status = $response['response']['code'];
875
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
876
 
877
+ update_post_meta($post->ID, 'response_body', json_encode($response_body));
878
+ update_post_meta($post->ID, 'status', $status);
 
 
879
 
880
+ if ($status != 200) {
881
+ error_log('There was a '.$status.' error sending your notification.');
882
+ if ($status != 0) {
883
+ set_transient('onesignal_transient_error', '<div class="error notice onesignal-error-notice">
884
+ <p><strong>OneSignal Push:</strong><em> There was a '.$status.' error sending your notification.</em></p>
885
+ </div>', 86400);
886
+ } else {
887
+ // A 0 HTTP status code means the connection couldn't be established
888
+ set_transient('onesignal_transient_error', '<div class="error notice onesignal-error-notice">
889
+ <p><strong>OneSignal Push:</strong><em> There was an error establishing a network connection. Please make sure outgoing network connections from cURL are allowed.</em></p>
890
+ </div>', 86400);
891
+ }
892
+ } else {
893
+ if (!empty($response)) {
894
+ onesignal_debug('OneSignal API Raw Response:', $response);
895
+
896
+ // API can send a 200 OK even if the notification failed to send
897
+ if (isset($response['body'])) {
898
+ $response_body = json_decode($response['body'], true);
899
+
900
+ if (isset($response_body['recipients'])) {
901
+ $recipient_count = $response_body['recipients'];
902
+ } else {
903
+ error_log('OneSignal: recipients not set in response body');
904
+ }
905
+
906
+ if (isset($response_body['id'])) {
907
+ $notification_id = $response_body['id'];
908
+ } else {
909
+ error_log('OneSignal: notification id not set in response body');
910
+ }
911
+ } else {
912
+ error_log('OneSignal: body not set in HTTP response');
913
+ }
914
+
915
+ // updates meta so that recipient count is available for GET request from client
916
+ update_post_meta($post->ID, 'recipients', $recipient_count);
917
+
918
+ // updates meta for use in cancelling scheduled notifs
919
+ update_post_meta($post->ID, 'notification_id', $notification_id);
920
+
921
+ $sent_or_scheduled = array_key_exists('send_after', $fields) ? 'scheduled' : 'sent';
922
+ $config_show_notification_send_status_message = $onesignal_wp_settings['show_notification_send_status_message'] == '1';
923
+
924
+ if ($config_show_notification_send_status_message) {
925
+ if ($recipient_count != 0) {
926
+ set_transient('onesignal_transient_success', '<div class="components-notice is-success is-dismissible">
927
+ <div class="components-notice__content">
928
+ <p><strong>OneSignal Push:</strong><em> Successfully '.$sent_or_scheduled.' a notification to '.$recipient_count.' recipients.</em></p>
929
+ </div>
930
+ </div>', 86400);
931
+ } else {
932
+ set_transient('onesignal_transient_success', '<div class="updated notice notice-success is-dismissible">
933
+ <p><strong>OneSignal Push:</strong><em>There were no recipients.</em></p>
934
+ </div>', 86400);
935
+ }
936
+ }
937
+ }
938
+ }
939
 
940
+ if (defined('ONESIGNAL_DEBUG') || class_exists('WDS_Log_Post')) {
941
+ fclose($out);
942
+ $debug_output = ob_get_clean();
943
+ }
 
944
 
945
+ self::update_last_sent_timestamp();
946
 
947
+ return $response;
948
+ }
949
+ } catch (Exception $e) {
950
+ onesignal_debug('Caught Exception:', $e->getMessage());
951
  }
952
+ }
953
 
954
+ public static function was_post_restored_from_trash($old_status, $new_status)
955
+ {
956
+ return $old_status === 'trash' && $new_status === 'publish';
957
+ }
958
+
959
+ public static function cancel_scheduled_notification($post)
960
+ {
961
+ $notification_id = get_post_meta($post->ID, 'notification_id')[0];
962
+ $onesignal_wp_settings = OneSignal::get_onesignal_settings();
963
+
964
+ $onesignal_delete_url = 'https://onesignal.com/api/v1/notifications/'.$notification_id.'?app_id='.$onesignal_wp_settings['app_id'];
965
  $onesignal_auth_key = $onesignal_wp_settings['app_rest_api_key'];
966
 
967
+ $request = array(
968
+ 'headers' => array(
969
+ 'content-type' => 'application/json;charset=utf-8',
970
+ 'Authorization' => 'Basic '.$onesignal_auth_key,
971
+ ),
972
+ 'method' => 'DELETE',
973
+ 'timeout' => 60,
974
+ );
975
 
976
+ $response = wp_remote_get($onesignal_delete_url, $request);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
977
 
978
+ if (is_wp_error($response) || !is_array($response) || !isset($response['body'])) {
979
+ $status = $response->get_error_code(); // custom code for WP_ERROR
980
+ $error_message = $response->get_error_message();
981
+ error_log("Couldn't cancel notification: There was a ".$status.' error returned from OneSignal: '.$error_message);
982
 
983
+ return;
984
+ }
985
  }
986
 
987
+ public static function on_transition_post_status($new_status, $old_status, $post)
988
+ {
989
+ if ($post->post_type == 'wdslp-wds-log' || self::was_post_restored_from_trash($old_status, $new_status)) {
990
+ // It's important not to call onesignal_debug() on posts of type wdslp-wds-log, otherwise each post will recursively generate 4 more posts
991
+ return;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
992
  }
993
 
994
+ if ($new_status == 'future') {
995
+ self::send_notification_on_wp_post($new_status, $old_status, $post);
 
996
 
997
+ return;
998
  }
999
 
1000
+ if (has_filter('onesignal_include_post')) {
1001
+ onesignal_debug('Applying onesignal_include_post filter.');
1002
+ if (apply_filters('onesignal_include_post', $new_status, $old_status, $post)) {
1003
+ // If the filter returns "$do_include_post: true", always process this post
1004
+ onesignal_debug('Processing post because the filter opted to include the post.');
1005
+ self::send_notification_on_wp_post($new_status, $old_status, $post);
1006
 
1007
+ return;
1008
+ }
1009
+ }
 
 
 
 
1010
 
1011
+ if (has_filter('onesignal_exclude_post')) {
1012
+ onesignal_debug('Applying onesignal_exclude_post filter.');
1013
+ if (apply_filters('onesignal_exclude_post', $new_status, $old_status, $post)) {
1014
+ // If the filter returns "$do_exclude_post: false", do not process this post at all
1015
+ onesignal_debug('Not processing post because the filter opted to exclude the post.');
1016
 
1017
+ return;
1018
+ }
1019
+ }
1020
+
1021
+ if (!(empty($post) ||
1022
+ $new_status !== 'publish' ||
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1023
  $post->post_type == 'page')) {
1024
+ self::send_notification_on_wp_post($new_status, $old_status, $post);
1025
+ }
1026
  }
 
1027
  }
1028
 
1029
+ ?>
onesignal.php CHANGED
@@ -6,7 +6,7 @@ defined( 'ABSPATH' ) or die('This page may not be accessed directly.');
6
  * Plugin Name: OneSignal Push Notifications
7
  * Plugin URI: https://onesignal.com/
8
  * Description: Free web push notifications.
9
- * Version: 1.17.5
10
  * Author: OneSignal
11
  * Author URI: https://onesignal.com
12
  * License: MIT
@@ -33,4 +33,4 @@ if (file_exists(plugin_dir_path( __FILE__ ) . 'onesignal-extra.php')) {
33
  add_action( 'init', array( 'OneSignal_Admin', 'init' ) );
34
  add_action( 'init', array( 'OneSignal_Public', 'init' ) );
35
 
36
- ?>
6
  * Plugin Name: OneSignal Push Notifications
7
  * Plugin URI: https://onesignal.com/
8
  * Description: Free web push notifications.
9
+ * Version: 1.17.6
10
  * Author: OneSignal
11
  * Author URI: https://onesignal.com
12
  * License: MIT
33
  add_action( 'init', array( 'OneSignal_Admin', 'init' ) );
34
  add_action( 'init', array( 'OneSignal_Public', 'init' ) );
35
 
36
+ ?>
readme.txt CHANGED
@@ -4,7 +4,7 @@ Donate link: https://onesignal.com
4
  Tags: chrome, firefox, safari, push, push notifications, push notification, chrome push, safari push, firefox push, notification, notifications, web push, notify, mavericks, android, android push, android notifications, android notification, mobile notification, mobile notifications, mobile, desktop notification, roost, goroost, desktop notifications, gcm, push messages, onesignal
5
  Requires at least: 3.8
6
  Tested up to: 5.2.1
7
- Stable tag: 1.17.5
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
@@ -18,10 +18,10 @@ After setup, your visitors opt-in to receive push notifications when you publish
18
 
19
  You can configure notification delivery at preset intervals, create user segments, and customize the opt-in process for visitors.
20
 
21
- OneSignal is free for up to 30,000 subscribers; there are no limits on the number of push notifications you can send. Contact [support@onesignal.com](mailto:support@onesignal.com) if you have any questions. We’d love to hear from you.
22
 
23
  = Company =
24
- OneSignal is trusted by over 650,000 developers and marketing strategists. We power push notifications for everyone from early stage startups to Fortune 500 Companies, sending 4 billion notifications per day. It is the most popular push notification plugin on Wordpress with 90,000+ installations.
25
 
26
  = Features =
27
  * **Supports Chrome** (Desktop & Android), **Safari** (Mac OS X), **Microsoft Edge** (Desktop & Android), **Opera** (Desktop & Android) and **Firefox** (Desktop & Android) on both HTTP and HTTPS sites.
@@ -65,7 +65,11 @@ HTTPS Setup Video: [youtube https://www.youtube.com/watch?v=BeTZ2KgytC0]
65
 
66
  == Changelog ==
67
 
68
- = 1.17.5 [
 
 
 
 
69
 
70
  - Updated notice message to reflect changes to time limiter, removed extra newline from description
71
 
4
  Tags: chrome, firefox, safari, push, push notifications, push notification, chrome push, safari push, firefox push, notification, notifications, web push, notify, mavericks, android, android push, android notifications, android notification, mobile notification, mobile notifications, mobile, desktop notification, roost, goroost, desktop notifications, gcm, push messages, onesignal
5
  Requires at least: 3.8
6
  Tested up to: 5.2.1
7
+ Stable tag: 1.17.6
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
18
 
19
  You can configure notification delivery at preset intervals, create user segments, and customize the opt-in process for visitors.
20
 
21
+ OneSignal’s free plan allows targeting up to 30,000 subscribers with push notifications. Contact support@onesignal.com if you have any questions. We’d love to hear from you!
22
 
23
  = Company =
24
+ OneSignal is trusted by over 708,000 developers and marketing strategists. We power push notifications for everyone from early stage startups to Fortune 500 Companies, sending 4 billion notifications per day. It is the most popular push notification plugin on Wordpress with 90,000+ installations.
25
 
26
  = Features =
27
  * **Supports Chrome** (Desktop & Android), **Safari** (Mac OS X), **Microsoft Edge** (Desktop & Android), **Opera** (Desktop & Android) and **Firefox** (Desktop & Android) on both HTTP and HTTPS sites.
65
 
66
  == Changelog ==
67
 
68
+ = 1.17.6 =
69
+
70
+ - Fixed bug where scheduled posts would send notifications immediately, added Gutenberg support for scheduled notifications
71
+
72
+ = 1.17.5 =
73
 
74
  - Updated notice message to reflect changes to time limiter, removed extra newline from description
75