Monday, October 5, 2015

Create mobile application with drupal - Tutorial

Build a Mobile App to Sell Products with Drupal

Category: 
This tutorial describes how to create a website and mobile application to sell physical products. Customers on a desktop or laptop computer will be able to purchase the product through the website, much like a typical e-commerce store.
Once we have built the mobile application, customers who have downloaded and installed the mobile app onto their Android or iOS (iPhone, iPad) device will be able to purchase the product as an In-App Purchase.
For this example website and mobile app, we're going to sell bottles of beer. *Cough* - Please don't actually sell beer without first getting permission from your local Big Brother.
The main 3 sets of tools we will utilize are:
This tutorial was inspired by this Session from DrupalCon Austin 2014. If you're new to any of these tools mentioned above, please watch the video for an introduction. Otherwise, let's get started!

1. Download and Install Drupal 7

2. Download and Install the Commerce Module for Drupal

If you're new to Drupal Commerce, I'd recommend checking out Commerce KickStart for a nice introduction. Otherwise, the Commerce module comes packed with many sub modules. To get started, we'll want to make sure the following modules are enabled on our Drupal site:
  • Cart
  • Checkout
  • Commerce
  • Commerce UI
  • Customer
  • Customer UI
  • Line Item
  • Line Item UI
  • Order
  • Order UI
  • Payment
  • Payment UI
  • Price
  • Product
  • Product Pricing
  • Product Pricing UI
  • Product Reference
  • Product UI
Woah, that was a lot of modules. Pretty much enable them all except for the Tax modules, and don't tell the King about it.

2a. Give users permission to go through the Checkout process

  1. On the Drupal site, go to: admin/people/permissions
  2. Next to the "Access checkout" permission, check the box for Anonymous and Authenticated users
  3. Click the "Save permissions" button

3. Add a Product Type

Go to:
admin/commerce/products/types/add
With the following info:
  • Name: Beer
  • Description: Mmmm, beer.
Then click the "Save and add fields" button.

4. Add a "Size" Field to the Product type

As a bare minimum, we want our customers to be able to choose the size of their beer. So let's add a new field on our Product type to accommodate this:
admin/commerce/products/types/beer/fields
Under the "Add new field" section, enter the following info:
  • Label: Size
  • Field type: List (text)
  • Widget: Select list
Then click the "Save" button. Next up, in our "Allowed values list" for the field, let's copy/paste these values:
Pint
12 oz
22 oz
40 oz
Then click the "Save" button. Next, specify these values:
  • Label: Size
  • Required field: Check the box
  • Default value: Pint
  • Enable this field to function as an attribute field on Add to Cart forms: Check this box
  • Number of values: 1
Then click the "Save settings" button.

5. Add some Products

We're now ready to add some products to sell. In Drupal, go to:
admin/commerce/products/add/beer
Then enter the following values:
  • Product SKU: bells-oberon-12-oz
  • Title: Bells Oberon 12 oz
  • Price: $4.00
  • Size: 12 oz
Click the "Save and add another" button, then enter the following values:
  • Product SKU: bells-oberon-pint
  • Title: Bells Oberon Pint
  • Price: $5.00
  • Size: Pint
As you can see we've now created 2 products which allow us to sell a Bells Oberon beer in either a 12 oz or pint size.
Repeat this procedure as many times as you want to build your beer catalog. After a while, we'll have a list of beer like so:
For now, prohibition is tough on the Internet so we only have 5 products to sell, within 3 types of beer.
  • Bells Oberon
  • Shorts Brew Soft Parade
  • Sierra Nevada Torpedo Extra IPA

6. Add a Content Type to Display the Products

In Drupal, go to:
admin/structure/types/add
Enter Beer as the Name, then click the "Save and add fields" button.

6a. Add a Field to Reference the Products

Then under the "Add new field" section, enter the following info:
  • Label: Beer Products
  • Field type: Product reference
  • Widget: Check boxes/radio buttons
Then click the "Save" button, then click the "Save field settings" button.  Next, specify these values:
  • Label: Beer Products
  • Required field: Check the box
  • Products types that can be referenced: Beer
  • Default value: Pint
  • Number of values: Unlimited
Then click the "Save settings" button.

6b. Add an Image Field to Show a Picture

If you're not already there, navigate to this page in Drupal:
admin/structure/types/manage/beer/fields
Under the "Add new field" section, enter the following info:
  • Label: Photo
  • Field type: Image
  • Widget: Image
