| 1 |
<?php |
| 2 |
|
| 3 |
require_once __DIR__ . '/api-group.php'; |
| 4 |
require_once __DIR__ . '/api-redirect.php'; |
| 5 |
require_once __DIR__ . '/api-log.php'; |
| 6 |
require_once __DIR__ . '/api-404.php'; |
| 7 |
require_once __DIR__ . '/api-settings.php'; |
| 8 |
require_once __DIR__ . '/api-plugin.php'; |
| 9 |
require_once __DIR__ . '/api-import.php'; |
| 10 |
require_once __DIR__ . '/api-export.php'; |
| 11 |
|
| 12 |
define( 'REDIRECTION_API_NAMESPACE', 'redirection/v1' ); |
| 13 |
|
| 14 |
/** |
| 15 |
* @apiDefine 401Error |
| 16 |
* |
| 17 |
* @apiError (Error 401) rest_forbidden You are not authorized to access this API endpoint |
| 18 |
* @apiErrorExample {json} 401 Error Response: |
| 19 |
* HTTP/1.1 401 Bad Request |
| 20 |
* { |
| 21 |
* "code": "rest_forbidden", |
| 22 |
* "message": "Sorry, you are not allowed to do that." |
| 23 |
* } |
| 24 |
*/ |
| 25 |
|
| 26 |
/** |
| 27 |
* @apiDefine 404Error |
| 28 |
* |
| 29 |
* @apiError (Error 404) rest_no_route Endpoint not found |
| 30 |
* @apiErrorExample {json} 404 Error Response: |
| 31 |
* HTTP/1.1 404 Not Found |
| 32 |
* { |
| 33 |
* "code": "rest_no_route", |
| 34 |
* "message": "No route was found matching the URL and request method" |
| 35 |
* } |
| 36 |
*/ |
| 37 |
|
| 38 |
/** |
| 39 |
* @apiDefine 400Error |
| 40 |
* |
| 41 |
* @apiError rest_forbidden You are not authorized to access this API endpoint |
| 42 |
* @apiErrorExample {json} 400 Error Response: |
| 43 |
* HTTP/1.1 400 Bad Request |
| 44 |
* { |
| 45 |
* "error": "invalid", |
| 46 |
* "message": "Invalid request" |
| 47 |
* } |
| 48 |
*/ |
| 49 |
|
| 50 |
/** |
| 51 |
* @apiDefine 400MissingError |
| 52 |
* @apiError (Error 400) rest_missing_callback_param Some required parameters are not present or not in the correct format |
| 53 |
* @apiErrorExample {json} 400 Error Response: |
| 54 |
* HTTP/1.1 400 Bad Request |
| 55 |
* { |
| 56 |
* "code": "rest_missing_callback_param", |
| 57 |
* "message": "Missing parameter(s): PARAM" |
| 58 |
* } |
| 59 |
*/ |
| 60 |
class Redirection_Api_Route { |
| 61 |
protected function add_error_details( WP_Error $error, $line, $code = 400 ) { |
| 62 |
global $wpdb; |
| 63 |
|
| 64 |
$data = array( |
| 65 |
'status' => $code, |
| 66 |
'error_code' => $line, |
| 67 |
); |
| 68 |
|
| 69 |
if ( isset( $wpdb->last_error ) && $wpdb->last_error ) { |
| 70 |
$data['wpdb'] = $wpdb->last_error; |
| 71 |
} |
| 72 |
|
| 73 |
$error->add_data( $data ); |
| 74 |
return $error; |
| 75 |
} |
| 76 |
|
| 77 |
public function permission_callback( WP_REST_Request $request ) { |
| 78 |
return Redirection_Capabilities::has_access( Redirection_Capabilities::CAP_PLUGIN ); |
| 79 |
} |
| 80 |
|
| 81 |
public function get_route( $method, $callback, $permissions = false ) { |
| 82 |
return [ |
| 83 |
'methods' => $method, |
| 84 |
'callback' => [ $this, $callback ], |
| 85 |
'permission_callback' => $permissions ? $permissions : [ $this, 'permission_callback' ], |
| 86 |
]; |
| 87 |
} |
| 88 |
} |
| 89 |
|
| 90 |
class Redirection_Api_Filter_Route extends Redirection_Api_Route { |
| 91 |
public function validate_filter( $value, $request, $param ) { |
| 92 |
$fields = $request->get_attributes()['args']['filterBy']['filter_fields']; |
| 93 |
|
| 94 |
if ( ! is_array( $value ) ) { |
| 95 |
return new WP_Error( 'rest_invalid_param', 'Filter is not an array', array( 'status' => 400 ) ); |
| 96 |
} |
| 97 |
|
| 98 |
if ( ! empty( $fields ) ) { |
| 99 |
foreach ( array_keys( $value ) as $key ) { |
| 100 |
if ( ! in_array( $key, $fields, true ) ) { |
| 101 |
return new WP_Error( 'rest_invalid_param', 'Filter type is not supported: ' . $key, array( 'status' => 400 ) ); |
| 102 |
} |
| 103 |
} |
| 104 |
} |
| 105 |
|
| 106 |
return true; |
| 107 |
} |
| 108 |
|
| 109 |
protected function get_filter_args( $order_fields, $filters = [] ) { |
| 110 |
return [ |
| 111 |
'filterBy' => [ |
| 112 |
'description' => 'Field to filter by', |
| 113 |
'validate_callback' => [ $this, 'validate_filter' ], |
| 114 |
'filter_fields' => $filters, |
| 115 |
], |
| 116 |
'orderby' => [ |
| 117 |
'description' => 'Field to order results by', |
| 118 |
'type' => 'string', |
| 119 |
'enum' => $order_fields, |
| 120 |
], |
| 121 |
'direction' => [ |
| 122 |
'description' => 'Direction of ordered results', |
| 123 |
'type' => 'string', |
| 124 |
'default' => 'desc', |
| 125 |
'enum' => [ 'asc', 'desc' ], |
| 126 |
], |
| 127 |
'per_page' => [ |
| 128 |
'description' => 'Number of results per page', |
| 129 |
'type' => 'integer', |
| 130 |
'default' => 25, |
| 131 |
'minimum' => 5, |
| 132 |
'maximum' => RED_MAX_PER_PAGE, |
| 133 |
], |
| 134 |
'page' => [ |
| 135 |
'description' => 'Page offset', |
| 136 |
'type' => 'integer', |
| 137 |
'minimum' => 0, |
| 138 |
'default' => 0, |
| 139 |
], |
| 140 |
]; |
| 141 |
} |
| 142 |
|
| 143 |
/** |
| 144 |
* Register a bulk action route |
| 145 |
* |
| 146 |
* @param String $namespace Namespace. |
| 147 |
* @param String $route Route. |
| 148 |
* @param Array $orders |
| 149 |
* @param Array $filters |
| 150 |
* @param Object $callback |
| 151 |
* @param boolean $permissions |
| 152 |
* @return void |
| 153 |
*/ |
| 154 |
public function register_bulk( $namespace, $route, $orders, $filters, $callback, $permissions = false ) { |
| 155 |
register_rest_route( $namespace, $route, array( |
| 156 |
$this->get_route( WP_REST_Server::EDITABLE, $callback, $permissions ), |
| 157 |
'args' => array_merge( $this->get_filter_args( $orders, $filters ), [ |
| 158 |
'items' => [ |
| 159 |
'description' => 'Comma separated list of item IDs to perform action on', |
| 160 |
'type' => 'array', |
| 161 |
'items' => [ |
| 162 |
'type' => 'string', |
| 163 |
], |
| 164 |
], |
| 165 |
] ), |
| 166 |
) ); |
| 167 |
} |
| 168 |
} |
| 169 |
|
| 170 |
class Redirection_Api { |
| 171 |
private static $instance = null; |
| 172 |
private $routes = array(); |
| 173 |
|
| 174 |
public static function init() { |
| 175 |
if ( is_null( self::$instance ) ) { |
| 176 |
self::$instance = new Redirection_Api(); |
| 177 |
} |
| 178 |
|
| 179 |
return self::$instance; |
| 180 |
} |
| 181 |
|
| 182 |
public function __construct() { |
| 183 |
global $wpdb; |
| 184 |
|
| 185 |
$wpdb->hide_errors(); |
| 186 |
|
| 187 |
$this->routes[] = new Redirection_Api_Redirect( REDIRECTION_API_NAMESPACE ); |
| 188 |
$this->routes[] = new Redirection_Api_Group( REDIRECTION_API_NAMESPACE ); |
| 189 |
$this->routes[] = new Redirection_Api_Log( REDIRECTION_API_NAMESPACE ); |
| 190 |
$this->routes[] = new Redirection_Api_404( REDIRECTION_API_NAMESPACE ); |
| 191 |
$this->routes[] = new Redirection_Api_Settings( REDIRECTION_API_NAMESPACE ); |
| 192 |
$this->routes[] = new Redirection_Api_Plugin( REDIRECTION_API_NAMESPACE ); |
| 193 |
$this->routes[] = new Redirection_Api_Import( REDIRECTION_API_NAMESPACE ); |
| 194 |
$this->routes[] = new Redirection_Api_Export( REDIRECTION_API_NAMESPACE ); |
| 195 |
} |
| 196 |
} |
| 197 |
|