96
How To Store Custom Data In Drupal 7 DrupalCamp Utah 2013 August 2, 2013 Walt Haas [email protected] http://drupal.org/user/156317 I "I screw up so you don't have to" How To Store Custom Data In Drupal 7 by Walt Haas is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License .

How to Store Custom Data in Drupal 7

Embed Size (px)

DESCRIPTION

Drupal guide

Citation preview

Page 1: How to Store Custom Data in Drupal 7

How To Store Custom Data In Drupal 7

DrupalCamp Utah 2013August 2, 2013

Walt [email protected]

http://drupal.org/user/156317 I

"I screw up so you don't have to"

How To Store Custom Data In Drupal 7by Walt Haas is licensed under a

Creative Commons Attribution-ShareAlike 3.0 Unported License.

Page 2: How to Store Custom Data in Drupal 7

The use case

You have a special type of data to store in Drupal. You need to figure out the best way to do this. This talk assumes that you already know how to install an existing module.

The talk attempts to show what you can do with existing modules. If you need to create a custom module, there are some examples of code you need to write.

Page 3: How to Store Custom Data in Drupal 7

Drupal is free software

Drupal is released under the GNU General Public License verson 2. This guarantees that Drupal is Free as in Freedom. Among the four software freedoms guaranteed to you by the GPLv2 are the freedom to study how the program works and the freedom to improve it.

This talk will support you in exercising these freedoms by showing examples of controlling Drupal through both the browser and PHP code.

If you want to use Drupal only through the browser, you may ignore the code examples.

Page 4: How to Store Custom Data in Drupal 7

Tips for learning

Start with a Minimal install profile not the default Standard profile. The Minimal profile makes it clearer where each piece of the puzzle comes from.

To get visibility of how the database works, use MySQL and phpMyAdmin.

To understand how the PHP code works, it helps to have an IDE with interactive debugging. Netbeans with Apache and Xdebug works well for this.

The Devel module and Drush have many useful tools.

Page 5: How to Store Custom Data in Drupal 7

Installing the examples

The examples for this talk can be installed from the author's sandbox on git.dupal.org by using git. In your modules directory (something like files/sites/all/modules/) do this :

git clone --branch master \ http://git.drupal.org/sandbox/WaltHaas/2048391.git \ data_storage_examples

Page 6: How to Store Custom Data in Drupal 7

Drupal core data storage

Drupal core with no optional modules enabled stores data in nodes. A node can be created independently of everything except the user that creates it.

Nodes are described by the type of content they hold. Each node has a content type.

We will use data about a collection of Drupal books as our example, progressing from the simplest to the most powerful way to manage this data.

Page 7: How to Store Custom Data in Drupal 7

Allow limited HTML in plain text

To display lists properly change the Plain text input formatAdministration » Configuration » Content authoring » Text formats

Page 8: How to Store Custom Data in Drupal 7

Content type creation

Start with a minimal installation. Log in as user 1. There are no content types:Administration » Structure

Page 9: How to Store Custom Data in Drupal 7

Create a new content type

Click on Add content type to create your first content type. Give it a name and let everything else default. Click Save content type:Administration » Structure » Content type

Page 10: How to Store Custom Data in Drupal 7

Content type permissions

Going to url/admin/people/permissions we see that there are now permissions available to control access to our new content typeAdministration » People

Page 11: How to Store Custom Data in Drupal 7

Create content of the new type

Now we can go to url/node/add/book1 to create content of type Book1. Give the content a Title and some Body text, then click Save to save this content:Add content

Page 12: How to Store Custom Data in Drupal 7

View the content we created

Our content looks like this:

We have both View and Edit permission. The submitting user and submission timestamp are both shown.

Page 13: How to Store Custom Data in Drupal 7

Edit the content we created

By clicking the Edit tab, we have the opportunity to edit the content:

Page 14: How to Store Custom Data in Drupal 7

Content revision and publication

On the Edit tab for our content page we see a way to track revisions to the content.

Page 15: How to Store Custom Data in Drupal 7

Revise the content

Let's change a line in the book description:

