/**
  * Match the request to a callback and call it
  *
  * @param WP_REST_Request $request Request to attempt dispatching
  * @return WP_REST_Response Response returned by the callback
  */
 public function dispatch($request)
 {
     $method = $request->get_method();
     $path = $request->get_route();
     foreach ($this->get_routes() as $route => $handlers) {
         foreach ($handlers as $handler) {
             $callback = $handler['callback'];
             $supported = $handler['methods'];
             $response = null;
             if (empty($handler['methods'][$method])) {
                 continue;
             }
             $match = preg_match('@^' . $route . '$@i', $path, $args);
             if (!$match) {
                 continue;
             }
             if (!is_callable($callback)) {
                 $response = new WP_Error('vp_rest_invalid_handler', __('The handler for the route is invalid'), array('status' => 500));
             }
             if (!is_wp_error($response)) {
                 $request->set_url_params($args);
                 $request->set_attributes($handler);
                 $request->sanitize_params();
                 $defaults = array();
                 foreach ($handler['args'] as $arg => $options) {
                     if (isset($options['default'])) {
                         $defaults[$arg] = $options['default'];
                     }
                 }
                 $request->set_default_params($defaults);
                 $check_required = $request->has_valid_params();
                 if (is_wp_error($check_required)) {
                     $response = $check_required;
                 }
             }
             if (!is_wp_error($response)) {
                 // check permission specified on the route.
                 if (!empty($handler['permission_callback'])) {
                     $permission = call_user_func($handler['permission_callback'], $request);
                     if (is_wp_error($permission)) {
                         $response = $permission;
                     } else {
                         if (false === $permission || null === $permission) {
                             $response = new WP_Error('vp_rest_forbidden', __("You don't have permission to do this."), array('status' => 403));
                         }
                     }
                 }
             }
             if (!is_wp_error($response)) {
                 /**
                  * Allow plugins to override dispatching the request
                  *
                  * @param boolean $dispatch_result Dispatch result, will be used if not empty
                  * @param WP_REST_Request $request
                  */
                 $dispatch_result = apply_filters('vp_rest_dispatch_request', null, $request);
                 // Allow plugins to halt the request via this filter
                 if (null !== $dispatch_result) {
                     $response = $dispatch_result;
                 } else {
                     $response = call_user_func($callback, $request);
                 }
             }
             if (is_wp_error($response)) {
                 $response = $this->error_to_response($response);
             } else {
                 $response = vp_rest_ensure_response($response);
             }
             $response->set_matched_route($route);
             $response->set_matched_handler($handler);
             return $response;
         }
     }
     return $this->error_to_response(new WP_Error('vp_rest_no_route', __('No route was found matching the URL and request method'), array('status' => 404)));
 }