6

I am trying to implement the following library in a new project.

"chriskacerguis/codeigniter-restserver": "^3.0"

I got a fresh codeigniter installation on my local server and I have done everything accordingly. Now I am trying to run the code its just showing the following error

Fatal error: Class Example cannot extend from trait Restserver\Libraries\REST_Controller in C:\xampp\htdocs\ci\application\controllers\api\Example.php on line 22 A PHP Error was encountered Severity: Compile Error

Message: Class Example cannot extend from trait Restserver\Libraries\REST_Controller

Filename: api/Example.php

Line Number: 22

Backtrace:

Code on line no 22 is as following

<?php
use Restserver\Libraries\REST_Controller;
defined('BASEPATH') OR exit('No direct script access allowed');

// Following line is line no 22
class Example extends REST_Controller {
    function __construct()
    {
        // Construct the parent class
        parent::__construct();

Paul Carrion
  • 99
  • 1
  • 5
  • Possible duplicate of [Extend Traits with Classes in PHP?](https://stackoverflow.com/questions/10056520/extend-traits-with-classes-in-php) – Alex Jun 30 '19 at 11:11
  • @Alex not exactly, it looks like a [restserver's library](https://github.com/chriskacerguis/codeigniter-restserver) design issue. At the end, the library is trying to call constants inside a trait; a big headache. – quantme Jun 30 '19 at 17:00
  • @Paul_Carrion I tried changing `class Example extends REST_Controller {` to `class Example {` and moving `use Restserver\Libraries\REST_Controller;` below that line 22 (how traits are supposed to be called), that's where everything gets complicated. Also tried CodeIgniter 4 but the same, I have not slept since then. – quantme Jun 30 '19 at 17:10
  • 1
    You aren't supposed to extend it. the docs on this lib specifically show you how to use it: https://github.com/chriskacerguis/codeigniter-restserver – Alex Jun 30 '19 at 20:20
  • @Alex Thanks, didn't notice the update and found the obsolete code. It's related to the [provided example](https://github.com/chriskacerguis/codeigniter-restserver/commit/2bb2fe4808cdf4f591ca55f480884909e026fbd1#diff-f45f456a047812d8014f0515c98a1591) file. – quantme Jun 30 '19 at 23:18

1 Answers1

11

You have to modify provided (and outdated until this answer's date) versions of application\libraries\REST_Controller.php and application\controllers\api\Example.php.

application\libraries\REST_Controller.php

  • Add require APPPATH . 'libraries/REST_Controller_Definitions.php'; just before trait REST_Controller {
require APPPATH . 'libraries/REST_Controller_Definitions.php';

trait REST_Controller {

application\controllers\api\Example.php

  • class Example extends CI_Controller { instead of class Example extends REST_Controller {
  • Place use REST_Controller { REST_Controller::__construct as private __resTraitConstruct; } as the first line after class Example extends CI_Controller {
  • Add parent::__construct(); and $this->__resTraitConstruct(); to __construct() function.
  • Change all response methods to HTTP response code instead of constants. For example $this->response($users, 200); instead of $this->response($users, REST_Controller::HTTP_OK);
<?php
use Restserver\Libraries\REST_Controller;
defined('BASEPATH') OR exit('No direct script access allowed');

// This can be removed if you use __autoload() in config.php OR use Modular Extensions
/** @noinspection PhpIncludeInspection */

//To Solve File REST_Controller not found
require APPPATH . 'libraries/REST_Controller.php';
require APPPATH . 'libraries/Format.php';

/**
 * This is an example of a few basic user interaction methods you could use
 * all done with a hardcoded array
 *
 * @package         CodeIgniter
 * @subpackage      Rest Server
 * @category        Controller
 * @author          Phil Sturgeon, Chris Kacerguis
 * @license         MIT
 * @link            https://github.com/chriskacerguis/codeigniter-restserver
 */
class Example extends CI_Controller {

    use REST_Controller {
        REST_Controller::__construct as private __resTraitConstruct;
    }

    function __construct()
    {
        // Construct the parent class
        parent::__construct();
        $this->__resTraitConstruct();

        // Configure limits on our controller methods
        // Ensure you have created the 'limits' table and enabled 'limits' within application/config/rest.php
        $this->methods['users_get']['limit'] = 500; // 500 requests per hour per user/key
        $this->methods['users_post']['limit'] = 100; // 100 requests per hour per user/key
        $this->methods['users_delete']['limit'] = 50; // 50 requests per hour per user/key
    }

    public function users_get()
    {
        // Users from a data store e.g. database
        $users = [
            ['id' => 1, 'name' => 'John', 'email' => 'john@example.com', 'fact' => 'Loves coding'],
            ['id' => 2, 'name' => 'Jim', 'email' => 'jim@example.com', 'fact' => 'Developed on CodeIgniter'],
            ['id' => 3, 'name' => 'Jane', 'email' => 'jane@example.com', 'fact' => 'Lives in the USA', ['hobbies' => ['guitar', 'cycling']]],
        ];

        $id = $this->get('id');

        // If the id parameter doesn't exist return all the users

        if ($id === null)
        {
            // Check if the users data store contains users (in case the database result returns NULL)
            if ($users)
            {
                // Set the response and exit
                $this->response($users, 200); // OK (200) being the HTTP response code
            }
            else
            {
                // Set the response and exit
                $this->response([
                    'status' => false,
                    'message' => 'No users were found'
                ], 404); // NOT_FOUND (404) being the HTTP response code
            }
        }

        // Find and return a single record for a particular user.

        $id = (int) $id;

        // Validate the id.
        if ($id <= 0)
        {
            // Invalid id, set the response and exit.
            $this->response(null, 400); // BAD_REQUEST (400) being the HTTP response code
        }

        // Get the user from the array, using the id as key for retrieval.
        // Usually a model is to be used for this.

        $user = null;

        if (!empty($users))
        {
            foreach ($users as $key => $value)
            {
                if (isset($value['id']) && $value['id'] === $id)
                {
                    $user = $value;
                }
            }
        }

        if (!empty($user))
        {
            $this->set_response($user, 200); // OK (200) being the HTTP response code
        }
        else
        {
            $this->set_response([
                'status' => false,
                'message' => 'User could not be found'
            ], 404); // NOT_FOUND (404) being the HTTP response code
        }
    }

    public function users_post()
    {
        // $this->some_model->update_user( ... );
        $message = [
            'id' => 100, // Automatically generated by the model
            'name' => $this->post('name'),
            'email' => $this->post('email'),
            'message' => 'Added a resource'
        ];

        $this->set_response($message, 201); // CREATED (201) being the HTTP response code
    }

    public function users_delete()
    {
        $id = (int) $this->get('id');

        // Validate the id.
        if ($id <= 0)
        {
            // Set the response and exit
            $this->response(null, 400); // BAD_REQUEST (400) being the HTTP response code
        }

        // $this->some_model->delete_something($id);
        $message = [
            'id' => $id,
            'message' => 'Deleted the resource'
        ];

        $this->set_response($message, 204); // NO_CONTENT (204) being the HTTP response code
    }

}

Hope it helps, it works for me.

quantme
  • 3,609
  • 4
  • 34
  • 49
  • I made the [following](https://codeshare.io/jGzQ9) changes in the code but it didnt work. it now says "Message: Class Example cannot extend from trait Restserver\Libraries\REST_Controller" – Paul Carrion Jul 02 '19 at 14:09
  • @PaulCarrion Sorry, my mistake, try extending to `CI_Controller` instead `REST_Controller`, I've edited the answer. – quantme Jul 02 '19 at 22:24
  • 1
    Working perfectly – Lefty Jul 14 '19 at 13:08
  • hello @quantme, how can i use "REST_Controller::HTTP_OK" constant which are already declared in REST_Controller_Definitions.php file? i dont want to use 200 directly. – Amit Joshi Jul 19 '19 at 06:14
  • @AmitJoshi For some reason, the developers used to have those constants inside `REST_Controller.php` and later "[migrate](https://github.com/chriskacerguis/codeigniter-restserver/commit/6425ad60f7f108c1e52c2d939dd6b550a5e73a96#diff-7d748d7e419940392ec500f54eab66f2)" that functionality to `REST_Controller_Definitions.php`. I did a pair of intents for the same reason you're looking for but without results. I guess they're preparing the library for CodeIgniter 4 or just "cleaning the kitchen". – quantme Jul 19 '19 at 07:24