• Hi,

    I am developing a REST API with a small number of routes. The API was working fine when I had all classes & functions prefixed with a ‘unique’ tag of q5_dvd.

    I decided to move to using namespaces instead of prefixing everything with the string ‘q5_dvd’, ie I placed the ‘namespace q5_dvd;’ statement at the head of each file and studiously removed all ‘q5_dvd’ prefixes from name references.

    The problem I have is now that when I attempt to register a rest route, the class WP_REST_Server cannot be found because it is looking for q5_dvd\WP_REST_Server, ie. php is expecting WP_REST_Server to be in the q5_dvd namespace.

    My understanding of PHP namespace functionality, is that if a class or method cannot be located in the current namespace, then PHP would then look globally, but that does not appear to be happening.

    Any assistance appreciated.

    Code is as follows:

    namespace q5_dvd;
    
    /**
     * DVD REST Plugin
     * ========================
     *
     * Plugin Name:		Q5 DVD
     * Plugin URI:  	https://quintic.co.uk/wordpress/plugins/q5-dvd/
     * Description: 	Proivides a REST api for requesting or uploading details of DVDs
     * Version:     	0.0.1
     * Author:      	Quintic
     * Author URI:  	https://www.quintic.co.uk/
     * Requires at least:5.2
     * Requires PHP: 	7.2
     * License:     	GPLv2 or later
     * License URI:	 	https://www.gnu.org/licenses/old-licenses/gpl-2.0.html
     * Text Domain: 	page-content
     * Domain Path: 	./languages
     *
     */
    
    if ( ! defined( 'ABSPATH' ) ) {
    	die( 'Invalid request.' );
    }
    
    if (! class_exists(__NAMESPACE__ .'\\endPoints')){
    	class endPoints
    	{
    		private $product_services;
    		
    		function __construct()
    		{
    			$this->product_services = array(
    			   new product_service_quintic(),
    			   new product_service_externals() 
    			  );
    		}
    		
    		public function v1_dvd_upc(WP_REST_Request $request)
    		{
    			return $this->response($request['UPC']);
    		}
    		
    		public function v1_dvd_barcode(WP_REST_Request $request)
    		{
    		 q5_debug($request->get_headers());
    			return $this->response($request['barcode']);
    		}
    		
    		private function response(string $barcode)
    		{
    			$product = 'Not Found';
    			foreach ($this->product_services as $product_service)
    			{
    				$response = $product_service->get_dvd_details($barcode);
    				if ($response->found)
    				{
    					$product = $response->product;
    					break;
    				}
    			}				
    
    			$response = new WP_REST_Response ($product);
    			$response->set_status(201);
    			$response->header('Location', 'https://www.quintic.co.uk/');
    			return rest_ensure_response($response);
    		}
    	}
    }
    
    // Route Registration
    if (! function_exists(__NAMESPACE__ . '\\register_endpoint')) {
    	function register_endpoint()
    	{	
    		$dvd_endpoints = new endPoints();
    
    		register_rest_route('q5-dvd/v1', '/dvd/barcode/(?P<barcode>\d+)', array(
    		'schema' => __NAMESPACE__ . '\\get_schema',
    		'methods' => WP_REST_Server::READABLE,
    		'callback' => array($dvd_endpoints, 'q5_dvd_v1_dvd_barcode'),
    		'permission_callback' => '__return_true',
    		'args' => array(
    			'barcode' => array(
    				'validate_callback' => function($param, $request, $key){
    					return is_numeric($param) && 
    					strlen($param) >= 12 &&
    					strlen($param) <= 13;
    				}
    				),
    			),
    		));
    		
    		register_rest_route('q5-dvd/v1', '/dvd/UPC/(?P<UPC>\d+)', array(
    		'schema' =>  __NAMESPACE__ . '\\get_schema',
    		'methods' => WP_REST_Server::READABLE,
    		'callback' => array($dvd_endpoints, 'q5_dvd_v1_dvd_upc'),
    		'permission_callback' => '__return_true',
    		'args' => array(
    			'UPC' => array(
    				'validate_callback' => function($param, $request, $key){
    					return is_numeric($param) && strlen($param) >= 11 && strlen($param) <= 12;
    				}
    				),
    			),
    		));
    	}
    }
    

    The code is the complete file, but the relevant aspect is the last function ‘register_endpoints’. Within that function I attempt to register two endpoints, both with arguments ‘methods’ => WP_REST_Server::READABLE,

    Without the namespace q5_dvd; statement at the beginning of the file (and with the q5_dvd tag on the classes and methods), everything is fine. So I am unclear how I need to indicate that WP_REST_Server is NOT in the q5_dvd namespace.

    Thanks

Viewing 2 replies - 1 through 2 (of 2 total)
  • Dion

    (@diondesigns)

    You should prefix classes that exist in the global namespace with a single baskslash, such as \WP_REST_Server, \WP_REST_Response, and \WP_REST_Request. It’s also good practice to do the same when calling functions that exist in the global namespace.

    Thread Starter Stephen Dickinson

    (@steved430)

    Hi Dion,

    Many thanks. That worked perfectly. The documentation I have read on the implementation of namespaces within PHP doesn’t mention this. Simply states Global space will be searched after current namespace.
    And I will admit, when I read that I thought that was poor. It means you have to error before you find the correct function – which is wasteful, plus it doesn’t indicate in the source code what is actually meant. So agree to your comment about adding the ‘\’ before functions as well.

    Thanks

    Steve

Viewing 2 replies - 1 through 2 (of 2 total)
  • The topic ‘Register REST routes when using Namespace’ is closed to new replies.