PHP, MySQL, Drupal, .htaccess, Robots.txt, Phponwebsites: 2016

21 Oct 2016

Add date pop-up calendar in custom drupal 7 form

     This blog describes how to add date pop-up calender to a custom form in the Drupal 7.

Use date pop-up calendar in custom form - drupal 7


     The use case is if you want to use date pop-up calendar in a custom form, then how you can do it in the drupal 7. Actually, the drupal 7 form API provides lots of form types like textfield, checkbox, checkboxes etc to create a custom form. Similarly, the date module  also provides the form type called date_popup. We can use it in the custom form in order to display the date pop-up in the custom form.

Use date pop-up calendar with the custom form in drupal 7:


   Let consider the below code snippet:

 
function phponwebsites_menu() {
  $items = array();

  $items['customform'] = array(
    'title' => t('Custom Form'),
    'type' => MENU_CALLBACK,
    'page callback' => 'drupal_get_form',
    'page arguments' => array('phponwebsites_display_date_popup_form'),
    'access callback' => TRUE,
  );

  return $items;
}

function phponwebsites_display_date_popup_form($form, &$form_state) {
  $form['date'] = array(
    '#type' => 'date_popup',
    '#default_value' => date('Y-m-d'),
    '#date_format'   => 'Y-m-d',
    '#date_year_range' => '0:+5',
    '#datepicker_options' => array('minDate' => 0, 'maxDate' => 0),
  );

  return $form;
}

    Where,
      '#date_format'   => 'Y-m-d' if you need to display only date
      '#date_format'   => 'Y-m-d H:i:s' if you need to display date & time
      '#date_year_range' => '0:+5' if you need to display only future 5 years
      '#datepicker_options' => array('minDate' => 0, 'maxDate' => 0) if you want to display only current date. We can hide the future & past dates using this option.

   Please add the above code into your module file and look into the "customform" page. It looks like the below image:

Display only current date in date -pop-up - drupal 7


   Now I've hope you know how to add date pop-up calendar with custom form in the drupal 7.

7 Oct 2016

Disable future dates in date popup - Drupal 7

     This blog describes how to disable future dates in the Drupal 7. One of the features in the date  module is displayed the date in the pop-up.

Disable future dates in the date pop up - drupal 7


The use case is if you want to display only past & current date rather than all the dates in the pop-up, then how to do it in Drupal 7. Actually, the date module provides API called hook_date_popup_process_alter to alter the date_popup widget elements.

Example for disabling future dates in Drupal 7:


   For instance, I am going to disable future dates in the article content type. Please consider the following code snippet.

/**
 * Implement hook_date_popup_process_alter().
 */
function phponwebsites_date_popup_process_alter(&$element, &$form_state, &$context) {

  if ($form_state['complete form']['#form_id'] == 'article_node_form' && $element['#field']['field_name'] == 'field_date') {
    $max = 0;
  }

  if (isset($element['#datepicker_options']['maxDate'])) {
    $max = $element['#datepicker_options']['maxDate'];
  }

  if (isset($max)) {
    $element['#datepicker_options'] = array(
      'maxDate' => "+$max D",
    );
  }
  $element['date'] = date_popup_process_date_part($element);
}

   I've disabled the dates only if the form is article & the field name is field_date. After added the above code to your module, you could see disabled future dates in the date pop up. It looks like the below image:


Disable future dates in the date pop-up in drupal 7


   Now I've hope you know how to disable the future dates at the date module in Drupal 7.


2 Aug 2016

Multiple URL alias for a node in pathauto - drupal 7

   As we discussed in my previous post, clean URL is one of the option to improve SEO. We've module called pathauto to clean URLs in drupal 7. It can allow us to set alias for content types, files, users & taxonomies. But we can set only one URL alias for a content type in drupal 7. You can set URL alias for a content type at admin/config/search/path/patterns. It looks like below image:


Pathauto module patterns in drupal 7


   Suppose you need two path for a content. For instance, the URL alias for a article need to node title and also article/node-title. Is it possible to set multiple path alias for a content type in drupal 7? Yes it is possible in drupal 7. We can set multiple URL alias for a conten type programmatically using pathauto module in drupal 7. We need to insert our path alias into the "url_alias" table while inserting & updating a node and remove path alias When delete a node.

Add URL alias programmatically when insert and update a node using pathauto module in drupal 7:


    For instance, I've choosen article content type. We need to insert & update a URL alias into the "url_alias" table using hook_node_insert() & hook_node_update() in drupal 7.


