: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
if ( empty( $upgrade_id ) ) {
$completed_upgrades = $this->get_completed_upgrades();
return in_array( $upgrade_id, $completed_upgrades, true );
* Conditional function to see if there are upgrades available.
public function has_uncomplete_upgrades() {
return (bool) count( $this->get_uncompleted_upgrades() );
* Returns array of uncompleted upgrades.
* This doesn't return an upgrade if:
* - It was previously complete.
* - If any false values in the upgrades $rules array are found.
public function get_uncompleted_upgrades() {
$required_upgrades = $this->get_routines();
foreach ( $required_upgrades as $upgrade_id => $upgrade ) {
// If the upgrade has already completed or one of the rules failed remove it from the list.
if ( $this->has_completed_upgrade( $upgrade_id ) || in_array( false, $upgrade['rules'], true ) ) {
unset( $required_upgrades[ $upgrade_id ] );
return $required_upgrades;
* Handles Ajax for processing a upgrade upgrade/que request.
public function process_upgrade_request() {
$upgrade_id = isset( $_REQUEST['upgrade_id'] ) ? sanitize_key( $_REQUEST['upgrade_id'] ) : false;
if ( ! $upgrade_id && ! $this->has_uncomplete_upgrades() ) {
'error' => __( 'A batch process ID must be present to continue.', 'popup-maker' ),
if ( ! check_ajax_referer( 'pum_upgrade_ajax_nonce', 'nonce' ) ) {
'error' => __( 'You do not have permission to initiate this request. Contact an administrator for more information.', 'popup-maker' ),
$upgrade_id = $this->get_current_upgrade_id();
$step = ! empty( $_REQUEST['step'] ) ? absint( $_REQUEST['step'] ) : 1;
* Instantiate the upgrade class.
* @var PUM_Interface_Batch_Process|PUM_Interface_Batch_PrefetchProcess $upgrade
$upgrade = $this->get_upgrade( $upgrade_id, $step );
if ( false === $upgrade ) {
'error' => sprintf( __( '%s is an invalid batch process ID.', 'popup-maker' ), esc_html( $upgrade_id ) ),
* Garbage collect any old temporary data in the case step is 1.
* Here to prevent case ajax passes step 1 without resetting process counts.
$using_prefetch = ( $upgrade instanceof PUM_Interface_Batch_PrefetchProcess );
// Handle pre-fetching data.
// Initialize any data needed to process a step.
$data = isset( $_REQUEST['form'] ) ? sanitize_key( $_REQUEST['form'] ) : [];
/** @var int|string|WP_Error $step */
$step = $upgrade->process_step();
if ( ! is_wp_error( $step ) ) {
// Finish and set the status flag if done.
if ( 'done' === $step ) {
$response_data['done'] = true;
$response_data['message'] = $upgrade->get_message( 'done' );
// Once all calculations have finished, run cleanup.
// Set the upgrade complete.
pum_set_upgrade_complete( $upgrade_id );
if ( $this->has_uncomplete_upgrades() ) {
// Since the other was complete return the next (now current) upgrade_id.
$response_data['next'] = $this->get_current_upgrade_id();
$response_data['done'] = false;
$response_data['message'] = $first_step ? $upgrade->get_message( 'start' ) : '';
$response_data['percentage'] = $upgrade->get_percentage_complete();
wp_send_json_success( $response_data );
wp_send_json_error( $step );
* Returns the first key in the uncompleted upgrades.
public function get_current_upgrade_id() {
$upgrades = $this->get_uncompleted_upgrades();
* Returns the current upgrade.
* @return bool|PUM_Interface_Batch_PrefetchProcess|PUM_Interface_Batch_Process
public function get_current_upgrade() {
$upgrade_id = $this->get_current_upgrade_id();
return $this->get_upgrade( $upgrade_id );
* Gets the upgrade process object.
* @param string $upgrade_id
* @return bool|PUM_Interface_Batch_Process|PUM_Interface_Batch_PrefetchProcess
public function get_upgrade( $upgrade_id = '', $step = 1 ) {
$upgrade = $this->registry->get( $upgrade_id );
$class = isset( $upgrade['class'] ) ? sanitize_text_field( $upgrade['class'] ) : '';
$class_file = isset( $upgrade['file'] ) ? $upgrade['file'] : '';
if ( ! class_exists( $class ) && ! empty( $class_file ) && file_exists( $class_file ) ) {
require_once $class_file;
'error' => sprintf( __( 'An invalid file path is registered for the %1$s batch process handler.', 'popup-maker' ), "<code>{$upgrade_id}</code>" ),
if ( empty( $class ) || ! class_exists( $class ) ) {
'error' => sprintf( __( '%1$s is an invalid handler for the %2$s batch process. Please try again.', 'popup-maker' ), "<code>{$class}</code>", "<code>{$upgrade_id}</code>" ),
* @var PUM_Interface_Batch_Process|PUM_Interface_Batch_PrefetchProcess
return new $class( $step );
* Add upgrades tab to tools page if there are upgrades available.
public function tools_page_tabs( $tabs = [] ) {
if ( $this->has_uncomplete_upgrades() ) {
$tabs['upgrades'] = __( 'Upgrades', 'popup-maker' );
* Renders upgrade form on the tools page upgrade tab.
public function tools_page_tab_content() {
if ( ! $this->has_uncomplete_upgrades() ) {
_e( 'No upgrades currently required.', 'popup-maker' );
// Enqueue admin JS for the batch processor.
wp_enqueue_script( 'pum-admin-batch' );
wp_enqueue_style( 'pum-admin-batch' );
$this->render_upgrade_notice();