0

I'm setting up a plugin to list a series of WooCommerce products. Sketched all structure and I find that the endpoint isn't being created and can't figure out what's wrong here.

Plugin file

<?php

function products_list(){
    require_once 'include/ProductEdition.class.php';
    $plugin = new ProductEdition();
    $plugin->render();
}


add_shortcode( 'products_list', 'products_list' );

Class

<?php

class ProductEdition {
    private $namespace = 'products-edition/v1/';
    private $productFactory = null;

    public function __construct()
    {
        add_action( 'rest_api_init', array($this, 'startAPI') );
        $this->productFactory = new WC_Product_Factory();
    }

    public function startAPI(){
        register_rest_route($this->namespace, 'products/', [
            [
                'methods' => \WP_REST_Server::READABLE,
                'callback' => array($this, 'getProducts'),
            ]
        ]);

        register_rest_route($this->namespace, 'product/', [
            [
                'methods' => \WP_REST_Server::CREATABLE,
                'callback' => array($this, 'updateProduct'),
            ]
        ]);
    }

    public function render(){
        $url = plugins_url() . "/products-list-shortcode/js/main.js";
        echo "<script src=\"".$url."\" type=\"text/javascript\"></script>";
    }

    public function getProducts(){
        $args = array(
            'post_type'      => 'product',
            'posts_per_page' => 3000
        );

        $loop = new WP_Query( $args );

        $products = [];

        while ( $loop->have_posts() ) : $loop->the_post();
            global $product;
            $image = wp_get_attachment_image_src( get_post_thumbnail_id( $product->get_id() ), 'single-post-thumbnail' );
            $image = is_bool($image) ? '' : "<a href='".$image[0]."' target='_blank'><img style='max-width: 100px' src=\"". $image[0] ."\" /></a>";

            $prod = [
                "ID"                => $product->ID,
                'sku'               => $product->get_sku(),
                'title'             => $product->get_title(),
                'description'       => $product->get_title(),
                'short_description' => $product->get_title(),
                'image'             => $image
                ];

            array_push($products, $prod);

        endwhile;

            return json_encode($products);
    }

    public function updateProduct($request){
        $product = $this->productFactory->get_product($request['id']);

        return json_encode( $product->set_attributes([
            'SKU'                   => $request['SKU'],
            'title'                 => $request['title'],
            'description'           => $request['description'],
            'short_description'     => $request['short_description'],
        ]) );
    }
}

Once this is instantiated, I'm loading main.js that has all the Frontend logic.

Main.js is calling this URL:

/wp-json/products-edition/v1/products

But when it tries to get the endpoint, it's returning 404.

What am I doing wrong here?

  • 1
    ProductEdition is only instantiated inside your shortcode, which means that your rest_api_init hook is never added. – Jacob Peattie Jun 12 at 17:48
  • That's it, thank you Jacob! – Pablo Jun 12 at 18:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.