• File: BaseRestApi.php
  • Full Path: /home/matthif/www/wp-content/plugins/optinmonster/OMAPI/BaseRestApi.php
  • Date Modified: 01/24/2025 1:58 PM
  • File size: 6.65 KB
  • MIME-type: text/x-php
  • Charset: utf-8
<?php
/**
 * Base Rest API Class, extend this if implementing a RestApi class.
 * Most of the code was migrated from OMAPI_RestApi.
 *
 * @since 2.8.0
 *
 * @package OMAPI
 * @author  Gabriel Oliveira and Eduardo Nakatsuka
 */

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

/**
 * Base Rest Api class.
 *
 * @since 2.8.0
 */
abstract class OMAPI_BaseRestApi {
    
/**
     * The Base OMAPI Object
     *
     *  @since 2.8.0
     *
     * @var OMAPI
     */
    
protected $base;

    
/**
     * The REST API Namespace
     *
     *  @since 2.8.0
     *
     * @var string The namespace
     */
    
protected $namespace 'omapp/v1';

    
/**
     * Whether request was given a valid api key.
     *
     *  @since 2.8.0
     *
     * @var null|bool
     */
    
protected $has_valid_api_key null;

    
/**
     * Build our object.
     *
     * @since 2.8.0
     */
    
public function __construct() {
        
$this->base OMAPI::get_instance();
        
$this->register_rest_routes();
    }

    
/**
     * Registers the Rest API routes for this class
     *
     * @since 2.8.0
     *
     * @return void
     */
    
abstract public function register_rest_routes();

    
/**
     * Determine if we can store settings.
     *
     * @since 2.0.0
     * @since 2.8.0 Migrated from OMAPI_RestApi
     *
     * @param  WP_REST_Request $request The REST Request.
     *
     * @return WP_Error|bool
     */
    
public function can_update_settings$request ) {
        try {

            
$this->verify_request_nonce$request );

        } catch ( 
Exception $e ) {
            return 
$this->exception_to_response$e );
        }

        return 
OMAPI::get_instance()->can_access'settings_update' );
    }

    
/**
     * Determine if OM API key is provided and valid.
     *
     * @since  1.9.10
     * @since 2.8.0 Migrated from OMAPI_RestApi
     *
     * @param  WP_REST_Request $request The REST Request.
     *
     * @return WP_Error|bool
     */
    
public function has_valid_api_key$request ) {
        
$header $request->get_header'X-OptinMonster-ApiKey' );

        
// Use this API Key to validate.
        
if ( ! $this->validate_api_key$header ) ) {
            return new 
WP_Error(
                
'omapp_rest_forbidden',
                
esc_html__'Could not verify your API Key.''optin-monster-api' ),
                array(
                    
'status' => rest_authorization_required_code(),
                )
            );
        }

        return 
$this->has_valid_api_key;
    }

    
/**
     * Determine if logged in or OM API key is provided and valid.
     *
     * @since  1.9.10
     * @since 2.8.0 Migrated from OMAPI_RestApi
     *
     * @param  WP_REST_Request $request The REST Request.
     *
     * @return bool
     */
    
public function logged_in_or_has_api_key$request ) {
        return 
$this->logged_in_and_can_access_route$request )
            || 
true === $this->has_valid_api_key$request );
    }

    
/**
     * Determine if logged in user can access this route (calls current_user_can).
     *
     * @since 2.6.4
     *
     * @param  WP_REST_Request $request The REST Request.
     *
     * @return bool
     */
    
public function logged_in_and_can_access_route$request ) {
        return 
OMAPI::get_instance()->can_access$request->get_route() );
    }

    
/**
     * Determine if the passed connection token is valid.
     *
     * @since 2.16.6
     *
     * @param WP_REST_Request $request The REST Request.
     *
     * @return WP_Error|bool
     */
    