Page 16: How to Store Custom Data in Drupal 7

Preview the change

Click the Preview button at the bottom. At the top of the new page we see:

Actually, that delimiter only works if you go to the Text formats page and add <!-- --> to the list of allowed HTML tags.

Page 17: How to Store Custom Data in Drupal 7

Save the revision

At the bottom of the Edit tab, check Create new revision, add a log message and click Save

Page 18: How to Store Custom Data in Drupal 7

Revisions tab appears

When we look at our content again, we see a new tab Revisions

Page 19: How to Store Custom Data in Drupal 7

See revision history

By clicking the Revisions tab, we see the log messages and authors:

Page 20: How to Store Custom Data in Drupal 7

Install the Diff module to see what changed

If we install the Diff module we can compare two versions:

Page 21: How to Store Custom Data in Drupal 7

Diff compare shows the changes

Compare highlights the additions, deletions and changes as in a software version control system:

Notice the red period at end of line on right

Page 22: How to Store Custom Data in Drupal 7

What did we just do in the DB?Add content type

Add content type adds a row to the {node_type} table:

Page 23: How to Store Custom Data in Drupal 7

What did we just do in the DB?Add content

Add content adds rows to the {node} and {node_revision} tables:

Page 24: How to Store Custom Data in Drupal 7

What did we just do in the DB?Create new revision

Create new revision adds a row to the {node_revision} table and updates the node's row of the {node} table:

Page 25: How to Store Custom Data in Drupal 7

What did we just do in the DB?Where did the text go?!

The text is not stored in the node directly. Instead, it is stored in a storage area called a field. When we created the Book1 content type, we automatically created a Body field for the content type. Add content adds a row to the {field_data_body} and {field_revision_body} tables:

Page 26: How to Store Custom Data in Drupal 7

What did we just do in the DB?Where did the text revision go?

Create new revision adds a row to the {field_revision_body} table and updates the node's row of the {field_data_body} table.

Page 27: How to Store Custom Data in Drupal 7

What did we just do in the DB?Added Drupal variables

We added some rows to the {variable} table

Page 28: How to Store Custom Data in Drupal 7

Create a content type in a module

This goes in the modulename.install file:

function modulename_install() { // Create the book1 node type $book1 = array(

'type' => 'book1','name' => t('Book1'),'base' => 'node_content','description' => t('Content type to hold a book description'),'has_title' => TRUE,'custom' => FALSE,

); $book1_type = node_type_set_defaults($book1); node_add_body_field($book1_type); node_type_save($book1_type);}

Page 29: How to Store Custom Data in Drupal 7

Properties of a node

Every node has the following properties:● Node ID● Version ID● Content type● Language● Title● Node owner user ID● Published? (true/false)● Creation timestamp● Last changed timestamp● Comments allowed? (true/false)● Promoted to front page? (true/false)● Sticky at top of lists? (true/false)● Translation set ID● Translation update necessary? (true/false)

Other properties can be added as fields, as shown later.

Page 30: How to Store Custom Data in Drupal 7

Review Drupal core data storage

Let's review what we just did. Drupal 7 core stores data in nodes. Nodes always have a content type. We added a content type and stored a node of that type with a title and some text.

The example showed how to define a content type with the browser or by implementing hook_install() in a module.

Page 31: How to Store Custom Data in Drupal 7

Looking at our data

Storing data is useless unless there is a way to find what you want in the stored data. The most popular way to do this in Drupal is with the Views module. You will also need the Chaos tool suite module that Views uses.

Enable the Chaos tools, Views and Views UI modules for the next step.

We also need more books in the database to make the example meaningful. The Bookshelf Example 1 module installs a dozen assorted books to work with.

Page 32: How to Store Custom Data in Drupal 7

Create a bookshelf view

With Views UI enabled we can create a bookshelf view:

Administration » Structure

Click Add new view

Page 33: How to Store Custom Data in Drupal 7

Name the new view

Give the view a name and select content type Book1

Click Continue & edit

Page 34: How to Store Custom Data in Drupal 7

View details

