updated core to 7.58 (right after the site was hacked)
This commit is contained in:
@ -0,0 +1,20 @@
|
||||
name = Entity Example
|
||||
description = A simple entity example showing the main steps required to set up your own entity.
|
||||
core = 7.x
|
||||
package = Example modules
|
||||
; Since someone might install our module through Composer, we want to be sure
|
||||
; that the Drupal Composer facade knows we're specifying a core module rather
|
||||
; than a project. We do this by namespacing the dependency name with drupal:.
|
||||
dependencies[] = drupal:field
|
||||
; Since the namespacing feature is new as of Drupal 7.40, we have to require at
|
||||
; least that version of core.
|
||||
dependencies[] = drupal:system (>= 7.40)
|
||||
files[] = entity_example.test
|
||||
configure = admin/structure/entity_example_basic/manage
|
||||
|
||||
; Information added by Drupal.org packaging script on 2017-01-10
|
||||
version = "7.x-1.x-dev"
|
||||
core = "7.x"
|
||||
project = "examples"
|
||||
datestamp = "1484076787"
|
||||
|
@ -0,0 +1,71 @@
|
||||
<?php
|
||||
/**
|
||||
* @file
|
||||
* Install for a basic entity - need to create the base table for our entity.
|
||||
* This table can have as many columns as you need to keep track of
|
||||
* entity-specific data that will not be added via attached fields.
|
||||
* The minimum information for the entity to work is an id and an entity name.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_schema().
|
||||
*
|
||||
* @ingroup entity_example
|
||||
*/
|
||||
function entity_example_schema() {
|
||||
$schema = array();
|
||||
|
||||
// The name of the table can be any name we choose. However, namespacing the
|
||||
// table with the module name is best practice.
|
||||
$schema['entity_example_basic'] = array(
|
||||
'description' => 'The base table for our basic entity.',
|
||||
'fields' => array(
|
||||
'basic_id' => array(
|
||||
'description' => 'Primary key of the basic entity.',
|
||||
'type' => 'serial',
|
||||
'unsigned' => TRUE,
|
||||
'not null' => TRUE,
|
||||
),
|
||||
// If we allow multiple bundles, then the schema must handle that;
|
||||
// We'll put it in the 'bundle_type' field to avoid confusion with the
|
||||
// entity type.
|
||||
'bundle_type' => array(
|
||||
'description' => 'The bundle type',
|
||||
'type' => 'text',
|
||||
'size' => 'medium',
|
||||
'not null' => TRUE,
|
||||
),
|
||||
// Additional properties are just things that are common to all
|
||||
// entities and don't require field storage.
|
||||
'item_description' => array(
|
||||
'description' => 'A description of the item',
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => TRUE,
|
||||
'default' => '',
|
||||
),
|
||||
'created' => array(
|
||||
'description' => 'The Unix timestamp of the entity creation time.',
|
||||
'type' => 'int',
|
||||
'not null' => TRUE,
|
||||
'default' => 0,
|
||||
),
|
||||
),
|
||||
'primary key' => array('basic_id'),
|
||||
);
|
||||
|
||||
return $schema;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Implements hook_uninstall().
|
||||
*
|
||||
* At uninstall time we'll notify field.module that the entity was deleted
|
||||
* so that attached fields can be cleaned up.
|
||||
*
|
||||
* @ingroup entity_example
|
||||
*/
|
||||
function entity_example_uninstall() {
|
||||
field_attach_delete_bundle('entity_example_basic', 'first_example_bundle');
|
||||
}
|
635
sites/all/modules/examples/entity_example/entity_example.module
Normal file
635
sites/all/modules/examples/entity_example/entity_example.module
Normal file
@ -0,0 +1,635 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Implements the basic functionality required to create and display an entity.
|
||||
*
|
||||
* This example does not use the
|
||||
* @link http://drupal.org/project/entity Entity API module @endlink, which is
|
||||
* used by many entity implementations and is recommended by many.
|
||||
*
|
||||
* An example of use of creating and managing entities using the Entity API
|
||||
* module is provided in the
|
||||
* @link http://drupal.org/project/model Model Entity module @endlink.
|
||||
*
|
||||
* @todo: Reference the ronald_istos article series
|
||||
* @todo: Reference the Drupal module development book
|
||||
* @todo: Add a single field
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup entity_example Example: Entity
|
||||
* @ingroup examples
|
||||
* @{
|
||||
* Example creating a core Entity API entity.
|
||||
*
|
||||
* Note that this example does not use or demonstrate the contrib Entity API,
|
||||
* which you can find here: http://drupal.org/project/entity
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_entity_info().
|
||||
*
|
||||
* This is the fundamental description of the entity.
|
||||
*
|
||||
* It provides a single entity with a single bundle and without revision
|
||||
* support.
|
||||
*/
|
||||
function entity_example_entity_info() {
|
||||
$info['entity_example_basic'] = array(
|
||||
// A human readable label to identify our entity.
|
||||
'label' => t('Example Basic Entity'),
|
||||
|
||||
// The controller for our Entity, extending the Drupal core controller.
|
||||
'controller class' => 'EntityExampleBasicController',
|
||||
|
||||
// The table for this entity defined in hook_schema()
|
||||
'base table' => 'entity_example_basic',
|
||||
|
||||
// Returns the uri elements of an entity.
|
||||
'uri callback' => 'entity_example_basic_uri',
|
||||
|
||||
// IF fieldable == FALSE, we can't attach fields.
|
||||
'fieldable' => TRUE,
|
||||
|
||||
// entity_keys tells the controller what database fields are used for key
|
||||
// functions. It is not required if we don't have bundles or revisions.
|
||||
// Here we do not support a revision, so that entity key is omitted.
|
||||
'entity keys' => array(
|
||||
// The 'id' (basic_id here) is the unique id.
|
||||
'id' => 'basic_id' ,
|
||||
// Bundle will be determined by the 'bundle_type' field.
|
||||
'bundle' => 'bundle_type',
|
||||
),
|
||||
'bundle keys' => array(
|
||||
'bundle' => 'bundle_type',
|
||||
),
|
||||
|
||||
// FALSE disables caching. Caching functionality is handled by Drupal core.
|
||||
'static cache' => TRUE,
|
||||
|
||||
// Bundles are alternative groups of fields or configuration
|
||||
// associated with a base entity type.
|
||||
'bundles' => array(
|
||||
'first_example_bundle' => array(
|
||||
'label' => 'First example bundle',
|
||||
// 'admin' key is used by the Field UI to provide field and
|
||||
// display UI pages.
|
||||
'admin' => array(
|
||||
'path' => 'admin/structure/entity_example_basic/manage',
|
||||
'access arguments' => array('administer entity_example_basic entities'),
|
||||
),
|
||||
),
|
||||
),
|
||||
// View modes allow entities to be displayed differently based on context.
|
||||
// As a demonstration we'll support "Tweaky", but we could have and support
|
||||
// multiple display modes.
|
||||
'view modes' => array(
|
||||
'tweaky' => array(
|
||||
'label' => t('Tweaky'),
|
||||
'custom settings' => FALSE,
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
return $info;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch a basic object.
|
||||
*
|
||||
* This function ends up being a shim between the menu system and
|
||||
* entity_example_basic_load_multiple().
|
||||
*
|
||||
* This function gets its name from the menu system's wildcard
|
||||
* naming conventions. For example, /path/%wildcard would end
|
||||
* up calling wildcard_load(%wildcard value). In our case defining
|
||||
* the path: examples/entity_example/basic/%entity_example_basic in
|
||||
* hook_menu() tells Drupal to call entity_example_basic_load().
|
||||
*
|
||||
* @param int $basic_id
|
||||
* Integer specifying the basic entity id.
|
||||
* @param bool $reset
|
||||
* A boolean indicating that the internal cache should be reset.
|
||||
*
|
||||
* @return object
|
||||
* A fully-loaded $basic object or FALSE if it cannot be loaded.
|
||||
*
|
||||
* @see entity_example_basic_load_multiple()
|
||||
* @see entity_example_menu()
|
||||
*/
|
||||
function entity_example_basic_load($basic_id = NULL, $reset = FALSE) {
|
||||
$basic_ids = (isset($basic_id) ? array($basic_id) : array());
|
||||
$basic = entity_example_basic_load_multiple($basic_ids, array(), $reset);
|
||||
return $basic ? reset($basic) : FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads multiple basic entities.
|
||||
*
|
||||
* We only need to pass this request along to entity_load(), which
|
||||
* will in turn call the load() method of our entity controller class.
|
||||
*/
|
||||
function entity_example_basic_load_multiple($basic_ids = FALSE, $conditions = array(), $reset = FALSE) {
|
||||
return entity_load('entity_example_basic', $basic_ids, $conditions, $reset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements the uri callback.
|
||||
*/
|
||||
function entity_example_basic_uri($basic) {
|
||||
return array(
|
||||
'path' => 'examples/entity_example/basic/' . $basic->basic_id,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_menu().
|
||||
*/
|
||||
function entity_example_menu() {
|
||||
$items['examples/entity_example'] = array(
|
||||
'title' => 'Entity Example',
|
||||
'page callback' => 'entity_example_info_page',
|
||||
'access arguments' => array('view any entity_example_basic entity'),
|
||||
);
|
||||
|
||||
// This provides a place for Field API to hang its own
|
||||
// interface and has to be the same as what was defined
|
||||
// in basic_entity_info() above.
|
||||
$items['admin/structure/entity_example_basic/manage'] = array(
|
||||
'title' => 'Administer entity_example_basic entity type',
|
||||
'page callback' => 'entity_example_basic_list_entities',
|
||||
'access arguments' => array('administer entity_example_basic entities'),
|
||||
);
|
||||
|
||||
// Add example entities.
|
||||
$items['admin/structure/entity_example_basic/manage/add'] = array(
|
||||
'title' => 'Add an Entity Example Basic Entity',
|
||||
'page callback' => 'entity_example_basic_add',
|
||||
'access arguments' => array('create entity_example_basic entities'),
|
||||
'type' => MENU_LOCAL_ACTION,
|
||||
);
|
||||
|
||||
// List of all entity_example_basic entities.
|
||||
$items['admin/structure/entity_example_basic/manage/list'] = array(
|
||||
'title' => 'List',
|
||||
'type' => MENU_DEFAULT_LOCAL_TASK,
|
||||
);
|
||||
|
||||
// The page to view our entities - needs to follow what
|
||||
// is defined in basic_uri and will use load_basic to retrieve
|
||||
// the necessary entity info.
|
||||
$items['examples/entity_example/basic/%entity_example_basic'] = array(
|
||||
'title callback' => 'entity_example_basic_title',
|
||||
'title arguments' => array(3),
|
||||
'page callback' => 'entity_example_basic_view',
|
||||
'page arguments' => array(3),
|
||||
'access arguments' => array('view any entity_example_basic entity'),
|
||||
);
|
||||
|
||||
// 'View' tab for an individual entity page.
|
||||
$items['examples/entity_example/basic/%entity_example_basic/view'] = array(
|
||||
'title' => 'View',
|
||||
'type' => MENU_DEFAULT_LOCAL_TASK,
|
||||
'weight' => -10,
|
||||
);
|
||||
|
||||
// 'Edit' tab for an individual entity page.
|
||||
$items['examples/entity_example/basic/%entity_example_basic/edit'] = array(
|
||||
'title' => 'Edit',
|
||||
'page callback' => 'drupal_get_form',
|
||||
'page arguments' => array('entity_example_basic_form', 3),
|
||||
'access arguments' => array('edit any entity_example_basic entity'),
|
||||
'type' => MENU_LOCAL_TASK,
|
||||
);
|
||||
|
||||
// Add example entities.
|
||||
$items['examples/entity_example/basic/add'] = array(
|
||||
'title' => 'Add an Entity Example Basic Entity',
|
||||
'page callback' => 'entity_example_basic_add',
|
||||
'access arguments' => array('create entity_example_basic entities'),
|
||||
);
|
||||
|
||||
return $items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Basic information for the page.
|
||||
*/
|
||||
function entity_example_info_page() {
|
||||
$content['preface'] = array(
|
||||
'#type' => 'item',
|
||||
'#markup' => t('The entity example provides a simple example entity.'),
|
||||
);
|
||||
if (user_access('administer entity_example_basic entities')) {
|
||||
$content['preface']['#markup'] = t('You can administer these and add fields and change the view !link.',
|
||||
array('!link' => l(t('here'), 'admin/structure/entity_example_basic/manage'))
|
||||
);
|
||||
}
|
||||
$content['table'] = entity_example_basic_list_entities();
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_permission().
|
||||
*/
|
||||
function entity_example_permission() {
|
||||
$permissions = array(
|
||||
'administer entity_example_basic entities' => array(
|
||||
'title' => t('Administer entity_example_basic entities'),
|
||||
),
|
||||
'view any entity_example_basic entity' => array(
|
||||
'title' => t('View any Entity Example Basic entity'),
|
||||
),
|
||||
'edit any entity_example_basic entity' => array(
|
||||
'title' => t('Edit any Entity Example Basic entity'),
|
||||
),
|
||||
'create entity_example_basic entities' => array(
|
||||
'title' => t('Create Entity Example Basic Entities'),
|
||||
),
|
||||
);
|
||||
return $permissions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a render array with all entity_example_basic entities.
|
||||
*
|
||||
* In this basic example we know that there won't be many entities,
|
||||
* so we'll just load them all for display. See pager_example.module
|
||||
* to implement a pager. Most implementations would probably do this
|
||||
* with the contrib Entity API module, or a view using views module,
|
||||
* but we avoid using non-core features in the Examples project.
|
||||
*
|
||||
* @see pager_example.module
|
||||
*/
|
||||
function entity_example_basic_list_entities() {
|
||||
$content = array();
|
||||
// Load all of our entities.
|
||||
$entities = entity_example_basic_load_multiple();
|
||||
if (!empty($entities)) {
|
||||
foreach ($entities as $entity) {
|
||||
// Create tabular rows for our entities.
|
||||
$rows[] = array(
|
||||
'data' => array(
|
||||
'id' => $entity->basic_id,
|
||||
'item_description' => l($entity->item_description, 'examples/entity_example/basic/' . $entity->basic_id),
|
||||
'bundle' => $entity->bundle_type,
|
||||
),
|
||||
);
|
||||
}
|
||||
// Put our entities into a themed table. See theme_table() for details.
|
||||
$content['entity_table'] = array(
|
||||
'#theme' => 'table',
|
||||
'#rows' => $rows,
|
||||
'#header' => array(t('ID'), t('Item Description'), t('Bundle')),
|
||||
);
|
||||
}
|
||||
else {
|
||||
// There were no entities. Tell the user.
|
||||
$content[] = array(
|
||||
'#type' => 'item',
|
||||
'#markup' => t('No entity_example_basic entities currently exist.'),
|
||||
);
|
||||
}
|
||||
return $content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for a page title when this entity is displayed.
|
||||
*/
|
||||
function entity_example_basic_title($entity) {
|
||||
return t('Entity Example Basic (item_description=@item_description)', array('@item_description' => $entity->item_description));
|
||||
}
|
||||
|
||||
/**
|
||||
* Menu callback to display an entity.
|
||||
*
|
||||
* As we load the entity for display, we're responsible for invoking a number
|
||||
* of hooks in their proper order.
|
||||
*
|
||||
* @see hook_entity_prepare_view()
|
||||
* @see hook_entity_view()
|
||||
* @see hook_entity_view_alter()
|
||||
*/
|
||||
function entity_example_basic_view($entity, $view_mode = 'tweaky') {
|
||||
// Our entity type, for convenience.
|
||||
$entity_type = 'entity_example_basic';
|
||||
// Start setting up the content.
|
||||
$entity->content = array(
|
||||
'#view_mode' => $view_mode,
|
||||
);
|
||||
// Build fields content - this is where the Field API really comes in to play.
|
||||
// The task has very little code here because it all gets taken care of by
|
||||
// field module.
|
||||
// field_attach_prepare_view() lets the fields load any data they need
|
||||
// before viewing.
|
||||
field_attach_prepare_view($entity_type, array($entity->basic_id => $entity),
|
||||
$view_mode);
|
||||
// We call entity_prepare_view() so it can invoke hook_entity_prepare_view()
|
||||
// for us.
|
||||
entity_prepare_view($entity_type, array($entity->basic_id => $entity));
|
||||
// Now field_attach_view() generates the content for the fields.
|
||||
$entity->content += field_attach_view($entity_type, $entity, $view_mode);
|
||||
|
||||
// OK, Field API done, now we can set up some of our own data.
|
||||
$entity->content['created'] = array(
|
||||
'#type' => 'item',
|
||||
'#title' => t('Created date'),
|
||||
'#markup' => format_date($entity->created),
|
||||
);
|
||||
$entity->content['item_description'] = array(
|
||||
'#type' => 'item',
|
||||
'#title' => t('Item Description'),
|
||||
'#markup' => $entity->item_description,
|
||||
);
|
||||
|
||||
// Now to invoke some hooks. We need the language code for
|
||||
// hook_entity_view(), so let's get that.
|
||||
global $language;
|
||||
$langcode = $language->language;
|
||||
// And now invoke hook_entity_view().
|
||||
module_invoke_all('entity_view', $entity, $entity_type, $view_mode,
|
||||
$langcode);
|
||||
// Now invoke hook_entity_view_alter().
|
||||
drupal_alter(array('entity_example_basic_view', 'entity_view'),
|
||||
$entity->content, $entity_type);
|
||||
|
||||
// And finally return the content.
|
||||
return $entity->content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_field_extra_fields().
|
||||
*
|
||||
* This exposes the "extra fields" (usually properties that can be configured
|
||||
* as if they were fields) of the entity as pseudo-fields
|
||||
* so that they get handled by the Entity and Field core functionality.
|
||||
* Node titles get treated in a similar manner.
|
||||
*/
|
||||
function entity_example_field_extra_fields() {
|
||||
$form_elements['item_description'] = array(
|
||||
'label' => t('Item Description'),
|
||||
'description' => t('Item Description (an extra form field)'),
|
||||
'weight' => -5,
|
||||
);
|
||||
$display_elements['created'] = array(
|
||||
'label' => t('Creation date'),
|
||||
'description' => t('Creation date (an extra display field)'),
|
||||
'weight' => 0,
|
||||
);
|
||||
$display_elements['item_description'] = array(
|
||||
'label' => t('Item Description'),
|
||||
'description' => t('Just like title, but trying to point out that it is a separate property'),
|
||||
'weight' => 0,
|
||||
);
|
||||
|
||||
// Since we have only one bundle type, we'll just provide the extra_fields
|
||||
// for it here.
|
||||
$extra_fields['entity_example_basic']['first_example_bundle']['form'] = $form_elements;
|
||||
$extra_fields['entity_example_basic']['first_example_bundle']['display'] = $display_elements;
|
||||
|
||||
return $extra_fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides a wrapper on the edit form to add a new entity.
|
||||
*/
|
||||
function entity_example_basic_add() {
|
||||
// Create a basic entity structure to be used and passed to the validation
|
||||
// and submission functions.
|
||||
$entity = entity_get_controller('entity_example_basic')->create();
|
||||
return drupal_get_form('entity_example_basic_form', $entity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Form function to create an entity_example_basic entity.
|
||||
*
|
||||
* The pattern is:
|
||||
* - Set up the form for the data that is specific to your
|
||||
* entity: the columns of your base table.
|
||||
* - Call on the Field API to pull in the form elements
|
||||
* for fields attached to the entity.
|
||||
*/
|
||||
function entity_example_basic_form($form, &$form_state, $entity) {
|
||||
$form['item_description'] = array(
|
||||
'#type' => 'textfield',
|
||||
'#title' => t('Item Description'),
|
||||
'#required' => TRUE,
|
||||
'#default_value' => $entity->item_description,
|
||||
);
|
||||
|
||||
$form['basic_entity'] = array(
|
||||
'#type' => 'value',
|
||||
'#value' => $entity,
|
||||
);
|
||||
|
||||
field_attach_form('entity_example_basic', $entity, $form, $form_state);
|
||||
|
||||
$form['submit'] = array(
|
||||
'#type' => 'submit',
|
||||
'#value' => t('Save'),
|
||||
'#weight' => 100,
|
||||
);
|
||||
$form['delete'] = array(
|
||||
'#type' => 'submit',
|
||||
'#value' => t('Delete'),
|
||||
'#submit' => array('entity_example_basic_edit_delete'),
|
||||
'#weight' => 200,
|
||||
);
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Validation handler for entity_example_basic_add_form form.
|
||||
*
|
||||
* We pass things straight through to the Field API to handle validation
|
||||
* of the attached fields.
|
||||
*/
|
||||
function entity_example_basic_form_validate($form, &$form_state) {
|
||||
field_attach_form_validate('entity_example_basic', $form_state['values']['basic_entity'], $form, $form_state);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Form submit handler: Submits basic_add_form information.
|
||||
*/
|
||||
function entity_example_basic_form_submit($form, &$form_state) {
|
||||
$entity = $form_state['values']['basic_entity'];
|
||||
$entity->item_description = $form_state['values']['item_description'];
|
||||
field_attach_submit('entity_example_basic', $entity, $form, $form_state);
|
||||
$entity = entity_example_basic_save($entity);
|
||||
$form_state['redirect'] = 'examples/entity_example/basic/' . $entity->basic_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Form deletion handler.
|
||||
*
|
||||
* @todo: 'Are you sure?' message.
|
||||
*/
|
||||
function entity_example_basic_edit_delete($form, &$form_state) {
|
||||
$entity = $form_state['values']['basic_entity'];
|
||||
entity_example_basic_delete($entity);
|
||||
drupal_set_message(t('The entity %item_description (ID %id) has been deleted',
|
||||
array('%item_description' => $entity->item_description, '%id' => $entity->basic_id))
|
||||
);
|
||||
$form_state['redirect'] = 'examples/entity_example';
|
||||
}
|
||||
|
||||
/**
|
||||
* We save the entity by calling the controller.
|
||||
*/
|
||||
function entity_example_basic_save(&$entity) {
|
||||
return entity_get_controller('entity_example_basic')->save($entity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Use the controller to delete the entity.
|
||||
*/
|
||||
function entity_example_basic_delete($entity) {
|
||||
entity_get_controller('entity_example_basic')->delete($entity);
|
||||
}
|
||||
|
||||
/**
|
||||
* EntityExampleBasicControllerInterface definition.
|
||||
*
|
||||
* We create an interface here because anyone could come along and
|
||||
* use hook_entity_info_alter() to change our controller class.
|
||||
* We want to let them know what methods our class needs in order
|
||||
* to function with the rest of the module, so here's a handy list.
|
||||
*
|
||||
* @see hook_entity_info_alter()
|
||||
*/
|
||||
interface EntityExampleBasicControllerInterface
|
||||
extends DrupalEntityControllerInterface {
|
||||
|
||||
/**
|
||||
* Create an entity.
|
||||
*/
|
||||
public function create();
|
||||
|
||||
/**
|
||||
* Save an entity.
|
||||
*
|
||||
* @param object $entity
|
||||
* The entity to save.
|
||||
*/
|
||||
public function save($entity);
|
||||
|
||||
/**
|
||||
* Delete an entity.
|
||||
*
|
||||
* @param object $entity
|
||||
* The entity to delete.
|
||||
*/
|
||||
public function delete($entity);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* EntityExampleBasicController extends DrupalDefaultEntityController.
|
||||
*
|
||||
* Our subclass of DrupalDefaultEntityController lets us add a few
|
||||
* important create, update, and delete methods.
|
||||
*/
|
||||
class EntityExampleBasicController
|
||||
extends DrupalDefaultEntityController
|
||||
implements EntityExampleBasicControllerInterface {
|
||||
|
||||
/**
|
||||
* Create and return a new entity_example_basic entity.
|
||||
*/
|
||||
public function create() {
|
||||
$entity = new stdClass();
|
||||
$entity->type = 'entity_example_basic';
|
||||
$entity->basic_id = 0;
|
||||
$entity->bundle_type = 'first_example_bundle';
|
||||
$entity->item_description = '';
|
||||
return $entity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves the custom fields using drupal_write_record().
|
||||
*/
|
||||
public function save($entity) {
|
||||
// If our entity has no basic_id, then we need to give it a
|
||||
// time of creation.
|
||||
if (empty($entity->basic_id)) {
|
||||
$entity->created = time();
|
||||
}
|
||||
// Invoke hook_entity_presave().
|
||||
module_invoke_all('entity_presave', $entity, 'entity_example_basic');
|
||||
// The 'primary_keys' argument determines whether this will be an insert
|
||||
// or an update. So if the entity already has an ID, we'll specify
|
||||
// basic_id as the key.
|
||||
$primary_keys = $entity->basic_id ? 'basic_id' : array();
|
||||
// Write out the entity record.
|
||||
drupal_write_record('entity_example_basic', $entity, $primary_keys);
|
||||
// We're going to invoke either hook_entity_update() or
|
||||
// hook_entity_insert(), depending on whether or not this is a
|
||||
// new entity. We'll just store the name of hook_entity_insert()
|
||||
// and change it if we need to.
|
||||
$invocation = 'entity_insert';
|
||||
// Now we need to either insert or update the fields which are
|
||||
// attached to this entity. We use the same primary_keys logic
|
||||
// to determine whether to update or insert, and which hook we
|
||||
// need to invoke.
|
||||
if (empty($primary_keys)) {
|
||||
field_attach_insert('entity_example_basic', $entity);
|
||||
}
|
||||
else {
|
||||
field_attach_update('entity_example_basic', $entity);
|
||||
$invocation = 'entity_update';
|
||||
}
|
||||
// Invoke either hook_entity_update() or hook_entity_insert().
|
||||
module_invoke_all($invocation, $entity, 'entity_example_basic');
|
||||
return $entity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a single entity.
|
||||
*
|
||||
* Really a convenience function for deleteMultiple().
|
||||
*/
|
||||
public function delete($entity) {
|
||||
$this->deleteMultiple(array($entity));
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete one or more entity_example_basic entities.
|
||||
*
|
||||
* Deletion is unfortunately not supported in the base
|
||||
* DrupalDefaultEntityController class.
|
||||
*
|
||||
* @param array $entities
|
||||
* An array of entity IDs or a single numeric ID.
|
||||
*/
|
||||
public function deleteMultiple($entities) {
|
||||
$basic_ids = array();
|
||||
if (!empty($entities)) {
|
||||
$transaction = db_transaction();
|
||||
try {
|
||||
foreach ($entities as $entity) {
|
||||
// Invoke hook_entity_delete().
|
||||
module_invoke_all('entity_delete', $entity, 'entity_example_basic');
|
||||
field_attach_delete('entity_example_basic', $entity);
|
||||
$basic_ids[] = $entity->basic_id;
|
||||
}
|
||||
db_delete('entity_example_basic')
|
||||
->condition('basic_id', $basic_ids, 'IN')
|
||||
->execute();
|
||||
}
|
||||
catch (Exception $e) {
|
||||
$transaction->rollback();
|
||||
watchdog_exception('entity_example', $e);
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @} End of "defgroup entity_example".
|
||||
*/
|
162
sites/all/modules/examples/entity_example/entity_example.test
Normal file
162
sites/all/modules/examples/entity_example/entity_example.test
Normal file
@ -0,0 +1,162 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Tests for entity_example module.
|
||||
*
|
||||
* Verify example module functionality.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Functionality tests for entity example module.
|
||||
*
|
||||
* @ingroup entity_example
|
||||
*/
|
||||
class EntityExampleTestCase extends DrupalWebTestCase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function getInfo() {
|
||||
return array(
|
||||
'name' => 'Entity example',
|
||||
'description' => 'Basic entity example tests',
|
||||
'group' => 'Examples',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setUp() {
|
||||
// Enable the module.
|
||||
parent::setUp('entity_example');
|
||||
|
||||
// Create and login user with access.
|
||||
$permissions = array(
|
||||
'access content',
|
||||
'view any entity_example_basic entity',
|
||||
'edit any entity_example_basic entity',
|
||||
'create entity_example_basic entities',
|
||||
'administer entity_example_basic entities',
|
||||
'administer site configuration',
|
||||
'administer fields',
|
||||
);
|
||||
$account = $this->drupalCreateUser($permissions);
|
||||
$this->drupalLogin($account);
|
||||
|
||||
// Attach a field.
|
||||
$field = array(
|
||||
'field_name' => 'entity_example_test_text' ,
|
||||
'type' => 'text',
|
||||
);
|
||||
field_create_field($field);
|
||||
$instance = array(
|
||||
'label' => 'Subject',
|
||||
'field_name' => 'entity_example_test_text',
|
||||
'entity_type' => 'entity_example_basic',
|
||||
'bundle' => 'first_example_bundle',
|
||||
);
|
||||
field_create_instance($instance);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test Entity Example features.
|
||||
*
|
||||
* - CRUD
|
||||
* - Table display
|
||||
* - User access
|
||||
* - Field management
|
||||
* - Display management
|
||||
*/
|
||||
public function testEntityExampleBasic() {
|
||||
// Create 10 entities.
|
||||
for ($i = 1; $i <= 10; $i++) {
|
||||
$edit[$i]['item_description'] = $this->randomName();
|
||||
$edit[$i]['entity_example_test_text[und][0][value]'] = $this->randomName(32);
|
||||
|
||||
$this->drupalPost('examples/entity_example/basic/add', $edit[$i], 'Save');
|
||||
$this->assertText('item_description=' . $edit[$i]['item_description']);
|
||||
|
||||
$this->drupalGet('examples/entity_example/basic/' . $i);
|
||||
$this->assertText('item_description=' . $edit[$i]['item_description']);
|
||||
$this->assertText($edit[$i]['entity_example_test_text[und][0][value]']);
|
||||
}
|
||||
|
||||
// Delete entity 5.
|
||||
$this->drupalPost('examples/entity_example/basic/5/edit', $edit[5], 'Delete');
|
||||
$this->drupalGet('examples/entity_example/basic/5');
|
||||
$this->assertResponse(404, 'Deleted entity 5 no longer exists');
|
||||
unset($edit[5]);
|
||||
|
||||
// Update entity 2 and verify the update.
|
||||
$edit[2] = array(
|
||||
'item_description' => 'updated entity 2 ',
|
||||
'entity_example_test_text[und][0][value]' => 'updated entity 2 test text',
|
||||
);
|
||||
$this->drupalPost('examples/entity_example/basic/2/edit', $edit[2], 'Save');
|
||||
$this->assertText('item_description=' . $edit[2]['item_description']);
|
||||
$this->assertText('updated entity 2 test text');
|
||||
|
||||
// View the entity list page and verify that the items which still exist
|
||||
// are there, and that the deleted #5 no longer is there.
|
||||
$this->drupalGet('admin/structure/entity_example_basic/manage');
|
||||
foreach ($edit as $id => $item) {
|
||||
$this->assertRaw('examples/entity_example/basic/' . $id . '">' . $item['item_description'] . '</a>');
|
||||
}
|
||||
$this->assertNoRaw('examples/entity_example/basic/5">');
|
||||
|
||||
// Add a field through the field UI and verify that it behaves correctly.
|
||||
$field_edit = array(
|
||||
'fields[_add_new_field][label]' => 'New junk field',
|
||||
'fields[_add_new_field][field_name]' => 'new_junk_field',
|
||||
'fields[_add_new_field][type]' => 'text',
|
||||
'fields[_add_new_field][widget_type]' => 'text_textfield',
|
||||
);
|
||||
$this->drupalPost('admin/structure/entity_example_basic/manage/fields', $field_edit, t('Save'));
|
||||
$this->drupalPost(NULL, array(), t('Save field settings'));
|
||||
$this->drupalPost(NULL, array(), t('Save settings'));
|
||||
$this->assertResponse(200);
|
||||
|
||||
// Now verify that we can edit and view this entity with fields.
|
||||
$edit[10]['field_new_junk_field[und][0][value]'] = $this->randomName();
|
||||
$this->drupalPost('examples/entity_example/basic/10/edit', $edit[10], 'Save');
|
||||
$this->assertResponse(200);
|
||||
$this->assertText('item_description=' . $edit[10]['item_description']);
|
||||
$this->assertText($edit[10]['field_new_junk_field[und][0][value]'], 'Custom field updated successfully');
|
||||
|
||||
// Create and login user without view access.
|
||||
$account = $this->drupalCreateUser(array('access content'));
|
||||
$this->drupalLogin($account);
|
||||
$this->drupalGet('admin/structure/entity_example_basic/manage');
|
||||
$this->assertResponse(403);
|
||||
$this->drupalGet('examples/entity_example/basic/2');
|
||||
$this->assertResponse(403, 'User does not have permission to view entity');
|
||||
|
||||
// Create and login user with view access but no edit access.
|
||||
$account = $this->drupalCreateUser(array('access content', 'view any entity_example_basic entity'));
|
||||
$this->drupalLogin($account);
|
||||
$this->drupalGet('admin/structure/entity_example_basic/manage');
|
||||
$this->assertResponse(403, 'Denied access to admin manage page');
|
||||
$this->drupalGet('examples/entity_example/basic/2');
|
||||
$this->assertResponse(200, 'User has permission to view entity');
|
||||
$this->drupalGet('examples/entity_example/basic/2/edit');
|
||||
$this->assertResponse(403, 'User is denied edit privileges');
|
||||
|
||||
// Create and login user with view and edit but no manage privs.
|
||||
$account = $this->drupalCreateUser(
|
||||
array(
|
||||
'access content',
|
||||
'view any entity_example_basic entity',
|
||||
'edit any entity_example_basic entity',
|
||||
)
|
||||
);
|
||||
$this->drupalLogin($account);
|
||||
$this->drupalGet('admin/structure/entity_example_basic/manage');
|
||||
$this->assertResponse(403, 'Denied access to admin manage page');
|
||||
$this->drupalGet('examples/entity_example/basic/2');
|
||||
$this->assertResponse(200, 'User has permission to view entity');
|
||||
$this->drupalGet('examples/entity_example/basic/2/edit');
|
||||
$this->assertResponse(200, 'User has edit privileges');
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user