public function has_connection_token$request ) {
        
$request_connection_token $request->get_param'connectionToken' );

        
$connection_token $this->base->get_option'connectionToken' );

        if ( 
'omwpoct_' $connection_token !== $request_connection_token ) {
            return new 
WP_Error(
                
'omapp_rest_forbidden',
                
esc_html__'Could not verify your connection token.''optin-monster-api' ),
                array(
                    
'status' => rest_authorization_required_code(),
                )
            );
        }

        return 
true;
    }

    
/**
     * Validate this API Key
     * We validate an API Key by fetching the Sites this key can fetch
     * And then confirming that this key has access to at least one of these sites
     *
     * @since 1.8.0
     * @since 2.8.0 Migrated from OMAPI_RestApi
     *
     * @param string $apikey The OM api key.
     *
     * @return bool True if the Key can be validated
     */
    
public function validate_api_key$apikey ) {
        
$this->has_valid_api_key OMAPI_ApiKey::validate$apikey );

        return 
$this->has_valid_api_key;
    }

    
/**
     * Convert an exception to a REST API WP_Error object.
     *
     * @since  2.0.0
     * @since 2.8.0 Migrated from OMAPI_RestApi
     *
     * @param  Exception $e The exception.
     *
     * @return WP_Error
     */
    
protected function exception_to_responseException $e ) {
        
// Return WP_Error objects directly.
        
if ( $e instanceof OMAPI_WpErrorException && $e->getWpError() ) {
            return 
$e->getWpError();
        }

        
$code $e->getCode();
        if ( empty( 
$code ) || $code 400 ) {
            
$code 400;
        }

        
$data = ! empty( $e->data ) ? $e->data : array();
        
$data wp_parse_args(
            
$data,
            array(
                
'status' => $code,
            )
        );

        
$error_code rest_authorization_required_code() === $code
            
'omapp_rest_forbidden'
            
'omapp_rest_error';

        return new 
WP_Error$error_code$e->getMessage(), $data );
    }

    
/**
     * Convert a WP_Error to a proper REST API WP_Error object.
     *
     * @since 2.6.5
     * @since 2.8.0 Migrated from OMAPI_RestApi
     *
     * @param  WP_Error $e The WP_Error object.
     * @param  mixed    $data Data to include in the error data.
     *
     * @return WP_Error
     */
    
protected function wp_error_to_responseWP_Error $e$data = array() ) {
        
$api OMAPI_Api::instance();

        
$data          is_array$data ) || is_object$data ) ? (array) $data : array();
        
$error_data    $e->get_error_data();
        
$error_message $e->get_error_message();
        
$error_code    $e->get_error_code();

        if ( empty( 
$error_data['status'] ) ) {

            
$status     is_numeric$error_data ) ? $error_data 400;
            
$error_code = (string) rest_authorization_required_code() === (string) $status
                
'omapp_rest_forbidden'
                
'omapp_rest_error';

            
$error_data wp_parse_args(
                array(
                    
'status' => $status,
                ),
                
$data
            
);

        } else {
            
$error_data wp_parse_args$error_data$data );
        }

        return new 
WP_Error$error_code$error_message$error_data );
    }

    
/**
     * Verify the request nonce and throw an exception if verification fails.
     *
     * @since  2.0.0
     * @since 2.8.0 Migrated from OMAPI_RestApi
     *
     * @param  WP_REST_Request $request The REST request.
     *
     * @return void
     *
     * @throws Exception If the nonce is missing or invalid.
     */
    
public function verify_request_nonce$request ) {
        
$nonce $request->get_param'nonce' );
        if ( empty( 
$nonce ) ) {
            
$nonce $request->get_header'X-WP-Nonce' );
        }

        if ( empty( 
$nonce ) ) {
            throw new 
Exceptionesc_html__'Missing security token!''optin-monster-api' ), rest_authorization_required_code() );
        }

        
// Check the nonce.
        
$result wp_verify_nonce$nonce'wp_rest' );
        if ( ! 
$result ) {
            throw new 
Exceptionesc_html__'Security token invalid!''optin-monster-api' ), rest_authorization_required_code() );
        }
    }
}