/**
 * Implements hook_node_insert()
 */
function phponwebsites_node_insert($node) {
  if ($node->type == 'article') {
    //save node alias
    _phponwebsites_insert_update_alias($node);
  }
}

/**
 * Implements hook_node_update()
 */
function phponwebsites_node_update($node) {
  if ($node->type == 'article') {
    //update node alias
    _phponwebsites_insert_update_alias($node);
  }
}

/**
 * Insert and update alias for course
 */
function _phponwebsites_insert_update_alias($node) {
  module_load_include('inc', 'pathauto');
  $title = pathauto_cleanstring($node->title);

  $values['source'] = 'node/' . $node->nid . '/article';
  $values['alias'] = 'article/' . $title;

  $all_values = array($values);

  foreach ($all_values as $all) {
    $query = db_merge('url_alias')
      ->fields(array('source' => $all['source'], 'alias' => $all['alias'], 'language' => LANGUAGE_NONE))
      ->key(array('source' => $all['source']))
      ->execute();
  }
}



Where,
 pathauto_cleanstring is obey the pathatuo module's rules which is mentioned at admin/config/search/path/settings. To know more details of pathauto_cleanstring, please visit http://www.drupalcontrib.org/api/drupal/contributions!pathauto!pathauto.inc/function/pathauto_cleanstring/7

After added the above code into your custome module(clear cache), you will create a article. You just test your url at admin/config/search/path in the pathauto's list. It looks like below image:


Pathauto module URL alias list in drupal 7


Now you could access the article by both node-title as well as article/node-title.


Multiple URL alias for a node using pathauto module in drupal 7



Delete URL alias programmatically when delete a node using pathauto module in drupal 7:


     We've inserted 2 URL alias for a node. So we need to delete those from "url_alias" table when delete a node. We can trigger it using hook_node_delete() in drupal 7. Consider the below code:



/**
 * Implements hook_node_delete()
 */
function arep_node_delete($node) {
  if ($node->type == 'article') {
    //delete node alias for ceu and non-ceu course
    module_load_include('inc', 'pathauto');
    $source[0] = 'node/' . $node->nid . '/article';

    foreach ($source as $s) {
      $path = path_load(
        array('source' => $s)
      );
      path_delete($path['pid']);
    }

  }
}


Where,
  path_load returns the details of a URL alias like source, alias, path id  & language. To know more details of path_load(), please visit https://api.drupal.org/api/drupal/includes!path.inc/function/path_load/7.x.

After added the above code into your customer module(clear cache), you will delete a node and check your URL alias at admin/config/search/path. Now tt should not be displayed here.

Now I've hope you know how to set multiple URL alias for a content type.


27 Jul 2016

Pathauto added special characters in url alias - drupal 7

    To improve SEO, we need to clean our URLs. By default in drupal, we've an option called clean URLs at the configuration. In drupal 7, we can also manage the URLs. For instance, you have a content type called services. You wanted to each service page have url like services/page-name. To do that, we've a pathauto module in drupal 7. The pathauto module allow us to manage the URLs for every content types, files, taxonomy & users and also we can remove some unnecessary words from URL like an, the and so on.

   The pathauto module can remove some unnecessary words like a, an, the and so on & also remove special characters like !, @, $ and so on. Unfortunately, it doesn't included some other symbols like copyright(©), trademark(™), registered(®) and so on. But it provide a hook to add new symbols into the punctuation settings called hook_pathauto_punctuation_chars_alter. After created a content with some symbols which are represented above, your page URL looks like below image:


Drupal 7 - remove special characters from url using pathauto module



/**
 * Implements hook_pathauto_punctuation_chars_alter().
 */
function phponwebsites_pathauto_punctuation_chars_alter(array &$punctuation) {
  $punctuation['copyright']          = array('value' => '©', 'name' => t('Copyright'));
  $punctuation['registered']         = array('value' => '®', 'name' => t('Registered trademark'));
  $punctuation['trademark']          = array('value' => '™', 'name' => t('Trademark'));
}

   After implemented above code into your module, you cold see added symbols are listing on Pathauto module's settings page at /admin/config/search/path/settings. If You didn't get these symbols, clear cache & test it again. It looks like below image:


Drupal 7 - pathauto settings after hook_pathauto_punctuation_chars_alter


Now you can create a content with those symbols. The pathauto module didn't added those symbols into the URL.

Now I hope you know how to remove some special characters from URL alias using pathauto module in drupal 7.

28 Jun 2016

PHP get particular key value from multidimensional array

