boxes.core.inc in Boxes 7.2
Box classes and plugin interface
File
includes/boxes.core.incView source
<?php
/**
* @file
* Box classes and plugin interface
*/
/**
* Interface for Plugin Classes
*/
interface BoxTypePluginInterface {
/**
* Constructor
*
* Plugin info should be called using boxes_fetch_plugin_info().
*
* @abstract
*
* @param $plugin_info array of information from the ctools plugin.
*/
public function __construct($plugin_info);
/**
* Get the ctools plugin info.
*
* If you pass in a key, then the key from the plugin info will be returned
* otherwise the entire plugin will be returned
*
* @abstract
*
* @param $key
* @return array of plugin info for value from a key
*/
public function getInfo($key = NULL);
/**
* Build the URL string for the plugin
*
* @abstract
*
* @return url
*/
public function buildURL();
/**
* Get the label name of the plugin
*
* @abstract
*
* @return label of the type
*/
public function getLabel();
/**
* Get the description of the plugin
*
* @abstract
*
* @return description of the type
*/
public function getDescription();
/**
* Set the Box object for later use
*
* @abstract
*
* @param Box $box
*/
public function setBox($box);
/**
* Is this type editable?
*
* @abstract
*
* @return boolean
*/
public function isEditable();
/**
* Define the form values and their defaults
*/
public function values();
/**
* The Plugin Form
*
* The Box object will be either loaded from the database or filled with the defaults.
*
* @param $box
* @param $form
* @param $form_state
* @return form array
*/
public function form($box, $form, &$form_state);
/**
* Validate function for box type form
*
* @abstract
*
* @param $values
* @param $form_state
*/
public function validate($values, &$form_state);
/**
* React to a box being saved
*
* @abstract
*
* @param Box $box
*/
public function submit(Box $box);
/**
* Return the block content.
*
* @abstract
*
* @param $box
* The box object being viewed.
* @param $content
* The default content array created by Entity API. This will include any
* fields attached to the entity.
* @param $view_mode
* The view mode passed into $entity->view().
* @return
* Return a renderable content array.
*/
public function view($box, $content, $view_mode = 'default', $langcode = NULL);
}
/**
* The Box entity class
*/
class Box extends Entity {
public $label;
public $description;
public $title;
public $type;
public $data;
public $delta;
public $view_mode;
protected $plugin;
/**
* Get Plugin info
*
* @param $key
* The plugin key to get the info for.
*/
public function getInfo($key = NULL) {
if ($this->plugin instanceof BoxTypePluginInterface) {
return $this->plugin
->getInfo($key);
}
return NULL;
}
public function defaultLabel() {
return $this->label;
}
public function __construct(array $values = array()) {
// If this is new then set the type first.
if (isset($values['is_new'])) {
$this->type = isset($values['type']) ? $values['type'] : '';
}
parent::__construct($values, 'box');
}
protected function setUp() {
parent::setUp();
if (!empty($this->type)) {
$plugin = boxes_load_plugin_class($this->type);
$this
->loadUp($plugin);
}
}
/**
* This is a work around for version of PDO that call __construct() before
* it loads up the object with values from the DB.
*/
public function loadUp($plugin) {
if (empty($this->plugin)) {
// If the plugin has been disabled, the $plugin will be a boolean.
// just load the base plugin so something will render.
if (!$plugin instanceof BoxTypePluginInterface) {
$plugin = boxes_load_plugin_class('box_default');
}
$this
->setPlugin($plugin);
$this
->setFields();
}
}
/**
* Load and set the plugin info.
* This can be called externally via loadUP()
*/
protected function setPlugin($plugin) {
$this->plugin = $plugin;
}
/**
* Set the fields from the defaults and plugin
* This can be called externally via loadUP()
*/
protected function setFields() {
// NOTE: When setFields is called externally $this->data is already unserialized.
if (!empty($this->plugin) && !empty($this->type)) {
$values = is_array($this->data) ? $this->data : unserialize($this->data);
foreach ($this->plugin
->values() as $field => $default) {
$this->{$field} = isset($values[$field]) ? $values[$field] : $default;
}
}
}
/**
* Override this in order to implement a custom default URI and specify
* 'entity_class_uri' as 'uri callback' hook_entity_info().
*/
protected function defaultUri() {
return array(
'path' => 'block/' . $this
->identifier(),
);
}
/**
* Get the plugin form
*/
public function getForm($form, &$form_state) {
return $this->plugin
->form($this, $form, $form_state);
}
/**
* Validate the plugin form
*/
public function validate($values, &$form_state) {
$this->plugin
->validate($values, $form_state);
}
/**
* URL string
*/
public function url() {
$uri = $this
->defaultUri();
return $uri['path'];
}
/**
* Build the URL string
*/
protected function buildURL($type) {
$url = $this
->url();
return $url . '/' . $type;
}
/**
* View URL
*/
public function viewURL() {
return $this
->buildURL('view');
}
/**
* View URL
*/
public function editURL() {
return $this
->buildURL('edit');
}
/**
* View URL
*/
public function deleteURL() {
return $this
->buildURL('delete');
}
/**
* Type name
*/
public function typeName() {
return $this
->getInfo('label');
}
/**
* Set the values from a plugin
*/
public function setValues($values) {
$this->data = array();
foreach ($this->plugin
->values() as $field => $value) {
$this->data[$field] = $values[$field];
}
}
/**
* Generate an array for rendering the entity.
*
* @see entity_view()
*/
public function view($view_mode = 'default', $langcode = NULL, $page = NULL) {
$content = parent::view($view_mode, $langcode);
if (empty($this->plugin)) {
return $content;
}
return $this->plugin
->view($this, $content, $view_mode, $langcode);
}
/**
* Override the save to add clearing of caches
*/
public function save() {
// Set the delta if it's not set already
if (empty($this->delta)) {
$max_length = 32;
// Base it on the label and make sure it isn't too long for the database.
$this->delta = drupal_clean_css_identifier(strtolower($this->label));
$this->delta = substr($this->delta, 0, $max_length);
// Check if delta is unique.
if (boxes_load_delta($this->delta)) {
$i = 0;
$separator = '-';
$original_delta = $this->delta;
do {
$unique_suffix = $separator . $i++;
$this->delta = substr($original_delta, 0, $max_length - drupal_strlen($unique_suffix)) . $unique_suffix;
} while (boxes_load_delta($this->delta));
}
}
$this->plugin
->submit($this);
$return = parent::save();
block_flush_caches();
cache_clear_all('boxes:' . $this->delta . ':', 'cache_block', TRUE);
return $return;
}
/**
* Override the delete to remove the fields and blocks
*/
public function delete() {
if ($this
->internalIdentifier()) {
// Delete the field values
field_attach_delete('box', $this);
// Delete any blocks
// @see block_custom_block_delete_submit()
db_delete('block')
->condition('module', 'boxes')
->condition('delta', $this
->identifier())
->execute();
db_delete('block_role')
->condition('module', 'boxes')
->condition('delta', $this
->identifier())
->execute();
// @see node_form_block_custom_block_delete_submit()
db_delete('block_node_type')
->condition('module', 'boxes')
->condition('delta', $this
->identifier())
->execute();
entity_get_controller($this->entityType)
->delete(array(
$this
->internalIdentifier(),
));
}
}
}
class BoxEntityAPIController extends EntityAPIController {
protected function setPlugin(Box $box) {
static $plugins = array();
if (empty($plugins[$box->type])) {
$plugins[$box->type] = boxes_load_plugin_class($box->type);
$box
->loadUp($plugins[$box->type]);
}
}
/**
* Overridden.
* @see EntityAPIController#load($ids, $conditions)
*
* We need to load the plugin and set the defaults before
* anything else is down to the record
*/
public function load($ids = array(), $conditions = array()) {
$entities = array();
// Revisions are not statically cached, and require a different query to
// other conditions, so separate the revision id into its own variable.
if ($this->revisionKey && isset($conditions[$this->revisionKey])) {
$revision_id = $conditions[$this->revisionKey];
unset($conditions[$this->revisionKey]);
}
else {
$revision_id = FALSE;
}
// Create a new variable which is either a prepared version of the $ids
// array for later comparison with the entity cache, or FALSE if no $ids
// were passed. The $ids array is reduced as items are loaded from cache,
// and we need to know if it's empty for this reason to avoid querying the
// database when all requested entities are loaded from cache.
$passed_ids = !empty($ids) ? array_flip($ids) : FALSE;
// Try to load entities from the static cache.
if ($this->cache && !$revision_id) {
$entities = $this
->cacheGet($ids, $conditions);
// If any entities were loaded, remove them from the ids still to load.
if ($passed_ids) {
$ids = array_keys(array_diff_key($passed_ids, $entities));
}
}
// Load any remaining entities from the database. This is the case if $ids
// is set to FALSE (so we load all entities), if there are any ids left to
// load or if loading a revision.
if (!($this->cacheComplete && $ids === FALSE && !$conditions) && ($ids === FALSE || $ids || $revision_id)) {
$queried_entities = array();
foreach ($this
->query($ids, $conditions, $revision_id) as $record) {
// This is what was overridden.
$this
->setPlugin($record);
// Skip entities already retrieved from cache.
if (isset($entities[$record->{$this->idKey}])) {
continue;
}
// Take care of serialized columns.
$schema = drupal_get_schema($this->entityInfo['base table']);
foreach ($schema['fields'] as $field => $info) {
if (!empty($info['serialize']) && isset($record->{$field})) {
$record->{$field} = unserialize($record->{$field});
// Support automatic merging of 'data' fields into the entity.
if (!empty($info['merge']) && is_array($record->{$field})) {
foreach ($record->{$field} as $key => $value) {
$record->{$key} = $value;
}
unset($record->{$field});
}
}
}
$queried_entities[$record->{$this->idKey}] = $record;
}
}
// Pass all entities loaded from the database through $this->attachLoad(),
// which attaches fields (if supported by the entity type) and calls the
// entity type specific load callback, for example hook_node_load().
if (!empty($queried_entities)) {
$this
->attachLoad($queried_entities, $revision_id);
$entities += $queried_entities;
}
if ($this->cache) {
// Add entities to the cache if we are not loading a revision.
if (!empty($queried_entities) && !$revision_id) {
$this
->cacheSet($queried_entities);
// Remember if we have cached all entities now.
if (!$conditions && $ids === FALSE) {
$this->cacheComplete = TRUE;
}
}
}
// Ensure that the returned array is ordered the same as the original
// $ids array if this was passed in and remove any invalid ids.
if ($passed_ids && ($passed_ids = array_intersect_key($passed_ids, $entities))) {
foreach ($passed_ids as $id => $value) {
$passed_ids[$id] = $entities[$id];
}
$entities = $passed_ids;
}
return $entities;
}
}
class BoxException extends Exception {
}
Classes
Name | Description |
---|---|
Box | The Box entity class |
BoxEntityAPIController | |
BoxException |
Interfaces
Name | Description |
---|---|
BoxTypePluginInterface | Interface for Plugin Classes |