Then click the "Save" button, then click the "Save field settings" button.  Next, specify these values:
  • Label: Photo
  • Required field: Check the box
Leave all the other settings as the default values provided, then click the "Save settings" button.

7. Create Content to Display Products

Now that we have some beer products created, we need to create some beer content to reference the beer products. This allows the "Add to cart" functionality to work within Drupal Commerce. On your Drupal site, go to:
node/add/beer
Enter these values:
  • Title: Bells Oberon
  • Beer Products:
    • bells-oberon-12-oz: Check this box
    • bells-oberon-pint: Check this box
  • PhotoUpload a picture to use
Click the "Save" button, then repeat that process for the other two types of beer, using these values:
  • Title: Sierra Nevada Torpedo Extra IPA
  • Beer Products:
    • sierra-nevada-torpedo-extra-ipa-12-oz: Check this box
    • sierra-nevada-torpedo-extra-ipa-22-oz: Check this box
  • PhotoUpload a picture to use
Then one more time with:
  • Title: Shorts Brew Soft Parade
  • Beer Products:
    • shorts-brew-soft-parade-12: Check this box
  • PhotoUpload a picture to use

8. Create a Page to Display the Product Content

We'll use Views to make a page to display our Beer content, in Drupal go to:
admin/structure/views/add
Enter these values:
  • View name: Beers
  • Show: Content
  • of type: Beer
  • sorted by: Title
Next check the "Create a page" box and enter these values (note, the zero used below means display all items):
  • Page title: Beers
  • Path: beers
  • Display format: Table
  • Items to display: 0
Then check the "Create a menu link" checkbox and enter these values:
  • Menu: Main menu
  • Link text: Beers
Then click the "Continue & edit" button.

8a. Display an Image with the Product Listing Page

Now, in the "Fields" section, follow these steps:
  1. Click the "Add" button
  2. Enter this keyword in the Search box: photo
  3. Check the box next to "Content: Photo"
  4. Click the "Add and configure fields" button
  5. Uncheck the "Create a label" box
  6. On the "Image style" select list, choose "Thumbnail (100 x 100)"
  7. On the "Link image to" select list, choose "Content"
  8. Click the "Apply" button
  9. In the "Fields" section, click the down arrow then click the "Rearrange" button
  10. Grab the handle next to the Photo field, and drag it above the Title field
  11. Click the "Apply" button
Finally, we can click the "Save" button on our View, then click the "Home" button to go home. We should now see a "Beers" button in our main menu, let's click it to look at our fine selection:

9. Enable a Payment Method

For this tutorial, we'll be using Stripe to accept a demonstration payment.
  1. Signup (or login) with Stripe
  2. Download and enable the Commerce Stripe module
    1. pay close attention to the README with this module to install it properly
  3. Go to: admin/commerce/config/payment-methods
  4. Click "enable" on the disabled Stripe payment method rule
  5. Click "edit" next to the enabled Stripe payment method rule
  6. Click "edit" next to the Stripe action
  7. In a separate window, login to Stripe website
  8. Go to: Your Account -> Account Settings -> API Keys
  9. Copy the Secret and Publishable test keys from Stripe
  10. Paste them back into the corresponding text fields in the "Payment Settings" section back on the Drupal site
  11. Click "Save"
  12. Flush all of Drupal's caches

10. E-commerce... done!

That's it, we've built a fully functional e-commerce website with Drupal Commerce to sell beer. Customers can now browse the beer on our website, add it to their cart, and complete the checkout process.
Let's now move on to building the mobile application...

11. Enable DrupalGap, Commerce DrupalGap and Commerce DrupalGap Stripe modules in Drupal

Since we'll be using DrupalGap to build the mobile application, let's download and enable the modules we'll need on our Drupal site:
Refer to each module's README file for important installation instructions about their dependencies and setup configurations.
VERY IMPORTANT: At this time of writing this, the Commerce Services module (a dependancy of Commerce DrupalGap) isn't evolved enough to handle permissions properly. So for this to work properly we have to enable certain permissions for anonymous and authenticated users that we wouldn't normally grant, or we have to use user #1 to bypass the permissions. See this issue for more details: https://www.drupal.org/node/1943426

12. Set up the DrupalGap Mobile Application Development Kit

