Example #1
0
 /**
  * Class constructor.
  *
  * @since 141111 First documented version.
  *
  * @param array $request_args Arguments to the constructor.
  *                            These should NOT be trusted; they come from a `$_REQUEST` action.
  * @param array $args         Any additional behavioral args.
  */
 public function __construct(array $request_args, array $args = [])
 {
     if (!isset($request_args['ID'])) {
         $request_args['ID'] = -1;
     }
     parent::__construct($request_args, $args);
 }
 /**
  * Form processor.
  *
  * @since 141111 First documented version.
  *
  * @param array $request_args Incoming action request args.
  *
  * @see   MenuPageActions::subForm()
  */
 public static function process(array $request_args)
 {
     $plugin = plugin();
     // Needed below.
     if (!current_user_can($plugin->manage_cap)) {
         if (!current_user_can($plugin->cap)) {
             return;
             // Unauthenticated; ignore.
         }
     }
     $reporting_errors = false;
     // Initialize.
     $process_confirmation = !empty($request_args['process_confirmation']);
     $args = compact('process_confirmation');
     if (isset($request_args['ID'])) {
         // Updating an existing subscription via ID?
         $sub_updater = new SubUpdater($request_args, $args);
         // Run updater.
         if ($sub_updater->didUpdate()) {
             // Updated successfully?
             $plugin->enqueueUserNotice(sprintf(__('Subscription ID #<code>%1$s</code> updated successfully.', 'comment-mail'), esc_html($request_args['ID'])), ['transient' => true, 'for_page' => $plugin->utils_env->currentMenuPage()]);
             $redirect_to = $plugin->utils_url->pageTableNavVarsOnly();
         } else {
             // There were errors; display those errors to the current user.
             $plugin->enqueueUserError(sprintf(__('Failed to update subscription ID #<code>%1$s</code>. Please review the following error(s):', 'comment-mail'), esc_html($request_args['ID'])) . '<ul class="pmp-list-items"><li>' . implode('</li><li>', $sub_updater->errorsHtml()) . '</li></ul>', ['transient' => true, 'for_page' => $plugin->utils_env->currentMenuPage()]);
         }
     } else {
         // We are doing a new insertion; i.e. a new subscription is being added here.
         $sub_inserter = new SubInserter($request_args, $args);
         // Run inserter.
         if ($sub_inserter->didInsert()) {
             // Inserted successfully?
             $plugin->enqueueUserNotice(sprintf(__('Subscription ID #<code>%1$s</code> created successfully.', 'comment-mail'), esc_html($sub_inserter->insertId())), ['transient' => true, 'for_page' => $plugin->utils_env->currentMenuPage()]);
             $redirect_to = $plugin->utils_url->pageTableNavVarsOnly();
         } else {
             // There were errors; display those errors to the current user.
             $plugin->enqueueUserError(__('Failed to create new subscription. Please review the following error(s):', 'comment-mail') . '<ul class="pmp-list-items"><li>' . implode('</li><li>', $sub_inserter->errorsHtml()) . '</li></ul>', ['transient' => true, 'for_page' => $plugin->utils_env->currentMenuPage()]);
         }
     }
     if (!empty($redirect_to)) {
         // If applicable.
         if (headers_sent()) {
             // Output started already?
             exit('      <script type="text/javascript">' . "         document.getElementsByTagName('body')[0].style.display = 'none';" . "         location.href = '" . $plugin->utils_string->escJsSq($redirect_to) . "';" . '      </script>' . '   </body>' . '</html>');
         }
         wp_redirect($redirect_to);
         exit;
     }
 }
 /**
  * Form processor.
  *
  * @since 141111 First documented version.
  *
  * @param array $request_args Incoming action request args.
  *
  * @see   SubManageActions::subForm()
  */
 public static function process(array $request_args)
 {
     $plugin = plugin();
     // Needed below.
     $args = ['process_confirmation' => true, 'user_initiated' => true, 'ui_protected_data_keys_enable' => true, 'ui_protected_data_user' => wp_get_current_user()];
     static::$processing = true;
     // Flag as `TRUE`; along w/ other statics below.
     if (isset($request_args['key'])) {
         // Key sanitizer; for added security.
         $request_args['key'] = $sub_key = $plugin->utils_sub->sanitizeKey($request_args['key']);
     }
     if (isset($request_args['ID'])) {
         // Updating an existing subscription via ID?
         $sub_updater = new SubUpdater($request_args, $args);
         // Run updater.
         if ($sub_updater->hasErrors()) {
             // Updater has errors?
             static::$processing_errors = $sub_updater->errors();
             static::$processing_error_codes = $sub_updater->errorCodes();
             static::$processing_errors_html = $sub_updater->errorsHtml();
         } elseif ($sub_updater->didUpdate()) {
             // Updated?
             static::$processing_successes = $sub_updater->successes();
             static::$processing_success_codes = $sub_updater->successCodes();
             static::$processing_successes_html = $sub_updater->successesHtml();
             static::$processing_email_key_change = $sub_updater->emailKeyChanged();
         }
     } elseif ($plugin->options['enable'] && $plugin->options['new_subs_enable']) {
         // This check is for added security only. The form should not be available.
         $sub_inserter = new SubInserter($request_args, $args);
         // Run inserter.
         if ($sub_inserter->hasErrors()) {
             // Inserter has errors?
             static::$processing_errors = $sub_inserter->errors();
             static::$processing_error_codes = $sub_inserter->errorCodes();
             static::$processing_errors_html = $sub_inserter->errorsHtml();
         } elseif ($sub_inserter->didInsert()) {
             // Inserted?
             static::$processing_successes = $sub_inserter->successes();
             static::$processing_success_codes = $sub_inserter->successCodes();
             static::$processing_successes_html = $sub_inserter->successesHtml();
         }
     }
 }
