# mainwp/6.2.1/includes/rest-api/controller/version2/class-mainwp-rest-global-batch-controller.php

MainWP Dashboard: Self-hosted WordPress Management for Agencies, version 6.2.1. 663 lines.

- Page: https://pluginprobe.com/plugins/mainwp/6.2.1/code/includes/rest-api/controller/version2/class-mainwp-rest-global-batch-controller.php
- Raw: https://pluginprobe.com/plugins/mainwp/6.2.1/raw/includes/rest-api/controller/version2/class-mainwp-rest-global-batch-controller.php
- Modified: 2026-09-09T15:30:44+00:00

Line numbers below start at 1. Link to a line or a range by appending a fragment to the
page URL, for example `https://pluginprobe.com/plugins/mainwp/6.2.1/code/includes/rest-api/controller/version2/class-mainwp-rest-global-batch-controller.php#L10-L20`.

```php
<?php
/**
 * MainWP REST Controller
 *
 * This class handles the REST API
 *
 * @package MainWP\Dashboard
 */

// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

/**
 * Class MainWP_Rest_Global_Batch_Controller
 *
 * @package MainWP\Dashboard
 */
class MainWP_Rest_Global_Batch_Controller extends MainWP_REST_Controller{ //phpcs:ignore -- NOSONAR - multi methods.

    /**
     * Protected static variable to hold the single instance of the class.
     *
     * @var mixed Default null
     */
    private static $instance = null;

    /**
     * Endpoint namespace.
     *
     * @var string
     */
    protected $namespace = 'mainwp/v2';

    /**
     * Route base.
     *
     * @var string
     */
    protected $rest_base = 'batch';

    /**
     * Controller names handled by the batch endpoint.
     *
     * @var array
     */
    protected $controller_names = array( 'sites', 'clients', 'tags' );

    /**
     * Actions the dispatch below reads per group, each marked with the shape it reads its items in:
     * an 'item' action passes every item on as a request body, an 'id' action casts every item to an int.
     *
     * @var array
     */
    const GROUP_ACTIONS = array(
        'sites'   => array(
            'create'             => 'item',
            'sync'               => 'id',
            'reconnect'          => 'id',
            'disconnect'         => 'id',
            'suspend'            => 'id',
            'check'              => 'id',
            'remove'             => 'id',
            'security'           => 'id',
            'plugins'            => 'id',
            'themes'             => 'id',
            'non-mainwp-changes' => 'id',
        ),
        'clients' => array(
            'create' => 'item',
        ),
        'tags'    => array(
            'create' => 'item',
        ),
    );

    /**
     * Method instance()
     *
     * Create public static instance.
     *
     * @static
     * @return static::$instance
     */
    public static function instance() {
        if ( null === static::$instance ) {
            static::$instance = new self();
        }
        return static::$instance;
    }

    /**
     * Method register_routes()
     *
     * Creates the necessary endpoints for the api.
     * Note, for a request to be successful the URL query parameters consumer_key and consumer_secret need to be set and correct.
     */
    public function register_routes() { // phpcs:ignore -- NOSONAR - complex.
        register_rest_route(
            $this->namespace,
            '/' . $this->rest_base,
            array(
                array(
                    'methods'             => WP_REST_Server::EDITABLE,
                    'callback'            => array( $this, 'batch_items' ),
                    'permission_callback' => array( $this, 'get_rest_permissions_check' ),
                ),
            )
        );
    }

    /**
     * Resolve a batch group's controller.
     *
     * Module controllers register under a namespace key of their own
     * (the Cost Tracker uses mainwp/v2/costs), so a miss on the shared
     * namespace is retried under the group's key before it is treated
     * as an unregistered group.
     *
     * @param string $con_name Group name.
     * @return MainWP_REST_Controller|false
     */
    private function get_batch_controller( $con_name ) {
        $server     = MainWP_Rest_Server::instance();
        $controller = $server->get_rest_controller( $this->namespace, $con_name );
        if ( false === $controller ) {
            $controller = $server->get_rest_controller( $this->namespace . '/' . $con_name, $con_name );
        }
        return $controller;
    }

    /**
     * Bulk create, update and delete items.
     *
     * @param WP_REST_Request $request Full details about the request.
     * @return array Of WP_Error or WP_REST_Response.
     */
    public function batch_items( $request ) { //phpcs:ignore -- NOSONAR complex function.
        /**
         * REST Server
         *
         * @var WP_REST_Server $wp_rest_server
         */
        global $wp_rest_server;

        // Get the request params.
        $all_params = $request->get_params();
        $items      = array_filter( $all_params );
        $query      = $request->get_query_params();
        $response   = array();

        $body_groups = $request->get_json_params();
        if ( empty( $body_groups ) || ! is_array( $body_groups ) ) {
            $body_groups = (array) $request->get_body_params();
        }

        // Groups the batch endpoint cannot dispatch (updates has no batch-capable create handler,
        // costs has no controller at all, anything else is unknown) are reported once each instead
        // of being dropped without a word or failing per item with a 405 from the core stub.
        //
        // The names come from the same merged params the limit check and the dispatch read, so a
        // group sent only in the query string is answered rather than counted in silence. A group is
        // always an array there, so scalar params (per_page, the auth keys) name none. The body is
        // read on top of that because a falsy group is filtered out of the items, and because for an
        // unsupported name the value does not matter, so a scalar body group is reported too.
        // Whichever source it came from, an underscore parameter is one WordPress reserves for the
        // REST server itself (_fields, _embed, _locale) and never a group the caller named.
        $groups = array();
        foreach ( $items as $param_name => $param_value ) {
            if ( is_array( $param_value ) && 0 !== strpos( (string) $param_name, '_' ) ) {
                $groups[ $param_name ] = true;
            }
        }
        foreach ( array_keys( $body_groups ) as $body_group_name ) {
            if ( 0 !== strpos( (string) $body_group_name, '_' ) ) {
                $groups[ $body_group_name ] = true;
            }
        }

        foreach ( array_keys( $groups ) as $group_name ) {
            if ( ! in_array( $group_name, $this->controller_names, true ) ) {
                $response[ $group_name ] = array(
                    'error' => array(
                        'code'    => 'rest_batch_group_not_supported',
                        /* translators: %s: batch group name */
                        'message' => sprintf( __( 'The %s group is not supported by the batch endpoint.', 'mainwp' ), $group_name ),
                        'data'    => array( 'status' => 400 ),
                    ),
                );
            }
        }

        // Shapes are checked against the items the dispatch below reads, not against the body, so a
        // group sent as a query parameter cannot skip the check. The group is dropped from the items
        // as well as reported, so nothing in it is dispatched.
        foreach ( $this->controller_names as $group_name ) {
            if ( isset( $items[ $group_name ] ) ) {
                $group_items = $items[ $group_name ];
            } elseif ( array_key_exists( $group_name, $body_groups ) ) {
                // A falsy group is filtered out of the items, so it is read back from the body to be
                // reported rather than passed over.
                $group_items = $body_groups[ $group_name ];
            } elseif ( array_key_exists( $group_name, $all_params ) ) {
                // A falsy group sent only in the query string is in neither of the above, and
                // skipping it answered the whole request with an empty success.
                $group_items = $all_params[ $group_name ];
            } else {
                continue;
            }

            if ( ! $this->is_dispatchable_group( $group_name, $group_items ) ) {
                $response[ $group_name ] = array(
                    'error' => array(
                        'code'    => 'rest_invalid_param',
                        /* translators: %s: batch group name */
                        'message' => sprintf( __( 'The %s group must be an object of supported action arrays.', 'mainwp' ), $group_name ),
                        'data'    => array( 'status' => 400 ),
                    ),
                );
                unset( $items[ $group_name ] );
            }
        }

        // Counted after the malformed groups are dropped: nothing in them is dispatched, so their items
        // must not be what pushes a request over the cap and hides the per-group error behind a 413.
        $limit = $this->check_batch_limit( $items );
        if ( is_wp_error( $limit ) ) {
            return $limit;
        }

        foreach ( $this->controller_names as $con_name ) {

            $controller_obj = $this->get_batch_controller( $con_name );

            if ( false === $controller_obj ) {
                continue;
            }

            if ( ! empty( $items[ $con_name ]['create'] ) ) {
                foreach ( $items[ $con_name ]['create'] as $item ) {
                    // Default parameters.
                    $defaults = array();
                    $schema   = $controller_obj->get_public_item_schema();

                    foreach ( $schema['properties'] as $arg => $options ) {
                        if ( isset( $options['default'] ) ) {
                            $defaults[ $arg ] = $options['default'];
                        }
                    }

                    $_item     = $this->prepare_batch_create_request( $request->get_route(), $item, $controller_obj->get_batch_create_args(), $defaults, $query );
                    $_response = is_wp_error( $_item ) ? $_item : $controller_obj->create_item( $_item );

                    if ( is_wp_error( $_response ) ) {
                        $response[ $con_name ]['create'][] = array(
                            'id'    => 0,
                            'error' => array(
                                'code'    => $_response->get_error_code(),
                                'message' => $_response->get_error_message(),
                                'data'    => $_response->get_error_data(),
                            ),
                        );
                    } else {
                        $response[ $con_name ]['create'][] = $wp_rest_server->response_to_data( $_response, '' );
                    }
                }
            }

            // check_batch_limit() counts update and delete items for every group, so they
            // are dispatched here the same way the per-controller batch route dispatches them.
            if ( ! empty( $items[ $con_name ]['update'] ) ) {
                foreach ( $items[ $con_name ]['update'] as $item ) {
                    $_item     = $this->prepare_batch_update_request( $request->get_route(), $item, $controller_obj->get_batch_update_args() );
                    $_response = is_wp_error( $_item ) ? $_item : $controller_obj->update_item( $_item );

                    if ( is_wp_error( $_response ) ) {
                        $response[ $con_name ]['update'][] = array(
                            'id'    => is_array( $item ) ? $this->batch_error_id( $item['id'] ?? 0 ) : 0,
                            'error' => array(
                                'code'    => $_response->get_error_code(),
                                'message' => $_response->get_error_message(),
                                'data'    => $_response->get_error_data(),
                            ),
                        );
                    } else {
                        $response[ $con_name ]['update'][] = $wp_rest_server->response_to_data( $_response, '' );
                    }
                }
            }

            if ( ! empty( $items[ $con_name ]['delete'] ) ) {
                foreach ( $items[ $con_name ]['delete'] as $id ) {
                    $_item     = $this->prepare_batch_id_request( $request->get_route(), $id, array( 'force' => true ), $controller_obj->get_batch_delete_args() );
                    $_response = is_wp_error( $_item ) ? $_item : $controller_obj->delete_item( $_item );

                    if ( is_wp_error( $_response ) ) {
                        $response[ $con_name ]['delete'][] = array(
                            'id'    => $this->batch_error_id( $id ),
                            'error' => array(
                                'code'    => $_response->get_error_code(),
                                'message' => $_response->get_error_message(),
                                'data'    => $_response->get_error_data(),
                            ),
                        );
                    } else {
                        $response[ $con_name ]['delete'][] = $wp_rest_server->response_to_data( $_response, '' );
                    }
                }
            }
        }

        $con_name = 'sites';

        $controller_obj = MainWP_Rest_Server::instance()->get_rest_controller( $this->namespace, $con_name );

        if ( $controller_obj ) {
            if ( ! empty( $items[ $con_name ]['sync'] ) ) {
                foreach ( $items[ $con_name ]['sync'] as $id ) {
                    $_item     = $this->prepare_batch_id_request( $request->get_route(), $id );
                    $_response = is_wp_error( $_item ) ? $_item : $controller_obj->sync_item( $_item );

                    if ( is_wp_error( $_response ) ) {
                        $response[ $con_name ]['sync'][] = array(
                            'id'    => $this->batch_error_id( $id ),
                            'error' => array(
                                'code'    => $_response->get_error_code(),
                                'message' => $_response->get_error_message(),
                                'data'    => $_response->get_error_data(),
                            ),
                        );
                    } else {
                        $response[ $con_name ]['sync'][] = $wp_rest_server->response_to_data( $_response, '' );
                    }
                }
            }

            if ( ! empty( $items[ $con_name ]['reconnect'] ) ) {
                foreach ( $items[ $con_name ]['reconnect'] as $id ) {
                    $_item     = $this->prepare_batch_id_request( $request->get_route(), $id );
                    $_response = is_wp_error( $_item ) ? $_item : $controller_obj->reconnect_item( $_item );

                    if ( is_wp_error( $_response ) ) {
                        $response[ $con_name ]['reconnect'][] = array(
                            'id'    => $this->batch_error_id( $id ),
                            'error' => array(
                                'code'    => $_response->get_error_code(),
                                'message' => $_response->get_error_message(),
                                'data'    => $_response->get_error_data(),
                            ),
                        );
                    } else {
                        $response[ $con_name ]['reconnect'][] = $wp_rest_server->response_to_data( $_response, '' );
                    }
                }
            }

            if ( ! empty( $items[ $con_name ]['disconnect'] ) ) {
                foreach ( $items[ $con_name ]['disconnect'] as $id ) {
                    $_item     = $this->prepare_batch_id_request( $request->get_route(), $id );
                    $_response = is_wp_error( $_item ) ? $_item : $controller_obj->disconnect_site( $_item );

                    if ( is_wp_error( $_response ) ) {
                        $response[ $con_name ]['disconnect'][] = array(
                            'id'    => $this->batch_error_id( $id ),
                            'error' => array(
                                'code'    => $_response->get_error_code(),
                                'message' => $_response->get_error_message(),
                                'data'    => $_response->get_error_data(),
                            ),
                        );
                    } else {
                        $response[ $con_name ]['disconnect'][] = $wp_rest_server->response_to_data( $_response, '' );
                    }
                }
            }

            if ( ! empty( $items[ $con_name ]['suspend'] ) ) {
                foreach ( $items[ $con_name ]['suspend'] as $id ) {
                    $_item     = $this->prepare_batch_id_request( $request->get_route(), $id );
                    $_response = is_wp_error( $_item ) ? $_item : $controller_obj->suspend_item( $_item );

                    if ( is_wp_error( $_response ) ) {
                        $response[ $con_name ]['suspend'][] = array(
                            'id'    => $this->batch_error_id( $id ),
                            'error' => array(
                                'code'    => $_response->get_error_code(),
                                'message' => $_response->get_error_message(),
                                'data'    => $_response->get_error_data(),
                            ),
                        );
                    } else {
                        $response[ $con_name ]['suspend'][] = $wp_rest_server->response_to_data( $_response, '' );
                    }
                }
            }

            if ( ! empty( $items[ $con_name ]['check'] ) ) {
                foreach ( $items[ $con_name ]['check'] as $id ) {
                    $_item     = $this->prepare_batch_id_request( $request->get_route(), $id );
                    $_response = is_wp_error( $_item ) ? $_item : $controller_obj->check_item( $_item );

                    if ( is_wp_error( $_response ) ) {
                        $response[ $con_name ]['check'][] = array(
                            'id'    => $this->batch_error_id( $id ),
                            'error' => array(
                                'code'    => $_response->get_error_code(),
                                'message' => $_response->get_error_message(),
                                'data'    => $_response->get_error_data(),
                            ),
                        );
                    } else {
                        $response[ $con_name ]['check'][] = $wp_rest_server->response_to_data( $_response, '' );
                    }
                }
            }

            if ( ! empty( $items[ $con_name ]['remove'] ) ) {
                foreach ( $items[ $con_name ]['remove'] as $id ) {
                    $_item     = $this->prepare_batch_id_request( $request->get_route(), $id );
                    $_response = is_wp_error( $_item ) ? $_item : $controller_obj->delete_item( $_item );

                    if ( is_wp_error( $_response ) ) {
                        $response[ $con_name ]['remove'][] = array(
                            'id'    => $this->batch_error_id( $id ),
                            'error' => array(
                                'code'    => $_response->get_error_code(),
                                'message' => $_response->get_error_message(),
                                'data'    => $_response->get_error_data(),
                            ),
                        );
                    } else {
                        $response[ $con_name ]['remove'][] = $wp_rest_server->response_to_data( $_response, '' );
                    }
                }
            }

            if ( ! empty( $items[ $con_name ]['security'] ) ) {
                foreach ( $items[ $con_name ]['security'] as $id ) {
                    $_item     = $this->prepare_batch_id_request( $request->get_route(), $id );
                    $_response = is_wp_error( $_item ) ? $_item : $controller_obj->security_item( $_item );

                    if ( is_wp_error( $_response ) ) {
                        $response[ $con_name ]['security'][] = array(
                            'id'    => $this->batch_error_id( $id ),
                            'error' => array(
                                'code'    => $_response->get_error_code(),
                                'message' => $_response->get_error_message(),
                                'data'    => $_response->get_error_data(),
                            ),
                        );
                    } else {
                        $response[ $con_name ]['security'][] = $wp_rest_server->response_to_data( $_response, '' );
                    }
                }
            }

            if ( ! empty( $items[ $con_name ]['plugins'] ) ) {
                foreach ( $items[ $con_name ]['plugins'] as $id ) {
                    $_item     = $this->prepare_batch_id_request( $request->get_route(), $id );
                    $_response = is_wp_error( $_item ) ? $_item : $controller_obj->get_site_plugins( $_item );

                    if ( is_wp_error( $_response ) ) {
                        $response[ $con_name ]['plugins'][] = array(
                            'id'    => $this->batch_error_id( $id ),
                            'error' => array(
                                'code'    => $_response->get_error_code(),
                                'message' => $_response->get_error_message(),
                                'data'    => $_response->get_error_data(),
                            ),
                        );
                    } else {
                        $response[ $con_name ]['plugins'][] = $wp_rest_server->response_to_data( $_response, '' );
                    }
                }
            }

            if ( ! empty( $items[ $con_name ]['themes'] ) ) {
                foreach ( $items[ $con_name ]['themes'] as $id ) {
                    $_item     = $this->prepare_batch_id_request( $request->get_route(), $id );
                    $_response = is_wp_error( $_item ) ? $_item : $controller_obj->get_site_themes( $_item );

                    if ( is_wp_error( $_response ) ) {
                        $response[ $con_name ]['themes'][] = array(
                            'id'    => $this->batch_error_id( $id ),
                            'error' => array(
                                'code'    => $_response->get_error_code(),
                                'message' => $_response->get_error_message(),
                                'data'    => $_response->get_error_data(),
                            ),
                        );
                    } else {
                        $response[ $con_name ]['themes'][] = $wp_rest_server->response_to_data( $_response, '' );
                    }
                }
            }

            if ( ! empty( $items[ $con_name ]['non-mainwp-changes'] ) ) {
                foreach ( $items[ $con_name ]['non-mainwp-changes'] as $id ) {
                    $_item     = $this->prepare_batch_id_request( $request->get_route(), $id );
                    $_response = is_wp_error( $_item ) ? $_item : $controller_obj->get_non_mainwp_changes_of_site( $_item );

                    if ( is_wp_error( $_response ) ) {
                        $response[ $con_name ]['non-mainwp-changes'][] = array(
                            'id'    => $this->batch_error_id( $id ),
                            'error' => array(
                                'code'    => $_response->get_error_code(),
                                'message' => $_response->get_error_message(),
                                'data'    => $_response->get_error_data(),
                            ),
                        );
                    } else {
                        $response[ $con_name ]['non-mainwp-changes'][] = $wp_rest_server->response_to_data( $_response, '' );
                    }
                }
            }
        }

        return $response;
    }


    /**
     * Check that a group carries only what the dispatch below can read.
     *
     * The dispatch indexes the group by action name and then walks each action list, so a scalar in
     * either place would reach a foreach over something that is not a list, a JSON list carries none
     * of the names it indexes by, and an action it does not read is silently dropped. Items are
     * checked too: a create item is passed on as a request body and an id item is cast to an int, so
     * neither can be an arbitrary value.
     *
     * @param string $group_name  Group name.
     * @param mixed  $group_items Group value taken from the request.
     * @return bool
     */
    private function is_dispatchable_group( $group_name, $group_items ) {
        if ( ! is_array( $group_items ) ) {
            return false;
        }

        // An empty group dispatches nothing and is not the caller getting the shape wrong. It is
        // taken out of the list test as well, which range() cannot answer for a count of zero.
        if ( array() === $group_items ) {
            return true;
        }

        if ( array_keys( $group_items ) === range( 0, count( $group_items ) - 1 ) ) {
            return false;
        }

        $actions = isset( self::GROUP_ACTIONS[ $group_name ] ) ? self::GROUP_ACTIONS[ $group_name ] : array();

        foreach ( $group_items as $action_name => $action_items ) {
            if ( ! isset( $actions[ $action_name ] ) || ! is_array( $action_items ) ) {
                return false;
            }

            // The dispatch walks an action as a list, so an object of named items would be
            // dispatched by its values with the names dropped and nothing said about the shape. An
            // empty action dispatches nothing, and range() cannot answer for a count of zero.
            if ( array() !== $action_items && array_keys( $action_items ) !== range( 0, count( $action_items ) - 1 ) ) {
                return false;
            }

            foreach ( $action_items as $item ) {
                if ( 'item' === $actions[ $action_name ] ) {
                    if ( ! is_array( $item ) ) {
                        return false;
                    }
                } elseif ( ! ( is_int( $item ) && $item > 0 ) && ! ( is_string( $item ) && ctype_digit( $item ) && (int) $item > 0 && ltrim( $item, '0' ) === (string) (int) $item ) ) {
                    // A fractional or exponent string is numeric, and the (int) cast below would read
                    // it as a whole id the caller never asked for, so only digits are accepted. Zero
                    // is refused with them: every site action skips an id that casts to 0, so the
                    // batch would answer with neither an operation nor an error for that item. A digit
                    // string past PHP_INT_MAX casts to PHP_INT_MAX, a different id than the one sent.
                    return false;
                }
            }
        }

        return true;
    }

    /**
     * Check batch limit.
     *
     * @param array $items Request items.
     * @return bool|WP_Error
     */
    protected function check_batch_limit( $items ) { //phpcs:ignore -- NOSONAR complex function.
        $limit = apply_filters( 'mainwp_rest_batch_items_limit', 100, $this->get_normalized_rest_base() );
        $total = 0;

        // The updates and costs groups are rejected as a whole by batch_items(), but their items
        // still count toward the cap so an oversized request is refused before anything else is
        // dispatched.
        $count_names = array_merge( $this->controller_names, array( 'updates', 'costs' ) );

        foreach ( $count_names as $con_name ) {
            if ( ! empty( $items[ $con_name ] ) && is_countable( $items[ $con_name ] ) ) {
                if ( ! empty( $items[ $con_name ]['create'] ) && is_countable( $items[ $con_name ]['create'] ) ) {
                    $total += count( $items[ $con_name ]['create'] );
                }

                if ( ! empty( $items[ $con_name ]['update'] ) && is_countable( $items[ $con_name ]['update'] ) ) {
                    $total += count( $items[ $con_name ]['update'] );
                }

                if ( ! empty( $items[ $con_name ]['delete'] ) && is_countable( $items[ $con_name ]['delete'] ) ) {
                    $total += count( $items[ $con_name ]['delete'] );
                }
            }
        }

        if ( ! empty( $items['sites']['sync'] ) && is_countable( $items['sites']['sync'] ) ) {
            $total += count( $items['sites']['sync'] );
        }

        if ( ! empty( $items['sites']['reconnect'] ) && is_countable( $items['sites']['reconnect'] ) ) {
            $total += count( $items['sites']['reconnect'] );
        }

        if ( ! empty( $items['sites']['disconnect'] ) && is_countable( $items['sites']['disconnect'] ) ) {
            $total += count( $items['sites']['disconnect'] );
        }

        if ( ! empty( $items['sites']['suspend'] ) && is_countable( $items['sites']['suspend'] ) ) {
            $total += count( $items['sites']['suspend'] );
        }

        if ( ! empty( $items['sites']['check'] ) && is_countable( $items['sites']['check'] ) ) {
            $total += count( $items['sites']['check'] );
        }

        if ( ! empty( $items['sites']['remove'] ) && is_countable( $items['sites']['remove'] ) ) {
            $total += count( $items['sites']['remove'] );
        }

        if ( ! empty( $items['sites']['security'] ) && is_countable( $items['sites']['security'] ) ) {
            $total += count( $items['sites']['security'] );
        }

        if ( ! empty( $items['sites']['plugins'] ) && is_countable( $items['sites']['plugins'] ) ) {
            $total += count( $items['sites']['plugins'] );
        }

        if ( ! empty( $items['sites']['themes'] ) && is_countable( $items['sites']['themes'] ) ) {
            $total += count( $items['sites']['themes'] );
        }

        if ( ! empty( $items['sites']['non-mainwp-changes'] ) && is_countable( $items['sites']['non-mainwp-changes'] ) ) {
            $total += count( $items['sites']['non-mainwp-changes'] );
        }

        if ( $total > $limit ) {
            /* translators: %s: items limit */
            return new WP_Error( 'mainwp_rest_request_entity_too_large', sprintf( __( 'Unable to accept more than %s items for this request.', 'mainwp' ), $limit ), array( 'status' => 413 ) );
        }

        return true;
    }
}

```