If you're new to DrupalGap, follow the Hello World guide to get started. For this example, we'll be developing the mobile app in Google Chrome using the Ripple plugin. Once everything is up and running, our app should look similar to the screen shot here.

13. Enable the Address Field, Commerce and Commerce DrupalGap Stripe modules for DrupalGap

Just like Drupal, DrupalGap has contributed modules. We'll need to download and these two modules to our app's modules directory within DrupalGap:
Then enable the modules in our settings.js file, for example:
Drupal.modules.contrib['addressfield'] = {};
Drupal.modules.contrib['commerce'] = {};
Drupal.modules.contrib['commerce_drupalgap_stripe'] = {};

14. Create a Custom DrupalGap Module to Customize the App

Again, just like Drupal, DrupalGap allows us to create our own modules to handle customization. Let'screate a custom module in DrupalGap, so its JavaScript file lives here:
www/app/modules/custom/my_module/my_module.js
Then enable the module from within the settings.js file:
Drupal.modules.contrib['my_module'] = {};

15. Create a JSON Page URL in Drupal to Retrieve the Beer List

Let the fun begin... first we need to access our beer list via JSON, so we need to setup a URL that will return JSON to us, in Drupal go to:
admin/structure/views/view/beers/edit
  1. Click +Add in the Display section
  2. Click Page
  3. Change the Display name to JSON
  4. Change the Format to JSON Data Document, on This page (override), then click the Apply (this display) button
  5. Uncheck the Views API mode checkbox, then click the Apply (this display) button
  6. Under Page Settings, change the Path to beers.json
  7. Under Fields, change the Label on both fields, so the first character in the label is lower case, on this display only
  8. Next to Fields, click the Add button
  9. Enter nid into the Search box
  10. Check the box next to Content: Nid and then press the Apply (this display) button
  11. Change the Label to nid and then press the Apply (this display) button
Now if we preview our results, we should see something like this:
{
  "nodes" : [
    {
      "node" : {
        "photo" : { "src": "http://localhost/drupal-7/sites/default/files/styles/thumbnail/public/sierranevada_torpedoextraipa12oz_0.jpg?itok=8sCnt0hP" },
        "title" : "Sierra Nevada Torpedo Extra IPA",
        "nid" : "293"
      }
    },
    {
      "node" : {
        "photo" : { "src": "http://localhost/drupal-7/sites/default/files/styles/thumbnail/public/soft-parade-1.jpg?itok=UWiqK1fL" },
        "title" : "Shorts Brew Soft Parade",
        "nid" : "294"
      }
    },
    {
      "node" : {
        "photo" : { "src": "http://localhost/drupal-7/sites/default/files/styles/thumbnail/public/bells-oberon-12_0.jpg?itok=Phb_X8bE" },
        "title" : "Bells Oberon",
        "nid" : "292"
      }
    }
  ],
  "view" : {
    "name" : "beers",
    "display" : "page_1",
    "path" : "admin/structure/views/nojs/preview/beers/page_1",
    "root" : "nodes",
    "child" : "node",
    "pages" : null,
    "page" : null,
    "count" : 3,
    "limit" : null
  }
}
Click the "Save" button to save the View. We're now ready to consume our beer as JSON, be sure to eat some food before consuming beer, and after I suppose.

16. Create a Page in the App to Display the Beer List

Since we created a custom module in DrupalGap earlier, we can use the my_module.js file to create a custom page using hook_menu(), like so:
/**
 * Implements hook_menu().
 */
function my_module_menu() {
  try {
    var items = {};
    items['beer-list'] = {
      title: 'Beer List',
      page_callback: 'my_module_beer_list_page'
    };
    return items;
  }
  catch (error) {
    console.log('my_module_menu - ' + error);
  }
}

function my_module_beer_list_page() {
  try {
    var content = {};
    content['my_beer_list'] = {
      theme: 'view',
      format: 'ul',
      path: 'beers.json',
      row_callback: 'my_module_beer_list_page_row',
      empty_callback: 'my_module_beer_list_page_empty'
    };
    return content;
  }
  catch (error) { console.log('my_module_beer_list_page - ' + error); }
}

function my_module_beer_list_page_row(view, row) {
  try {
    var image = theme('image', { path: row.photo.src });
    var title = '<h2>' + row.title + '</h2>';
    var html = l(image + title, 'node/' + row.nid);
    return html;
  }
  catch (error) { console.log('my_module_beer_list_page_row - ' + error); }
}