Example #4
0
 /**
  * Import processor.
  *
  * @since 141111 First documented version.
  */
 protected function maybeImport()
 {
     if (!current_user_can($this->plugin->cap)) {
         return;
         // Unauthenticated; ignore.
     }
     $csv_headers = [];
     // Initialize.
     $current_csv_line_number = $current_csv_line_index = 0;
     if (!($csv_resource_file = $this->csvResourceFile())) {
         return;
         // Not possible; i.e. no resource.
     }
     while (($_csv_line = fgetcsv($csv_resource_file, 0, ',', '"', '"')) !== false) {
         ++$current_csv_line_number;
         // Increment line counter.
         ++$current_csv_line_index;
         // Increment line index also.
         $_csv_line = $this->plugin->utils_string->trimDeep($_csv_line);
         if ($current_csv_line_index === 1 && !empty($_csv_line[0])) {
             foreach ($_csv_line as $_csv_header) {
                 $csv_headers[] = (string) $_csv_header;
             }
             unset($_csv_header);
             // Housekeeping.
             --$current_csv_line_number;
             continue;
             // Skip this line.
         }
         if ($current_csv_line_index >= 1 && !$csv_headers) {
             $this->errors[] = __('Missing first-line CSV headers; please try again.', 'comment-mail');
             break;
             // Stop here; we have no headers in this importation.
         }
         if ($current_csv_line_index >= 1 && !in_array('ID', $csv_headers, true)) {
             if (!in_array('email', $csv_headers, true) || !in_array('post_id', $csv_headers, true)) {
                 $this->errors[] = __('First-line CSV headers MUST contain (at a minimum); one of:', 'comment-mail') . ' ' . __('<code>"ID"</code>, or <code>"email"</code> together with a <code>"post_id"</code>.', 'comment-mail');
                 break;
                 // Stop here; we have no headers in this importation.
             }
         }
         $_import = [];
         // Reset this on each pass.
         $_import['ID'] = $this->csvLineColumnValueFor('ID', $csv_headers, $_csv_line);
         $_import['key'] = $this->csvLineColumnValueFor('key', $csv_headers, $_csv_line);
         $_import['user_id'] = $this->csvLineColumnValueFor('user_id', $csv_headers, $_csv_line);
         $_import['post_id'] = $this->csvLineColumnValueFor('post_id', $csv_headers, $_csv_line);
         $_import['comment_id'] = $this->csvLineColumnValueFor('comment_id', $csv_headers, $_csv_line);
         $_import['deliver'] = $this->csvLineColumnValueFor('deliver', $csv_headers, $_csv_line);
         $_import['status'] = $this->csvLineColumnValueFor('status', $csv_headers, $_csv_line);
         $_import['fname'] = $this->csvLineColumnValueFor('fname', $csv_headers, $_csv_line);
         $_import['lname'] = $this->csvLineColumnValueFor('lname', $csv_headers, $_csv_line);
         $_import['email'] = $this->csvLineColumnValueFor('email', $csv_headers, $_csv_line);
         $_import['insertion_ip'] = $this->csvLineColumnValueFor('insertion_ip', $csv_headers, $_csv_line);
         $_import['insertion_region'] = $this->csvLineColumnValueFor('insertion_region', $csv_headers, $_csv_line);
         $_import['insertion_country'] = $this->csvLineColumnValueFor('insertion_country', $csv_headers, $_csv_line);
         $_import['last_ip'] = $this->csvLineColumnValueFor('last_ip', $csv_headers, $_csv_line);
         $_import['last_region'] = $this->csvLineColumnValueFor('last_region', $csv_headers, $_csv_line);
         $_import['last_country'] = $this->csvLineColumnValueFor('last_country', $csv_headers, $_csv_line);
         $_import['insertion_time'] = $this->csvLineColumnValueFor('insertion_time', $csv_headers, $_csv_line);
         $_import['last_update_time'] = $this->csvLineColumnValueFor('last_update_time', $csv_headers, $_csv_line);
         $_sub_inserter = new SubInserter($_import, ['process_confirmation' => $this->process_confirmations]);
         if ($_sub_inserter->didInsertUpdate()) {
             // Have insert|update success?
             ++$this->total_imported_subs;
             // Increment counter; this was a success.
         } elseif ($_sub_inserter->hasErrors()) {
             // If the inserter has errors for this line; report those.
             $_sub_inserter_errors = array_values($_sub_inserter->errors());
             // Values only; discard keys.
             $_sub_inserter_error_prefix = sprintf(__('_Line #%1$s:_', 'comment-mail'), esc_html($current_csv_line_number));
             foreach ($_sub_inserter_errors as &$_sub_inserter_error) {
                 $_sub_inserter_error = $_sub_inserter_error_prefix . ' ' . $_sub_inserter_error;
             }
             $this->errors = array_merge($this->errors, $_sub_inserter_errors);
         }
         unset($_sub_inserter, $_sub_inserter_errors);
         // Housekeeping.
         unset($_sub_inserter_error, $_sub_inserter_error_prefix);
         if ($current_csv_line_number + 1 > $this->max_limit) {
             break;
             // Reached the max limit.
         }
     }
     unset($_csv_line, $_import);
     // Housekeeping.
     fclose($csv_resource_file);
     // Close resource file.
     $this->enqueueNoticesAndRedirect();
     // Issue notices and redirect user.
 }
