Skip to content
This repository has been archived by the owner on Dec 11, 2022. It is now read-only.

Extending the Entity Class

Hunter Perrin edited this page Jun 12, 2019 · 12 revisions

To create a new type of data object in Nymph, you extend the Entity class. This is equivalent to creating a new table in a relational database. If you are going to use the class on the client side, you also need to create a corresponding JavaScript class. Below are two examples, one in PHP, and one in JavaScript. A more in depth explanation follows the examples.

Extending Entity in PHP
namespace MyApp;

use Respect\Validation\Validator as v;
use Respect\Validation\Exceptions\NestedValidationException;

/**
 * @property string $name The todo's text.
 * @property bool $done Whether it's done.
 */
class Todo extends \Nymph\Entity {
  const ETYPE = 'todo';
  protected $clientEnabledMethods = ['archive'];
  protected $whitelistData = ['name', 'done'];
  protected $protectedTags = ['archived'];
  protected $whitelistTags = [];

  public function __construct($id = 0) {
    $this->done = false;
    parent::__construct($id);
  }

  public function archive() {
    if ($this->hasTag('archived')) {
      return true;
    }
    $this->addTag('archived');
    return $this->save();
  }

  public function save() {
    if (!\Tilmeld\Tilmeld::gatekeeper()) {
      // Only allow logged in users to save.
      return false;
    }
    try {
      v::notEmpty()
        ->attribute('name', v::stringType()->notEmpty()->prnt()->length(1, 2048))
        ->attribute('done', v::boolType())
        ->setName('todo')
        ->assert($this->getValidatable());
    } catch (NestedValidationException $exception) {
      throw new \Exception($exception->getFullMessage());
    }
    return parent::save();
  }
}
Extending Entity in JavaScript
import { Nymph, Entity } from 'nymph-client';

export class Todo extends Entity {
  constructor(id) {
    super(id);
    this.done = false;
  }

  $archive(...args) {
    return this.$serverCall('archive', args);
  }
}

// The name of the server class
Todo.class = 'MyApp\\Todo';

Nymph.setEntityClass(Todo.class, Todo);

export default Todo;

In both cases, defaults are set in the constructor. In this case, the 'done' property is set to false.

The first difference between the two versions to take note is the order of the statements in the constructor. In the PHP class, parent::__construct($id); comes at the end of the constructor. This is necessary because any defaults set before this call will be overwritten by the parent constructor loading the entity. In the JavaScript class, super(id); comes at the beginning of the constructor. This is necessary because the class variables are set by the Entity class's constructor. Also, defaults will be overwritten when the AJAX call completes, meaning it is fine to set them after the parent constructor.

In PHP, the etype is set to "todo". The etype of an entity determines which table the entity will be placed in. When you search for an entity, you give Nymph a class name. Nymph will use that class's etype to determine where to search for entities. If you don't provide a class name, the Entity class and the "entity" etype will be used.

The $clientEnabledMethods property and the $clientEnabledStaticMethods static property in PHP determine which methods and static methods can be called from the client using $serverCall and serverCallStatic. In the JavaScript class, the return this.$serverCall('archive', args); statement takes advantage of this feature.

In JavaScript, the server class that corresponds to a client class is set in the class static property.

Finally, in PHP, the Todo class validates all of its data in the save method using Respect Validator (composer require respect/validation). Without this validation, a malicious user could send invalid data types or even megabytes worth of data in an entity. Any PHP validation library should support validation in Nymph using the getValidatable method.

Clone this wiki locally