function my_module_beer_list_page_empty(view) {
  try {
    return "Sorry, we are out of beer.";
  }
  catch (error) { console.log('my_module_beer_list_page_empty - ' + error); }
}
Then if we set this newly created page as our App's front page in the settings.js file:
// App Front Page
drupalgap.settings.front = 'beer-list';
We'll be able to see our beer list!

17. Let's Go Shopping for Beer!

Since DrupalGap comes with the ability to view nodes, and we chose to render our beer list with each item as a clickable link to its node page (e.g. node/123), we can click on an item in our beer list to view it. Since it is 9:30 AM at the time of writing this paragraph, I won't actually drink a beer, but if I had to choose, I'd click on the Oberon for now.
Now that we're viewing the beer node, we can see that our "Add to Cart" form and picture of the beer were automatically rendered for us, neat-o. If we were to scroll down in the app, we could see the whole picture, but you get the idea. Since its early, let's select a 12 0z instead of a pint, and click the add to cart button.
Then we can proceed through the checkout process, which is similar to most e-commerce workflows:

18. All Done!

Now if we were to look in the admin order section in Drupal:
admin/commerce/orders
We would see our new order sitting there with a status of pending:

Tuesday, September 15, 2015

Handling long-running background tasks in Drupal 7

In my previous post, I discussed how to import a large dataset into Drupal via Drush's batch API. In this blog post, I'll cover how to create background tasks in Drupal 7 that will take long amounts of time to finish.

Why would you ever want that?

If you have a task that must occur regularly, but will take a long amount of time to complete, the cron queue might be a good solution. For instance, if you have a lot of nodes that need to stay synchronized with a remote dataset, you might want to synchronize a large portion of them during a cron run, but would like your other cron tasks to complete in a timely manner.
Drupal provides an easy interface to adding such long-running background tasks via hook_cron_queue_info() andhook_cron().

Implement hook_cron()

hook_cron() is run everytime the drupal cron job is run. However, it is not very well suited to longer running tasks since it runs them sequentially. To avoid holding up the other cron job tasks, we'll need to create an item in the DrupalQueue.
  function mymodule_cron() {
    // ...
    // get dataset to work on
    // ...
 
    $queue = DrupalQueue::get("resync");
    foreach ($dataset as $data) {
      $queue->createItem($data);
    }
  }
Now on every cron run, we'll insert a bunch of items in our queue to process. Let's go ahead and let Drupal know what to do for each queue's item.
  function mymodule_cron_queue_info() {
    $queues['resync'] = array (
      'worker callback' => 'mymodule_resync_item',
      'time' => 180,    // Time, in seconds, to let this process run [Optional]
    );
  }
 
  function mymodule_resync_item($data) {
    // ...
    // Code to resync data here
    // ...
  }
With just those three methods you have created background tasks that will not hold up the normal cron job tasks! It is worth noting that you don't have to enter these queue items via hook_cron(), but could add them during some other time. You might create the queue items on node creation or deletion, for instance.

so for example 
function MODULENAME_cron() {
$nodes=expired_nodes('type'); //a function that fetch the nodes id array i want
  $queue = DrupalQueue::get('update_node');
  foreach ($nodes as $row) {
    $queue->createItem($row);
  }
  return $queue;
}
 
function MODULENAME_cron_queue_info() {
  $queues['update_node'] = array(
    'worker callback' => 'MODULENAME_callback',
    'time' => 30, // time in second for each worker
  );
  return $queues;
}
 
function MODULENAME_callback($data){
      foreach ($data as $row) {
db_insert('field_data_field_SOMENAME')
  ->fields(array(
    'entity_type' => 'node',
    'bundle' => 'event',
    'entity_id'=>$row,
    'revision_id'=>$row,
    'language'=>'und',
    'delta'=>0,
    'field_other_tid'=>196,
  ))
  ->execute();
db_insert('field_revision_field_SOMENAME')
  ->fields(array(
    'entity_type' => 'node',
    'bundle' => 'event',
    'entity_id'=>$row,
    'revision_id'=>$row,
    'language'=>'und',
    'delta'=>0,
    'field_other_tid'=>196,
  ))
    ->execute();
  }
}

How to Migrate large data eg 100k or more into drupal 7 smoothly ?