The top part of this page selects data and controls how it will be presented. Note that any changes you make are not saved until you click the Save button.

Page 35: How to Store Custom Data in Drupal 7

View auto preview

For the moment, scroll down the page to the Auto preview checkbox and look at the text below. This is a preview of what the user will see. By default it shows title, user that posted the content and the summary section of the node.

Page 36: How to Store Custom Data in Drupal 7

View auto preview continued

When you change the control parameters in the top section of the page this preview section will be automatically updated to show you what the view will look like with the new parameters.

You can experiment freely and see the results immediately. Your changes will not affect the publicly visible view until you click the Save button at the top.

Page 37: How to Store Custom Data in Drupal 7

Change view format

Let's try a different format. In the middle of the page is a Page details box. In the left column, find Format: Unformatted list and click on it. A modal window appears:

Page 38: How to Store Custom Data in Drupal 7

Select table format

In the modal window, check the Table box then click Apply (all displays). The Page: Style options modal window appears. Click Apply (all displays) again. The main window for the view reappears. The Auto preview section has been updated and now shows the new format, which is the book title with a link to the node:

Page 39: How to Store Custom Data in Drupal 7

Select fields to show

In the Page details section, below Format we now see

The table format allows us to select which part of the content will appear in the view. Click on Add in the button just to the right of Fields

Page 40: How to Store Custom Data in Drupal 7

Add a field to the view

A modal window appears with a list of content items we may add to the table. Title with link are already part of the table but, confusingly, aren't checked. Scroll down the list to Content: Post date and check the box next to that.

Click Apply (all displays)

Page 41: How to Store Custom Data in Drupal 7

Select format of this field

Another modal window appears. Scroll down to the selector labeled Date format and choose Short format.

Click Apply (all displays)

Page 42: How to Store Custom Data in Drupal 7

Preview now shows date

The auto preview section now shows the content Post date in a new column:

We will see that how we store data in a content type controls what data is available to be shown in a view, an important consideration.

Page 43: How to Store Custom Data in Drupal 7

Add a filter to the view

A filter allows us to select which books will appear in the view based on some criterion we choose. In the Page details section, below Fields find Filter criteria. Click on Add in the button just to the right of Filter criteria

Page 44: How to Store Custom Data in Drupal 7

Select filter field

A modal window Add filter criteria appears. Find the line with Content: Body (body) and check the box next to it.

Click Apply (all displays)

Page 45: How to Store Custom Data in Drupal 7

Configure filter criterion

Another modal window appears allowing us to configure the filter criterion. Check the box next to Expose this filter to visitors

Page 46: How to Store Custom Data in Drupal 7

Allow viewers to set filter

Near the bottom of the modal window select Operator Contains and check Expose operator and Remember the last selection

Click Apply (all displays)

Page 47: How to Store Custom Data in Drupal 7

Check operation of filter

The Auto preview section of the view now has a tool to choose books. If we specify theme and click Apply we get a list of only those nodes with the word "theme" in the body of the node. Available content filter criteria is another important design consideration.

Page 48: How to Store Custom Data in Drupal 7

Save the view

Our view is not yet permanent. Near the top of the Page settings section, in the center, notice Path: /bookshelf1

Click the Save button in the upper right to save the view.

Now we can go to url/bookshelf1 to use the view

Page 49: How to Store Custom Data in Drupal 7

Review: importance of Views

The Views module is one of the most popular Drupal modules because of its abililty to select and display data.

What the Views module can do with your data depends heavily on exactly how you store it.

Therefore, as you develop your data storage scheme, check your decisions by testing how they work with Views.

Page 51: How to Store Custom Data in Drupal 7

Useful contributed modules 2

● Delta● Deployment● Devel● Diff● Display Suite● DraggableViews● Dynamic display block● Email Field● Entity API● Entity Dependency API You must write PHP code to describe any entity

dependencies of your content type beyond the core entities and entity reference fields.

● Entity reference● Features● Feeds May require custom mapper for target fields● Field collection

Page 52: How to Store Custom Data in Drupal 7

Useful contributed modules 3

