Pages

Tuesday, August 28, 2012

How does the emailing system (drupal_mail) work in Drupal 6?


Drupal uses a reasonably powerful mechanism to create, prepare and send emails generated within the system. We maintain two modules related to emails in Drupal - Mail Merge and MailQ (Mail Queue) - and get the opportunity to work with the mail subsystem in Drupal. Here is a brief write-up on how the mail system works in Drupal.
The workflow when sending a mail with drupal_mail
1) Module calls drupal_mail
drupal_mail($module, $key, $to, $language, $params = array(), $from = NULL, $send = TRUE)
The params array should have all the necessary information related to the mail that is to be sent. Do note that the mail is yet to be prepared and that will happen only during hook_mail calls.
2) drupal_mail then calls
2.a) hook_mail of the module calling drupal_mail
hook_mail is to be used by the module to copy parameters to $message.
The following parameters are already mapped back into $message from drupal_mail
  $message = array(
    'id'       => $module .'_'. $key,
    'to'       => $to,
    'from'     => isset($from) ? $from : $default_from,
    'language' => $language,
    'params'   => $params,
    'subject'  => '',
    'body'     => array()
  );
Drupal mail also sets the following as default headers
  $headers = array(
    'MIME-Version'              => '1.0',
    'Content-Type'              => 'text/plain; charset=UTF-8; format=flowed; delsp=yes',
    'Content-Transfer-Encoding' => '8Bit',
    'X-Mailer'                  => 'Drupal'
  );
If default_from is present it is used to set the following headers as well. default_from is either the site_mail if set or from php.ini sendmail_from parameter
  $headers['From'] = $headers['Sender'] = $headers['Return-Path'] = $headers['Errors-To'] = $default_from;
  $message['headers'] = $headers;
2.b) hook_mail_alter across all modules
Other modules can then alter $message as required via the hook_mail_alter call.
3) If $send parameter of drupal_mail is not set to FALSE drupal_mail will call drupal_mail_send
3.a) drupal_mail_send calls drupal_mail_wrapper($message) if smtp_library is set and the module is present. This is how the different modules like mimemail or smtp mail hooks into the mailing system in Drupal.
drupal_mail_wrapper is expected to send out the mail and if smpt_library is not set then drupal_mail_sendwill try to send out the mail using the php mail function.
How MailQ works in Drupal by plugging into drupal_mail
MailQ is a module designed to allow drupal sites hosted on shared hosting servers distribute the email loads on the system across time to work around the hourly email limits typically set by the hosting providers.
MailQ is designed to catch all mails sent by drupal by setting up a drupal_mail_wrapper which will queue all mails during non-cron regular site operations and which will send them out during cron runs. MailQ sets the smtp_library to itself forcing drupal_mail_send to call the drupal_mail_wrapper from mailq during normal operations. Mailq drupal_mail_wrapper will then store all the messages into the database queue and then process these in batches during cron runs by calling drupal_mail_send

How to add dynamic login / logout link to your primary menu


The Drupal Menu System handles both the navigational system (visible menus and links) as well as the Drupal callbacks in the back end. The menu links listed on the header of a Drupal site is normally the primary menu or the secondary menu. These menus are sets of static links that you create via the Drupal admin interface. However sometimes it is useful to have a login / logout link in the primary or the secondary menu depending on whether the user is logged out or logged in. Here is how you add this.
Add the following piece of code to your preprocess_page hook in your module (modulename_preprocess_page()) or in your theme template.php (themename_preprocess_page())
  if ($user->uid != 0) {
    $new_links['account-link'] = array(
      'attributes' => array('title' => 'Account link'), 
      'href' => 'user', 
      'title' => 'My Account'
    );
    $new_links['logout-link'] = array(
      'attributes' => array('title' => 'Logout link'), 
      'href' => 'logout', 
      'title' => 'Logout'
    );
  } else {
    $new_links['login-link'] = array(
      'attributes' => array('title' => 'Login link'), 
      'href' => 'user', 
      'title' => 'Login'
    );
  }
  $vars['secondary_links'] = array_merge_recursive($vars['secondary_links'], $new_links);

The above snippet will add a 'My Account' and a 'Logout' link for logged in users and 'Login' link for anonymous users to the secondary_links. If instead you wanted to add the links to your primary links you can replace the last line with
  $vars['primary_links'] = array_merge_recursive($vars['primary_links'], $new_links);

You will also have to make sure that none of the caching mechanisms set up on your site caches this across roles.

How to create a custom view in Drupal 7