Data migration... huuuh..Always a tedious job and specially for large data.Traditional programmer follow many protocols to do correct data migration to drupal . Many things need to take care like number of batch record to be migrate , manual concentration of each batches,php time out and many more. So the best solution we could follow a batch_process ,Drush  with queue API.

  I had quite a bit of data to work with so I had to utilize the batch API. The Batch API allows you to run one or more method on to a large set of data without worrying about PHP timeouts and can provide feedback on the progress of the operation. I had created a module to handle the updating and importing of the library data. To create the batch queue you must build an array for batch_set();

function mymodule_setup_batch($start=1, $stop=100000) {
  //  ...
  //  Populate $lots_of_data from record $start to record $stop.
  //  ...
 
  //Break up all of our data so each process does not time out.
  $chunks = array_chunk($lots_of_data, 20);
  $operations = array();
  $count_chunks = count($chunks);
 
  //for every chunk, assign some method to run on that chunk of data
  foreach ($chunks as $chunk) {
    $i++;
    $operations[] = array("mymodule_method_to_work_on_a_small_part", array( $chunk ,'details'=> t('(Importing chunk @chunk  of  @count)', array('@chunk '=>$i, '@count'=>$count_chunks))));
    $operations[] = array("mymodule_another_method",array($chunk));
  }
 
  //put all that information into our batch array
  $batch = array(
    'operations' => $operations,
    'title' => t('Import batch'),
    'init_message' => t('Initializing'),
    'error_message' => t('An error occurred'),
    'finished' => 'mymodule_finished_method'
  );
 
  //Get the batch process all ready!
  batch_set($batch);
  $batch =& batch_get();
 
  //Because we are doing this on the back-end, we set progressive to false.
  $batch['progressive'] = FALSE;
 
  //Start processing the batch operations.
  drush_backend_batch_process();
}
You'll also have to write what our operation methods will do. Each of these will be called with the parameters we set up earlier. In this case both methods will work on the same data, one right after the other.
function mymodule_method_to_work_on_a_small_part ($chunk, $operation_details, &$context) {
  //Do something to $chunk, maybe create a node?
  $context['message'] = $operation_details; //Will show what chunk we're on.
}
function mymodule_another_method($chunk, &$context) {
  //Do some more work.
  $context['message'] = t('We have done a second thing to a chunk of data');
}
We also need to code the method that is called when it is finished:
function mymodule_finished_method($success, $results, $operations) {
  //Let the user know we have finished!
  print t('Finished importing!');
}

Drushing data

I have always enjoyed the use of Drush, but I have never created my own Drush commands. It turns out, it is a very easy process. I decided to go ahead and make an import command, so I could start the batch process off and import a section of the entire dataset from the terminal. I placed the above code into a file mymodule.drush.inc and created the following methods:
function mymodule_drush_command() {
  $items  = array();
  $items['myimport'] = array(
    'callback'    => 'mymodule_setup_batch',
    'description' => dt('Import'),
    'arguments'   => array(
      'start'     => "start",
      'stop'      => "stop",
    ),
  );
  return $items;
}
 
function mymodule_drush_help($section) {
  switch ($section) {
    case 'drush:myimport':
      return dt("import items from the Internal Database [start record] [end record].");
  }
}

Friday, September 11, 2015

How to increase performance of high traffic drupal website


Followings are the steps to increase the performance of drupal websites

How to build custom entity in drupal ?

For a traditional php/zend/codeignitor  programmer the logic behind developing any stuff is to create db tables with some form , save these content into db table and show these data on view parsing through controller .
How to do this custom module / programming stuff in drupal ?
Let us take entity api example step by step


Entities are a great way to organize your data in Drupal. If you are familiar with nodes, taxonomy terms, comments or users, you should also know that since Drupal 7, these have been entities. Another important aspect about them is that they are fieldable via the Field API.
In this tutorial I will show you how you can define your own custom entity type and get started working with it. Why would one want to do this instead of using nodes? Because although they are great, nodes can sometimes be overkill. There is a lot of functionality you may not need such as revisions or commenting.
For example we will define our own custom entity type called Insurance to represent simple information we have about our projects (title, price and deadline)(title,price,tenaure ). Then we will look at a few things about working with the entities of this type.
  dditionally, you need the Entity API contrib module enabled on your site and set as a dependency to your custom module. The Entity API module is very powerful when working with entities as it provides a lot of functionality that the Drupal core lacks.

Defining our own Drupal entity type