● Field group● FileField Sources● Field Permissions● Fivestar● Flag● Geocoder● Geofield● Geolocation● Global Redirect● Google Analytics● Invisimail● Is Useful● Link● Location● Menu block● Menu Breadcrumb

Page 54: How to Store Custom Data in Drupal 7

Useful contributed modules 5

● reCAPTCHA Works on a form, such as the comment form on a content type

● Redirect● References Use the Entity reference module instead● RESTful Web Services● Revisioning● Scheduler● Search configuration● Search Restrict● Services To control access to specific fields you may need to implement a

hook● SpamSpan filter works, but Invisimail looks better● TagClouds● User Points● Univerally Unique IDentifier

Page 55: How to Store Custom Data in Drupal 7

Useful contributed modules 6

● Views When Views UI is enabled, custom content types are listed as candidates for display

● Voting API● Workbench● XML sitemap

Page 56: How to Store Custom Data in Drupal 7

Drupal 7 stores user data in entities and fields. These are abstract concepts. So far we have worked with one kind of entity, Node, and one kind of field, Body.

The entity abstraction was introduced in Drupal 7. In earlier versions of Drupal, Nodes, Users and Files were independent. In Drupal 7, these are all instances of the entity abstraction.

How Drupal 7 stores data

Page 57: How to Store Custom Data in Drupal 7

Views shows entities

On the Add new view page, the first selector shows a list of the entities (among other things) that can be used as the basis of a view.

This entity determines what data the view will be able to find. For example, if we choose Content we can only access Users that have created Content nodes.

Page 58: How to Store Custom Data in Drupal 7

Add a few entities

Enable the Comment and Taxonomy modules to define additional entities. Now the Add new view page lists the additional entities in the first selector

Page 59: How to Store Custom Data in Drupal 7

Entity construction kit

You can define new entity types through the browser by installing the Entity Construction Kit (ECK) module. Entity types defined this way are available to views.

Page 60: How to Store Custom Data in Drupal 7

Defining an entity in a module

Any module can define an entity by implementing hook_entity_info(). You can use the DrupalDefaultEntityController class or define a controller class that implements the DrupalEntityControllerInterface. These are defined in files/includes/entity.inc where you can see the functions common to all entities. By using one of these you have access to a variety of common entity functions.There are only a few entity functions in Drupal 7 core. Additional entity functions are available in the Entity API module.

Page 61: How to Store Custom Data in Drupal 7

Fields

In Drupal 7 a field is a piece of storage attached to an entity. The code for this is found in Drupal core in files/modules/fields/

CAUTION!The terminology used for this is very confused. Drupal documentation frequently applies the word "field" to a column in a database table. A field constructed by the field module is stored in a table with seven columns of bookkeeping data in addition to the columns that store the data you want. Which meaning is intended is not always clear from context! This talk tries to keep a clear distinction between field and column.

Page 62: How to Store Custom Data in Drupal 7

Extra fields

MORE CONFUSION!

The documentation further confuses things by giving the name “extra fields” to columns like the title column in a node that aren’t fields in the Drupal 7 sense.

The motivation for this confusing terminology seems to be that you reference these columns in Views and elsewhere as if they were fields.

Sometimes they’re called “pseudo fields”

Page 63: How to Store Custom Data in Drupal 7

Body field is optional

When you create a content type, a body field is added by default. You can delete the body field if you want. The node title is a column in the node table and cannot be deleted.

You can add fields to a content type as shown in the next section.

Page 64: How to Store Custom Data in Drupal 7

Field types

Each field holds data of some defined type, known as the field type. In a minimal install, the Field, Field SQL storage and Text modules are enabled, because they are required by Drupal core. The Text module defines fields of character string types.

You can add fields to any fieldable entity. These include Comment, Node, Taxonomy term, User, and any other entity defined with 'fieldable' => TRUE

Page 65: How to Store Custom Data in Drupal 7

Add a field to a content type

To add fields to entities with a browser, you need to enable the Field UI module. With this module enabled, you can control the fields attached to Book1 atAdministration » Structure » Content types » Book1