By default Drupal 7 has two types of views - The Full node view and the Teaser view. This has been the case for all previous versions of Drupal. However if your requirements are different, then you might have to create a custom view that is tailored to meet your specific needs. Check out how to create a simple custom “View mode” for nodes in Drupal 7.
Step1: Create a custom module
Step2: Create an additional view mode -’Grid Pane’ by simply implementing hook_entity_info_alter() in our custom module.
/** 
* Implements hook_entity_info_alter().
*/
function CustomModule_entity_info_alter(&$entity_info) {
  $entity_info['node']['view modes']['grid_pane'] = array(
    'label' => t('Grid Pane'),
    'custom settings' => TRUE,
  );
}
Step3: Now apply some theme and custom layout for the content. We can add a custom node.tpl.php template for this view mode for flexible theming and use standard hook_preprocess_node() function to control the variables available in the template.
To make Drupal use a different .tpl.php file for view mode we need to add a new template suggestion in hook_preprocess_node (). Copy the standard node.tpl.php for the content type you need and name it like “node--article--grid_pane.tpl.php”.
/**
* Implements hook_preprocess_node().
*/
function tdbcustom_preprocess_node(&$vars) {
  /*dpm(entity_get_info());*/
  if($vars['view_mode'] == 'grid_pane') {
    $vars['theme_hook_suggestions'][] = 'node__' . $vars['type'] . '__grid_pane';
  }
}
Step4: Install the custom module and we are done. Once we create a new view mode, we can go to Admin->Structure->content types->[Manage Display] page and select which fields to display format and additional options for fields, like which image style to use for image fields etc. For example:
Drupal

How to create a related content (nodes) view block in Drupal 7


Are you looking to create a block of nodes related to one of the taxonomy terms in your current node? Just take an easy way to get this done on your Drupal site.
For Drupal 7, follow these steps:
  1. Create a custom content type for nodes eg:mobile. Add fields (title, a small image, date, whatever you like).Set one field for taxonomy term reference.
  2. Add vocabulary terms in to taxonomy.
  3. Create a view for related content(nodes) as a block.
  4. Add the fields (whatever you like) which has to be displayed in the related content block.
  5. Filter criteria :
    • Set the content type mobile
    • Set the content which is to be published
    • Set the taxonomy word. (Add taxonomy terms in the taxonomy manager ) Add the filter: "Content: Has taxonomy term ID".
  6. Pager: Set the no of nodes.
  7. Create a custom module block for showing the view. Steps for creating a custom module:
    • Create a folder in sites/all/modules folder - name the folder eg:my_module
    • Creating my_module.info files to provide Drupal with module information Add this code into .info files :
      name = my_module
      description = This is a demo module for the Drupal
      core = 7.x
      files[] = my_module.module
      
      
    • Creating my_module.module files to store Drupal code
      /*
      ** Implementation of hook_block_info()
      */
      
       function my_module_block_info() {
         $blocks['related_custom_block'] = array(
        'info' => t('Related content'),
        'cache' => DRUPAL_NO_CACHE,
        );
       return $blocks;
       }
      
      
      /*
      ** Implementation of hook_block_view()
      */
      
       function my_module_block_view($delta = '') {
       $block = array();
       switch ($delta) {
         case 'related_custom_block':
           $block['subject'] = t('Related content');
           if (arg(0) == 'node' && arg(1) != '') {
             $node = node_load(arg(1));
             if ($node->type == 'content_type') {
       //content_type please write your content type name
               $array_term = array();
               foreach($node->field_taxonomy_category['und'] AS $key => $value) { 
      // write your taxonomy term machine name instead of 'field_taxonomy_category'
                $array_term[] = $value['tid'];
               }
               $view = views_get_view('you_might_also_like'); 
      //write your view name
               $display_id = 'block';
               $view->set_display($display_id);
               $filter = $view->get_item($display_id, 'filter', 'field_taxonomy_category_tid');
      // write your taxonomy term machine name instead of 'field_taxonomy_category_tid'
               $filter['value'] = $array_term;
               $view->set_item($display_id, 'filter', 'field_taxonomy_category_tid', $filter);
      // write your taxonomy term machine name instead of 'field_taxonomy_category_tid'
               $viewsoutput = $view->render();
               $block['content'] = $viewsoutput;
             }
             else {
               $block['content'] = '';
             }
           }
           else {
             $block['content'] = '';
           }    
         break;
      }
       return $block;
      }
      
      
  8. Enable the custom module my_module .
  9. Save the view .
  10. Go to block listing .
  11. Assign the block into the region, and you are done.