<?php

class EntityTranslationNodeRevisioningHandler extends EntityTranslationNodeHandler {

  protected $isModerated = FALSE;
  const REVISIONING_SCHEME = 'revisioning';

  public function __construct($entity_type, $entity_info, $entity) {
    parent::__construct('node', $entity_info, $entity);
    if ($this->isModerated = revisioning_content_is_moderated($this->bundle, $entity)) {
      $this->refreshEntity();
      $this->setPathScheme(self::REVISIONING_SCHEME);
    }
  }

  public function initPathScheme($path = NULL) {
    if ($this->isModerated) {
      $this->setPathScheme(self::REVISIONING_SCHEME);
      return self::REVISIONING_SCHEME;
    }
    else {
      return parent::initPathScheme($path);
    }
  }

  public function getTranslations() {
    $this->refreshEntity();
    return parent::getTranslations();
  }

  protected function getPathInstance($path) {
    if (!empty($this->pathScheme) && $this->pathScheme == self::REVISIONING_SCHEME) {
      $path_segments = explode('/', $path);
      foreach ($path_segments as $index => $segment) {
        if ($segment == '%node') {
          $path_segments[$index] = $this->getEntityId();
        }
        elseif ($segment == '%vid') {
          $path_segments[$index] = $this->revisionId;
        }
        elseif ($segment{0} == '%' && isset($this->routerMap[$index])) {
          $path_segments[$index] = $this->routerMap[$index];
        }
      }

      return implode('/', $path_segments);
    }
    else {
      return parent::getPathInstance($path);
    }
  }

  public function setEntity($entity) {
    // Sometimes this method is called right after the constructor, effectively
    // resetting our node to an older revision. Allow it to be stored again, but
    // call our refresh method right after it, to be sure we have the right
    // data.
    parent::setEntity($entity);
    $this->refreshEntity();
  }

  protected function refreshEntity() {
    // @todo Always load latest revision?? At least we are sure it contains
    // translation data; for the last published revision, we cannot be sure...
    $latest_revision_id = revisioning_get_latest_revision_id($this->getEntityId());
    if ($latest_revision_id !== $this->revisionId) {
      $old_revision_id = $this->revisionId;
      parent::setEntity(node_load($this->getEntityId(), $latest_revision_id));

      // If we needed to refresh, it is possible we have a sibling floating
      // around which contains the actual entity form. This can happen in our
      // case, as the correct revision is not always loaded in each context (for
      // example, a different node could be loaded for the access callback,
      // meaning the entity_translation_get_handler() function will return a new
      // handler, different from our current one. In that case, check if the
      // factory contains another instance for the same node, but for the
      // latest revision ID. If so, check if we are in an entity form context.
      // This is necessary to get the language tabs right.
      if (!empty($this->factory)) {
        $handler = $this->factory->getHandler('node', $this->entity);
        if ($handler != $this) {
          if ($handler->isEntityForm()) {
            $this->entityForm = TRUE;
          }
        }
      }
    }
  }
}