You can get specific key from multidimensional array using any one of the below methods:

  1. Get Specific key value form multidimensional array using array_column:


     The array_column() returns the values from a single column in the input array. It works only from PHP version 5.5. You've a multidimentional array with details of user name and country. You tried to get the name of every array from multidimentional array. Consider the following exampale:

  <?php

    $array = array(
      0 => array(
        'name' => 'Guru',
        'country' => 'India'
      ),
      1 => array(
        'name' => 'Clark',
        'country' => 'USA'
      ),
      2 => array(
        'name' => 'Smith',
        'country' => 'United Kingdom'
      ),
      3 => array(
        'name' => 'John',
        'country' => 'USA'
      ),
    );

    $namesArray = array_column($array, 'name');
    print_r($namesArray);exit;

    When you run this program in the browser, you will get the output like below one:

    Array ( [0] => Guru [1] => Clark [2] => Smith [3] => John )

    For more details about array_coulmn, visit http://php.net/manual/en/function.array-column.php.

  2. Get Specific key value form multidimensional array using array_map:


    The array_map() applies the callback to the elements of the given arrays. It works from PHP version 4.0.6. The array_map() is alternate of array_column() in PHP

  <?php
    $namesArray = array_map(function($arr){
        return $arr['name'];
      }, $array);
    print_r($namesArray);exit;

    It will give same output as array_column. For more details about array_map, visit http://php.net/manual/en/function.array-map.php.

  3. Get Specific key value form multidimensional array using foreach loop:


  <?php
  $namesArray = array();
  foreach($array as $key => $val) {
    $namesArray[] =  $val['name'];
  }
  print_r($namesArray);exit;

  It will also give sample output as array_coulmn & array_map.

  Now I've hope you know how to get particular key value from multidimensional array in PHP.

Releated Articles:

28 Apr 2016

Create a node programmatially in Drupal 7

      This blog describes about how to create a new node programmatically in Drupal 7. If you want to add a new node, you can done at node/add by default. In Drupal, you can also add a node programmatically. Let see the below code.

<?php
// create object
  $node = new stdClass();
  // set title for a node
  $node->title = t('Created node programmatically');
  // set node type
  $node->type = 'article';
  // set node language
  $node->language = LANGUAGE_NONE;
  // set value to node body
  $node->body[LANGUAGE_NONE][0]['value'] = t('This node has been created programmatically in Drupal 7');
  // set value to node body summary
  //$node->body[LANGUAGE_NONE][0]['summary'] = text_summary(t('This node has been created programmatically in Drupal 7'));
  // set node body format like plain_text, filtered_html, full_html
  $node->body[LANGUAGE_NONE][0]['format'] = 'filtered_html';
  node_object_prepare($node);
  // author for a node
  $node->uid = 1;
  // status of node  0 - unpublished, 1 - published
  $node->status = 1;
  // promoted to front page or not
  $node->promote = 0;
  // sitcky at top of tha page
  $node->sticky = 0;
  // comments 0 - hidden, 1 - closed, 2 - opened
  $node->comment = 1;

  // add term
  $node->field_tags[$node->language][]['tid'] = 1;

  // get the file path
  $file_path = drupal_get_path('module', 'phponwebsites') . '/Desert.jpg';
  // create file object
  $file = (object) array(
    'uid' => 1,
    'uri' => $file_path,
    'filemime' => file_get_mimetype($file_path),
    'status' => 1,
  );
  // Save the file to the public directory. You can specify a subdirectory, for example, 'public://images'
  $file = file_copy($file, 'public://');
  // assign the file object into image field
  $node->field_image[LANGUAGE_NONE][0] = (array)$file;
  // Prepare node for a submit
  $node = node_submit($node);
  //save the node
  node_save($node);


    After ran this code, you can see newly created node at admin/content. When you view that node, it looks like below image:

Create a new node programmatially in Drupal 7 at Phponwebsites


     Now I’ve hope you know how to create a new node programmatically in Drupal 7.

21 Apr 2016

Redirect users after login in Drupal 7

    This blog describes about how to redirect users after logged into a site in Drupal 7. By default, Drupal redirects users to user page after logged into a site.  Suppose you want to redirect users into any other pages as you want. Then you can done that in Drupal 7.
  You can redirect users after login in Drupal using the following two ways:
1. Redirect users after logged into a site using hook_user_login()
2. Redirect users after logged into a site using custom form submit

Redirect users after form submit in Drupal 7