Page 66: How to Store Custom Data in Drupal 7

Add a field to the user entity

With the Field UI module enabled, you can control the fields attached to the User entity atAdministration » Configuration » People » Account settings

Page 67: How to Store Custom Data in Drupal 7

Basic field types

The basic field types are defined in the various modules in files/modules/field/modules/. The “Select a field type” pulldown will always offer at least the field types defined by the Text module, which are: Long text, Long text with summary and Text. If you are learning how to write a module that defines a field type, these fields are defined in files/modules/field/modules/text/text.module:text_field_info() and are a good example.

Page 68: How to Store Custom Data in Drupal 7

Number field types

If you enable the Number module the field type pulldown will offer three more field types: Decimal, Float and Integer. These are defined in files/modules/field/modules/number/number.module:number_field_info()

Page 69: How to Store Custom Data in Drupal 7

Fields vs. field types

It's important to be clear on the distinction between field and field type.

A field type is a general type of information such as integer, float, character string etc. Field types can only be defined by a module.

You create a field by assigning a name to a field type. For example, you could create First Name and Last Name fields of field type Text. You can use the Field UI to create a field of an existing field type.

Page 70: How to Store Custom Data in Drupal 7

Create two fields of same field type, add them to User entity

Use Add new field to add two different fields of the same field type to the User entity

Page 71: How to Store Custom Data in Drupal 7

The new field is now available to other fieldable entities

Administration » Structure » Content types » Book1

Page 72: How to Store Custom Data in Drupal 7

Field bundles

A bundle is the collection of fields attached to some entity type. Core defines a bundle for every node type, for comments on each node type, for taxonomy terms (for each vocabulary), and one for user, aptly named 'user'.

The rows in {field_data_...} tables contain bundle names in the bundle column. For example

Page 73: How to Store Custom Data in Drupal 7

Field instances

A field instance is the way a field is tailored for use with a particular bundle. Our example First Name field is bundled with the User entity and the Book1 content type, so we can show it to the viewer in different ways. For example on the Book1 content type we might label the First Name field as Author First Name and require it:

Page 74: How to Store Custom Data in Drupal 7

Field instances continued

When the same First Name field is bundled with the User entity we can give it a different label and make it optional

Configuration information for instances is stored in the {field_config_instance} table in a BLOB

Page 75: How to Store Custom Data in Drupal 7

Create a field in PHP code

If the field type already exists, creating a field takes about 35 lines of code. Download the examples and look in file

data_storage_examples_bookshelf2.install

for function

_data_storage_examples_bookshelf2_attach_field()

Page 76: How to Store Custom Data in Drupal 7

Widgets and formatters

Every field has a widget and a formatter.

A widget is a means for a user to enter data through their browser. The form of widget depends on the field type of the field. Some field types offer more than one widget. When you add a new field, you select the widget for it. The help text says Form element to edit the data

A formatter is a way to present the data to a browser user. The formatter also depends on the field type of the field. You select the format and labels for the field on the Manage display tab.

Page 77: How to Store Custom Data in Drupal 7

Fields vs. columns

We have seen how to create and use a Drupal 7 field. Inside the database the value of a field is stored in a table with eight or more columns. Seven columns are used for bookkeeping information about the field value. If we add a field of integer type called "Logins" to the user entity we create {field_data_field_logins}and {field_revision_field_logsins} tables in the DB:

Page 78: How to Store Custom Data in Drupal 7

Multi-value fields

A field type can be defined to hold more than one value. The number of values allowed by a field type is called the cardinality of the field type. Cardinality can be a certain number or "unlimited" (4294967295).

If you enable the List core module, four new field types are available: Boolean, List(float), List(integer), List(text). You define a set of key|value pairs that can be assigned to the field. Only the listed values are eligible to be stored in the field. Let's add a list of ice cream flavors to the user entity:

Page 79: How to Store Custom Data in Drupal 7

Add a List(text) field to User

We add a multi-value field listing the flavors the user likes to the User entity

Page 80: How to Store Custom Data in Drupal 7

List the available flavors

