Пример #1
0
/**
 * Check view and edit permissions.
 *
 * @param $op
 *   The type of operation. Either 'view' or 'edit'.
 */
function have_access($op)
{
    global $user;
    $db = DBConnection::instance();
    $field_id = (int) _post('fid');
    if (!$field_id) {
        $field_id = (int) _get('fid');
    }
    $field = (object) $db->dq("SELECT entity_id, entity_type, delta FROM {mytinytodo_fields} WHERE id = ?", $field_id)->fetch_assoc();
    $field_info = field_info_field_by_id($field->delta);
    if ($field->entity_type == 'node') {
        if (!($node = node_load($field->entity_id))) {
            return false;
        }
        $node_access = $op == 'edit' ? 'update' : $op;
        if (node_access($node_access, $node, $user) && field_access($op, $field_info, $field->entity_type, $node, $user)) {
            return true;
        }
    } else {
        if ($field->entity_type == 'user') {
            if (!($account = user_load($field->entity_id))) {
                return false;
            }
            if (field_access($op, $field_info, $field->entity_type, $account, $user)) {
                return true;
            }
        } else {
            if ($field->entity_type == 'comment') {
                if (!($comment = comment_load($field->entity_id))) {
                    return false;
                }
                if ($op == 'view' && !user_access('access comments')) {
                    return false;
                } else {
                    if ($op == 'edit' && !comment_access($op, $comment)) {
                        return false;
                    }
                }
                if (field_access($op, $field_info, $field->entity_type, $comment, $user)) {
                    return true;
                }
            } else {
                if (module_exists('entity')) {
                    if (!($entity = entity_load($field_id))) {
                        return false;
                    }
                    $entity_access = $op == 'edit' ? 'update' : $op;
                    if (entity_access($entity_access, $field->entity_type, $entity, $user) && field_access($op, $field_info, $field->entity_type, $entity, $user)) {
                        return true;
                    }
                }
            }
        }
    }
    return false;
}
Пример #2
0
/**
 * Delete a single revision of field data for an entity.
 *
 * This hook is invoked from field_attach_delete_revision() to ask the field
 * storage module to delete field revision data.
 *
 * Deleting the current (most recently written) revision is not
 * allowed as has undefined results.
 *
 * @param $entity_type
 *   The entity type of entity, such as 'node' or 'user'.
 * @param $entity
 *   The entity on which to operate. The revision to delete is
 *   indicated by the entity's revision ID property, as identified by
 *   hook_fieldable_info() for $entity_type.
 * @param $fields
 *   An array listing the fields to delete. The keys and values of the
 *   array are field IDs.
 */
function hook_field_storage_delete_revision($entity_type, $entity, $fields)
{
    list($id, $vid, $bundle) = entity_extract_ids($entity_type, $entity);
    if (isset($vid)) {
        foreach ($fields as $field_id) {
            $field = field_info_field_by_id($field_id);
            $revision_name = _field_sql_storage_revision_tablename($field);
            db_delete($revision_name)->condition('entity_type', $entity_type)->condition('entity_id', $id)->condition('revision_id', $vid)->execute();
        }
    }
}
Пример #3
0
/**
 * Execute an EntityFieldQuery.
 *
 * This hook is called to find the entities having certain entity and field
 * conditions and sort them in the given field order. If the field storage
 * engine also handles property sorts and orders, it should unset those
 * properties in the called object to signal that those have been handled.
 *
 * @param EntityFieldQuery $query
 *   An EntityFieldQuery.
 *
 * @return
 *   See EntityFieldQuery::execute() for the return values.
 */
