You are here

state_flow.inc in State Machine 6

File

modules/state_flow/plugins/state_flow.inc
View source
<?php

/**
 * @file
 * State Flow implementation of the State Machine class
 */
state_machine_load_class_file();
class StateFlow extends StateMachine {
  public function init() {

    // Initialize states
    $this
      ->create_state('draft');
    $this
      ->create_state('published', array(
      'on_enter' => array(
        $this,
        'on_enter_published',
      ),
      'on_exit' => array(
        $this,
        'on_exit_published',
      ),
    ));

    // Initialize events
    $this
      ->create_event('publish', array(
      'origin' => 'draft',
      'target' => 'published',
    ));
    $this
      ->create_event('unpublish', array(
      'origin' => 'published',
      'target' => 'draft',
    ));
  }

  /**
   * Returns an array of available states.
   */
  public function get_available_states() {
    return $this->states;
  }
  public function on_enter_published() {
    $this
      ->set_published();
    $this
      ->set_node_revision();
    $this
      ->set_principle_revision();
  }
  public function on_exit_published() {
    $this
      ->set_unpublished();
  }
  public function persist() {
    $vid = $this
      ->get_latest_revision($this->object->nid);
    $nid = $this->object->nid;
    $state = $this
      ->get_current_state();
    $data = array(
      'vid' => $vid,
      'nid' => $nid,
      'state' => $state,
      'timestamp' => time(),
      'status' => 1,
    );
    $update = $this
      ->existing_revision($nid, $vid) ? array(
      'vid',
    ) : NULL;
    $result = drupal_write_record('node_revision_states', $data, $update);
    return;
  }
  public function load() {
    return $this
      ->latest_state($this->object->nid);
  }
  public function set_published() {
    $this->object->status = 1;
    drupal_write_record('node', $this->object, 'nid');
  }
  public function set_unpublished() {
    $this->object->status = 0;
    drupal_write_record('node', $this->object, 'nid');
  }
  public function set_node_revision() {
    $vid = $this
      ->get_latest_revision($this->object->nid);
    if (!empty($vid) && $vid != $this->object->vid) {
      $this->object->vid = $vid;
      drupal_write_record('node', $this->object, 'nid');
    }
  }
  public function set_principle_revision() {
    $nid = $this->object->nid;
    $vid = $this
      ->get_latest_revision($nid);
    $result = db_query('UPDATE {node_revision_states} SET status = 0 WHERE nid = %d AND vid != %d', $nid, $vid);
    return;
  }
  public function get_latest_revision($nid) {
    $result = db_result(db_query('SELECT MAX(vid) FROM {node_revisions} WHERE nid = %d', $nid));
    return $result;
  }
  public function existing_revision($nid, $vid) {
    $result = db_result(db_query('SELECT COUNT(*) FROM {node_revision_states} WHERE nid = %d AND vid = %d', $nid, $vid));
    return $result ? TRUE : FALSE;
  }
  public function latest_state($nid) {
    $query = "SELECT state\n              FROM {node_revision_states}\n              WHERE nid = %d AND status = 1 AND vid = %d\n              ORDER BY timestamp\n              DESC\n              LIMIT 1";
    return db_result(db_query($query, $nid, $this
      ->get_latest_revision($nid)));
  }
  public function get_event($key) {
    if (!array_key_exists($key, $this->events)) {
      return FALSE;
    }
    if (is_array($this->events[$key])) {
      $options = $this->events[$key];
      $this->events[$key] = new StateFlow_Event($this, $options);
    }
    return $this->events[$key];
  }

}
class StateFlow_Event extends StateMachine_Event {
  public function validate() {
    if (parent::validate()) {
      if (!empty($this->options['permission'])) {
        return user_access($this->options['permission']);
      }
      return TRUE;
    }
    return FALSE;
  }

}

Classes