The first thing we need to do to create a new entity type is to declare its schema definition. That is, write the code that will generate the database table for the entity data. In my demo.install file I have the following code:
/**
 * Implements hook_schema().
 */
function demo_schema() {

  $schema = array();

  $schema['demo_insurance'] = array(
    'description' => 'The base table for the Project entity',
    'fields' => array(
      'id' => array(
        'description' => 'Primary key of the Project entity',
        'type' => 'serial',
        'unsigned' => TRUE,
        'not null' => TRUE,
      ),
      'name' => array(
        'description' => 'Policy name.',
        'type' => 'varchar',
        'length' => 255,
        'not null' => FALSE,
      ),
      'price' => array(
        'description' => 'Insurance price.',
        'type' => 'text',
        'size' => 'big',
        'not null' => FALSE,
        'default' => NULL
      ),
      'tanure' => array(
        'description' => 'Insurance tanure.',
        'type' => 'int',
        'length' => 11,
        'not null' => FALSE,
      ),
    ),
    'primary key' => array('id'),
  );

  return $schema;
}
This is a simple implementation of hook_schema() through which we create a demo_projects table that has 4 columns: id, name, description and deadline, the first representing the primary key. Nothing big.
The next thing we need to do is implement hook_entity_info(). There are a lot of options we can specify in this hook, but here are the most basic and required ones (this goes in the demo.module file):
/**
 * Implements hook_entity_info().
 */
function demo_entity_info() {

  $info = array();

  $info['insurance'] = array(
    'label' => t('insurance'),
    'base table' => 'demo_insurance',
    'entity keys' => array(
      'id' => 'id',
      'label' => 'name',
    ),
    'module' => 'demo',
  );

  return $info;
}
With this hook we return a new key in the $info array that represents the entity machine name. Inside this array we specify the options (we will add more in the course of this tutorial). For now, we will stick tolabel (human readable name of the entity type), base table that stores the entity data, entity keyswhich are the properties that act as identifiers for the entities and module that specifies which module defines the entity type. The last one is not mandatory but recommended.
And with this we have registered our own basic entity type with Drupal. To test out if it works, enable the module for the first time and check if the table was created in the database. Then populate it with a few rows to have something to work with:
INSERT INTO `demo_insurance` (`id`, `name`, `price`, `tanure`)
VALUES
    (1, 'Summer House', '10000', '120m'),
    (2, 'Winter House', '25000', '60m');
Finally, register a path with Drupal (any path for testing only) using hook_menu() and paste the following in its callback function:
$projects = entity_load('insurance', array(1, 2));
dpm($projects);
return 'Some string';
First, we use the entity_load() function to load the project entities with the IDs of 1 and 2 and then we print them to the screen using the Devel dpm() function (so make sure Devel is enabled on your site for testing). And don’t forget that the callback function for the page needs to return something otherwise it won’t build.
Now if you navigate to that page you’ll see in Krumo the data from the 2 entities in the database.
Alternatively, you can use the EntityFieldQuery class to query for the new entities by any property you want (not just the id). For more information about how this works you can check out this Sitepoint tutorialthat will get you started.

Entity class and controller

Unfortunately, Drupal core does not come with too many helper functions to work with entities (entity_load() is pretty much the only one). However, the Entity API module fills this gap.
In order to make use of its functionality, we need to alter the entity info we declared earlier and specify the PHP classes that can be used to work with the entities. For now, we’ll add 2 more keys to the array keyedproject inside our hook_entity_info() declaration:
...

'entity class' => 'Entity',
'controller class' => 'EntityAPIController',

...
The first one is the base class provided by Entity API that will offer some wrapping functionality for the entities. This class is declared in the entity.inc file of the module and if you look inside, you’ll notice that many of its methods call the methods of another (controller) class. This is the class we specified for the controller class key.
The EntityAPIController class (found in entity.controller.inc file of the module) offers some sensible defaults for working with the entities. It extends the default Drupal coreDrupalDefaultEntityController class and it is responsible – among many other things – for performing CRUD operations.
Both of these classes can be extended in your custom module to adjust functionality (like querying, loading or displaying the entities). We will see how to do this in a minute.
But first, I want to show you how to save a new entity. Currently, in my database I have 2 records with the ids 1 and 2. I want to adjust the code we wrote in the test page callback above to create a new entity with the id of 3 if one doesn’t already exist. It can look something like this:
 $projects = entity_load('insurance', array(1, 2, 3));

 if (!isset($projects[3])) {
   $entity = entity_create('insurance', array('id' => 3));
   $entity->name = t('accidental policy');
   $entity->price= t('5000');
$entity->tanure= t('60m');
$entity->save(); } dpm($projects); return 'Some string';
As you can see, now we try to load 3 project entities and check for the existence of the third. If it doesn’t exist, we use the entity_create() helper function provided by Entity API, set the properties to some random values and then use the save() method on the entity to persist it to the database. This method is provided by the Entity class and its job is to call the save() method on the controller class we defined above. And that method will perform the logic necessary to persist the entity. But all this happens behind the scenes and we don’t have to worry about it.
If you reload that page, you should see only 2 returned project entities, but if loaded a second time, there should be 3.