On the Field settings tab for the Likes flavors field, list the allowed values. If we don't list a key, the value will be used as the key.

Page 81: How to Store Custom Data in Drupal 7

Set the list number of values

Allow the user to select any number of flavors

Page 82: How to Store Custom Data in Drupal 7

Edit flavor preference(s) of a user

Edit any user. On the Edit tab we now see a list labeled Likes flavors with a check box for each allowed flavor value. Check the user's prefered flavors and click Save.

Page 83: How to Store Custom Data in Drupal 7

View Likes flavors field for a user

View the user and see their flavor preference(s) listed

Page 84: How to Store Custom Data in Drupal 7

Likes flavors field in the database

By creating the Likes flavors field, we added tables {field_data_likes_flavors} and {field_revision_likes_flavors} to the database

Think of the value of "Likes flavors" as an array. The delta column is the array index for the values in the field_likes_flavor_values column.

Page 86: How to Store Custom Data in Drupal 7

Review of fields and entities

Entities are a new concept in Drupal 7.

Nodes and users are both entities.

Entities exist (mostly) independently.

Some entities are fieldable, meaning you can attach a field to them. Nodes and users are both fieldable.

Fields depend on the entity they are attached to.

Fields can be created by the Field UI module from an existing field type. Field types are created by modules.

Page 87: How to Store Custom Data in Drupal 7

Book2 content type

In the Book1 content type we had only a Body field. Information about author(s), publisher and the URL of the book description were lines in the body field. Unfortunately, the only way to use Views to find a book is to search the body text.

If we list Author(s) and Publishers in separate fields we can have Views search them specifically, so let's define a Book2 content type that puts this information in different fields.

We install the Date and Link modules to define field types

Page 88: How to Store Custom Data in Drupal 7

Book2 field definitions

We define separate fields for Author(s), Publisher, Publication date, ISBN and a link to the publisher’s description of the book

Page 89: How to Store Custom Data in Drupal 7

Book2 multiple authors

Publisher’s description is a URL. The field is configured to use the field label as title. Author(s) is a multi-value text field. Unlimited authors can be added.

Page 90: How to Store Custom Data in Drupal 7

Book2 publication fields

Publication date is a field. Publisher and ISBN are text fields.

Page 91: How to Store Custom Data in Drupal 7

Bookshelf2 view

We create a view that allows filtering on several fields. The column headers can be clicked to sort the rows on the respective column.

Page 92: How to Store Custom Data in Drupal 7

Bookshelf2 view is default

When you install the Bookshelf2 example module, this view is installed automatically, along with the data for a dozen books.

Access the view at url/bookshelf2

Enable the Views UI module and edit this view to see how the fields and filters are set up. The clickable column headers are set in Format: Settings and only work when there are no Sort criteria specified.

Page 93: How to Store Custom Data in Drupal 7

Custom entity facilities

Support for entities does not include revision managment. If you want revision support for your custom entity you need to write it yourself. For an example of how to do this see the User Revision contributed module.

Entity support in Drupal core is limited. The Entity API module provides additional useful functions.

Page 94: How to Store Custom Data in Drupal 7

Modules that define entity types

These contributed modules define entity types● Drupal Commerce● Field collection● Location location_entity submodule● Ubercart

In some cases it isn't clear why this decision was made instead of using a content type.

Page 95: How to Store Custom Data in Drupal 7

Direct database API calls

Modules can make calls directly to the database API. In fact, most do. Some things can't be accomplished through fields and entities.

Don’t make this choice unless you understand what you are giving up! Before you code direct database API calls, make sure that there isn't a way in the Entity API or Field API to reach your goal.

Page 96: How to Store Custom Data in Drupal 7

Junction tables

One goal that generally requires direct DB API calls is constructing a many-to-many junction table.

Examples of this in Drupal core are the {users_roles} and {taxonomy_index} tables. The {taxonomy_index} table matches taxonomy term entities with the tagged entity.

An example in a contributed module is the Flag module, which defines flags and maintains a junction table matching flags to entities. The flags aren't entities or fields, but the targets of the junction table are entities.