class FlexiformFormEntityManagerDefault in Flexiform 7
Class that manages entities in a flexiform.
Hierarchy
- class \FlexiformFormEntityManagerDefault implements FlexiformFormEntityManagerInterface
Expanded class hierarchy of FlexiformFormEntityManagerDefault
File
- includes/
flexiform.form_entity_manager.inc, line 70 - Contains the default entity manager for flexiforms.
View source
class FlexiformFormEntityManagerDefault implements FlexiformFormEntityManagerInterface {
/**
* The form builder.
* @var FlexiformBuilderInterface
*/
protected $builder;
/**
* An array of callbacks keyed by $type and $entity_namespace
* @var array
*/
protected $callbacks = array();
/**
* The entity settings keyed by entity namespace.
* @var array
*/
protected $entitySettings = array();
/**
* The entities after they have been prepared.
* @var array
*/
protected $entities = array();
/**
* Whether the entities have been prepared or not.
*/
protected $prepared = array();
/**
* The base entity key.
* @var string
*/
protected $base_entity_key = '';
/**
* An array of booleans keyed by namespace of entities to skip on save.
*
* @var bool[]
*/
protected $skip_save = array();
/**
* Build and instance of this entity manager.
*
* @param array $settings
* An array of entity settings keyed by entity namespace.
*/
public function __construct(array $settings, FlexiformBuilderInterface $builder) {
$this->entitySettings = $settings;
$this->builder = $builder;
}
/**
* Set the base entity.
*/
public function setBaseEntity($entity, $namespace = 'base_entity') {
$this->entities[$namespace] = $entity;
$this->base_entity_key = $namespace;
return $this;
}
/**
* Get the base entity.
*/
public function getBaseEntity() {
return $this->entities[$this->base_entity_key];
}
/**
* Prepare the entities needed for the form, either by creating or loading.
*/
public function prepareEntities() {
foreach ($this->entitySettings as $namespace => $info) {
$this
->prepareEntity($namespace);
}
}
/**
* Prepare an individual entity.
*
* @param $namespace
* The namespace of the entity to be prepared.
*
* @todo: Put some infinite recursion checking in place.
*/
public function prepareEntity($namespace) {
// Don't prepare again if and entity is already prepared.
if (!empty($this->prepared[$namespace])) {
return;
}
// If this is the base entity and its not prepared we must throw an error
// as without a base entity set nothing is going to work.
if (empty($this->entities[$this->base_entity_key])) {
throw new Exception(t('Cannot Prepare Entities without the base entity being set, this must be set using setBaseEntity.'));
}
$info = $this
->getEntitySettings($namespace);
// First make sure that any parameters have been prepared.
if (!empty($info['parameters'])) {
foreach ($info['parameters'] as $param_namespace) {
if (empty($this->prepared[$param_namespace])) {
$this
->prepareEntity($param_namespace);
}
}
}
// Prepare this entity.
if ($handler = $this
->getEntityHandler($namespace)) {
$this->entities[$namespace] = $handler
->getEntity();
$this->prepared[$namespace] = TRUE;
}
}
/**
* Get the entity handler class.
*
* @param $namespace
* The namespace of the entity to get.
*
* @return FlexiformFormEntityInterface
* The form entity handler object.
*/
public function getEntityHandler($namespace) {
if ($getter = $this
->getEntityGetterInfo($namespace)) {
$class = $getter['class'];
if (empty($class) || !class_exists($class) || !in_array('FlexiformFormEntityInterface', class_implements($class))) {
throw new Exception(t('Form Entity Class %class not found or not suitable using %getter', array(
'%getter' => $getter['label'],
'%class' => $class,
)));
}
return new $class($this, $namespace, $getter);
}
return FALSE;
}
/**
* Get the entities.
*
* @return array
* An array of all the entities ready to be used in this form.
*/
public function getEntities() {
// If not all entities are prepared.
if (count(array_filter($this->prepared)) != count($this->entitySettings)) {
$this
->prepareEntities();
}
return $this->entities;
}
/**
* Get the entities without checking if they are prepared.
*
* @return array
* An array of all the entities that have been prepared at the time this
* method is called.
*/
public function getEntitiesRaw() {
return $this->entities;
}
/**
* Get an entity from the set.
*
* This method will prepare the entity if it has not already been prepared.
*
* @param string $namespace
* The namespace of the required entity.
*
* @return Entity|stdClass
* The prepared entity object.
*/
public function getEntity($namespace) {
if (empty($this->prepared[$namespace])) {
$this
->prepareEntity($namespace);
}
if (isset($this->entities[$namespace])) {
return $this->entities[$namespace];
}
return FALSE;
}
/**
* Get an entities settings from the settings array.
*
* @param string $namespace
* The namespace of the required entity settings.
*
* @return array
* Settings for the entity with namespace $namespace.
*/
public function getEntitySettings($namespace) {
if (isset($this->entitySettings[$namespace])) {
return $this->entitySettings[$namespace];
}
return FALSE;
}
/**
* Get the entity type from the settings.
*/
public function getEntityType($namespace) {
if (isset($this->entitySettings[$namespace])) {
return $this->entitySettings[$namespace]['entity_type'];
}
return FALSE;
}
/**
* Get an entities bundle from the settings.
*/
public function getEntityBundle($namespace) {
if (isset($this->entitySettings[$namespace])) {
return $this->entitySettings[$namespace]['bundle'];
}
return FALSE;
}
/**
* Get an entities getter info.
*/
public function getEntityGetterInfo($namespace) {
if (isset($this->entitySettings[$namespace])) {
if (isset($this->entitySettings[$namespace]['getter'])) {
$getter = $this->entitySettings[$namespace]['getter'];
return flexiform_entity_getter_info($getter);
}
}
return FALSE;
}
/**
* Mark an entity to be skipped or not on save.
*
* @param string $namespace
* The namespace of the entity to skip.
* @param bool $skip
* Whether to skip this entity on save.
*/
public function skipOnSave($namespace, $skip) {
$this->skip_save[$namespace] = $skip;
}
/**
* Save Entities.
*/
public function saveEntities() {
foreach ($this->entitySettings as $namespace => $info) {
// Allow forms to skip saving particular entities.
if (!empty($this->skip_save[$namespace])) {
continue;
}
if (($handler = $this
->getEntityHandler($namespace)) && ($entity = $this
->getEntity($namespace))) {
$this
->executeCallbacks('preSave', $namespace);
$handler
->saveEntity($entity);
$this
->executeCallbacks('postSave', $namespace);
}
}
// Reset the skip entities.
$this->skip_save = array();
}
/**
* Execute Save Callbacks.
*
* Save callbacks can be registered against an entity_namespace to be run
* just after (post) or just before (pre) an entity is saved. If an entity is
* skipped for whatever reason these callbacks do not run.
*
* @param string $type
* The type of callback to fire, either 'postSave' or 'preSave'
* @param string $namespace
* The namespace of the entity.
*/
public function executeCallbacks($type, $namespace) {
if (empty($this->callbacks[$type][$namespace])) {
return;
}
foreach ($this->callbacks[$type][$namespace] as $callback) {
array_unshift($callback['extra_args'], $this
->getEntity($namespace));
call_user_func_array($callback['callback'], $callback['extra_args']);
}
}
/**
* Register a Callback
*
* Register callbacks to be run at certain times by the entity manager.
*
* @param string $type
* The type of callback to fire, either 'post' or 'pre'
* @param string $namespace
* The namespace of the entity.
* @param callable $callback
* The callback to fire.
* @param array $extra
* Array of extra arguments to pass to the callback.
*/
public function registerCallback($type, $namespace, $callback, $extra = array()) {
$this->callbacks[$type][$namespace][] = array(
'callback' => $callback,
'extra_args' => $extra,
);
}
/**
* Save Entity Settings.
*/
public function saveEntitySettings() {
$flexiform = $this
->getBuilder()
->getFlexiform();
$flexiform->entities = $this->entitySettings;
$flexiform
->save();
}
/**
* Remove and entity from this form.
*/
public function removeEntitySettings($namespace) {
unset($this->entitySettings[$namespace]);
$this
->saveEntitySettings();
}
/**
* Update entity settings.
*/
public function updateEntitySettings($namespace, $settings) {
$this->entitySettings[$namespace] = $settings;
$this
->saveEntitySettings();
}
/**
* Find out if any entities depend on this entity.
*/
public function checkForDependants($namespace) {
$dependants = array();
foreach ($this->entitySettings as $curNamespace => $settings) {
if (!empty($settings['parameters'])) {
foreach ($settings['parameters'] as $param => $paramNamespace) {
if ($namespace === $paramNamespace) {
$dependants[$curNamespace] = $settings['label'];
}
}
}
}
return $dependants;
}
/**
* Get the builder.
*/
public function getBuilder() {
return $this->builder;
}
}