Example #5
0
 /**
  * Sub. import processor.
  *
  * @since 141111 First documented version.
  *
  * @param int       $post_id Post ID.
  * @param \stdClass $sub     Subscriber obj. data.
  */
 protected function maybeImportSub($post_id, \stdClass $sub)
 {
     if (!($post_id = (int) $post_id)) {
         return;
         // Not possible.
     }
     if (empty($sub->email) || empty($sub->time) || empty($sub->status)) {
         $this->logFailure('Not importing subscription; data missing', $sub);
         return;
         // Not possible; data missing.
     }
     if ($sub->status !== 'Y' && $sub->status !== 'R') {
         $this->logFailure('Not importing subscription; not an active subscriber', $sub);
         return;
         // Not an active subscriber.
     }
     if ($sub->status === 'Y') {
         // All comments?
         $sub_insert_data = ['post_id' => $post_id, 'status' => 'subscribed', 'deliver' => 'asap', 'fname' => $sub->fname, 'email' => $sub->email, 'insertion_time' => $sub->time];
         $sub_inserter = new SubInserter($sub_insert_data);
         if ($sub_inserter->didInsert()) {
             ++$this->total_imported_subs;
             ++$this->total_created_subs;
         } else {
             $this->logFailure('Failed to insert an All Comments (Y) subscription', array_merge($sub_insert_data, $sub_inserter->errors()));
             ++$this->total_skipped_subs;
         }
     } else {
         // Otherwise, specific comment(s) only; i.e. "Replies Only".
         $_sub_comment_ids = $this->subCommentIds($post_id, $sub->email);
         if (!empty($_sub_comment_ids)) {
             /*
              * This is where the behavior of Comment Mail and StCR diverge when it comes to how they store subscriptions.
              * StCR only stores one (1) `R` subscription per email per Post ID, while Comment Mail creates a Replies Only subscription
              * for each comment the user has posted on a given Post ID. That means the Total StCR Subscriptions imported will
              * likely be much lower than the total subscriptions created by Comment Mail. See also: http://bit.ly/1QtwEWO
              *
              * Note how we count imported subs outside of this foreach loop, but we count created subs inside the foreach loop.
              */
             ++$this->total_imported_subs;
             foreach ($_sub_comment_ids as $_comment_id) {
                 $_sub_insert_data = ['post_id' => $post_id, 'comment_id' => $_comment_id, 'status' => 'subscribed', 'deliver' => 'asap', 'fname' => $sub->fname, 'email' => $sub->email, 'insertion_time' => $sub->time];
                 $_sub_inserter = new SubInserter($_sub_insert_data);
                 if ($_sub_inserter->didInsert()) {
                     ++$this->total_created_subs;
                 } else {
                     $this->logFailure('Failed to import Replies Only (R) subscription', array_merge($_sub_insert_data, $_sub_inserter->errors()));
                     ++$this->total_skipped_subs;
                     --$this->total_imported_subs;
                     // Imported subs are counted outside this foreach loop, so we need to decrease here when we have a failure.
                 }
             }
         } else {
             // No comments associated with $sub->email were found for $post_id
             $this->logFailure('Failed to import Replies Only (R) subscription', ['note' => 'Associated comment has been deleted, trashed, or marked as spam', 'post_id' => $post_id, 'email' => $sub->email]);
             ++$this->total_skipped_subs;
         }
         unset($_comment_id, $_sub_insert_data, $_sub_inserter, $_sub_comment_ids);
         // Housekeeping.
     }
 }