flexiform.flexiform.inc in Flexiform 7
Same filename in this branch
flexiform.flexiform.inc Helper function for embedding the fields into the flexiform in an arbitrary order
File
includes/flexiform.flexiform.incView source
<?php
/**
* @file flexiform.flexiform.inc
* Helper function for embedding the fields into the flexiform in an arbitrary order
*/
/**
* Get the base entity for a flexible form.
*
* If an id is passed, load the entity and return it. Otherwise create a new
* entity with the correct type and bundle.
*
* @param Flexiform $flexiform
* A flexiform object.
* @param int $base_entity_id
* (optional) The id of the base entity if it already exists.
*
* @return stdClass|Entity
* The base entity for the form.
*/
function flexiform_get_base_entity($flexiform, $base_entity_id = FALSE) {
if ($base_entity_id) {
$base_entity = entity_load_single($flexiform->base_entity, $base_entity_id);
//@todo: Check the entity is the right bundle.
return $base_entity;
}
$info = entity_get_info($flexiform->base_entity);
$values = array();
if (!empty($info['entity keys']['bundle'])) {
$values[$info['entity keys']['bundle']] = $flexiform->base_entity_bundle;
}
$base_entity = entity_create($flexiform->base_entity, $values);
return $base_entity;
}
/**
* Form callback wrapper: fill out a flexiform.
*
* @param $flexiform
* The flexiform being submitted by this form.
* @param $base_entity
* The base entity for this form.
*
* @see flexiform()
* @see flexiform_simple()
*/
function flexiform_wrapper($flexiform, $base_entity) {
$form_id = 'flexiform__' . $flexiform->form;
return drupal_get_form($form_id, $flexiform, $base_entity);
}
/**
* Form callback wrapper: flexiform modals.
*
* @param $flexiform
* The flexiform being wrapped.
* @param $base_entity
* The base entity for this form.
* @param string $display
* The active modal display.
*/
function flexiform_modal_wrapper($flexiform, $base_entity, $display) {
ctools_include('ajax');
ctools_include('modal');
// Prepare form id and form args.
$form_id = "flexiform__{$flexiform->form}";
$args = array(
$flexiform,
$base_entity,
);
// Setup form state.
$form_state = array(
'ajax' => TRUE,
'build_info' => array(
'args' => $args,
),
);
$commands = ctools_modal_form_wrapper($form_id, $form_state);
if (!empty($form_state['executed']) && empty($form_state['rebuild'])) {
$configuration = $flexiform
->getDisplay($display)->configuration;
// The form has been executed, so let's redirect to the destination page.
$commands = array();
if (!empty($_GET['destination'])) {
$commands[] = ctools_ajax_command_redirect($_GET['destination']);
}
elseif (!empty($form_state['redirect'])) {
$options = array();
if (is_array($form_state['redirect'])) {
list($url, $options) = $form_state['redirect'];
}
else {
$url = $form_state['redirect'];
}
$commands[] = ctools_ajax_command_redirect($url, 0, $options);
}
elseif ($configuration['ajax_behavior'] == 'modal_dismiss') {
$commands[] = ctools_modal_command_dismiss();
}
else {
$commands[] = ctools_ajax_command_reload();
}
}
drupal_alter('flexiform_modal_submit_commands', $commands, $flexiform, $form_state);
ajax_deliver(array(
'#type' => 'ajax',
'#commands' => $commands,
));
drupal_exit();
}
/**
* Build a flexiform.
*
* @param array $form
* @param array $form_state
* @param Flexiform $flexiform
* @param Entity|stdClass $base_entity
* @param bool $include_actions
* Boolean flag for whether the actions element should be included at the
* bottom of the form.
*
* @return
* Constructed form array.
*/
function flexiform($form, &$form_state, $flexiform, $base_entity) {
// @TODO: Consider moving all of these functions into .module easier accessibility.
form_load_include($form_state, 'inc', 'flexiform', 'includes/flexiform.flexiform');
$form['#flexiform_builder'] = $builder = $flexiform
->getBuilder($base_entity);
$form = $builder
->form($form, $form_state);
$form['actions'] = array(
'#type' => 'container',
'#attributes' => array(
'class' => array(
'form-actions',
),
),
'#weight' => 400,
);
// We add the form's #submit array to this button along with the actual submit
// handler to preserve any submit handlers added by a form callback_wrapper.
$submit = array();
if (!empty($form['#submit'])) {
$submit += $form['#submit'];
}
// Get button settings.
$submit_text = t('Save');
if (!empty($flexiform->settings['buttons']['submit_text'])) {
$submit_text = $flexiform->settings['buttons']['submit_text'];
}
$form['actions']['submit'] = array(
'#type' => 'submit',
'#value' => $submit_text,
'#submit' => $submit + array(
'flexiform_submit',
),
);
if (!empty($flexiform->settings['ajax']['submit'])) {
$wrapper_id = $form_state['build_info']['form_id'] . '-ajax-wrapper';
$form['#prefix'] = '<div id="' . $wrapper_id . '">';
$form['#suffix'] = '</div>';
$form['actions']['submit']['#ajax'] = array(
'wrapper' => $wrapper_id,
'callback' => 'flexiform_submit_ajax',
);
}
// We append the validate handler to #validate in case a form callback_wrapper
// is used to add validate handlers earlier.
$form['#validate'][] = 'flexiform_validate';
if (module_exists('honeypot')) {
if (!empty($flexiform->settings['honeypot'])) {
$protections = array_keys(array_filter($flexiform->settings['honeypot']));
honeypot_add_form_protection($form, $form_state, $protections);
}
}
return $form;
}
/**
* Validation callback for a flexiform stuff.
*/
function flexiform_validate($form, &$form_state) {
$form['#flexiform_builder']
->formValidate($form, $form_state);
}
/**
* Submit callback for a flexiform.
*/
function flexiform_submit($form, &$form_state) {
$form['#flexiform_builder']
->formSubmit($form, $form_state);
$form['#flexiform_builder']
->formSubmitRedirect($form, $form_state);
}
/**
* Submit AJAX callback for a flexiform.
*/
function flexiform_submit_ajax($form, $form_state) {
/** @var \Flexiform $flexiform */
$flexiform = $form['#flexiform'];
if (empty($form_state['executed'])) {
return $form;
}
switch ($flexiform->settings['ajax']['response']) {
case 'refresh':
$wrapper = $form_state['triggering_element']['#ajax']['wrapper'];
// Prevent submitted values bleeding into the new form.
$original_post = $_POST;
$_POST = array();
// Prepare args. We reload entities to ensure we have the right one.
$args = $form_state['build_info']['args'];
$base_entity = $args[1];
$base_entity_id = entity_id($flexiform->base_entity, $base_entity);
$args[1] = entity_load_single($flexiform->base_entity, $base_entity_id);
$new_form = call_user_func_array('drupal_get_form', array_merge(array(
$form_state['build_info']['form_id'],
), $args));
$_POST = $original_post;
unset($original_post);
$commands = array(
ajax_command_replace('#' . $wrapper, drupal_render($new_form)),
ajax_command_prepend('#' . $wrapper, theme('status_messages')),
);
break;
case 'reload':
ctools_include('ajax');
$commands = array(
ctools_ajax_command_reload(),
);
break;
case 'redirect':
ctools_include('ajax');
$redirect = !empty($flexiform->settings['ajax']['redirect']) ? $flexiform->settings['ajax']['redirect'] : '';
$redirect = $form['#flexiform_builder']
->replaceCtoolsSubstitutions($redirect);
$options = array();
if (!empty($form_state['redirect'])) {
if (is_array($form_state['redirect'])) {
$redirect = $form_state['redirect'][0];
$options = $form_state['redirect'][1];
}
else {
$redirect = $form_state['redirect'];
}
}
$commands = array(
ctools_ajax_command_redirect($redirect, 0, $options),
);
break;
}
$context = array(
'flexiform' => $flexiform,
'form' => $form,
'form_state' => $form_state,
);
drupal_alter('flexiform_ajax_submit_commands', $commands, $context);
return array(
'#type' => 'ajax',
'#commands' => $commands,
);
}
/**
* Add elements for an entity to the form based on settings in the $elements array.
*
* @param $entity_namespace
* The namespace for this entity in this form
* @param $flexiform
* The flexiform object.
* @param $entity
* The entity object
* @param $elements array
* An array of elementss to be included in the form. Keyed by element_name.
* @param $form
* @param $form_state
*/
function flexiform_embed_entity_elements($entity_namespace, $flexiform, $entity, $elements, &$form, &$form_state) {
// Set up our form bits
if (!isset($form['#parents'])) {
$form['#parents'] = array();
}
// All the fields for this entity need to end up with the correct parents
// so set the #parents here to be the entity namespace and unset it after the
// loop.
array_push($form['#parents'], $entity_namespace);
// Iterate over the fields
foreach ($elements as $element_name => $settings) {
$element_namespace = FlexiformElement::makeElementNamespace($settings['type'], $entity_namespace, $element_name);
$element = FlexiformElement::getElement($flexiform, $settings['type'], $element_namespace, $settings);
$form += $element
->form($form, $form_state, $entity);
}
array_pop($form['#parents']);
}
/**
* Prepare the entities needed for the form, either by creating or loading
*
* @param $flexiform
* The form definition
* @param $base_entity
* The base entity of the form.
*
* @return
* An array of entities keyed by namespace
*/
function flexiform_prepare_entities($flexiform, $base_entity) {
$flexiform
->getBuilder($base_entity)
->prepareEntities();
}
/**
* Get the namespace we use for the entity
*
* @param $entity_type
* The entity type e.g. node,user or taxonomy term
* @param $entity
* The entity object
*
* @return
* A Unique namespace for the entity in this form
*/
function flexiform_get_entity_namespace($entity_type, $entity) {
$entity_info = entity_get_info($entity_type);
return $entity_type . '__' . $entity->{$entity_info['entity keys']['id']};
}
/**
* Get the fields on a form from a particular entity namespace
*
* @param $entity_namespace
* The namespace as give by flexiform_get_entity_namespace
* @param $form
* Fully Built form object
*
* @return
* A form array with only the fields from that entity included without the namespace prefixed
*/
function flexiform_get_entity_namespace_fields($entity_namespace, $form) {
$entity_form = array();
$namespace_length = strlen($entity_namespace);
foreach ($form as $key => $field) {
if (substr($key, 0, 1) == '#') {
$entity_form[$key] = $field;
}
elseif (substr($key, 0, $namespace_length) == $entity_namespace) {
$entity_form[substr($key, $namespace_length + 2)] = $field;
}
}
$entity_form['#parents'][] = $entity_namespace;
return $entity_form;
}
/**
* Get the bundle key for an entity type
*/
function _flexiform_get_bundle_key($entity_type) {
$info = entity_get_info($entity_type);
return empty($info['entity keys']['bundle']) ? FALSE : $info['entity keys']['bundle'];
}
/**
* Get the bundle for an entity type and entity
*/
function _flexiform_get_bundle($entity_type, $entity) {
$bundle_key = _flexiform_get_bundle_key($entity_type);
if (!$bundle_key) {
return $entity_type;
}
else {
return $entity->{$bundle_key};
}
}
/**
* Getter callback for 'base entity'
*
* @param Flexiform $flexiform
* The flexiform object.
* @param Entity|stdClass $base_entity
* The base entity for the form.
* @param array $entities
* An array of entities already embedded in the form.
* @param string $namespace
* The namespace of the entity being got for this form.
* @param array $config
* The settings for this getter, as defined in flexiform_getter_info.
*/
function flexiform_entity_getter_base_entity($flexiform, $base_entity, $entities, $namespace, $config) {
return $base_entity;
}
/**
* Getter callback for 'base entity'
*/
function flexiform_entity_setter_base_entity($flexiform, $base_entity, $entity, $entity_type, $entities, $namespace, $config) {
entity_save($entity_type, $entity);
}
Functions
Name![]() |
Description |
---|---|
flexiform | Build a flexiform. |
flexiform_embed_entity_elements | Add elements for an entity to the form based on settings in the $elements array. |
flexiform_entity_getter_base_entity | Getter callback for 'base entity' |
flexiform_entity_setter_base_entity | Getter callback for 'base entity' |
flexiform_get_base_entity | Get the base entity for a flexible form. |
flexiform_get_entity_namespace | Get the namespace we use for the entity |
flexiform_get_entity_namespace_fields | Get the fields on a form from a particular entity namespace |
flexiform_modal_wrapper | Form callback wrapper: flexiform modals. |
flexiform_prepare_entities | Prepare the entities needed for the form, either by creating or loading |
flexiform_submit | Submit callback for a flexiform. |
flexiform_submit_ajax | Submit AJAX callback for a flexiform. |
flexiform_validate | Validation callback for a flexiform stuff. |
flexiform_wrapper | Form callback wrapper: fill out a flexiform. |
_flexiform_get_bundle | Get the bundle for an entity type and entity |
_flexiform_get_bundle_key | Get the bundle key for an entity type |