Skip to content

Creating custom objects

Victor Jonsson edited this page May 21, 2014 · 23 revisions

An object in PHP-Rocker defines a container that holds arbitrary data of some sort. There's no limit to what type of objects you can define but they will all obey to the following rules:

  • An object has a name, ID-number and arbitrary meta data (EAV data-model)
  • You can access the objects using the id-number, or the name, of the objects. Thus must the name of each object be unique, you can think of it as a guid for the object.
  • You can search for objects by querying the meta data, not the guid nor the id-number.
  • Objects have no relations to each other (on a data-model level)

PHP-Rocker will define a user object when installed. Here's how you add your own object definitions:

  1. Add your own class directory
  2. Create an object factory class
  3. Create an object operation class
  4. Configure and install

1) Add your own class directory

The same as the first step when creating a custom operation

2) Create an object factory class

Create a class extending \Rocker\Object\AbstractObjectFactory.

<?php
namespace MyCompany;

class DogFactory extends \Rocker\Object\AbstractObjectFactory {

    /**
     * @return string
     */
    function objectTypeName()
    {
        return 'dog'; // used as table prefix in the database
    }

    /**
     * @return string
     */
    function objectClassName()
    {
        return '\\Rocker\\Object\\PlainObject'; 
        // Here you can refer to a class of your own, that extends PlainObject. You can
        // also use an entirely new class as long as it implements \Rocker\Object\ObjectInterface
    }

    /**
     * @param string|int $id Name or id of the dog you want to load
     * @return \Rocker\Object\ObjectInterface
     */
    function load($id)
    {
        return parent::loadObject($id);
    }

    /**
     * @param string $name
     * @return \Rocker\Object\ObjectInterface
     * @throws \Exception
     */
    public function create($name)
    {
        // Here you could add your own logic and throw \InvalidArgumentException in case
        // this object shouldn't be possible to create for some reason
        return parent::createObject($name);
    }
    
    /**
     * @param \Rocker\Object\ObjectInterface $obj
     * @throws \InvalidArgumentException
     */
    public function update($obj)
    {
        // Here you could add your own logic and throw \InvalidArgumentException in case
        // this object shouldn't be possible to update for some reason
        $this->updateObject($obj);
    }

    /**
     * @param \Rocker\Object\ObjectInterface $user
     * @throws \InvalidArgumentException
     */
    public function delete($obj)
    {
        // Here you could add your own logic and throw \InvalidArgumentException in case
        // this object shouldn't be possible to delete for some reason
        $this->deleteObject($obj);
    }
}

3) Create an object operation class

Create a class extending \Rocker\API\AbstractObjectOperation. The AbstractObjectOperation is a child class of AbstractOperation that you can read more about here.

<?php
namespace MyCompany;


class DogOperation extends \Rocker\API\AbstractObjectOperation {

     /**
      * @return \MyCompany\DogFactory
      */
     function createFactory($db, $cache) {
         return new DogFactory($db, $cache);
     }

     /**
     * @param \MyCompany\DogFactory $factory
     * @param \Rocker\REST\OperationResponse $response
     * @param \Fridge\DBAL\Connection\ConnectionInterface $db
     * @param \Rocker\Cache\CacheInterface $cache
     * @param \Rocker\Server $server
     */
     protected function createNewObject($dogFactory, $response, $db, $cache, $server) {
       try {

            // Create dog
            $newDog = $dogFactory->create($_REQUEST['name']);

            // Add some meta data for the dog
            $newDog->meta()->set('color', isset($_REQUEST['color']) ? $_REQUEST['color']:'unknown');
            $newDog->meta()->set('breed', isset($_REQUEST['breed']) ? $_REQUEST['breed']:'unknown');
            $newDog->meta()->set('born', isset($_REQUEST['born']) ? $_REQUEST['born']:'unknown');
            $dogFactory->update($newDog);
            
            // Update the response object
            $response->setStatus(201);
            $response->setBody( $this->objectToArray($newDog, $server, $db, $cache) );

        } catch (\Rocker\Object\DuplicationException $e) {
            $response->setStatus(409);
            $response->setBody(array('error' => 'It already exists a dog with given name'));
        }
    }
}

4) Configure and install

Add your dog operation to the array named application.operations in config.php

  ...
  'application.operations' => array(
      ...
      'dog/*' => '\\MyCompany\\DogOperation'
  )

Add your dog factory to the array of "installable" objects, named application.install.

   ...
   'application.install' => array(
      '\\Rocker\\Object\\User\\UserFactory',
      '\\MyCompany\\DogFactory'
   )

Run $ php -f install.php in the console which will create the database tables for your dog objects.

— Now your'e able to create/read/update/delete (and search for) dog objects on your server!!!

Create a dog
$ curl -X POST http://website.com/api/dog -d 'name=Rex&color=Black&born=2009'

HTTP/1.1 201 Created
Date: Tue, 12 Mar 2013 06:27:44 GMT
...

{
    "id" : 1,
    "name" : "Rex",
    "meta" : {
        "color" : "Black",
        "born" : "2009",
        "breed" : "unknown"
    }
}
```

##### Load a dog *(you can also load the dog using its ID-number)*

$ curl http://website.com/api/dog/Rex

HTTP/1.1 200 Ok Date: Tue, 12 Mar 2013 06:37:44 GMT ...

{ "id" : 1, "name" : "Rex", "meta" : { "color" : "Black", "born" : "2009", "breed" : "unknown" } }


##### Search for dogs

Search for dogs that is of some type of retriever and that lives in France

curl http://website.com/api/dog?q[breed]=*retriever*&q[country]=France

HTTP/1.1 200 Ok Date: Tue, 12 Mar 2013 06:37:44 GMT ... { "query" => "q[breed]=retriever&q[country]=France", "matching" => 413, "offset" => 0, "limit" => 0, "objects" => [ ... ] }


Search for dogs that is of some type of retriever and born before 2010, limit the result to 10 dogs and start
off from offset 5.

curl http://website.com/api/dog?q[breed]=*retriever*&q[born<]=2010&offset=5&limit=10

HTTP/1.1 200 Ok Date: Tue, 12 Mar 2013 06:37:44 GMT ... { "query" => "q[breed]=retriever&q[born<]=2010", "matching" => 39, "offset" => 5, "limit" => 10, "objects" => [ ... ] }


##### Update a dog

$ curl -X POST http://website.com/api/dog/Rex -d 'name=Rex+the+second&meta[born]=2004'

HTTP/1.1 200 Ok Date: Tue, 12 Mar 2013 06:37:44 GMT ...

{ "id" : 1, "name" : "Rex the second", "meta" : { "color" : "Black", "born" : "2004", "breed" : "unknown" } }


##### Delete a dog

$ curl -X DELETE http://website.com/api/dog/1

HTTP/1.1 204 No Content Date: Tue, 12 Mar 2013 06:18:59 GMT ...

Clone this wiki locally