Encapsulation, Inheritance, and Polymorphism – using Drupal Entities – Some Drupal History



Encapsulation, Inheritance, and Polymorphism – using Drupal Entities – Some Drupal History

0 0


presentation-entities-d7

Presentation from SandCAMP 2016 - Encapsulation, Inheritance, and Polymorphism

On Github tomfriedhof / presentation-entities-d7

Encapsulation, Inheritance, and Polymorphism

using Drupal Entities

Presented by Tom Friedhof

Hello everyone, thanks for coming today to my session on Drupal Entities.

Tom Friedhof

  • we are a Los Angeles based Digital Agency,
  • Drupal is our platform of choice.
  • Our agency has been working on the Drupal platform now for about a decade. We've been part of the community for a while.

Subscribe to our YouTube Channel

http://youtube.com/activelamp

  • Go to our YouTube channel right now and subscribe
  • Now go to all your social feeds and tell everyone to subscribe (just kidding) kind of.
  • We are going to be publishing the 3 sessions that I'm giving this week on our channel

Who here is currently coding entities?

- Start off by asking a really quick question

What I'll be covering today

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

Less How, more Why?

  • This presentation will be more about the why, not the how.
  • There a bunch of tutorials online for the how.
  • However, I will share with you guys a Yeoman generator we created for coding new entities.

Some Drupal History

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

Everything was a node

  • I entered the scene around 4.6
  • Back then there was something called Flexinode
  • That eventually became CCK for 4.7, 5.x, 6.x
  • Views module came out around the same time

Drupal Utopia

Photo Credit - We had everything we needed to win Championships

Drupal Utopia

CCK + Views = FTW

- With CCK and Views we can build anything.

Everything was a node

Users, Terms, Panels, Everything!

- All sorts of CCK fields being published, and tons of modules were created that all were based on using Nodes as the primary source for data or content on a Drupal site.

Drupal 7

Entity + Field API

  • after about 4 years of being in the CCK and Views Drupal utopia, a better way to manage data in Drupal was released.
  • everything in Drupal that managed data became Entities, and all Entities became fieldable.

Something was missing.

Entity API module

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

  • basically the stuff that didn't make it in to Drupal 7 core because of timing
  • you need it to get the full benefit of Entities in Drupal 7
  • gives you Views and Rules integration, and basic CRUD operations on your custom entities

Define your own PHP Class

Real objects... no more stdClass()

  • This did not ship with Drupal core
  • This IMO is the try power of entities
  • Why is this such a cool feature? real objects
  • What do you get with real objects? The ability for Encapsulation

Encapsulation

have one PHP class that defines all the methods and data that surround that single object in one PHP class.

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();
All the logic surrounding this data is one place.

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.
  • How do you deal with similar data the needs different fields?
  • Lets talk about creating another entity first.

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);
  }
  ...
}
This slide has fragments which are also stepped through in the notes window.

Inheritance

Super powerful!

  • How do you deal with similar data the needs different fields?
  • Lets talk about creating another entity first.

Writing Views Handlers

Next session in Room G7

  • As a side note, if you come to my next session in the next hour I'll be talking about extending the Views module and writing your own handlers... and this is exactly how you do it.... using Inheritance.

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

  • Thanks for coming to this session
  • Please go to our YouTube channel and subscribe, and share our channel. We're going to be releasing this session as well as other great content over there.

Questions?

Send me an email:

tom@activelamp.com or in IRC #drupal-la
Encapsulation, Inheritance, and Polymorphism using Drupal Entities Presented by Tom Friedhof Hello everyone, thanks for coming today to my session on Drupal Entities.