Redirect users after logged into a site using hook_user_login:


     Drupal provides hook called hook_user_login to make changes while user login successfully. Let see the below code.

/**
 * Implement hook_user_login()
 */
function phponwebsites_user_login(&$form, &$form_state) {
 //add page here to where you want redirect users after login
  $form['redirect'] = '<front>';
}

    Now you can check whether you redirect to front page or not after login. Now  Drupal will be redirect you to front page.

Redirect users after logged into a site using custom form submit:


   Drupal have alternate method to redirect users after login. Ie, You need to add custom form submit handler to a form using hook_form_alter(). Then add a page to redirect users in that custom form submit handler in Drupal 7. Let see the below code.


/**
 * Implement hook_form_alter().
 */
function phponwebsites_form_alter(&$form, &$form_state, $form_id) {
  if ($form_id == "user_login" || $form_id == "user_login_block") {
    $form['#submit'][] = 'phponwebsites_custom_login_submit';
  }
}  
function phponwebsites_custom_login_submit(&$form, &$form_state) {
  //page to be redirect
  $form['redirect'] = '<front>';
}


Now you will be redirect to front page after logged into a drupal site. Now I’ve hope you should know how to redirect users after logged into a site in Drupal 7.

19 Apr 2016

Create page without header and footer in Drupal 7

    This blog describes about create only page contents without header and footer in Drupal 7. All of you know almost all of the pages in Drupal have header and footer. Suppose you want to create a page without header and footer in Drupal 7. Is it possible? Yes, it is possible in Drupal 7. You can create a page without header and footer using 'delivery callback' in hook_menu.

Render a page without header and footer in Drupal 7:


     Drupal provide a option to create page without header and footer. Let see the below code for render a page without header and footer in Drupal 7.

/**
 * Implement hook_menu().
 */
function phponwebsites_menu() {
  $items['sample-wo-header-footer'] = array(
    'title' => 'A page without header and footer in Drupal 7',
    'access callback' => TRUE,
    'page callback' => 'phponwebsites_without_header_footer',
    'type' => MENU_CALLBACK,
    'delivery callback' => 'deliver_plain',
  );
  return $items;
}

function deliver_plain($page_callback_result) {
  print $page_callback_result;
}

/**
 * Implement phponwebsites_without_header_footer().
 */
function phponwebsites_without_header_footer() {
  return 'This is the page without header and footer';
}


   You could see the page without any header and footer when you view page in a browser. Now I've hope you how to render a page without header and footer in Drupal 7.

16 Apr 2016

Clear views cache when insert, update and delete a node in Drupal 7

This blog describes how to clear views cache while inserting, updating and deleting a node in Drupal 7. If we want to improve site performance, then views caching is one of the options.

   For example, you have views which display list of records. It will update occasionally. Then we can render views data from cache rather than server if we set cache for views. We can set views cache at its settings page. Suppose you have cached views for 5 mins. Then it didn't display updated data until 5 mins even if new node is added to that views. It displays updated data only after 5 mins because the views is cached for 5 mins. In that situation, the user can't view new data in cached views. So we need to clear views cache when add , update and delete a node. So only we can see new data in views and also data is rendered from cache.

Clear views cahce when insert, update and delete a node in drupal 7


Clear views cache when insert a new node in Drupal 7:

   The newly added node has not been displayed in views list if the cache is applied to a views. So we need to clear views cache when insert a new node using hook_node_insert(). Lets see the code for clear views cache while inserting a node:

 <?php
 /**
  * Imeplement hook_node_insert().
  */
 function phponwebsites_node_insert($node) {
   if ($node->type == 'tasks') {
     //clear views cache
     $viewsname = 'activity';
     cache_clear_all($viewsname, 'cache_views_data', TRUE);
   }
 }

Clear views cache when update a node in Drupal 7:

   When you tried to update a node, the updated data in that node has not been displayed in views. So we need to clear views cache when update a node using hook_node_update(). Lets see the code for clear views cache while updating a node:

 <?php
 /**
  * Imeplement hook_node_update().
  */
 function phponwebsites_node_update($node) {
   if ($node->type == 'article') {
     //clear views cache
     $viewsname = 'articles';
     cache_clear_all($viewsname, 'cache_views_data', TRUE);
   }
 }