Overriding the entity classes

The last thing I want to show you in this part of the tutorial is how to display your entities. For this, we will stick to the page callback function we’ve been working with and have it render a list of our entities.
The first thing we need to do is override the buildContent() method of the defaultEntityAPIController class. The reason is that the controller cannot make assumptions about our data so we need to provide some information about how to display it. First, let’s declare our controller class that extends the previous one:
/**
 * Extending the EntityAPIController for the Project entity.
 */
class ProjectEntityController extends EntityAPIController {

}
I chose the class name ProjectEntityController and you need to make sure that you replace with this name the value you set for the controller class key in the hook_entity_info()implementation. Don’t forget.
Inside of this class, we can copy the method name from the original one and have it return the same its parent would:
public function buildContent($entity, $view_mode = 'full', $langcode = NULL, $content = array()) {

$build = parent::buildContent($entity, $view_mode, $langcode, $content);

// Our additions to the $build render array

return $build;

}
As such, there are no new changes. But now we can add our own data to the returned value of this method which is nothing more than a Drupal render array. So for example we can write this right before we return the $build array:
$build['price'] = array(
  '#type' => 'markup',
  '#markup' => check_plain($entity->description),
  '#prefix' => '<div class="project-description">',
  '#suffix' => '</div>',
);
$build['tanure'] = array(
  '#type' => 'markup',
  '#markup' => date('d F, Y', check_plain($entity->deadline)),
  '#prefix' => '<p>Deadline: ',
  '#suffix' => '</p>',
);
We are basically adding two new items to the array. The first one will wrap the description with a<div class="project-description"> and the second will output a formatted date in between paragraph tags. This is basic Drupal theming so brush up on that if you don’t understand what’s going on here. But you will notice that the project name is missing. That will be rendered automatically by Drupal because we specified it as the label in the entity keys of the hook_entity_info() implementation.
The final step is to go to our page callback function and make it display our entities. A quick way of doing that (just for demonstration purposes):
$projects = entity_load('project', array(1, 2, 3));

$list = entity_view('project', $projects);

$output = array();

foreach ($list['project'] as $project) {
  $output[] = drupal_render($project);
}

return implode($output);
As before, we first load our entities with the respective ids. Then, we run them through theentity_view() helper function that will end up calling the buildContent() method we just overrode. This function returns a list of render arrays for each entity. We render each one and store the result in the$output array that we then implode and return.
You can refresh the page and you should see a listing of all the entities you loaded. Make sure you clear the caches so that the changes become visible.

  Welcome back to the second part of this tutorial in which we explore the world of custom entities in Drupal. If you haven’t already, I strongly recommend you read the first installment, but let’s do a short recap nonetheless.

In the previous article we’ve defined the schema for our entity type and registered it with Drupal. We’ve also overridden the EntityAPIController to build up the display for our entities.
In this part of the tutorial we will continue and talk about a few other cool things we can do with entities in Drupal. First, we’ll quickly set up the pages where we can display the individual project entities. Next, we will build a straightforward but very powerful admin interface to manage them. Then, we will make our entity type fieldable so we can add fields through the UI. And finally, we’ll expose it to Views so we can create proper listings of project entities.
If you want, you can follow along with the source code from the first branch of the Git repository, or take a peek into the second branch which contains all the code we will cover today.

Individual entity pages

The first thing we’ll do is create the pages for displaying individual project entities. We’ll start by adding a new item to our hook_menu() implementation:
  $items['project/%'] = array(
    'title' => 'Project',
    'page callback' => 'demo_view_project',
    'page arguments' => array(1),
    'access arguments' => array('access content'),
  );
