PluginProbe
Redirection / 4.6.2
Redirection v4.6.2
5.10.0 5.9.0 5.8.1 5.8.0 3.7.2 3.7.3 4.0 4.0.1 4.1 4.1.1 4.2 4.2.1 4.2.2 4.2.3 4.3 4.3.1 4.3.2 4.3.3 4.4 4.4.1 4.4.2 4.5 4.5.1 4.6.2 4.7.1 All 130 releases
redirection / api / api-redirect.php

api-redirect.php in Redirection 4.6.2, at api/api-redirect.php

317 lines 11.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * @api {get} /redirection/v1/redirect Get redirects
5 * @apiName GetRedirects
6 * @apiDescription Get a paged list of redirects based after applying a set of filters and result ordering.
7 * @apiGroup Redirect
8 *
9 * @apiUse RedirectQueryParams
10 *
11 * @apiUse RedirectList
12 * @apiUse 401Error
13 * @apiUse 404Error
14 */
15
16 /**
17 * @api {post} /redirection/v1/redirect Create redirect
18 * @apiName CreateRedirect
19 * @apiDescription Create a new redirect, and return a paged list of redirects.
20 * @apiGroup Redirect
21 *
22 * @apiUse RedirectItem
23 * @apiUse RedirectQueryParams
24 *
25 * @apiUse RedirectList
26 * @apiUse 401Error
27 * @apiUse 404Error
28 * @apiError (Error 400) redirect_create_failed Failed to create redirect
29 * @apiErrorExample {json} 404 Error Response:
30 * HTTP/1.1 400 Bad Request
31 * {
32 * "code": "redirect_create_failed",
33 * "message": "Failed to create redirect"
34 * }
35 */
36
37 /**
38 * @api {post} /redirection/v1/redirect/:id Update redirect
39 * @apiName UpdateRedirect
40 * @apiDescription Update an existing redirect.
41 * @apiGroup Redirect
42 *
43 * @apiParam (URL) {Integer} :id Redirect ID to update
44 *
45 * @apiUse RedirectItem
46 *
47 * @apiUse RedirectList
48 * @apiUse 401Error
49 * @apiUse 404Error
50 * @apiError (Error 400) redirect_update_failed Failed to update redirect
51 * @apiErrorExample {json} 404 Error Response:
52 * HTTP/1.1 400 Bad Request
53 * {
54 * "code": "redirect_update_failed",
55 * "message": "Failed to update redirect"
56 * }
57 */
58
59 /**
60 * @api {post} /redirection/v1/bulk/redirect/:type Bulk redirect action
61 * @apiName BulkAction
62 * @apiDescription Enable, disable, and delete a set of redirects. The endpoint will return the next page of results after.
63 * performing the action, based on the supplied query parameters. This information can be used to refresh a list displayed to the client.
64 * @apiGroup Redirect
65 *
66 * @apiParam (URL) {String="delete","enable","disable"} :type Type of bulk action that is applied to every group ID.
67 *
68 * @apiParam (Query Parameter) {Integer[]} items Array of redirect IDs to perform the action on
69 * @apiUse RedirectQueryParams
70 *
71 * @apiUse RedirectList
72 * @apiUse 401Error
73 * @apiUse 404Error
74 * @apiUse 400MissingError
75 * @apiError (Error 400) redirect_invalid_items Invalid array of items
76 * @apiErrorExample {json} 404 Error Response:
77 * HTTP/1.1 400 Bad Request
78 * {
79 * "code": "redirect_invalid_items",
80 * "message": "Invalid array of items"
81 * }
82 */
83
84 /**
85 * @apiDefine RedirectItem Redirect
86 * All data associated with a redirect
87 *
88 * @apiParam {String="enabled","disabled"} status Status of the redirect
89 * @apiParam {Integer} position Redirect position, used to determine order multiple redirects occur
90 * @apiParam {Object} match_data Additional match parameters
91 * @apiParam {Object} match_data.source Match against the source
92 * @apiParam {Boolean} match_data.source.flag_regex `true` for regular expression, `false` otherwise
93 * @apiParam {String="ignore","exact","pass"} match_data.source.flag_query Which query parameter matching to use
94 * @apiParam {Boolean} match_data.source.flag_case] `true` for case insensitive matches, `false` otherwise
95 * @apiParam {Boolean} match_data.source.flag_trailing] `true` to ignore trailing slashes, `false` otherwise
96 * @apiParam {Boolean} regex True for regular expression, `false` otherwise
97 * @apiParam {String} url The source URL
98 * @apiParam {String="url","referrer","agent","login","header","custom","cookie","role","server","ip","page","language"} match_type What URL matching to use
99 * @apiParam {String} [title] A descriptive title for the redirect, or empty for no title
100 * @apiParam {Integer} group_id The group this redirect belongs to
101 * @apiParam {String} action_type What to do when the URL is matched
102 * @apiParam {Integer} action_code The HTTP code to return
103 * @apiParam {String} action_data Any data associated with the `action_type` and `match_type`. For example, the target URL
104 */
105
106 /**
107 * @apiDefine RedirectList A list of redirects
108 * A list of redirects
109 *
110 * @apiSuccess {Object[]} items Array of redirect objects
111 * @apiSuccess {Integer} items.id ID of redirect
112 * @apiSuccess {String} items.url Source URL to match
113 * @apiSuccess {String} items.match_url Match URL
114 * @apiSuccess {Object} items.match_data Match against the source
115 * @apiSuccess {String} items.match_type What URL matching to use
116 * @apiSuccess {String} items.action_type What to do when the URL is matched
117 * @apiSuccess {Integer} items.action_code The HTTP code to return
118 * @apiSuccess {String} items.action_data Any data associated with the action_type. For example, the target URL
119 * @apiSuccess {String} items.title Optional A descriptive title for the redirect, or empty for no title
120 * @apiSuccess {String} items.hits Number of hits this redirect has received
121 * @apiSuccess {String} items.regex True for regular expression, false otherwise
122 * @apiSuccess {String} items.group_id The group this redirect belongs to
123 * @apiSuccess {String} items.position Redirect position, used to determine order multiple redirects occur
124 * @apiSuccess {String} items.last_access The date this redirect was last hit
125 * @apiSuccess {String} items.status Status of the redirect
126 * @apiSuccess {Integer} total Number of items
127 *
128 * @apiSuccessExample {json} Success-Response:
129 * HTTP/1.1 200 OK
130 * {
131 * "items": [
132 * {
133 * id: 3,
134 * url: "/source",
135 * match_url: "/source",
136 * match_data: "",
137 * action_code: "",
138 * action_type: "",
139 * action_data: "",
140 * match_type: "url",
141 * title: "Redirect title",
142 * hits: 5,
143 * regex: true,
144 * group_id: 15,
145 * position: 1,
146 * last_access: "2019-01-01 01:01:01"
147 * status: "enabled"
148 * }
149 * ],
150 * "total": 1
151 * }
152 */
153
154 /**
155 * @apiDefine RedirectQueryParams
156 *
157 * @apiParam (Query Parameter) {String="enabled","disabled"} filterBy[status] Filter the results by the supplied status
158 * @apiParam (Query Parameter) {String} filterBy[url] Filter the results by the supplied URL
159 * @apiParam (Query Parameter) {String="regular","plain"} filterBy[url-match] Filter the results by `regular` expressions or non regular expressions
160 * @apiParam (Query Parameter) {String} filterBy[match] Filter the results by the supplied match type
161 * @apiParam (Query Parameter) {String} filterBy[action] Filter the results by the supplied action type
162 * @apiParam (Query Parameter) {Integer} filterBy[http] Filter the results by the supplied redirect HTTP code
163 * @apiParam (Query Parameter) {String="year","month","all"} filterBy[access] Filter the results by how long the redirect was last accessed
164 * @apiParam (Query Parameter) {String} filterBy[target] Filter the results by the supplied redirect target
165 * @apiParam (Query Parameter) {String} filterBy[title] Filter the results by the supplied redirect title
166 * @apiParam (Query Parameter) {Integer} filterBy[group] Filter the results by the supplied redirect group ID
167 * @apiParam (Query Parameter) {Integer="1","2","3"} filterBy[module] Filter the results by the supplied module ID
168 * @apiParam (Query Parameter) {String="url","last_count","last_access","position","id"} orderby Order in which results are returned
169 * @apiParam (Query Parameter) {String="asc","desc"} direction Direction to order the results by (ascending or descending)
170 * @apiParam (Query Parameter) {Integer{1...200}} per_page Number of results per request
171 * @apiParam (Query Parameter) {Integer} page Current page of results
172 */
173 class Redirection_Api_Redirect extends Redirection_Api_Filter_Route {
174 public function __construct( $namespace ) {
175 $orders = [ 'url', 'last_count', 'last_access', 'position', 'id' ];
176 $filters = [ 'status', 'url-match', 'match', 'action', 'http', 'access', 'url', 'target', 'title', 'group' ];
177
178 register_rest_route( $namespace, '/redirect', array(
179 'args' => $this->get_filter_args( $orders, $filters ),
180 $this->get_route( WP_REST_Server::READABLE, 'route_list', [ $this, 'permission_callback_manage' ] ),
181 $this->get_route( WP_REST_Server::EDITABLE, 'route_create', [ $this, 'permission_callback_add' ] ),
182 ) );
183
184 register_rest_route( $namespace, '/redirect/(?P<id>[\d]+)', array(
185 $this->get_route( WP_REST_Server::EDITABLE, 'route_update', [ $this, 'permission_callback_add' ] ),
186 ) );
187
188 register_rest_route( $namespace, '/redirect/post', array(
189 $this->get_route( WP_REST_Server::READABLE, 'route_match_post', [ $this, 'permission_callback_manage' ] ),
190 'args' => [
191 'text' => [
192 'description' => 'Text to match',
193 'type' => 'string',
194 ],
195 ],
196 ) );
197
198 $this->register_bulk( $namespace, '/bulk/redirect/(?P<bulk>delete|enable|disable|reset)', $orders, 'route_bulk', [ $this, 'permission_callback_bulk' ] );
199 }
200
201 public function permission_callback_manage( WP_REST_Request $request ) {
202 return Redirection_Capabilities::has_access( Redirection_Capabilities::CAP_REDIRECT_MANAGE );
203 }
204
205 public function permission_callback_bulk( WP_REST_Request $request ) {
206 if ( $request['bulk'] === 'delete' ) {
207 return Redirection_Capabilities::has_access( Redirection_Capabilities::CAP_REDIRECT_DELETE );
208 }
209
210 return $this->permission_callback_add( $request );
211 }
212
213 public function permission_callback_add( WP_REST_Request $request ) {
214 return Redirection_Capabilities::has_access( Redirection_Capabilities::CAP_REDIRECT_ADD );
215 }
216
217 public function route_list( WP_REST_Request $request ) {
218 return Red_Item::get_filtered( $request->get_params() );
219 }
220
221 public function route_create( WP_REST_Request $request ) {
222 $params = $request->get_params();
223 $urls = array();
224
225 if ( isset( $params['url'] ) ) {
226 $urls = array( $params['url'] );
227
228 if ( is_array( $params['url'] ) ) {
229 $urls = $params['url'];
230 }
231
232 foreach ( $urls as $url ) {
233 $params['url'] = $url;
234 $redirect = Red_Item::create( $params );
235
236 if ( is_wp_error( $redirect ) ) {
237 return $this->add_error_details( $redirect, __LINE__ );
238 }
239 }
240 }
241
242 return $this->route_list( $request );
243 }
244
245 public function route_update( WP_REST_Request $request ) {
246 $params = $request->get_params();
247 $redirect = Red_Item::get_by_id( intval( $params['id'], 10 ) );
248
249 if ( $redirect ) {
250 $result = $redirect->update( $params );
251
252 if ( is_wp_error( $result ) ) {
253 return $this->add_error_details( $result, __LINE__ );
254 }
255
256 return array( 'item' => $redirect->to_json() );
257 }
258
259 return $this->add_error_details( new WP_Error( 'redirect_update_failed', 'Invalid redirect details' ), __LINE__ );
260 }
261
262 public function route_bulk( WP_REST_Request $request ) {
263 $action = $request['bulk'];
264 $items = explode( ',', $request['items'] );
265
266 if ( is_array( $items ) ) {
267 foreach ( $items as $item ) {
268 $redirect = Red_Item::get_by_id( intval( $item, 10 ) );
269
270 if ( $redirect ) {
271 if ( $action === 'delete' ) {
272 $redirect->delete();
273 } elseif ( $action === 'disable' ) {
274 $redirect->disable();
275 } elseif ( $action === 'enable' ) {
276 $redirect->enable();
277 } elseif ( $action === 'reset' ) {
278 $redirect->reset();
279 }
280 }
281 }
282
283 return $this->route_list( $request );
284 }
285
286 return $this->add_error_details( new WP_Error( 'redirect_invalid_items', 'Invalid array of items' ), __LINE__ );
287 }
288
289 public function route_match_post( WP_REST_Request $request ) {
290 $params = $request->get_params();
291 $search = isset( $params['text'] ) ? $params['text'] : false;
292 $results = [];
293
294 if ( $search ) {
295 global $wpdb;
296
297 $posts = $wpdb->get_results(
298 $wpdb->prepare(
299 "SELECT ID,post_title,post_name FROM $wpdb->posts WHERE post_status='publish' AND (post_title LIKE %s OR post_name LIKE %s) " .
300 "AND post_type NOT IN ('nav_menu_item','wp_block','oembed_cache')",
301 '%' . $wpdb->esc_like( $search ) . '%', '%' . $wpdb->esc_like( $search ) . '%'
302 )
303 );
304
305 foreach ( (array) $posts as $post ) {
306 $results[] = [
307 'title' => $post->post_title,
308 'slug' => $post->post_name,
309 'url' => get_permalink( $post->ID ),
310 ];
311 }
312 }
313
314 return $results;
315 }
316 }
317