Clear views cache when delete a node in Drupal 7:

   After delete a node, you could see the deleted node is displayed in the views. So we need to clear views when delete a node using hook_node_delete(). Lets see the code for clear views cache while deleting a node:

 <?php
 /**
  * Imeplement hook_node_delete().
  */
 function phponwebsites_node_delete($node) {
   if ($node->type == 'article') {
     //clear views cache
     $viewsname = 'articles';
     cache_clear_all($viewsname, 'cache_views_data', TRUE);
   }
 }

   You can see the performance of views page will be increased and you can see changes in your views. Now I've hope you know how to clear views cache when insert, update and delete a node in Drupal 7.

15 Apr 2016

Login using email and username in Drupal 7

   This blog describes about how to login using both email and username in Drupal 7. All of you know we could login using only username in Drupal 7.

Login using mail address and usename in Drupal 7


       I've tried to login using email without any contrib modules. Finally i got the code. First alter form to add custom form validation. In custom form validation, get the name from user table by email and set that value into name field in form.  Let see the code:

<?php
/**
 * Implement hook_form_alter().
 */
function phponwebsites_form_alter(&$form, &$form_state, $form_id) {

  if ($form_id == "user_login" || $form_id == "user_login_block") {
    $form['name']['#title'] = t('Username or E-mail Address');
    // Ensure a valid validate array.
    $form['#validate'] = is_array($form['#validate']) ? $form['#validate'] : array();
    // login using username or email address
    array_unshift($form['#validate'],'phponwebsites_user_login_validate');
  }
}

 /**
 * Implement phponwebsites_user_login_validate()
 *
 * Return name by its email address
 */
function phponwebsites_user_login_validate($form, &$form_state) {
  if (isset($form_state['values']['name']) && strpos($form_state['values']['name'], '@') !== false) {
      $name = db_query("SELECT name FROM {users} WHERE LOWER(mail) = LOWER(:name)", array(':name' => $form_state['values']['name']))->fetchField();
    }
  if (isset($name)) {
    form_set_value($form['name'], $name, $form_state);
  }
}

   Now you can login using both username and email. I've hope you know how to login using both username and email in Drupal 7.

10 Jan 2016

Drupal 7 – Hide Promoted to front page & Sticky at top of lists options

    This blog describes how to hide "Promoted to front page" and "Sticky at top of lists" options from node form in drupal 7. When adding or editing a node, you can see "Publishing options" at bottom of the page which contains 'Published', 'Promoted to front page' and 'Sticky at top of lists' checkbox options. It should look like below image:

Promoted to front page & Sticky at top of lists in Drupal 7

       The "Published" option is used to publish the content. The "Promoted to front page" option is used to display content in the front page. The 'Sticky at top of lists' option is used to keep the content sticked to the top of front page. If you don't want to show "Promoted to front page" and "Sticky at top of lists" options, then you can hide those options using hook_form_alter(), hook_form_FORM_ID_alter() and hook_form_BASE_FORM_ID_alter().

Hide Promoted to front page & Sticky at top of lists options in single node form:


       If you want to hide "Promoted to front page" and "Sticky at top of lists" options only in single node form, then you can remove those options from node form using either hook_form_alter() or hook_form_FORM_ID_alter() in drupal 7.  For example, we go to hide those options from article node form.

/**
 * Implement hook_form_alter().
 */
function phponwebsites_form_alter(&$form, &$form_state, $form_id) {
  // to hide promoted to front page option
  if (isset($form['options']['promote'])) {
    $form['options']['promote']['#access'] = FALSE;
  }

  // to hide sticky at top of lists option
  if (isset($form['options']['sticky'])) {
    $form['options']['sticky']['#access'] = FALSE;
  }
}

     Now you go to article node form and check whether "Promoted to front page" and "Sticky at top of lists" options are hidden or not. You couldn’t see those options in article node form. It should look like below image:

Hide Promoted to front page & Sticky at top of lists in drupal 7

Hide Promoted to front page & Sticky at top of lists options in multiple node forms:


     If you want to hide "Promoted to front page" and "Sticky at top of lists" options in all node forms, then you can remove those options using  hook_form_BASE_FORM_ID_alter() in drupal 7.

/**
 * Implement hook_form_BASE_FORM_ID_alter().
 */
function phponwebsites_form_node_form_alter(&$form, &$form_state, $form_id) {
  // to hide promoted to front page option
  if (isset($form['options']['promote'])) {
    $form['options']['promote']['#access'] = FALSE;
  }

  // to hide sticky at top of lists option
  if (isset($form['options']['sticky'])) {
    $form['options']['sticky']['#access'] = FALSE;
  }
}

     Now you could not see those options in all node forms. Now you know how to hide "Promoted to front page" and "Sticky at top of lists" options from node form in drupal 7.