We are registering a path (project/id) and a callback function (demo_view_project()) to which we pass the wildcard URL argument (the ID of the project). As for access, anybody with theaccess content permission can see the page.
Next, let’s write the said callback function (keep in mind this is a simple example just for demonstration purposes):
/**
 * Callback function for displaying the individual project page
 */
function demo_view_project($id) {

  $projects = entity_load('project', array($id));
  $project = $projects[$id];

  drupal_set_title($project->name);
  $output = entity_view('project', array($project));

  return $output;

}
This is again very simple: we load the entity with the ID passed from the URL, we set the title of the page, run the entity object through entity_view() and return it as page output. We’ve covered these Entity API concepts last time when we listed our projects. You can now clear the cache and navigate toproject/1 and you should see the project with the ID of 1. If you see the project name twice, don’t worry, this will become clear in the next section when we let Drupal know which one is the default URI callback for the project entities.

Admin user interface

Now that we can display the individual entities, let’s leverage the power of the Entity API module to set up a quick admin user interface to manage them. There are a few simple steps we need to take for this.
First, let’s edit our hook_entity_info() implementation for our entity type and add the following (I’ll explain everything after):
...

'access callback' => 'demo_access_callback',
'uri callback' => 'entity_class_uri',
'admin ui' => array(
  'path' => 'admin/projects',
  'controller class' => 'EntityDefaultUIController',
),

...
And replace this line:
'entity class' => 'Entity',
With this:
'entity class' => 'ProjectEntity', 
With these modification, we do 4 things:
  1. We specify an access callback function for the entity type. We’ll need this for the admin UI and we’ll declare the callback function in a minute.
  2. We set the uri callback to the default one provided by the entity class (I will come back to this at point 4).
  3. We set the admin ui information: path to the UI page and the controller class that will handle it.EntityDefaultUIController is the default UI class that comes with Entity API and it is declared in the entity.ui.inc file.
  4. We change the name of the entity class for this entity type to one that does not exist yet. We will create it now by extending the previous one so that we can override its defaultUri() method:
    /**
     * Project entity class extending the Entity class
     */
    class ProjectEntity extends Entity {
    
      /**
       * Change the default URI from default/id to project/id
       */
      protected function defaultUri() {
        return array('path' => 'project/' . $this->identifier());
      }
    
    }
    
As you can see, we are basically changing that path to the individual project entity returned by this class method. When the time comes, I will point out why this was handy but this will be the default one I mentioned at point 2. Now let’s quickly also declare our access callback function mentioned at point 1:
/**
 * Access callback for project entities.
 */
function demo_access_callback($op, $project = NULL, $account = NULL) {
  if ($op == 'view' || $op == 'update' || $op == 'create' || $op == 'delete') {
    return TRUE;
  }
  else {
    return FALSE;
  }
}
As you can see, this is not much of an access callback function as it returns true for everything. Here you will normally perform proper access checks but for our demonstration purposes it works just fine.
Now there is one last thing we need to do to make use of our admin interface: declare a simple add/edit form for the project entity and its submit handler:
/**
 * Form definition for adding / editing a project.
 */
function project_form($form, &$form_state, $project = NULL) {

  $form['name'] = array(
    '#title' => t('Project name'),
    '#type' => 'textfield',
    '#default_value' => isset($project->name) ? $project->name : '',
    '#required' => TRUE,
  );

  $form['description'] = array(
    '#title' => t('Project description'),
    '#type' => 'textarea',
    '#default_value' => isset($project->description) ? $project->description : '',
    '#required' => TRUE,
  );

  $form['deadline'] = array(
    '#title' => t('Project deadline'),
    '#type' => 'textfield',
    '#default_value' => isset($project->deadline) ? $project->deadline : '',
    '#required' => TRUE,
  );  

  $form['submit'] = array(
    '#type' => 'submit', 
    '#value' => isset($project->id) ? t('Update project') : t('Save project'),
    '#weight' => 50,
  );

  return $form;
}

/**
 * Submit handler for the project add/edit form.
 */
function project_form_submit($form, &$form_state) {
  $project = entity_ui_form_submit_build_entity($form, $form_state);
  $project->save();
  drupal_set_message(t('The project: @name has been saved.', array('@name' => $project->name)));
  $form_state['redirect'] = 'admin/projects';
}

in this way we can create   entire different set of module with different table  and save data in it.