security update core+modules
This commit is contained in:
@@ -171,7 +171,7 @@ class EntityAPIController extends DrupalDefaultEntityController implements Entit
|
||||
if ($this->revisionKey) {
|
||||
// Compare revision id of the base and revision table, if equal then this
|
||||
// is the default revision.
|
||||
$query->addExpression('base.' . $this->revisionKey . ' = revision.' . $this->revisionKey, $this->defaultRevisionKey);
|
||||
$query->addExpression('CASE WHEN base.' . $this->revisionKey . ' = revision.' . $this->revisionKey . ' THEN 1 ELSE 0 END', $this->defaultRevisionKey);
|
||||
}
|
||||
return $query;
|
||||
}
|
||||
@@ -373,10 +373,7 @@ class EntityAPIController extends DrupalDefaultEntityController implements Entit
|
||||
// Do nothing, in case invalid or no ids have been passed.
|
||||
return;
|
||||
}
|
||||
// This transaction causes troubles on MySQL, see
|
||||
// http://drupal.org/node/1007830. So we deactivate this by default until
|
||||
// is shipped in a point release.
|
||||
// $transaction = isset($transaction) ? $transaction : db_transaction();
|
||||
$transaction = isset($transaction) ? $transaction : db_transaction();
|
||||
|
||||
try {
|
||||
$ids = array_keys($entities);
|
||||
@@ -400,9 +397,7 @@ class EntityAPIController extends DrupalDefaultEntityController implements Entit
|
||||
db_ignore_slave();
|
||||
}
|
||||
catch (Exception $e) {
|
||||
if (isset($transaction)) {
|
||||
$transaction->rollback();
|
||||
}
|
||||
$transaction->rollback();
|
||||
watchdog_exception($this->entityType, $e);
|
||||
throw $e;
|
||||
}
|
||||
@@ -587,6 +582,30 @@ class EntityAPIController extends DrupalDefaultEntityController implements Entit
|
||||
$entity->content = $content;
|
||||
$langcode = isset($langcode) ? $langcode : $GLOBALS['language_content']->language;
|
||||
|
||||
// Allow modules to change the view mode.
|
||||
$context = array(
|
||||
'entity_type' => $this->entityType,
|
||||
'entity' => $entity,
|
||||
'langcode' => $langcode,
|
||||
);
|
||||
drupal_alter('entity_view_mode', $view_mode, $context);
|
||||
// Make sure the used view-mode gets stored.
|
||||
$entity->content += array('#view_mode' => $view_mode);
|
||||
|
||||
// By default add in properties for all defined extra fields.
|
||||
if ($extra_field_controller = entity_get_extra_fields_controller($this->entityType)) {
|
||||
$wrapper = entity_metadata_wrapper($this->entityType, $entity);
|
||||
$extra = $extra_field_controller->fieldExtraFields();
|
||||
$type_extra = &$extra[$this->entityType][$this->entityType]['display'];
|
||||
$bundle_extra = &$extra[$this->entityType][$wrapper->getBundle()]['display'];
|
||||
|
||||
foreach ($wrapper as $name => $property) {
|
||||
if (isset($type_extra[$name]) || isset($bundle_extra[$name])) {
|
||||
$this->renderEntityProperty($wrapper, $name, $property, $view_mode, $langcode, $entity->content);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add in fields.
|
||||
if (!empty($this->entityInfo['fieldable'])) {
|
||||
// Perform the preparation tasks if they have not been performed yet.
|
||||
@@ -608,6 +627,24 @@ class EntityAPIController extends DrupalDefaultEntityController implements Entit
|
||||
return $build;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders a single entity property.
|
||||
*/
|
||||
protected function renderEntityProperty($wrapper, $name, $property, $view_mode, $langcode, &$content) {
|
||||
$info = $property->info();
|
||||
|
||||
$content[$name] = array(
|
||||
'#label_hidden' => FALSE,
|
||||
'#label' => $info['label'],
|
||||
'#entity_wrapped' => $wrapper,
|
||||
'#theme' => 'entity_property',
|
||||
'#property_name' => $name,
|
||||
'#access' => $property->access('view'),
|
||||
'#entity_type' => $this->entityType,
|
||||
);
|
||||
$content['#attached']['css']['entity.theme'] = drupal_get_path('module', 'entity') . '/theme/entity.theme.css';
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements EntityAPIControllerInterface.
|
||||
*/
|
||||
|
||||
@@ -30,6 +30,8 @@ class Entity {
|
||||
protected $entityType;
|
||||
protected $entityInfo;
|
||||
protected $idKey, $nameKey, $statusKey;
|
||||
protected $defaultLabel = FALSE;
|
||||
protected $wrapper;
|
||||
|
||||
/**
|
||||
* Creates a new entity.
|
||||
@@ -55,7 +57,7 @@ class Entity {
|
||||
$this->entityInfo = entity_get_info($this->entityType);
|
||||
$this->idKey = $this->entityInfo['entity keys']['id'];
|
||||
$this->nameKey = isset($this->entityInfo['entity keys']['name']) ? $this->entityInfo['entity keys']['name'] : $this->idKey;
|
||||
$this->statusKey = empty($info['entity keys']['status']) ? 'status' : $info['entity keys']['status'];
|
||||
$this->statusKey = empty($this->entityInfo['entity keys']['status']) ? 'status' : $this->entityInfo['entity keys']['status'];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -110,6 +112,23 @@ class Entity {
|
||||
return !empty($this->entityInfo['entity keys']['bundle']) ? $this->{$this->entityInfo['entity keys']['bundle']} : $this->entityType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the EntityMetadataWrapper of the entity.
|
||||
*
|
||||
* @return EntityDrupalWrapper
|
||||
* An EntityMetadataWrapper containing the entity.
|
||||
*/
|
||||
public function wrapper() {
|
||||
if (empty($this->wrapper)) {
|
||||
$this->wrapper = entity_metadata_wrapper($this->entityType, $this);
|
||||
}
|
||||
elseif ($this->wrapper->value() !== $this) {
|
||||
// Wrapper has been modified outside, so let's better create a new one.
|
||||
$this->wrapper = entity_metadata_wrapper($this->entityType, $this);
|
||||
}
|
||||
return $this->wrapper;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the label of the entity.
|
||||
*
|
||||
@@ -119,10 +138,18 @@ class Entity {
|
||||
* @see entity_label()
|
||||
*/
|
||||
public function label() {
|
||||
if (isset($this->entityInfo['label callback']) && $this->entityInfo['label callback'] == 'entity_class_label') {
|
||||
// If the default label flag is enabled, this is being invoked recursively.
|
||||
// In this case we need to use our default label callback directly. This may
|
||||
// happen if a module provides a label callback implementation different
|
||||
// from ours, but then invokes Entity::label() or entity_class_label() from
|
||||
// there.
|
||||
if ($this->defaultLabel || (isset($this->entityInfo['label callback']) && $this->entityInfo['label callback'] == 'entity_class_label')) {
|
||||
return $this->defaultLabel();
|
||||
}
|
||||
return entity_label($this->entityType, $this);
|
||||
$this->defaultLabel = TRUE;
|
||||
$label = entity_label($this->entityType, $this);
|
||||
$this->defaultLabel = FALSE;
|
||||
return $label;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -253,7 +280,8 @@ class Entity {
|
||||
*/
|
||||
public function getTranslation($property, $langcode = NULL) {
|
||||
$all_info = entity_get_all_property_info($this->entityType);
|
||||
$property_info = $all_info[$property];
|
||||
// Assign by reference to avoid triggering notices if metadata is missing.
|
||||
$property_info = &$all_info[$property];
|
||||
|
||||
if (!empty($property_info['translatable'])) {
|
||||
if (!empty($property_info['field'])) {
|
||||
|
||||
@@ -251,7 +251,11 @@ function entity_property_verify_data_type($data, $type) {
|
||||
return TRUE;
|
||||
}
|
||||
elseif (isset($info[$type]['entity keys']['name'])) {
|
||||
return entity_property_verify_data_type($data, 'token');
|
||||
// Read the data type of the name key from the metadata if available.
|
||||
$key = $info[$type]['entity keys']['name'];
|
||||
$property_info = entity_get_property_info($type);
|
||||
$property_type = isset($property_info['properties'][$key]['type']) ? $property_info['properties'][$key]['type'] : 'token';
|
||||
return entity_property_verify_data_type($data, $property_type);
|
||||
}
|
||||
return entity_property_verify_data_type($data, empty($info[$type]['fieldable']) ? 'text' : 'integer');
|
||||
}
|
||||
@@ -392,7 +396,12 @@ function entity_property_verbatim_get($data, array $options, $name, $type, $info
|
||||
*/
|
||||
function entity_property_verbatim_date_get($data, array $options, $name, $type, $info) {
|
||||
$name = isset($info['schema field']) ? $info['schema field'] : $name;
|
||||
return is_numeric($data[$name]) ? $data[$name] : strtotime($data[$name], REQUEST_TIME);
|
||||
if (is_array($data) || (is_object($data) && $data instanceof ArrayAccess)) {
|
||||
return is_numeric($data[$name]) ? $data[$name] : strtotime($data[$name], REQUEST_TIME);
|
||||
}
|
||||
elseif (is_object($data)) {
|
||||
return is_numeric($data->$name) ? $data->$name : strtotime($data->$name, REQUEST_TIME);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -503,6 +512,8 @@ function entity_property_text_formatted_info() {
|
||||
'label' => t('Text format'),
|
||||
'options list' => 'entity_metadata_field_text_formats',
|
||||
'getter callback' => 'entity_property_verbatim_get',
|
||||
'setter callback' => 'entity_property_verbatim_set',
|
||||
'setter permissions' => 'administer filters',
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -6,12 +6,16 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* Default controller for providing UI.
|
||||
* Default UI controller providing admin UI.
|
||||
*
|
||||
* This controller suites best for managing configuration entities.
|
||||
* For a controller suiting content entities, see EntityContentUIController.
|
||||
*/
|
||||
class EntityDefaultUIController {
|
||||
|
||||
protected $entityType;
|
||||
protected $entityInfo, $path;
|
||||
protected $id_count;
|
||||
|
||||
/**
|
||||
* Defines the number of entries to show per page in overview table.
|
||||
@@ -30,7 +34,8 @@ class EntityDefaultUIController {
|
||||
*/
|
||||
public function hook_menu() {
|
||||
$items = array();
|
||||
$id_count = count(explode('/', $this->path));
|
||||
// Set this on the object so classes that extend hook_menu() can use it.
|
||||
$this->id_count = count(explode('/', $this->path));
|
||||
$wildcard = isset($this->entityInfo['admin ui']['menu wildcard']) ? $this->entityInfo['admin ui']['menu wildcard'] : '%entity_object';
|
||||
$plural_label = isset($this->entityInfo['plural label']) ? $this->entityInfo['plural label'] : $this->entityInfo['label'] . 's';
|
||||
|
||||
@@ -60,12 +65,12 @@ class EntityDefaultUIController {
|
||||
$items[$this->path . '/manage/' . $wildcard] = array(
|
||||
'title' => 'Edit',
|
||||
'title callback' => 'entity_label',
|
||||
'title arguments' => array($this->entityType, $id_count + 1),
|
||||
'title arguments' => array($this->entityType, $this->id_count + 1),
|
||||
'page callback' => 'entity_ui_get_form',
|
||||
'page arguments' => array($this->entityType, $id_count + 1),
|
||||
'page arguments' => array($this->entityType, $this->id_count + 1),
|
||||
'load arguments' => array($this->entityType),
|
||||
'access callback' => 'entity_access',
|
||||
'access arguments' => array('update', $this->entityType, $id_count + 1),
|
||||
'access arguments' => array('update', $this->entityType, $this->id_count + 1),
|
||||
);
|
||||
$items[$this->path . '/manage/' . $wildcard . '/edit'] = array(
|
||||
'title' => 'Edit',
|
||||
@@ -77,7 +82,7 @@ class EntityDefaultUIController {
|
||||
$items[$this->path . '/manage/' . $wildcard . '/clone'] = array(
|
||||
'title' => 'Clone',
|
||||
'page callback' => 'entity_ui_get_form',
|
||||
'page arguments' => array($this->entityType, $id_count + 1, 'clone'),
|
||||
'page arguments' => array($this->entityType, $this->id_count + 1, 'clone'),
|
||||
'load arguments' => array($this->entityType),
|
||||
'access callback' => 'entity_access',
|
||||
'access arguments' => array('create', $this->entityType),
|
||||
@@ -85,10 +90,10 @@ class EntityDefaultUIController {
|
||||
// Menu item for operations like revert and delete.
|
||||
$items[$this->path . '/manage/' . $wildcard . '/%'] = array(
|
||||
'page callback' => 'drupal_get_form',
|
||||
'page arguments' => array($this->entityType . '_operation_form', $this->entityType, $id_count + 1, $id_count + 2),
|
||||
'page arguments' => array($this->entityType . '_operation_form', $this->entityType, $this->id_count + 1, $this->id_count + 2),
|
||||
'load arguments' => array($this->entityType),
|
||||
'access callback' => 'entity_access',
|
||||
'access arguments' => array('delete', $this->entityType, $id_count + 1),
|
||||
'access arguments' => array('delete', $this->entityType, $this->id_count + 1),
|
||||
'file' => 'includes/entity.ui.inc',
|
||||
);
|
||||
|
||||
@@ -492,6 +497,128 @@ class EntityDefaultUIController {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* UI controller providing UI for content entities.
|
||||
*
|
||||
* For a controller providing UI for bundleable content entities, see
|
||||
* EntityBundleableUIController.
|
||||
* For a controller providing admin UI for configuration entities, see
|
||||
* EntityDefaultUIController.
|
||||
*/
|
||||
class EntityContentUIController extends EntityDefaultUIController {
|
||||
|
||||
/**
|
||||
* Provides definitions for implementing hook_menu().
|
||||
*/
|
||||
public function hook_menu() {
|
||||
$items = parent::hook_menu();
|
||||
$wildcard = isset($this->entityInfo['admin ui']['menu wildcard']) ? $this->entityInfo['admin ui']['menu wildcard'] : '%entity_object';
|
||||
|
||||
// Unset the manage entity path, as the provided UI is for admin entities.
|
||||
unset($items[$this->path]);
|
||||
|
||||
$defaults = array(
|
||||
'file' => $this->entityInfo['admin ui']['file'],
|
||||
'file path' => isset($this->entityInfo['admin ui']['file path']) ? $this->entityInfo['admin ui']['file path'] : drupal_get_path('module', $this->entityInfo['module']),
|
||||
);
|
||||
|
||||
// Add view, edit and delete menu items for content entities.
|
||||
$items[$this->path . '/' . $wildcard] = array(
|
||||
'title callback' => 'entity_ui_get_page_title',
|
||||
'title arguments' => array('view', $this->entityType, $this->id_count),
|
||||
'page callback' => 'entity_ui_entity_page_view',
|
||||
'page arguments' => array($this->id_count),
|
||||
'load arguments' => array($this->entityType),
|
||||
'access callback' => 'entity_access',
|
||||
'access arguments' => array('view', $this->entityType, $this->id_count),
|
||||
) + $defaults;
|
||||
$items[$this->path . '/' . $wildcard . '/view'] = array(
|
||||
'title' => 'View',
|
||||
'type' => MENU_DEFAULT_LOCAL_TASK,
|
||||
'load arguments' => array($this->entityType),
|
||||
'weight' => -10,
|
||||
) + $defaults;
|
||||
$items[$this->path . '/' . $wildcard . '/edit'] = array(
|
||||
'page callback' => 'entity_ui_get_form',
|
||||
'page arguments' => array($this->entityType, $this->id_count),
|
||||
'load arguments' => array($this->entityType),
|
||||
'access callback' => 'entity_access',
|
||||
'access arguments' => array('edit', $this->entityType, $this->id_count),
|
||||
'title' => 'Edit',
|
||||
'type' => MENU_LOCAL_TASK,
|
||||
'context' => MENU_CONTEXT_PAGE | MENU_CONTEXT_INLINE,
|
||||
) + $defaults;
|
||||
$items[$this->path . '/' . $wildcard . '/delete'] = array(
|
||||
'page callback' => 'drupal_get_form',
|
||||
'page arguments' => array($this->entityType . '_operation_form', $this->entityType, $this->id_count, 'delete'),
|
||||
'load arguments' => array($this->entityType),
|
||||
'access callback' => 'entity_access',
|
||||
'access arguments' => array('delete', $this->entityType, $this->id_count),
|
||||
'title' => 'Delete',
|
||||
'type' => MENU_LOCAL_TASK,
|
||||
'context' => MENU_CONTEXT_INLINE,
|
||||
'file' => $this->entityInfo['admin ui']['file'],
|
||||
'file path' => isset($this->entityInfo['admin ui']['file path']) ? $this->entityInfo['admin ui']['file path'] : drupal_get_path('module', $this->entityInfo['module']),
|
||||
) + $defaults;
|
||||
|
||||
return $items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Operation form submit callback.
|
||||
*/
|
||||
public function operationFormSubmit($form, &$form_state) {
|
||||
parent::operationFormSubmit($form, $form_state);
|
||||
// The manage entity path is unset for the content entity UI.
|
||||
$form_state['redirect'] = '<front>';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* UI controller providing UI for bundleable content entities.
|
||||
*
|
||||
* Adds a bundle selection page to the entity/add path, analogously to the
|
||||
* node/add path.
|
||||
*/
|
||||
class EntityBundleableUIController extends EntityContentUIController {
|
||||
|
||||
/**
|
||||
* Provides definitions for implementing hook_menu().
|
||||
*/
|
||||
public function hook_menu() {
|
||||
$items = parent::hook_menu();
|
||||
|
||||
// Extend the 'add' path.
|
||||
$items[$this->path . '/add'] = array(
|
||||
'title callback' => 'entity_ui_get_action_title',
|
||||
'title arguments' => array('add', $this->entityType),
|
||||
'page callback' => 'entity_ui_bundle_add_page',
|
||||
'page arguments' => array($this->entityType),
|
||||
'access callback' => 'entity_access',
|
||||
'access arguments' => array('create', $this->entityType),
|
||||
'type' => MENU_LOCAL_ACTION,
|
||||
);
|
||||
$items[$this->path . '/add/%'] = array(
|
||||
'title callback' => 'entity_ui_get_action_title',
|
||||
'title arguments' => array('add', $this->entityType, $this->id_count + 1),
|
||||
'page callback' => 'entity_ui_get_bundle_add_form',
|
||||
'page arguments' => array($this->entityType, $this->id_count + 1),
|
||||
'access callback' => 'entity_access',
|
||||
'access arguments' => array('create', $this->entityType),
|
||||
);
|
||||
|
||||
if (!empty($this->entityInfo['admin ui']['file'])) {
|
||||
// Add in the include file for the entity form.
|
||||
foreach (array('/add', '/add/%') as $path_end) {
|
||||
$items[$this->path . $path_end]['file'] = $this->entityInfo['admin ui']['file'];
|
||||
$items[$this->path . $path_end]['file path'] = isset($this->entityInfo['admin ui']['file path']) ? $this->entityInfo['admin ui']['file path'] : drupal_get_path('module', $this->entityInfo['module']);
|
||||
}
|
||||
}
|
||||
|
||||
return $items;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Form builder function for the overview form.
|
||||
*
|
||||
@@ -597,39 +724,6 @@ function entity_ui_controller_form_submit($form, &$form_state) {
|
||||
entity_ui_controller($form_state['entity_type'])->$method($form, $form_state);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the page title for the passed operation.
|
||||
*/
|
||||
function entity_ui_get_page_title($op, $entity_type, $entity = NULL) {
|
||||
$label = entity_label($entity_type, $entity);
|
||||
switch ($op) {
|
||||
case 'edit':
|
||||
return t('Edit @label', array('@label' => $label));
|
||||
case 'clone':
|
||||
return t('Clone @label', array('@label' => $label));
|
||||
case 'revert':
|
||||
return t('Revert @label', array('@label' => $label));
|
||||
case 'delete':
|
||||
return t('Delete @label', array('@label' => $label));
|
||||
case 'export':
|
||||
return t('Export @label', array('@label' => $label));
|
||||
}
|
||||
return entity_ui_get_action_title($op, $entity_type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the page/menu title for local action operations.
|
||||
*/
|
||||
function entity_ui_get_action_title($op, $entity_type) {
|
||||
$info = entity_get_info($entity_type);
|
||||
switch ($op) {
|
||||
case 'add':
|
||||
return t('Add @entity_type', array('@entity_type' => drupal_strtolower($info['label'])));
|
||||
case 'import':
|
||||
return t('Import @entity_type', array('@entity_type' => drupal_strtolower($info['label'])));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Submit builder for the main entity form, which extracts the form values and updates the entity.
|
||||
*
|
||||
@@ -670,3 +764,4 @@ function theme_entity_ui_overview_item($variables) {
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
|
||||
|
||||
@@ -228,10 +228,6 @@ abstract class EntityMetadataWrapper {
|
||||
* If there is no access information for this property, TRUE is returned.
|
||||
*/
|
||||
public function access($op, $account = NULL) {
|
||||
if (empty($this->info['parent']) && $this instanceof EntityDrupalWrapper) {
|
||||
// If there is no parent just incorporate entity based access.
|
||||
return $this->entityAccess($op == 'edit' ? 'update' : 'view', $account);
|
||||
}
|
||||
return !empty($this->info['parent']) ? $this->info['parent']->propertyAccess($this->info['name'], $op, $account) : TRUE;
|
||||
}
|
||||
|
||||
@@ -500,19 +496,15 @@ class EntityStructureWrapper extends EntityMetadataWrapper implements IteratorAg
|
||||
|
||||
protected function propertyAccess($name, $op, $account = NULL) {
|
||||
$info = $this->getPropertyInfo($name);
|
||||
// If the property should be accessed and it's an entity, make sure the user
|
||||
// is allowed to view that entity.
|
||||
if ($op == 'view' && $this->$name instanceof EntityDrupalWrapper && !$this->$name->entityAccess($op, $account)) {
|
||||
return FALSE;
|
||||
}
|
||||
// If a property should be edited and this is an entity, make sure the user
|
||||
// has update access for this entity.
|
||||
|
||||
// If a property should be edited and this is part of an entity, make sure
|
||||
// the user has update access for this entity.
|
||||
if ($op == 'edit') {
|
||||
$entity = $this;
|
||||
while (!($entity instanceof EntityDrupalWrapper) && isset($entity->info['parent'])) {
|
||||
$entity = $entity->info['parent'];
|
||||
}
|
||||
if ($entity instanceof EntityDrupalWrapper && !$entity->entityAccess('update', $account)) {
|
||||
if ($entity instanceof EntityDrupalWrapper && $entity->entityAccess('update', $account) === FALSE) {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
@@ -523,6 +515,7 @@ class EntityStructureWrapper extends EntityMetadataWrapper implements IteratorAg
|
||||
elseif ($op == 'edit' && isset($info['setter permission'])) {
|
||||
return user_access($info['setter permission'], $account);
|
||||
}
|
||||
// If access is unknown, we return TRUE.
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -662,7 +655,7 @@ class EntityDrupalWrapper extends EntityStructureWrapper {
|
||||
$this->bundle = $this->type;
|
||||
}
|
||||
// Detect the bundle if not set yet and add in properties from the bundle.
|
||||
elseif (!$this->bundle && !empty($this->entityInfo['fieldable']) && $load && $this->dataAvailable()) {
|
||||
elseif (!$this->bundle && $load && $this->dataAvailable()) {
|
||||
try {
|
||||
if ($entity = $this->value()) {
|
||||
list($id, $vid, $bundle) = entity_extract_ids($this->type, $entity);
|
||||
@@ -766,7 +759,7 @@ class EntityDrupalWrapper extends EntityStructureWrapper {
|
||||
elseif ($this->id === FALSE && !$this->data) {
|
||||
$this->updateParent(NULL);
|
||||
}
|
||||
elseif ($previous_id != $this->id) {
|
||||
elseif ($previous_id !== $this->id) {
|
||||
$this->updateParent($this->id);
|
||||
}
|
||||
return $this;
|
||||
@@ -804,6 +797,34 @@ class EntityDrupalWrapper extends EntityStructureWrapper {
|
||||
return $this->type;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* Note that this method checks property access, but can be used for checking
|
||||
* entity access *only* if the wrapper is not a property (i.e. has no parent
|
||||
* wrapper).
|
||||
* To be safe, better use EntityDrupalWrapper::entityAccess() for checking
|
||||
* entity access.
|
||||
*/
|
||||
public function access($op, $account = NULL) {
|
||||
if (!empty($this->info['parent'])) {
|
||||
// If this is a property, make sure the user is able to view the
|
||||
// currently referenced entity also.
|
||||
if ($this->entityAccess('view', $account) === FALSE) {
|
||||
return FALSE;
|
||||
}
|
||||
if (parent::access($op, $account) === FALSE) {
|
||||
return FALSE;
|
||||
}
|
||||
// If access is unknown, we return TRUE.
|
||||
return TRUE;
|
||||
}
|
||||
else {
|
||||
// This is not a property, so fallback on entity access.
|
||||
return $this->entityAccess($op == 'edit' ? 'update' : 'view', $account);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the operation $op is allowed on the entity.
|
||||
*
|
||||
@@ -811,6 +832,12 @@ class EntityDrupalWrapper extends EntityStructureWrapper {
|
||||
*/
|
||||
public function entityAccess($op, $account = NULL) {
|
||||
$entity = $this->dataAvailable() ? $this->value() : NULL;
|
||||
// The value() method could return FALSE on entities such as user 0, so we
|
||||
// need to use NULL instead to conform to the expectations of
|
||||
// entity_access().
|
||||
if ($entity === FALSE) {
|
||||
$entity = NULL;
|
||||
}
|
||||
return entity_access($op, $this->type, $entity, $account);
|
||||
}
|
||||
|
||||
@@ -1025,8 +1052,11 @@ class EntityListWrapper extends EntityMetadataWrapper implements IteratorAggrega
|
||||
// Support setting lists of fully loaded entities.
|
||||
if ($this->isEntityList && $values && is_object(reset($values))) {
|
||||
foreach ($values as $key => $value) {
|
||||
list($id, $vid, $bundle) = entity_extract_ids($this->itemType, $value);
|
||||
$values[$key] = $id;
|
||||
// Ignore outdated NULL value references in lists of entities.
|
||||
if (isset($value)) {
|
||||
list($id, $vid, $bundle) = entity_extract_ids($this->itemType, $value);
|
||||
$values[$key] = $id;
|
||||
}
|
||||
}
|
||||
}
|
||||
return parent::set($values);
|
||||
|
||||
Reference in New Issue
Block a user