public function __construct()
 {
     parent::__construct(site_url('pnfw/unregister/'), 'POST');
     global $wpdb;
     $push_tokens = $wpdb->get_blog_prefix() . 'push_tokens';
     $user_id = $wpdb->get_var($wpdb->prepare("SELECT user_id FROM {$push_tokens} WHERE token = %s AND os = %s", $this->token, $this->os));
     $res = $wpdb->delete($push_tokens, array("token" => $this->token, "os" => $this->os));
     if ($res === false) {
         $this->json_error('500', __('Unable to delete token', 'pnfw'));
     }
     $user = new WP_User($user_id);
     if (in_array(PNFW_Push_Notifications_for_WordPress_Lite::USER_ROLE, $user->roles) && empty($user->user_email)) {
         pnfw_log(PNFW_SYSTEM_LOG, sprintf(__("Automatically deleted the anonymous user %s (%s) since left without tokens.", 'pnfw'), $user->user_login, $user_id));
         require_once ABSPATH . 'wp-admin/includes/user.php';
         if (is_multisite()) {
             require_once ABSPATH . 'wp-admin/includes/ms.php';
             if (is_user_member_of_blog($user_id)) {
                 wpmu_delete_user($user_id);
             }
         } else {
             wp_delete_user($user_id);
         }
     }
     exit;
 }
 private function get_auth_token()
 {
     $clientId = get_option("pnfw_adm_client_id");
     if (empty($clientId)) {
         pnfw_log(PNFW_KINDLE_LOG, __("ADM Client ID is not correctly set.", 'pnfw'));
         return null;
     }
     $clientSecret = get_option("pnfw_adm_client_secret");
     if (empty($clientSecret)) {
         pnfw_log(PNFW_KINDLE_LOG, __("ADM Client Secret is not correctly set.", 'pnfw'));
         return null;
     }
     // Encode the body of your request, including your clientID and clientSecret values.
     $body = 'grant_type=client_credentials';
     $body .= '&scope=messaging:push';
     $body .= '&client_id=' . urlencode($clientId);
     $body .= '&client_secret=' . urlencode($clientSecret);
     $headers = array('Content-Type: application/x-www-form-urlencoded;charset=UTF-8');
     $ch = curl_init();
     curl_setopt($ch, CURLOPT_URL, 'https://api.amazon.com/auth/O2/token');
     curl_setopt($ch, CURLOPT_POST, true);
     curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
     curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
     curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
     curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
     $response = curl_exec($ch);
     $status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
     curl_close($ch);
     if ($status != 200) {
         return null;
     }
     $json = json_decode($response, true);
     return $json['access_token'];
 }
 function notify_new_post_in_background($post)
 {
     $do_not_send_push_notifications_for_this_post = get_post_meta($post->ID, 'pnfw_do_not_send_push_notifications_for_this_post', true);
     // This check has to be done here and not in the notify_new_custom_post which is
     // performed too early (the value of the post meta has not yet been stored)
     if ($do_not_send_push_notifications_for_this_post) {
         pnfw_log(PNFW_SYSTEM_LOG, sprintf(__('Notifications for the %s %s deliberately not sent', 'pnfw'), $post->post_type, $post->post_title));
         return;
     }
     if (get_option("pnfw_ios_push_notifications")) {
         require_once dirname(__FILE__) . '/notifications/class-pnfw-post-notifications-ios.php';
         $sender = new PNFW_Post_Notifications_iOS();
         $sender->send_post_to_user_categories($post);
     }
     if (get_option("pnfw_android_push_notifications")) {
         require_once dirname(__FILE__) . '/notifications/class-pnfw-post-notifications-android.php';
         $sender = new PNFW_Post_Notifications_Android();
         $sender->send_post_to_user_categories($post);
     }
     if (get_option("pnfw_kindle_push_notifications")) {
         require_once dirname(__FILE__) . '/notifications/class-pnfw-post-notifications-kindle.php';
         $sender = new PNFW_Post_Notifications_Kindle();
         $sender->send_post_to_user_categories($post);
     }
 }
    public static function output()
    {
        ?>
  <div class="wrap">
   <div id="icon-options-general" class="icon32"></div>
   <h2><?php 
        _e('Tokens', 'pnfw');
        ?>
</h2>

   <?php 
        if (isset($_REQUEST['action']) && 'delete' === $_REQUEST['action']) {
            if (!isset($_REQUEST['_wpnonce']) || !wp_verify_nonce($_REQUEST['_wpnonce'], 'delete' . $_REQUEST['id'])) {
                _e('Are you sure you want to do this?', 'pnfw');
                die;
            }
            global $wpdb;
            $table_name = $wpdb->get_blog_prefix() . 'push_tokens';
            $user_id = $wpdb->get_var($wpdb->prepare("SELECT user_id FROM {$table_name} WHERE id = %d", $_REQUEST['id']));
            $wpdb->delete($table_name, array('id' => $_REQUEST['id']));
            pnfw_log(PNFW_ALERT_LOG, sprintf(__("Removed from the Tokens page the token with ID %s.", 'pnfw'), $_REQUEST['id']));
            $user = new WP_User($user_id);
            if (in_array(PNFW_Push_Notifications_for_WordPress_Lite::USER_ROLE, $user->roles) && empty($user->user_email)) {
                pnfw_log(PNFW_SYSTEM_LOG, sprintf(__("Automatically deleted the anonymous user %s (%s) since left without tokens.", 'pnfw'), $user->user_login, $user_id));
                if (is_multisite()) {
                    require_once ABSPATH . 'wp-admin/includes/ms.php';
                    if (is_user_member_of_blog($user_id)) {
                        wpmu_delete_user($user_id);
                    }
                } else {
                    wp_delete_user($user_id);
                }
            }
            ?>

    <div class="updated below-h2" id="message"><p><?php 
            _e('Item deleted', 'pnfw');
            ?>
</p></div>
    <?php 
        } else {
            if (isset($_REQUEST['action']) && 'send_test_notification' === $_REQUEST['action']) {
                if (!isset($_REQUEST['_wpnonce']) || !wp_verify_nonce($_REQUEST['_wpnonce'], 'send_test_notification' . $_REQUEST['id'])) {
                    _e('Are you sure you want to do this?', 'pnfw');
                    die;
                }
                global $wpdb;
                $table_name = $wpdb->get_blog_prefix() . 'push_tokens';
                $rows = $wpdb->get_results($wpdb->prepare("SELECT os, token FROM {$table_name} WHERE id = %d", $_REQUEST['id']));
                if (count($rows) > 0) {
                    $os = $rows[0]->os;
                    $token = $rows[0]->token;
                    $title = __('This is a test notification', 'pnfw');
                    if ('iOS' == $os) {
                        require_once dirname(__FILE__) . '/../includes/notifications/class-pnfw-notifications-ios.php';
                        $sender = new PNFW_Notifications_iOS();
                        $count = $sender->send_title_to_tokens($title, array($token));
                    } else {
                        if ('Android' == $os) {
                            require_once dirname(__FILE__) . '/../includes/notifications/class-pnfw-notifications-android.php';
                            $sender = new PNFW_Notifications_Android();
                            $count = $sender->send_title_to_tokens($title, array($token));
                        } else {
                            if ('Fire OS' == $os) {
                                require_once dirname(__FILE__) . '/../includes/notifications/class-pnfw-notifications-kindle.php';
                                $sender = new PNFW_Notifications_Kindle();
                                $count = $sender->send_title_to_tokens($title, array($token));
                            }
                        }
                    }
                    if ($count > 0) {
                        ?>
 <div class="updated below-h2" id="message"><p><?php 
                        echo sprintf(__('Notification sent to %s device', 'pnfw'), $os);
                        ?>
</p></div> <?php 
                    } else {
                        $url = admin_url('admin.php?page=pnfw-debug-identifier');
                        ?>
 <div class="error below-h2" id="message"><p><?php 
                        echo sprintf(__("There was an error sending the notification. For more information, see the <a href='%s'>Debug</a> page", 'pnfw'), $url);
                        ?>
</p></div> <?php 
                    }
                } else {
                    ?>
 <div class="error below-h2" id="message"><p><?php 
                    echo _e('Error');
                    ?>
</p></div> <?php 
                }
            }
        }
        $tokesTable = new Tokens_Table();
        $tokesTable->prepare_items();
        $tokesTable->display();
        ?>
  </div>
 <?php 
    }
 function json_error($error, $detail)
 {
     header('Content-Type: application/json');
     switch ($error) {
         case '401':
             header('HTTP/1.1 401 Unauthorized');
             $reason = __('Unauthorized', 'pnfw');
             break;
         case '404':
             header('HTTP/1.1 404 Not Found');
             $reason = __('Not Found', 'pnfw');
             break;
         default:
             header('HTTP/1.1 500 Internal Server Error');
             $reason = __('Internal Server Error', 'pnfw');
     }
     $response = array('error' => $error, 'reason' => $reason, 'detail' => $detail);
     pnfw_log(PNFW_ALERT_LOG, sprintf(__('%s API Error (%s) from IP address %s: %s, %s.', 'pnfw'), self::get_request_uri(), $error, self::get_remote_addr(), $reason, $detail));
     echo json_encode($response);
     exit;
 }
    public static function output()
    {
        ?>
  <div class="wrap">
   <div id="icon-options-general" class="icon32"></div>
   <h2><?php 
        _e('App Subscribers', 'pnfw');
        ?>
    <a href="<?php 
        echo add_query_arg('pnfw_download_subscribers', 'true', admin_url('admin.php?page=pnfw-app-subscribers-identifier'));
        ?>
" class="add-new-h2"><?php 
        _e('Export CSV', 'pnfw');
        ?>
</a>
   </h2>

   <?php 
        if (isset($_REQUEST['action']) && 'delete' === $_REQUEST['action']) {
            if (!isset($_REQUEST['_wpnonce']) || !wp_verify_nonce($_REQUEST['_wpnonce'], 'delete' . $_REQUEST['id'])) {
                _e('Are you sure you want to do this?', 'pnfw');
                die;
            }
            pnfw_log(PNFW_ALERT_LOG, sprintf(__("Removed from the App Subscribers page the user with ID %s.", 'pnfw'), $_REQUEST['id']));
            if (is_multisite()) {
                $blog_id = get_current_blog_id();
                if (pnfw_is_exclusive_user_member_of_blog($_REQUEST['id'], $blog_id)) {
                    require_once ABSPATH . 'wp-admin/includes/ms.php';
                    // If the user is linked only to this site it will be completely removed
                    wpmu_delete_user($_REQUEST['id']);
                    pnfw_log(PNFW_SYSTEM_LOG, sprintf(__("Completely deleted the user %s.", 'pnfw'), $_REQUEST['id']));
                } else {
                    // If the user is also linked to other sites it will be removed only from this
                    remove_user_from_blog($_REQUEST['id'], $blog_id);
                    pnfw_log(PNFW_SYSTEM_LOG, sprintf(__("Disassociated the user %s from blog %s", 'pnfw'), $_REQUEST['id'], $blog_id));
                }
            } else {
                wp_delete_user($_REQUEST['id']);
            }
            ?>

          <div class="updated below-h2" id="message"><p><?php 
            _e('User deleted', 'pnfw');
            ?>
</p></div>
         <?php 
        }
        ?>





   <?php 
        $app_subscribers = new App_Subscribers_Table();
        $app_subscribers->prepare_items();
        $app_subscribers->display();
        ?>



  </div>
 <?php 
    }
 function upgrade()
 {
     global $wpdb;
     switch (get_option('pnfw_db_version', 0)) {
         case 0:
             // Must be done BEFORE pnfw_log
             $table_name = $wpdb->get_blog_prefix() . 'push_logs';
             $sql = "CREATE TABLE IF NOT EXISTS {$table_name} (\n      `id` INT UNSIGNED NOT NULL AUTO_INCREMENT,\n      `type` INT UNSIGNED NOT NULL,\n      `text` TEXT,\n      `timestamp` DATETIME NOT NULL,\n      PRIMARY KEY (`id`));";
             $wpdb->query($sql);
             pnfw_log(PNFW_SYSTEM_LOG, sprintf(__('Upgrading from version %d.', 'pnfw'), 0));
             // Create new tables
             $table_name = $wpdb->get_blog_prefix() . 'push_viewed';
             $sql = "CREATE TABLE IF NOT EXISTS {$table_name} (\n      `user_id` BIGINT (20) UNSIGNED NOT NULL,\n      `post_id` BIGINT (20) UNSIGNED NOT NULL,\n      `timestamp` DATETIME NOT NULL,\n      PRIMARY KEY (`user_id`, `post_id`));";
             $wpdb->query($sql);
             $table_name = $wpdb->get_blog_prefix() . 'push_sent';
             $sql = "CREATE TABLE IF NOT EXISTS {$table_name} (\n      `user_id` BIGINT (20) UNSIGNED NOT NULL,\n      `post_id` BIGINT (20) UNSIGNED NOT NULL,\n      `timestamp` DATETIME NOT NULL,\n      PRIMARY KEY (`user_id`, `post_id`));";
             $wpdb->query($sql);
             $table_name = $wpdb->get_blog_prefix() . 'push_excluded_categories';
             $sql = "CREATE TABLE IF NOT EXISTS {$table_name} (\n      `user_id` BIGINT (20) UNSIGNED NOT NULL,\n      `category_id` BIGINT (20) UNSIGNED NOT NULL,\n      PRIMARY KEY (`user_id`, `category_id`));";
             $wpdb->query($sql);
             // Add user_id column
             $push_tokens = $wpdb->get_blog_prefix() . 'push_tokens';
             $wpdb->query("ALTER TABLE {$push_tokens} ADD (\n      `user_id` BIGINT (20) UNSIGNED NULL,\n      `lang` VARCHAR (2) NULL,\n      `active` BOOLEAN,\n      `activation_code` VARCHAR (40) NULL);");
             // Creare new user role
             add_role(self::USER_ROLE, __('App Subscriber', 'pnfw'), array('read' => true));
             // Create a user for every token with user_id NULL
             $rows = $wpdb->get_results("SELECT token, os FROM {$push_tokens} WHERE user_id IS NULL");
             foreach ($rows as $row) {
                 // Create anonymous wordpress user
                 $user_id = wp_insert_user(array('user_login' => $this->create_unique_user_login(), 'user_email' => NULL, 'user_pass' => NULL, 'role' => self::USER_ROLE));
                 // Add its user_id to push_tokens table
                 if (!is_wp_error($user_id)) {
                     $wpdb->update($push_tokens, array('user_id' => $user_id, 'active' => true), array('token' => $row->token, 'os' => $row->os));
                 }
             }
             // Drop deprecated table
             $table_name = $wpdb->get_blog_prefix() . 'push_notifications_sent_per_day';
             $wpdb->query("DROP TABLE IF EXISTS {$table_name};");
             // Remove deprecated register page
             $page = get_page_by_path('register');
             if (isset($page)) {
                 wp_delete_post($page->ID, true);
             }
             // Disable old feedback provider
             wp_clear_scheduled_hook('ds_feedback_provider_event');
             // Rename options
             $this->rename_option('ds_enable_push_notifications', 'pnfw_enable_push_notifications');
             $this->rename_option('ds_ios_push_notifications', 'pnfw_ios_push_notifications');
             $this->rename_option('ds_android_push_notifications', 'pnfw_android_push_notifications');
             $this->rename_option('ds_kindle_push_notifications', 'pnfw_kindle_push_notifications');
             $this->rename_option('ds_ios_use_sandbox', 'pnfw_ios_use_sandbox');
             $this->rename_option('ds_sandbox_ssl_certificate_media_id', 'pnfw_sandbox_ssl_certificate_media_id');
             $this->rename_option('ds_sandbox_ssl_certificate_password', 'pnfw_sandbox_ssl_certificate_password');
             $this->rename_option('ds_production_ssl_certificate_media_id', 'pnfw_production_ssl_certificate_media_id');
             $this->rename_option('ds_production_ssl_certificate_password', 'pnfw_production_ssl_certificate_password');
             $this->rename_option('ds_google_api_key', 'pnfw_google_api_key');
             $this->rename_option('ds_adm_client_id', 'pnfw_adm_client_id');
             $this->rename_option('ds_adm_client_secret', 'pnfw_adm_client_secret');
             $this->rename_option('ds_api_consumer_key', 'pnfw_api_consumer_key');
             $this->rename_option('ds_api_consumer_secret', 'pnfw_api_consumer_secret');
             $this->rename_option('ds_enabled_post_types', 'pnfw_enabled_post_types');
             // Upgrade option to new values
             $post_types = get_option('pnfw_enabled_post_types', array());
             $post_types[] = 'post';
             update_option('pnfw_enabled_post_types', $post_types);
             // Schedule new Feedback Provider if needed
             if (get_option("pnfw_ios_push_notifications")) {
                 global $feedback_provider;
                 $feedback_provider->run();
             }
             $this->manage_routes();
             flush_rewrite_rules();
             pnfw_log(PNFW_SYSTEM_LOG, sprintf(__('Db version %d upgraded.', 'pnfw'), 0));
             update_option('pnfw_db_version', self::DB_VERSION);
     }
 }
 protected function raw_send($tokens, $title, $user_info)
 {
     // No devices, do nothing
     if (empty($tokens)) {
         return 0;
     }
     require_once dirname(__FILE__) . '/../../libs/PHP_GCM/Message.php';
     require_once dirname(__FILE__) . '/../../libs/PHP_GCM/Sender.php';
     require_once dirname(__FILE__) . '/../../libs/PHP_GCM/Result.php';
     require_once dirname(__FILE__) . '/../../libs/PHP_GCM/MulticastResult.php';
     require_once dirname(__FILE__) . '/../../libs/PHP_GCM/Constants.php';
     require_once dirname(__FILE__) . '/../../libs/PHP_GCM/InvalidRequestException.php';
     $api_key = get_option("pnfw_google_api_key");
     if (empty($api_key)) {
         pnfw_log(PNFW_ANDROID_LOG, __("Google API Key is not correctly set.", 'pnfw'));
         return 0;
     }
     $pnfw_add_message_field_in_payload = (bool) get_option('pnfw_add_message_field_in_payload');
     if ($pnfw_add_message_field_in_payload) {
         if (is_multisite()) {
             global $blog_id;
             $current_blog_details = get_blog_details(array('blog_id' => $blog_id));
             $blog_title = $current_blog_details->blogname;
         } else {
             $blog_title = get_bloginfo('name');
         }
         $payload_data = array_merge(array('title' => $blog_title, 'message' => $title), $user_info);
     } else {
         $payload_data = array_merge(array('title' => $title), $user_info);
     }
     $sender = new PHP_GCM\Sender($api_key);
     $message = new PHP_GCM\Message('push', $payload_data);
     $max_bulk_size = 999;
     $chunks = array_chunk($tokens, $max_bulk_size);
     $sent = 0;
     foreach ($chunks as $chunk) {
         try {
             $multicastResult = $sender->sendNoRetryMulti($message, $chunk);
             $results = $multicastResult->getResults();
             for ($i = 0, $count = count($results); $i < $count; $i++) {
                 $result = $results[$i];
                 // This means error
                 if (is_null($result->getMessageId())) {
                     // If device is not registered or invalid remove it from table
                     if ('NotRegistered' == $result->getErrorCode() || 'InvalidRegistration' == $result->getErrorCode()) {
                         $this->delete_token($chunk[$i]);
                     }
                     // else not recoverable error, ignore
                 } else {
                     $this->notification_sent($chunk[$i]);
                     // If there is a canonical registration id we must update
                     $token = $result->getCanonicalRegistrationId();
                     if (!is_null($token)) {
                         $this->update_token($chunk[$i], $token);
                     }
                 }
             }
             unset($result);
             $sent += $multicastResult->getSuccess();
         } catch (\InvalidArgumentException $e) {
             pnfw_log(PNFW_ANDROID_LOG, sprintf(__('Invalid argument (%s): %s', 'pnfw'), (string) $e->getCode(), strip_tags($e->getMessage())));
         } catch (PHP_GCM\InvalidRequestException $e) {
             pnfw_log(PNFW_ANDROID_LOG, sprintf(__('Invalid request (%s): %s', 'pnfw'), (string) $e->getCode(), strip_tags($e->getMessage())));
         } catch (\Exception $e) {
             pnfw_log(PNFW_ANDROID_LOG, sprintf(__('Could not send message (%s): %s', 'pnfw'), (string) $e->getCode(), strip_tags($e->getMessage())));
         }
     }
     return $sent;
 }
 protected function raw_send($tokens, $title, $user_info)
 {
     // No devices, do nothing
     if (empty($tokens)) {
         return 0;
     }
     require_once dirname(__FILE__) . '/../../libs/ApnsPHP/Abstract.php';
     require_once dirname(__FILE__) . '/../../libs/ApnsPHP/Exception.php';
     require_once dirname(__FILE__) . '/../../libs/ApnsPHP/Feedback.php';
     require_once dirname(__FILE__) . '/../../libs/ApnsPHP/Message.php';
     require_once dirname(__FILE__) . '/../../libs/ApnsPHP/Log/Interface.php';
     require_once dirname(__FILE__) . '/../../libs/ApnsPHP/Log/Embedded.php';
     require_once dirname(__FILE__) . '/../../libs/ApnsPHP/Message/Custom.php';
     require_once dirname(__FILE__) . '/../../libs/ApnsPHP/Message/Exception.php';
     require_once dirname(__FILE__) . '/../../libs/ApnsPHP/Push.php';
     require_once dirname(__FILE__) . '/../../libs/ApnsPHP/Push/Exception.php';
     require_once dirname(__FILE__) . '/../../libs/ApnsPHP/Push/Server.php';
     require_once dirname(__FILE__) . '/../../libs/ApnsPHP/Push/Server/Exception.php';
     require_once dirname(__FILE__) . '/../class-pnfw-apnsphp-logger.php';
     $certificate = get_attached_file(get_option("pnfw_production_ssl_certificate_media_id"));
     $passphrase = get_option("pnfw_production_ssl_certificate_password");
     $environment = ApnsPHP_Abstract::ENVIRONMENT_PRODUCTION;
     if (get_option("pnfw_ios_use_sandbox")) {
         $certificate = get_attached_file(get_option("pnfw_sandbox_ssl_certificate_media_id"));
         $passphrase = get_option("pnfw_sandbox_ssl_certificate_password");
         $environment = ApnsPHP_Abstract::ENVIRONMENT_SANDBOX;
     }
     if (empty($certificate)) {
         pnfw_log(PNFW_IOS_LOG, __("iOS SSL certificate is not correctly set.", 'pnfw'));
         return 0;
     }
     if (empty($passphrase)) {
         pnfw_log(PNFW_IOS_LOG, __("iOS SSL certificate password is not correctly set.", 'pnfw'));
         return 0;
     }
     if (!file_exists($certificate)) {
         pnfw_log(PNFW_IOS_LOG, __("iOS SSL Certificate does not exists.", 'pnfw'));
         return 0;
     }
     $pnfw_ios_payload_sound = get_option('pnfw_ios_payload_sound', 'default');
     try {
         $push = new ApnsPHP_Push($environment, $certificate);
         $push->setLogger(new PNFW_ApnsPHP_Logger());
         $push->setProviderCertificatePassphrase($passphrase);
         foreach ($tokens as &$token) {
             try {
                 $this->notification_sent($token);
                 $message = new ApnsPHP_Message($token);
                 foreach (array_keys($user_info) as $key) {
                     $message->setCustomProperty($key, strval($user_info[$key]));
                 }
                 $message->setText($title);
                 $message->setSound($pnfw_ios_payload_sound);
                 $message->setBadge($this->get_badge_count($token));
                 $push->add($message);
             } catch (Exception $e) {
                 // The only exception here is the invalid token, so delete it
                 $this->delete_token($token);
             }
         }
         unset($token);
         $queued = count($push->getQueue(false));
         // Empty queue, do nothing
         if ($queued == 0) {
             return 0;
         }
         // Connect to the Apple Push Notification Service
         $push->connect();
         // Send all messages in the message queue
         $push->send();
         // Disconnect from the Apple Push Notification Service
         $push->disconnect();
         return $queued;
     } catch (Exception $e) {
         pnfw_log(PNFW_IOS_LOG, strip_tags($e->getMessage()));
         return 0;
     }
 }
 private function reassign_token_to($user_id)
 {
     global $wpdb;
     $push_tokens = $wpdb->get_blog_prefix() . 'push_tokens';
     $old_user_id = $wpdb->get_var($wpdb->prepare("SELECT user_id FROM {$push_tokens} WHERE token=%s AND os=%s", $this->token, $this->os));
     if ($old_user_id == $user_id) {
         $wpdb->query("UNLOCK TABLES;");
         return false;
         // reassign the tokens to the same user
     }
     pnfw_log(PNFW_SYSTEM_LOG, sprintf(__("Reassign %s token %s from user %s to user %s.", 'pnfw'), $this->os, $this->token, $old_user_id, $user_id));
     $active = empty($this->email);
     if (get_option('pnfw_disable_email_verification')) {
         $active = true;
     }
     $wpdb->update($push_tokens, array('lang' => $this->lang, "user_id" => $user_id, 'active' => $active, 'activation_code' => $this->activation_code), array("token" => $this->token, "os" => $this->os));
     if ($this->user_without_tokens($old_user_id)) {
         $wpdb->query("UNLOCK TABLES;");
         $old_user_categories = wp_get_object_terms($old_user_id, 'user_cat', array('fields' => 'ids'));
         $this->set_categories($user_id, $old_user_categories);
         $old_user = new WP_User($old_user_id);
         if (in_array(PNFW_Push_Notifications_for_WordPress_Lite::USER_ROLE, $old_user->roles) && empty($old_user->user_email)) {
             pnfw_log(PNFW_SYSTEM_LOG, sprintf(__("Automatically deleted the anonymous user %s (%s) since left without tokens.", 'pnfw'), $old_user->user_login, $old_user_id));
             require_once ABSPATH . 'wp-admin/includes/user.php';
             if (is_multisite()) {
                 require_once ABSPATH . 'wp-admin/includes/ms.php';
                 if (is_user_member_of_blog($old_user_id)) {
                     wpmu_delete_user($old_user_id);
                 }
             } else {
                 wp_delete_user($old_user_id);
             }
         }
     } else {
         $wpdb->query("UNLOCK TABLES;");
         $old_user_categories = wp_get_object_terms($old_user_id, 'user_cat', array('fields' => 'ids'));
         $this->set_categories($user_id, $old_user_categories);
     }
     return true;
 }
 function feedback_provider()
 {
     pnfw_log(PNFW_FEEDBACK_PROVIDER_LOG, __("Feedback Provider is running.", 'pnfw'));
     require_once dirname(__FILE__) . '/../libs/ApnsPHP/Abstract.php';
     require_once dirname(__FILE__) . '/../libs/ApnsPHP/Exception.php';
     require_once dirname(__FILE__) . '/../libs/ApnsPHP/Feedback.php';
     require_once dirname(__FILE__) . '/../libs/ApnsPHP/Message.php';
     require_once dirname(__FILE__) . '/../libs/ApnsPHP/Log/Interface.php';
     require_once dirname(__FILE__) . '/../libs/ApnsPHP/Log/Embedded.php';
     require_once dirname(__FILE__) . '/../libs/ApnsPHP/Message/Custom.php';
     require_once dirname(__FILE__) . '/../libs/ApnsPHP/Message/Exception.php';
     require_once dirname(__FILE__) . '/../libs/ApnsPHP/Push.php';
     require_once dirname(__FILE__) . '/../libs/ApnsPHP/Push/Exception.php';
     require_once dirname(__FILE__) . '/../libs/ApnsPHP/Push/Server.php';
     require_once dirname(__FILE__) . '/../libs/ApnsPHP/Push/Server/Exception.php';
     require_once dirname(__FILE__) . '/class-pnfw-apnsphp-logger.php';
     $certificate = get_attached_file(get_option("pnfw_production_ssl_certificate_media_id"));
     $passphrase = get_option("pnfw_production_ssl_certificate_password");
     $environment = ApnsPHP_Abstract::ENVIRONMENT_PRODUCTION;
     if (get_option("pnfw_ios_use_sandbox")) {
         $certificate = get_attached_file(get_option("pnfw_sandbox_ssl_certificate_media_id"));
         $passphrase = get_option("pnfw_sandbox_ssl_certificate_password");
         $environment = ApnsPHP_Abstract::ENVIRONMENT_SANDBOX;
     }
     if (empty($certificate)) {
         pnfw_log(PNFW_FEEDBACK_PROVIDER_LOG, __("iOS SSL certificate is not correctly set.", 'pnfw'));
         return;
     }
     if (empty($passphrase)) {
         pnfw_log(PNFW_FEEDBACK_PROVIDER_LOG, __("iOS SSL certificate password is not correctly set.", 'pnfw'));
         return;
     }
     if (!file_exists($certificate)) {
         pnfw_log(PNFW_FEEDBACK_PROVIDER_LOG, __("iOS SSL Certificate does not exists.", 'pnfw'));
         return;
     }
     try {
         // Instantiate a new ApnsPHP_Feedback object
         $feedback = new ApnsPHP_Feedback($environment, $certificate);
         $feedback->setLogger(new PNFW_ApnsPHP_Logger());
         $feedback->setProviderCertificatePassphrase($passphrase);
         // Connect to the Apple Push Notification Feedback Service
         $feedback->connect();
         // Retrieve devices from Apple Push Notification Feedback Service
         $devices = $feedback->receive();
         // Disconnect from the Apple Push Notification Feedback Service
         $feedback->disconnect();
     } catch (Exception $e) {
         pnfw_log(PNFW_FEEDBACK_PROVIDER_LOG, strip_tags($e->getMessage()));
         return;
     }
     global $wpdb;
     $push_tokens = $wpdb->get_blog_prefix() . 'push_tokens';
     foreach ($devices as &$device) {
         $user_id = $wpdb->get_var($wpdb->prepare("SELECT user_id FROM {$push_tokens} WHERE os = 'iOS' AND token = %s", $device['deviceToken']));
         $wpdb->delete($push_tokens, array('token' => $device['deviceToken'], 'os' => 'iOS'));
         pnfw_log(PNFW_FEEDBACK_PROVIDER_LOG, sprintf(__("The Feedback Provider removed iOS token of user %s: %s.", 'pnfw'), $user_id, $device['deviceToken']));
         $user = new WP_User($user_id);
         if (in_array(PNFW_Push_Notifications_for_WordPress_Lite::USER_ROLE, $user->roles) && empty($user->user_email)) {
             pnfw_log(PNFW_SYSTEM_LOG, sprintf(__("Automatically deleted the anonymous user %s (%s) since left without tokens.", 'pnfw'), $user->user_login, $user_id));
             if (is_multisite()) {
                 require_once ABSPATH . 'wp-admin/includes/ms.php';
                 if (is_user_member_of_blog($user_id)) {
                     wpmu_delete_user($user_id);
                 }
             } else {
                 wp_delete_user($user_id);
             }
         }
     }
     unset($device);
 }
 protected function delete_token($token)
 {
     pnfw_log($this->type, sprintf(__("Removed invalid %s token: %s.", 'pnfw'), $this->os, $token));
     $user_id = $this->get_user_id($token);
     $this->wpdb->delete($this->push_tokens, array('token' => $token, 'os' => $this->os));
     $user = new WP_User($user_id);
     if (in_array(PNFW_Push_Notifications_for_WordPress_Lite::USER_ROLE, $user->roles) && empty($user->user_email)) {
         pnfw_log($this->type, sprintf(__("Automatically deleted the anonymous user %s (%s) since left without tokens.", 'pnfw'), $user->user_login, $user_id));
         require_once ABSPATH . 'wp-admin/includes/user.php';
         if (is_multisite()) {
             require_once ABSPATH . 'wp-admin/includes/ms.php';
             if (is_user_member_of_blog($user_id)) {
                 wpmu_delete_user($user_id);
             }
         } else {
             wp_delete_user($user_id);
         }
     }
 }
 public function log($sMessage)
 {
     pnfw_log(PNFW_IOS_LOG, $sMessage);
 }