Encapsulation, Inheritance, and Polymorphism

using Drupal Entities

Presented by Tom Friedhof

Tom Friedhof

Subscribe to our YouTube Channel

http://youtube.com/activelamp

Who here is currently coding entities?

What I'll be covering today

  • What is a Drupal entity?
  • Why you should use them.


Less How, more Why?

Some Drupal History

https://www.flickr.com/photos/40571214@N00/9667435812/

Everything was a node

Drupal Utopia

Photo Credit

Drupal Utopia

CCK + Views = FTW

Everything was a node

Users, Terms, Panels, Everything!

Drupal 7

Entity + Field API

Something was missing.

Entity API module

https://www.drupal.org/project/entity

Define your own PHP Class

Real objects... no more stdClass()

Encapsulation

Entity Class


/**
 * @file
 * Tournament match class.
 */
class TourneyMatchEntity extends TourneyEntity {
  ...
  /**
   * Get the winner of the match
   */
  public function getWinner() {
    if (is_null($this->matchWinner)) {
      $this->matchWinner = $this->determineWinner();
    }
    return $this->matchWinner;
  }
  ...
}
						

Implementation code


/**
 * Get the winner of the match
 */
$match = tourney_match_load(1);

/**
 * Call method directly on object.
 */
$winner = $match->getWinner();
						

Encapsulation

  • A language mechanism for restricting access to some of the object's components
  • A language construct that facilitates the bundling of data with the methods (or other functions) operating on that data.[
--Wikipedia definition

Questions about Encapsulation?

Similar Data, Different Model?

  • Create a bundle.
  • Create another entity.

Using a Base Class


class TourneyEntity extends Entity {
  ...
  public function save() {
    if ((isset($this->is_new) && $this->is_new) || $this->created == 0) {
      $this->created = time();
    }
    $this->changed = time();
    parent::save();
  }

  /**
   * Return the uri to the entity object
   */
  public function getUri() {
    return TourneyEntity::path($this->id, $this->entityType);
  }
  ...
}
						

Inheritance

Super powerful!

Writing Views Handlers

Next session in Room G7

Questions about Inheritance?

Using Bundles

  • All bundles share the same entity class
  • How can I get a specific class per bundle?

Proxy Pattern

https://sourcemaking.com/design_patterns/proxy

Define your Entity with the Proxy


/**
 * Implements hook_entity_info().
 */
function it_service_entity_info() {
  $info = array(
    'it_service' => array(
      'label' => t('IT Service'),
      'plural label' => t('IT Services'),
      'description' => t('A single service provided by IT Services.'),
      'entity class' => 'Drupal\it_service\Entity\ItServiceProxy',
      'controller class' => 'EntityAPIController',
      'base table' => 'it_service',
      'fieldable' => TRUE,
      ...
    )
  );
  return $info;
}
						

Proxy Class


namespace Drupal\it_service\Entity;
...
class ItServiceProxy extends ItServiceBase {

  protected $entityClass;
  protected $entityType = 'it_service';

  /**
   * ItServiceProxy constructor.
   */
  public function __construct(array $values, $entityType) {
    $values['type'] = !empty($this->type) ? $this->type : $values['type'];
    $this->type = $values['type'];
    if (is_null($this->entityClass)) {
      $this->makeEntity($values['type']);
    }
  }

  private function makeEntity($bundle) {
    $className = 'Drupal\it_service\Entity\\' . CaseConverter::toCamelCase($bundle);
    if (class_exists($className)) {
      $this->entityClass = new $className(['type' => $bundle], $this->entityType);
    }
    else {
      throw new \Exception(t('A class does not exist for @bundleName bundle.', ['@bundleName' => $className]));
    }
  }

  function __call($name, $args) {
    if (!method_exists($this->entityClass, $name)) return FALSE;

    $method = new \ReflectionMethod($this->entityClass, $name);
    return $method->invoke($this->entityClass, $args);
  }

}
						

Polymorphism in Drupal!

Bonus

Show me how to create an entity!

It's on GitHub!

https://github.com/activelamp/generator-entityD7

Subscribe to our YouTube Channel

http://youtube.com/activelamp

Questions?

Send me an email:

tom@activelamp.com

or in IRC #drupal-la