function hook_field_storage_query($query)
{
    $load_current = $options['age'] == FIELD_LOAD_CURRENT;
    $field = field_info_field_by_id($field_id);
    $field_name = $field['field_name'];
    $table = $load_current ? _field_sql_storage_tablename($field) : _field_sql_storage_revision_tablename($field);
    $field_columns = array_keys($field['columns']);
    // Build the query.
    $query = db_select($table, 't');
    $query->join('field_config_entity_type', 'e', 't.etid = e.etid');
    // Add conditions.
    foreach ($conditions as $condition) {
        // A condition is either a (column, value, operator) triple, or a
        // (column, value) pair with implied operator.
        @(list($column, $value, $operator) = $condition);
        // Translate operator and value if needed.
        switch ($operator) {
            case 'STARTS_WITH':
                $operator = 'LIKE';
                $value = db_like($value) . '%';
                break;
            case 'ENDS_WITH':
                $operator = 'LIKE';
                $value = '%' . db_like($value);
                break;
            case 'CONTAINS':
                $operator = 'LIKE';
                $value = '%' . db_like($value) . '%';
                break;
        }
        // Translate field columns into prefixed db columns.
        if (in_array($column, $field_columns)) {
            $column = _field_sql_storage_columnname($field_name, $column);
        }
        // Translate entity types into numeric ids. Expressing the condition on the
        // local 'etid' column rather than the JOINed 'type' column avoids a
        // filesort.
        if ($column == 'type') {
            $column = 't.etid';
            if (is_array($value)) {
                foreach (array_keys($value) as $key) {
                    $value[$key] = _field_sql_storage_etid($value[$key]);
                }
            } else {
                $value = _field_sql_storage_etid($value);
            }
        }
        // Track condition on 'deleted'.
        if ($column == 'deleted') {
            $condition_deleted = TRUE;
        }
        $query->condition($column, $value, $operator);
    }
    // Exclude deleted data unless we have a condition on it.
    if (!isset($condition_deleted)) {
        $query->condition('deleted', 0);
    }
    // For a count query, return the count now.
    if ($options['count']) {
        return $query->fields('t', array('etid', 'entity_id', 'revision_id'))->distinct()->countQuery()->execute()->fetchField();
    }
    // For a data query, add fields.
    $query->fields('t', array('bundle', 'entity_id', 'revision_id'))->fields('e', array('type'))->orderBy('t.etid')->orderBy('t.entity_id');
    // Initialize results array
    $return = array();
    // Getting $count entities possibly requires reading more than $count rows
    // since fields with multiple values span over several rows. We query for
    // batches of $count rows until we've either read $count entities or received
    // less rows than asked for.
    $entity_count = 0;
    do {
        if ($options['limit'] != FIELD_QUERY_NO_LIMIT) {
            $query->range($options['cursor'], $options['limit']);
        }
        $results = $query->execute();
        $row_count = 0;
        foreach ($results as $row) {
            $row_count++;
            $options['cursor']++;
            // If querying all revisions and the entity type has revisions, we need
            // to key the results by revision_ids.
            $entity_type = entity_get_info($row->type);
            $id = $load_current || empty($entity_type['entity keys']['revision']) ? $row->entity_id : $row->revision_id;
            if (!isset($return[$row->type][$id])) {
                $return[$row->type][$id] = entity_create_stub_entity($row->type, array($row->entity_id, $row->revision_id, $row->bundle));
                $entity_count++;
            }
        }
    } while ($options['limit'] != FIELD_QUERY_NO_LIMIT && $row_count == $options['limit'] && $entity_count < $options['limit']);
    // The query is complete when the last batch returns less rows than asked
    // for.
    if ($row_count < $options['limit']) {
        $options['cursor'] = FIELD_QUERY_COMPLETE;
    }
    return $return;
}
Пример #4
0
 /**
  * An lightest-weight version of entity save that invokes field storage.
  *
  * @param string $entity_type
  *   The entity type of $entity.
  * @param object $entity
  *   The entity object to update.
  * @param array $fields
  *   (optional) An optional array of field names that if provided will only
  *   cause those specific fields to be saved, if values are provided.
  *
  * @throws \InvalidArgumentException
  */
 public static function updateFieldValuesStorage($entity_type, $entity, array $fields = array())
 {
     list($id, , $bundle) = entity_extract_ids($entity_type, $entity);
     if (empty($id)) {
         throw new InvalidArgumentException(t('Cannot call EntityHelper::updateFieldValues() on an unsaved entity.'));
     }
     // Let any module update field data before the storage engine, accumulating
     // saved fields along the way.
     $skip_fields = array();
     foreach (module_implements('field_storage_pre_update') as $module) {
         $function = $module . '_field_storage_pre_update';
         $function($entity_type, $entity, $skip_fields);
     }
     // Collect the storage backends used by the remaining fields in the entities.
     $storages = array();
     foreach (field_info_instances($entity_type, $bundle) as $instance) {
         $field = field_info_field_by_id($instance['field_id']);
         $field_id = $field['id'];
         $field_name = $field['field_name'];
         // Check if we care about saving this field or not.
         if (!empty($fields) && !in_array($field_name, $fields)) {
             continue;
         }
         // Leave the field untouched if $entity comes with no $field_name property,
         // but empty the field if it comes as a NULL value or an empty array.
         // Function property_exists() is slower, so we catch the more frequent
         // cases where it's an empty array with the faster isset().
         if (isset($entity->{$field_name}) || property_exists($entity, $field_name)) {
             // Collect the storage backend if the field has not been written yet.
             if (!isset($skip_fields[$field_id])) {
                 $storages[$field['storage']['type']][$field_id] = $field_id;
             }
         }
     }
     // Field storage backends save any remaining unsaved fields.
     foreach ($storages as $storage => $storage_fields) {
         $storage_info = field_info_storage_types($storage);
         module_invoke($storage_info['module'], 'field_storage_write', $entity_type, $entity, FIELD_STORAGE_UPDATE, $storage_fields);
     }
     // Clear the cache for this entity now.
     entity_get_controller($entity_type)->resetCache(array($id));
 }