أكواد دروبال سريعة

كتابات: 


Drupal code snippets you can use it when you doing custom code. Some of these codes is just for testing purposes since it may affect your website performance.
http://maps.google.com/maps?&z=14&q=24.789072,46.635504&ll=24.789072,46.635504
ET: 0x980EB9Bcd7fC3b7880EdACD8B73D726b4ae5FE75 Z: znjRHe5kpYCUxVWbbJTHzQFMH97xQC5xHVU
https://www.google.com/maps/place/24.827073,46.613617/@24.827073,46.613617,17z
https://moz.com/ugc/everything-you-never-wanted-to-know-about-google-maps-parameters
https://api.slack.com/custom-integrations/legacy-tokens
Calculate location region with point Polygon http://assemblysys.com/php-point-in-polygon-algorithm/
/* maintenance-page styling */
body.maintenance-page #page{width:480px;background:#f7f7f7;margin:27px auto;padding:12px;text-align:center;
  border:1px solid #e7e7e7;border-radius:12px;}
body.maintenance-page #page a{text-decoration:none;font-weight:bold;}
body.maintenance-page #logo img{max-width:300px}
// Starting plain Drupal script.
define('DRUPAL_ROOT', getcwd());
include_once DRUPAL_ROOT . '/includes/bootstrap.inc';
drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
http://nmc-codes.blogspot.com/2012/07/how-to-create-custom-ubercart-payment.html
https://stackoverflow.com/questions/10675711/what-is-the-hook-for-successful-payment-in-ubercart-3-x-for-drupal-7
https://www.drupal.org/node/1669968
http://api.ubercart.me/api/drupal/ubercart%21uc_order%21uc_order.api.php/function/hook_uc_order/7
// CSS LTR numbers in Arabic pages.
unicode-bidi: embed; direction: ltr;

  // Fix Drupal jQuery sign dollar conflict.
( function($) {
  'use strict';

  // Keep the jQuery code with sign dollar here inside this.

})(jQuery);

// Language switcher invoke.
$block = module_invoke('locale', 'block_view', 'language');
$block = module_invoke('search', 'block_view', 'search');
print $block['content'];
print render($block['content']);

// Invoke custom block.
$my_block_name = module_invoke('custom', 'block_view', 'my_block_name');
print render($my_block_name['content']);
// Print view in templates.
print views_embed_view('users', 'block_1');
            // Set default value for MVF field.
            $form['field_price']['und'][0]['#items'][0]['value'] = 122;
            $form['field_price']['und'][0]['#items'][0]['target_id'] = 157;
// Page tpl for specific node type.
function THEME_preprocess_page(&$variables) {
  if (isset($variables['node']->type)) {
    $variables['theme_hook_suggestions'][] = 'page__' . $variables['node']->type;
  }
}
// Discard unsaved view.
Clear cache won't help. Just signout then signin again.

// FieldQuery to get order by custom field.
  $query = new EntityFieldQuery;
  $query->entityCondition('entity_type', 'uc_order', '=')
    ->fieldCondition('field_contract_reference', 'target_id', '160', '=')
    ->range(0, 1);

  // Drupal GET query parameters.
  drupal_get_query_parameters();

  // Load user data by custom field using Field Query.
  $query = new EntityFieldQuery();
  $query->entityCondition('entity_type', 'user')
    ->propertyCondition('status', 1)
    ->fieldCondition('field_mobile_number', 'value', '050505', '=');
  $result = $query->execute();

        // Generate thumb style image automatically to prepare it for first request.
        image_style_create_derivative(image_style_load('100x100'), $fileData->uri, image_style_path('100x100', $fileData->uri));

  // Load all users from specific user role.
  $role = user_role_load_by_name($role_name);
  $query = 'SELECT ur.uid
    FROM {users_roles} AS ur
    WHERE ur.rid = :rid';
  $result = db_query($query, array(':rid' => $role->rid));
  $uids = $result->fetchCol();
  $users = user_load_multiple($uids);

  // Create node programmatically.
  $node = new stdClass();
  $node->type = 'page';
  node_object_prepare($node);
  $node->language = LANGUAGE_NONE;
  $node->title = 'Test page';
  $node->body['und'][0]['value'] = 'The test';
  $node->uid = 1;
  $node->status = 1;
  node_submit($node);
  node_save($node);

  // Create taxonomy term programmatically.
  $term = new stdClass();
  $term->name = 'NAME';
  $term->description = 'DESCRIPTION';
  $term->vid = taxonomy_vocabulary_machine_name_load('VOCABULARY')->vid;
  //$term->parent = 0;
  taxonomy_term_save($term);

  // Form vertical tabs.
  $form['mysite_settings'] = array(
    '#type' => 'vertical_tabs',
  );

  $form['myvar_settings_fieldset'] = array(
    '#type' => 'fieldset',
    '#title' => t('Website main info'),
    '#weight' => 1,
    '#group' => 'mysite_settings',
    '#collapsible' => TRUE,
    '#collapsed' => FALSE,
  );

  $form['myvar_settings_fieldset']['website_tilte'] = array(
    '#type' => 'textfield',
    '#title' => t('Website title'),
    '#default_value' => variable_get('website_tilte',''),
   //'#required' => TRUE,
  ); 

  // Upload and save file from $_FILES.
  if(isset($_FILES['file']['tmp_name'])){
    // Rebuild FILES to suite file_save_upload() needs.
    $_FILES['files']['tmp_name']['file'] = $_FILES['file']['tmp_name'];
    $_FILES['files']['name']['file'] = $_FILES['file']['name'];
    $_FILES['files']['size']['file'] = $_FILES['file']['size'];
    $_FILES['files']['error']['file'] = $_FILES['file']['error'];

    // Handle file uploads.
    $validators = array('file_validate_is_image' => array());

    // Check for a new uploaded logo.
    $fileData = file_save_upload('file', $validators, 'public://', FILE_EXISTS_RENAME);
    if (isset($fileData)) {
      // Move the file, into the Drupal file system
      if ($fileData = file_move($fileData, 'public://', FILE_EXISTS_RENAME)) {
        // Generate thumb style image.
        image_style_create_derivative(image_style_load('100x100'), $fileData->uri, image_style_path('100x100', $fileData->uri));

        // Add thumb size.
        $fileData->thumb = image_style_url('100x100', $fileData->uri);
        return $fileData;
      }else{
        return 'ERROR';
      }
    }else{
      return 'ERROR';
    }

  }else{
    return NULL;
  }

  // Create taxonomy vocabulary text field programmatically.
   $field = array(
      'field_name' => 'field_NAME',
      'type' => 'text',
      'label' => t('FIELD NAME')
    );
    field_create_field($field);
    // Attach the field to our taxonomy entity
    $field_instance = array(
        'field_name' => 'field_NAME',
        'entity_type' => 'taxonomy_term',
        'bundle' => 'VOCABULARY_NAME',
        'label' => t('FIELD NAME'),
        'description' => t('This field just for test.'),
        'required' => false,
        'widget' => array(
          'type' => 'text_textfield',
          'weight' => 3
        )
    );
    field_create_instance($field_instance);

// Changing a field type from Integer to Decimal
// Source: http://drupal.stackexchange.com/a/151367/24113

// Change this to your field name, obvs.
$field = 'field_myfieldname';

// Update the storage tables
$tables = array('field_data', 'field_revision');
foreach ($tables as $table) {
  $tablename = $table .'_'. $field;
  $fieldname = $field .'_value';
  db_change_field($tablename, $fieldname, $fieldname, array(
    'type' => 'numeric',
    'precision' => 10,
    'scale' => 2,
    'not null' => FALSE,
  ));
}

// Fetch the current field configuration
$field_config = db_query("SELECT data FROM {field_config} WHERE field_name = :field_name", array(
    ':field_name' => $field,
  ))
  ->fetchObject();
$data = unserialize($field_config->data);

// Update the settings entry
$data['settings'] = array(
  'precision' => 10,
  'scale' => 2,
  'decimal_separator' => '.',
);

// Store the new field config, update the field type at the same time
db_update('field_config')
  ->fields(array(
    'data' => serialize($data),
    'type' => 'number_decimal',
  ))
  ->condition('field_name', $field)
  ->execute();    

// If you are confident about what bundles have instances of this field you can
// go straight to the db_query with a hardcoded entity_type / bundle.
$instances = field_info_field_map();
foreach ($instances[$field]['bundles'] as $entity_type => $bundles) {
  foreach ($bundles as $bundle) {

    // Fetch the field instance data
    $field_config_instance = db_query("SELECT data FROM {field_config_instance}
                                       WHERE field_name = :field_name
                                       AND entity_type = :entity_type
                                       AND bundle = :bundle", array(
        ':field_name' => $field,
        ':entity_type' => $entity_type,
        ':bundle' => $bundle,
      ))
      ->fetchObject();
    $data = unserialize($field_config_instance->data);

    // Update it with the new display type
    $data['display']['default']['type'] = 'number_decimal';

    // Store it back to the database
    db_update('field_config_instance')
      ->fields(array('data' => serialize($data)))
      ->condition('field_name', $field)
      ->condition('entity_type', $entity_type)
      ->condition('bundle', $bundle)
      ->execute();

  }
}

 20161223
// Redirect user after register
function custom_user_register_form($form, &$form_state) {
  $form_state['redirect'] = 'user/intro';
}

// Use custom page.tpl for specific content type.
// And the new template will be page--type-page.tpl.php
function CUSTOM_preprocess_page(&$vars) {
  if($vars['node']->type == 'page'){
    $vars['theme_hook_suggestions'][] = 'page__type_'.$vars['node']->type.'';
  }
}

// Add classes to submit button of sepcific form.
// Source: http://drupal.stackexchange.com/questions/4008/how-do-i-alter-the-submission-button-class
function mymodule_form_alter(&$form, &$form_state, $form_id) {
  if ($form_id = 'my_form') {
    $form['actions']['submit']['#attributes']['class'][] = 'form-submitone';
  }
}

// Render node.
// Source: http://stackoverflow.com/questions/8564265/render-a-drupal-node
$nid = 739;
$nodeview = node_view(node_load($nid));
print drupal_render($nodeview);

  // Drupal enable service resource programmatically for existing endpoint.
  $endpoint = services_endpoint_load('ENDPOINT_NAME');
  $endpoint->resources['RESOURCE_NAME']['operations']['index']['enabled'] = 1;
  services_endpoint_save($endpoint);

/**
 * Alter views output.
 */
function HOOK_services_views_execute_view_alter(&$output, $view) {
  if ($view->name == 'test') {
    $paged_output = array(
      'results' => $output,
      'total_rows' => $view->total_rows,
    );
    $output = $paged_output;
  }
}

/**
 * Implements hook_views_query_alter().
 */
function custom_ad_views_query_alter(&$view, &$query) {
  // STILL NEED TO BE REVIEWED.
  $view->exposed_input['field_CUSTOM'] = 'TEST';
  $view->exposed_data['field_CUSTOM'] = 'TEST';
}

    // Drupal ubercart Save address extra field programmatically using module 
    // Extra Fields Checkout Pane ( uc_extra_fields_pane ) 
    // Since hook_ucxf_field is not work very well when $op = insert or update .. 
    // so you can handle that using this code:
    // $address_fields = UCXF_FieldList::getAllAddressFields();
    $order = uc_order_load(385);
    $fields = UCXF_FieldList::getFieldsFromPane('extra_delivery');
    uc_extra_fields_pane_value_save(
      array(
        'element_id' => $order->order_id,
        'element_type' => UCXF_Value::UCXF_VALUE_ORDER_BILLING,
        'field_id' => $fields['ucxf_FIELDNAME']->field_id,
        'value' => 'VALUE_HERE',
      )
    );

// Alter and override field value before display.
// Altering displayed value using Drupal hook.
/**
 * Implements hook_field_attach_view_alter().
 */
function HOOK_field_attach_view_alter(&$output, $context) {
  if ($context['entity_type'] == 'profile2') {
	if( isset($output['field_NAME']) ){
	  $output['field_NAME'][0]['#title'] = 'NEW_VALUE';
	}
  }

  if (isset($context['entity_type']) && ($context['entity_type'] == 'node') && isset($context['entity']) && isset($context['entity']->type) && ($context['entity']->type == 'CONTENT_TYPE') ) {
    if( isset($context['entity']->field_NAME['und']) ){
      // $context['entity']->field_NAME['und'][0]['value'] = 'NEW_VALUE1';
      // $output['field_NAME']['#object']->field_NAME['und'][0]['value'] = 'NEW_VALUE2';
      // $output['field_NAME']['#items'][0]['value'] = 'NEW_VALUE3';
      $output['field_NAME'][0]['#markup'] = 'NEW_VALUE';
    }
  }
}

  // Save new value in field collection.
  // field_YOUR_FIELD_COLLECTION = Your field collection name.
  // field_SUB_FIELD_ONE = the field collection element.
  // field_SUB_FIELD_TWO = the field collection element.

  // Prepare field collection entity array.
  $MY_COLLECTION = array();
  $MY_COLLECTION['field_name'] = 'field_YOUR_FIELD_COLLECTION';
  $MY_COLLECTION['field_SUB_FIELD_ONE'][LANGUAGE_NONE][0]['value'] = '';
  $MY_COLLECTION['field_SUB_FIELD_TWO'][LANGUAGE_NONE][0]['value'] = '';

  // Get the needful node
  $node = node_load(111);

  // Create this entity
  $MY_entity = entity_create('field_collection_item', $MY_COLLECTION);
  $MY_entity->setHostEntity('node', $node); // If node use this line.
  $MY_entity->setHostEntity('user', $user); // If user use this line.
  $MY_entity->save(); 

  // You can repeat this part if your field collection has unlimited values.

  // -------------------

  // Update field collection value by field collection id.
  $field_MY_COLLECTION = field_collection_item_load($node->field_MY_COLLECTION['und'][0]['value']);
  $field_MY_COLLECTION->field_SUB_COLLECTION['und'][0]['value'] = 'NEW_VALUE';
  $field_MY_COLLECTION->save(TRUE);

  // -------------------

  // Delete field collection values. source: https://www.drupal.org/node/2684165
  foreach ($node->[FIELD_NAME][LANGUAGE_NONE] as $key => $value) {
    // Build array of field collection values.
    $field_collection_item_values[] = $value['value'];
    // Unset them.  
    unset($node->[FIELD_NAME][LANGUAGE_NONE][$key]);
  }
  // Delete field collection items.
  entity_delete_multiple('field_collection_item', $field_collection_item_values);

  // 20170210
  function template_preprocess_node(&$variables) {
    $variables['submitted'] = t('Submitted by !username on !datetime', array('!username' => $variables['name'], '!datetime' => $variables['date']));
  }

  // OR change date type.
  if( isset($variables['node']->created) ){
    $created_date = format_date($variables['node']->created, 'custom', 'F d, Y');
    $variables['submitted'] = t('Submitted by !username on !datetime', array('!username' => $variables['name'], '!datetime' => $created_date));
  }

  // OR in tpl file.

  // 20170211
  // Get theme logo from theme settings.
  global $theme_key;
  $theme_logo_url = theme_get_setting('logo', $theme_key);

// 20170214
// Get taxonomy terms by vocabulary name.
$vocab = taxonomy_vocabulary_machine_name_load('cities');
$terms = taxonomy_get_tree($vocab->vid);
foreach($terms as $term){
  $termData = taxonomy_term_load($term->tid);
}

  // 20170214
  // Get all terms from specific vocabulary by taxonomy custom field.
  $vocab = taxonomy_vocabulary_machine_name_load('VOCABULARY_NAME');
  $query = new EntityFieldQuery();
  $query->entityCondition('entity_type', 'taxonomy_term')
     ->propertyCondition('vid', $vocab->vid)
     ->fieldCondition('field_custom', 'value', 'AAAA', '=');
  $result = $query->execute();
  foreach ($result['taxonomy_term'] as $val) {
    $term = taxonomy_term_load($val->tid);
  }

  // If the field is multi-value.
  ->fieldCondition('field_custom', 'value', array('new'), 'IN');
  // Iif you need all results except 'new'.
  // You should try yourself then tell me please :)

  // Getting nodes between period from custom field.
  $first_day = date('Y-m-d 00:00:01', (time() - (86400*2) ) );
  $last_day =  date("Y-m-d 00:00:01", (time() - (86400*4) ) );
  $query = new EntityFieldQuery();
  $query->entityCondition('entity_type', 'node')
            ->entityCondition('bundle', 'CONTENT_TYPE')
            ->fieldCondition('field_CUSTOM', 'value', array($first_day, $last_day), 'BETWEEN');
  $result = $query->execute();

  // 20170218
  // Get all system users.
  $query = db_select('users', 'u');
  $query->fields('u', array('uid'))->condition('uid', 0, '>');
  $result = $query->execute();
  while($record = $result->fetchAssoc()) {
    $thisUser = user_load($record['uid'], TRUE);
  }

  // 20170220
  // Useful Drupal things.
function custom_menu_alter(&$items) {
  $items['node/add']['access callback'] = FALSE;
}

  // 20170301
  // DB query to get specific field value from database.
  $uid = db_select('users', 'u')
      ->fields('u', array('uid'))
      ->condition('name', $form_state['values']['user'])
      ->execute()
      ->fetchField();
  print $uid;

  // 20170316
  // Update field settings programmatically.
  // To be used in hook_update_N.
  $instance_info = field_info_instance('node', 'field_NAME', 'CONTENT_TYPE_NAME');
  print_r($instance_info); // Print to see the structure.
  $instance_info['description'] = 'DESCRIPTION';
  field_update_instance($instance_info);

// 20170321
/**
 * Get view result count.
 */
function custom_get_view_result_count($view_name, $view_display, $args = array(), $items_per_page = 0, $offset = 0){
  // Source: https://api.drupal.org/comment/46928#comment-46928
  $view = views_get_view($view_name);
  $view->set_display($view_display);
  $view->set_arguments($args);
  $view->set_items_per_page($items_per_page);
  // change the amount of items to show
  //$view->set_items_per_page(4);
  $view->set_offset($offset);
  $view->pre_execute();
  $view->execute();
  return count($view->result);

  // Print pager programmatically.
  $category_products_count = custom_get_view('product_blocks', 'category_products', array($term->tid));
  $category_products_count = count($category_products_count->result);
  pager_default_initialize($category_products_count, $results_per_page, $element = 0);
  print theme('pager');
}

/**
 * Get view result.
 */
function custom_get_view_result($view_name, $view_display, $args = array(), $items_per_page = 0){
  // Source: https://api.drupal.org/comment/46928#comment-46928
  $view = views_get_view($view_name);
  $view->set_display($view_display);
  $view->set_arguments($args);
  $view->set_items_per_page($items_per_page);
  // change the amount of items to show
  //$view->set_items_per_page(4);
  $view->pre_execute();
  $view->execute();
  return $view->result;
}

  // Drush check if database connection is working or not.
  drush sqlq --db-prefix "SELECT uid FROM {users} WHERE uid=1"

  // check drush status with verbose and debug parameters.
  drush -vd status

// 20170327
// Helper function to create block programmatically.
/**
 * Programmatically creates block.
 * This function is helpful in automated process.
 */
function custom_create_block($attributes) {

  // Defaults
  $defaults = array(
    'title'      => '',
    'desc'       => '',
    'body'       => '',
    'format'     => 'filtered_html',
    'visibility' => 0,
    'pages'      => '', // path
    'custom'     => 0,
    'module'     => 'block',
    'roles'      => array(),
    'regions'    => array(),
  );
 
  // Attributes
  $attr = array(
    'title' => (isset($attributes['title']))?$attributes['title']:$defaults['title'],
    'desc' => (isset($attributes['desc']))?$attributes['desc']:$defaults['desc'],
    'body' => (isset($attributes['body']))?$attributes['body']:$defaults['body'],
    'format' => (isset($attributes['format']))?$attributes['format']:$defaults['format'],
    'visibility' => (isset($attributes['visibility']))?$attributes['visibility']:$defaults['visibility'],
    'pages' => (isset($attributes['pages']))?$attributes['pages']:$defaults['pages'],
    'custom' => (isset($attributes['custom']))?$attributes['custom']:$defaults['custom'],
    'module' => (isset($attributes['module']))?$attributes['module']:$defaults['module'],
    'roles' => (isset($attributes['roles']))?$attributes['roles']:$defaults['roles'],
    'regions' => (isset($attributes['regions']))?$attributes['regions']:$defaults['regions'],
  );
 
  // load the function
  module_load_include('inc', "block", "block.admin");
 
  // make believe variable
  $form_state = array();
 
  // Fill variable
  $form_state['values']['title']          = $attr['title'];
  $form_state['values']['info']           = $attr['desc'];
  $form_state['values']['body']['value']  = $attr['body'];
  $form_state['values']['body']['format'] = $attr['format'];
  $form_state['values']['visibility']     = $attr['visibility'];
  $form_state['values']['pages']          = $attr['pages'];
  $form_state['values']['custom']         = $attr['custom'];
  $form_state['values']['roles']          = $attr['roles'];
  $form_state['values']['module']         = $attr['module'];
  $form_state['values']['regions']        = $attr['regions'];
 
  // Create block
  block_add_block_form_submit(array(), $form_state);

}

  // Use:
  // Create block and assign it to Footer region.
  custom_create_block(array(
    'title' => 'TEST TITLE',
    'desc' => 'BLOCK DESCRIPTION',
    'body' => 'BODY TEXT.',
    'format' => 'plain_text',
    'regions' => array('THEME_NAME'=>'footer'),
  ));

  // Theme table pagination.
  // This will paginate all results you have.
  $header = array(
    'name' => array('data' => t('Name')),
    'date' => array('data' => t('Date')),
  );

  $rows = array();
  $rows[0]['name'] = 'Ahmad';
  $rows[0]['date'] = '2017';
  $rows[1]['name'] = 'Ibrahim';
  $rows[1]['name'] = '2016';

  // Initialize pager.
  $results_count = count($rows); // You can get this from query if results stored in your database.
  $per_page = 50;
  $current_page = pager_default_initialize($results_count, $per_page);

  // Split your list into page sized chunks.
  $chunks = array_chunk($rows, $per_page, TRUE);

  // Show the appropriate items from the list.
  $output = theme('table', array('header' => $header, 'rows' => $chunks[$current_page]));

  // Show the pager.
  $output .= theme('pager', array('quantity', $results_count));

  print $output;

// 20170407
// Retrieve last nid inserted by user in last 30 seconds.
$uid = $user->uid;
$content_type = 'article';
$interval_seconds = 30;
$nid = db_query("SELECT nid AS count FROM {node} WHERE uid = :uid AND type = :type AND created > :created ORDER BY nid DESC",
        array(':uid' => $uid, ':type'=>$content_type, ':created'=>(time() - $interval_seconds) ))->fetchField();
print 'NID:'.$nid;

// 20170407
// Count directly from node table using db query.
$the_count = db_query("SELECT COUNT(nid) AS count FROM {node} WHERE uid = :uid", array(':uid' => $uid))->fetchField();
// Count directly from taxonomy table using db query.
$the_count = db_query("SELECT COUNT(nid) AS count FROM {taxonomy_index} WHERE tid = :tid", array(':tid' => $tid))->fetchField();

// 20170407
// Limit depth level of Simple hierarchical select shs contrib module by using hook_shs_term_get_children_alter(). 
function HOOK_shs_term_get_children_alter(&$terms, &$alter_options) {
  if($alter_options['parent'] == 2){
    $terms = FALSE;
  }
}

// 20170407
// Alter view and change filter value if has no more than 2 parents.
function HOOK_views_pre_view(&$view) {
  if ($view->name === 'taxonomy_references'){
    $view_filters = $view->display_handler->get_option('filters');
    //$view_filters['parent']['value'] = $view_filters['parent']['value'];
    if(isset($view->args) && isset($view->args[0])){
      $parents_count = count(taxonomy_get_parents_all($view->args[0]));
      if($parents_count > 2){
        $view_filters['parent']['value'] = $view_filters['parent']['value'];
      }else{
	$view_filters['parent']['value'] = 0;
      }
    }

    $overrides = array();
    $overrides['filters'] = $view_filters;
    foreach ($overrides as $option => $definition) {
      $view->display_handler->override_option($option, $definition);
    }
  }
}

  // Source: http://www.drupaldump.com/view-3-alter-filters-programmatically

// 20170407
// Limit taxonomy deep level.
// CUSTOM_CONFIG
/**
 * Implement hook_form_FORM_ID_alter().
 */
function HOOK_form_product_node_form_alter(&$form, &$form_state, $form_id) {
  // Remove third and up depth levels.
  if( isset($form['field_NAME']) && is_array($form['field_NAME'][LANGUAGE_NONE]['#options']) ){
    foreach($form['field_NAME'][LANGUAGE_NONE]['#options'] as $index => $value){
      if(strstr($value, '---')){
        unset($form['field_NAME'][LANGUAGE_NONE]['#options'][$index]);
      }
    }
  }
}

// 20170407
// Get all term related nodes.
$alltermNodes = taxonomy_select_nodes($term->tid);
print_r($alltermNodes);
print count($alltermNodes);

// 20170409
// CUSTOM_CONFIG
// Delete all terms from a vocabulary (bulk delete).
// Source: http://drupal.stackexchange.com/questions/38275/how-to-delete-all-terms-from-a-vocabulary-bulk-delete
$vocabulary = taxonomy_vocabulary_machine_name_load('my_custom_vocabulary');
foreach (taxonomy_get_tree($vocabulary->vid) as $term) {
  taxonomy_term_delete($term->tid);
}

// 20170503
// Logout all users using drush command.
// Source: https://drupal.stackexchange.com/questions/21681/how-to-logout-all-active-users/97693#97693
// You can empty the sessions table using drush
drush sqlq "TRUNCATE sessions"

// or if you have set prefixes for table names:
drush sqlq --db-prefix "TRUNCATE {sessions}"

// 20170510
// Drupal cronjob for multisite.
// Source: https://www.drupal.org/docs/7/setting-up-cron/multisite-cron
* * * * * cd /srv/www/sites; drush @sites core-cron --yes

  // 20170516
  // Create taxonomy vocabulary programmatically.
  $NAME_vocab = (object) array(
     'name' => 'NAME OF VOCABULARY',
     'description' => 'THE DESCRIPTION',
     'machine_name' => 'MACHINE_NAME_OF_YOUR_VOCABULARY',
  );
  taxonomy_vocabulary_save($NAME_vocab);

  // Delete taxonomy vocabulary programmatically.
  $NAME_vocab = taxonomy_vocabulary_machine_name_load('MACHINE_NAME_OF_YOUR_VOCABULARY');
  taxonomy_vocabulary_delete($NAME_vocab->vid);

  // 20170610
 // Drupal change publishing options programmatically.
  // Change node type publish options programmatically.
  variable_set('node_options_CONTENTT_YPE_NAME', array('status', 'revision'));
  // Example: variable_set('node_options_page', array('status', 'promote', 'sticky', 'revision'));
  // Source: https://www.drupal.org/node/1169864

  // To handle revisions and other content type options.
  variable_set('node_options_CONTENTT_YPE_NAME', array('revision', 'revision_moderation'));
  variable_set('node_preview_CONTENTT_YPE_NAME', 0);
  variable_set('node_submitted_CONTENTT_YPE_NAME', 1);
  variable_set('revisioning_auto_publish_CONTENTT_YPE_NAME', 0);
  variable_set('new_revisions_CONTENTT_YPE_NAME', 0);

  // Change and set content type comments status programmatically.
  variable_set('comment_individual_profile', '0'); // Hidden.
  variable_set('comment_individual_profile', '1'); // Closed.
  variable_set('comment_individual_profile', '2'); // Open.

  // 20170611
  // Get file name from URL using Drupal way.
  $image_url = $category['image_path'];
  $parsed_image_url = drupal_parse_url($image_url);
  $parsed_image_url = $parsed_image_url['path'];
  $parsed_image_filename = basename($parsed_image_url);

  // 20170611
  // Save translated taxonomy term programmatically localized.
      $term = new stdClass();
      $term->name = 'ENGLISH NAME'; // English name should be here since English is the source language.
      $term->description = 'ENGLISH DESCRIPTION'; // English description should be here since English is the source language.
      $term->language = 'en';

      $term->name_field['ar'][0]['value'] = 'ARABIC NAME';
      $term->name_field['en'][0]['value'] = 'ENGLISH NAME';
      $term->description_field['ar'][0]['value'] = 'ARABIC DESCRIPTION';
      $term->description_field['en'][0]['value'] = 'ENGLISH DESCRIPTION';
      $term->vid = taxonomy_vocabulary_machine_name_load('VOCAB_NAME')->vid;
      taxonomy_term_save($term);

      // Apply translation for this term after we got tid.
      $al_term = taxonomy_term_load($term->tid);
      $al_term->translations = new stdClass();
      $al_term->translations->original = 'en';
      $al_term->translations->data = array();
      $al_term->translations->data['ar'] = array();
      $al_term->translations->data['ar']['entity_type'] = 'taxonomy_term';
      $al_term->translations->data['ar']['entity_id'] = $al_term->tid;
      $al_term->translations->data['ar']['language'] = 'ar';
      $al_term->translations->data['ar']['source'] = 'en';
      $al_term->translations->data['ar']['uid'] = variable_get('foodics_integration_user', 0);
      $al_term->translations->data['ar']['status'] = '1';
      $al_term->translations->data['ar']['translate'] = '0';
      $al_term->translations->data['ar']['created'] = time();
      $al_term->translations->data['ar']['changed'] = time();
      $al_term->translations->data['ar']['revision_id'] = $al_term->tid;

      $al_term->translations->data['en'] = array();
      $al_term->translations->data['en']['entity_type'] = 'taxonomy_term';
      $al_term->translations->data['en']['entity_id'] = $al_term->tid;
      $al_term->translations->data['en']['language'] = 'en';
      $al_term->translations->data['en']['source'] = '';
      $al_term->translations->data['en']['uid'] = variable_get('foodics_integration_user', 0);
      $al_term->translations->data['en']['status'] = '1';
      $al_term->translations->data['en']['translate'] = '0';
      $al_term->translations->data['en']['created'] = time();
      $al_term->translations->data['en']['changed'] = time();
      $al_term->translations->data['en']['revision_id'] = $al_term->tid;
      taxonomy_term_save($al_term);

  // 20170611
  // Save Drupal Ubercart attribute programmatically.
  $attribute = new stdClass();
  $attribute->name = 'Test Attribute';
  $attribute->label = 'Test Label';
  $attribute->description = 'Test Description';
  $attribute->display = 2; // Radio buttons. (0:Text field, 1:Select box, 2:Radio buttons, Checkboxes)
  $attribute->required = 0;
  $attribute->ordering = 0;
  uc_attribute_save($attribute);

  // 20170611
  // Create attribute option related to attribute in Ubercart.
  $attribute_option = new stdClass();
  $attribute_option->aid = 12; // Attribute ID.
  $attribute_option->name = 'OPTION NAME';
  $attribute_option->cost = 0;
  $attribute_option->price = 2; // Price
  $attribute_option->weight = 0;
  $attribute_option->ordering = 0;
  uc_attribute_option_save($attribute_option);

  // 20170614
  // Translate strings programmatically add string trnslated.
  // Source: http://dropbucket.org/node/323
$report = array(
  'skips'=>0,
  'updates'=>0,
  'deletes'=>0,
  'additions'=>0
);
$context = 'asd'; // attribute_names
$source = 'Test';
$textgroup = 'default'; // field , node, default, menu ...
$langcode = 'ar'; // Translation language.
$translation = 'تجربة'; // New translation
$mode = LOCALE_IMPORT_OVERWRITE; // LOCALE_IMPORT_KEEP
$location = ''; //  '/node/3', ...
_locale_import_one_string_db($report, $langcode, $context, $source, $translation, $textgroup, $location, $mode);

  // 20170619
  // Drupal 7 add relation between product and attribute.
  // This code snippet will help you to save drupal ubercart product with attribute programmatically.
  // Add relation between this attribute and this product.
  // Source inspired from Drupal 6 Code: http://jamestombs.co.uk/2010-10-27/programmatically-create-ubercart-products-with-attributes-and-selected-options-in-drupal-6/1314

  // This query should be performed after save product as node.
  // We will load the node and the attribute.
  $node = node_load(111);
  $attribute = uc_attribute_load(64);
              db_query("INSERT INTO {uc_product_attributes} (nid, aid, label, ordering, default_option, required, display) VALUES (:nid, :aid, :label, :ordering, :default_option, :required, :display)", 
                array(
                  ':nid' => $node->nid,
                  ':aid' => $attribute->aid,
                  ':label' => $attribute->name,
                  ':ordering' => $attribute->ordering,
                  ':default_option' => $attribute_default_option,
                  ':required' => $attribute->required,
                  ':display' => $attribute->display,
                ));

  // Also review the next snippet to relate attribute options.

  // 20170619
  // Please review previous snippet of saving attributes programmatically to load needful entities (node and attribute).
  // Save relation betwen product with attribute options programmatically.
                db_query("INSERT INTO {uc_product_options} (nid, oid, cost, price, weight, ordering) VALUES (:nid, :oid, :cost, :price, :weight, :ordering)", 
                  array(
                    ':nid' => $node->nid,
                    ':oid' => $attribute_option->oid,
                    ':cost' => $attribute_option->cost,
                    ':price' => $attribute_option->price,
                    ':weight' => $attribute_option->weight,
                    ':ordering' => $attribute_option->ordering,
                  ));

  // 20170712
  // Drupal services always return TRUE.
  // When you call services endpoint it is return array having true value while it should show the service real data result.
  // This mean your service resources is overriden. recreate the service again might help to fix this issue.

  // 20170715
  // Drupal save date field.
   $node->field_date[LANGUAGE_NONE][0] = array(
      'value' => '2015-02-02 00:00:00', // format_date(strtotime('now'), 'custom', 'Y-m-d H:i:s', 'Asia/Riyadh'),
      'timezone' => 'Asia/Riyadh',  
      'timezone_db' => 'Asia/Riyadh',
    );

  // 20170716
  // Revert feature programmatically.
  features_revert_module('FEATURE_MODULE_NAME');

  // 20170716
  // Delete field programmatically. Useful when revert feature to delete field.
  // Check if field exists.
  if (field_info_field('field_company_agent_mobile')) {
    // Delete field_company_agent_mobile.
    field_delete_field('field_company_agent_mobile');
  }

  // 20170723
  // Save password_policy programmatically policy password for Drupal contrib module.
  $policy['name'] = 'Test Name';
  $policy['description'] = 'Test Description';
  $policy['roles'] = array(2 => 2); // 2 = authenticated user.
  $policy['expiration'] = FALSE;
  $policy['warning'] = FALSE;
  $policy['weight'] = TRUE;
  $policy['enabled'] = TRUE;
  $policy['constraints'] = array();
  $policy['constraints']['alphanumeric'] = 1;
  $policy['constraints']['length'] = 8;
  password_policy_save_policy($policy);

  // 20170723
  // Replace title to title_field programmatically.
  if (title_field_replacement_toggle('node', 'CONTENT_TYPE_MACHINE_NAME', 'title')) {
    title_field_replacement_batch_set('node', 'CONTENT_TYPE_MACHINE_NAME', 'title');
  }

  // 20170718
  // Turn off bootstrap theme CDN.
  // before that make sure to add bootstrap js files in your sub theme folder.
  $theme_settings = variable_get('theme_SUBTHEMENAME_settings', array());
  $theme_settings['bootstrap_cdn_provider'] = '';
  variable_set('theme_SUBTHEMENAME_settings', $theme_settings);

  // things to put in theme.info file.
  stylesheets[all][] = css/bootstrap.min.css
  scripts[] = js/bootstrap.min.js

  // 20170726
  // Enable new language programmatically.

  // Enable this module since it will enable all dependencies for translations.
  module_enable(array('i18n_string'), TRUE);

  // Add Arabic language.
  $languages = language_list();
  if (!isset($languages['ar'])) {
    locale_add_language('ar'); // ar = Arabic language.
    $languages = language_list();
  }

  // Set Arabic as default language.
  variable_set('language_default', $languages['ar']); // ar = Arabic language.

  // Import translation file.
  $MYMODULE_path = drupal_get_path('module', 'YOUR_CUSTOM_MODULE_NAME');
  $po_file = $MYMODULE_path . '/translations/drupal-7.56.ar.po';
  $file = new stdClass();
  $file->uri = $po_file;
  $file->filename = basename($po_file);
  _locale_import_po($file, 'ar', LOCALE_IMPORT_OVERWRITE, 'default'); // ar = Arabic language.

  // Import our custom translation file.
  // @NOTE: It's very useful to use potx module to extract your custom module phrases.
  $MYMODULE_path = drupal_get_path('module', 'YOUR_CUSTOM_MODULE_NAME');
  $po_file = $MYMODULE_path . '/translations/custom.po';
  $file = new stdClass();
  $file->uri = $po_file;
  $file->filename = basename($po_file);
  _locale_import_po($file, 'ar', LOCALE_IMPORT_OVERWRITE, 'default'); // ar = Arabic language.

  // Enable language detection by URL.
  $negotation = array(
    LOCALE_LANGUAGE_NEGOTIATION_URL => 1,
    LANGUAGE_NEGOTIATION_DEFAULT => 5,
  );
  language_negotiation_set(LANGUAGE_TYPE_INTERFACE, $negotation);

  // Set English prefix.
  db_update('languages')
    ->fields(array('prefix' => 'en'))
    ->condition('language', 'en')
    ->execute();

  // Remove Arabic prefix.
  db_update('languages')
    ->fields(array('prefix' => ''))
    ->condition('language', 'ar')
    ->execute();

  // Clear all caches to update menu items.
  drupal_flush_all_caches();
  cache_clear_all('*', 'cache', TRUE);

  // We can clear only locale cache but since we should call for re-cache menus and another.
  // stuff it is recommended that we clear everything.
  cache_clear_all('locale:', 'cache', TRUE);

  // 20170730
  // Select unique fields for content type using entity_unique module.
  // Extracting all bundle fields to set entity unique fields for MYCONTENTTYPE.
  $entity_type = 'node';
  $bundle_name = 'MYCONTENTTYPE';
  $info = entity_get_info($entity_type);
  $property_info = entity_get_property_info($entity_type);
  $property_info = $property_info['properties'];
  $field_info = field_info_instances($entity_type, $bundle_name);
  $unwanted_properties = $info['entity keys'];
  // Entity label stays so we remowe it from unwanted array.
  unset($unwanted_properties['label']);
  $unwanted_properties += array(
    'is_new',
    'url',
    'edit_url',
    'log',
    'body',
    'revision',
    'source',
    'commerce_price',
    'description',
    'vocabulary',
  );
  $unwanted_fields = array('body', 'commerce_price');
  $correct_properties = array_diff(array_keys($property_info), $unwanted_properties);
  $correct_fields = array_diff(array_keys($field_info), $unwanted_fields);
  foreach ($correct_properties as $value) {
    $options[$value] = 0;
  }
  foreach ($correct_fields as $value) {
    $options[$value] = 0;
  }

  // Set the required fields for uniqueness.
  $options['field_MYCUSTOMFIELD'] = 'field_MYCUSTOMFIELD';
  $options['field_MYANOTHERCUSTOMFIELD'] = 'field_MYANOTHERCUSTOMFIELD';
  variable_set('entity_unique_advanced_node_MYCONTENTTYPE', $options);

  // 20170731
  // Disable views programmatically.
  // Disable no need view pages like revision and summary page.
  $content_revisions_view = views_get_view('revisioning_content_revisions_summary');
  $content_revisions_view->display['page']->display_options['enabled'] = FALSE;
  views_save_view($content_revisions_view);
  $content_summary_view = views_get_view('revisioning_content_summary');
  $content_summary_view->display['page_1']->display_options['enabled'] = FALSE;
  views_save_view($content_summary_view);

  // 20170801
  // Custom managed_file field in drupal custom form.
  $form['image'] = array(
    '#type' => 'managed_file',
    '#title' => t('picture'),
    '#description' => t('Allowed extensions: gif png jpg jpeg'),
    '#default_value' => (isset($form_state['values']['image']->fid) ? $form_state['values']['image']->fid : ''),
    '#upload_location' => 'public://',
    '#upload_validators' => array(
      'file_validate_extensions' => array('gif png jpg jpeg'),
      // Pass the maximum file size in bytes
      'file_validate_size' => array(MAX_FILE_SIZE * 1024 * 1024),
    ),
);

  // 20170801
  // When you use hook_init() make sure to consider these line of codes.
  // Make sure your code is not run when using cli (drush).
  // Make sure does not run when installing Drupal either.
  if (drupal_is_cli() || drupal_installation_attempted()) {
    return;
  }
  // Don't run when site is in maintenance mode
  if (variable_get('maintenance_mode', 0)) {
    return;
  }
  // Ignore non index.php requests (like cron)
  if (!empty($_SERVER['SCRIPT_FILENAME']) && realpath(DRUPAL_ROOT . '/index.php') != realpath($_SERVER['SCRIPT_FILENAME'])) {
    return;
  }

  // Maybe you would like to turn off caching.
  // turn caching off for this page as it is dependant on role.
  $GLOBALS['conf']['cache'] = FALSE;

  // Source: http://cgit.drupalcode.org/front/tree/front_page.module

  // 20170803
  // Drupal Form API state AJAX.
  // https://www.metaltoad.com/blog/drupal-7-form-api-using-states-multiple-conditionals-and-or-and-xor

  // 20170805
  // Drupal set mailsystem configurations programmatically
  // Check on mail_system value.
  $mail_system = variable_get('mail_system');
  if (isset($mail_system['default-system']) && ($mail_system['default-system'] == 'DefaultMailSystem')) {
    // Do something.
  }

  // Change mailsystem value programmatically
  $mail_system = variable_get('mail_system', array('default-system' => 'DefaultMailSystem'));
  $mail_system['default-system'] = 'DefaultMailSystem';
  variable_set('mail_system', $mail_system);

  // 20170805
  // Drupal ubercart create custom payment method.
  http://nmc-codes.blogspot.com/2012/07/how-to-create-custom-ubercart-payment.html

  // 20170805
  // Experment code to config Amazon s3 for backup_migrate module.
  // This code is not working just for testing.
/*
  $values_array = array();
  $values_array['host'] = 's3.amazonaws.com';
  $values_array['scheme'] = 'https';
  $values_array['path'] = 's3.example.com';
  $values_array['user'] = 'https'; // Access Key ID.
  $values_array['pass'] = 'https'; // Secret Access Key.
  $values_array['subdir'] = '';

  $record = $this->to_array();
  drupal_write_record($this->db_table, $record, !empty($this->storage) ? $this->get_primary_key() : array());
  exit;
    $params['subtype'] = $destination_type;
    return backup_migrate_crud_create_item('destination', $params);
*/
/*
$values_array = array();
$values_array['host'] = 's3.amazonaws.com';
$values_array['scheme'] = 'https';
$values_array['path'] = 's3.example.com';
$values_array['user'] = 'https'; // Access Key ID.
$values_array['pass'] = 'https'; // Secret Access Key.
$values_array['subdir'] = '';


    $form['scheme']['#type'] = 'value';
    $form['scheme']['#value'] = 'https';
    $form['host']['#type'] = 'value';
    $form['host']['#value'] = 's3.amazonaws.com';

    $form['path']['#title'] = 'S3 Bucket';
    $form['path']['#default_value'] = $this->get_bucket();
    $form['path']['#description'] = 'This bucket must already exist. It will not be created for you.';

    $form['user']['#title'] = 'Access Key ID';
    $form['pass']['#title'] = 'Secret Access Key';

    $form['subdir'] = array(
      '#type' => 'textfield',
      '#title' => t('Subdirectory'),
      '#default_value' => $this->get_subdir(),
      '#weight' => 25
    );
    $form['settings']['#weight'] = 50;


    if (!$this->get_id()) {
      $this->unique_id();
    }
    $record = $this->to_array();
    drupal_write_record($this->db_table, $record, !empty($this->storage) ? $this->get_primary_key() : array());

  $out = '';
  foreach (backup_migrate_crud_types() as $type => $info) {
    $type = backup_migrate_crud_type_load($type);
    $out[] = theme('backup_migrate_group', array('title' => t($type->title_plural), 'body' => $type->get_list()));
  }
  print_r($out);
  exit;
*/

  // 20170808
  // Assign field collection multi values in form validation step.
  // Error line: Recoverable fatal error :Argument 1 passed to field_collection_item_is_empty() must be an instance of FieldCollectionItemEntity, instance of stdClass given, called in .../sites/all/modules/contrib/field_collection/field_collection.module on line 702 and defined in field_collection_item_is_empty() (line 710 from ..../sites/all/modules/contrib/field_collection/field_collection.module).

  // Load field instance info to get field_id.
  $field_info_instance = field_info_instance('node', 'field_COLLECTION_NAME', 'CONTENT_TYPE_NAME');

  // Load field FieldCollectionItemEntity to attach it to this field collection.
  $field_collection_item = field_collection_item_load($field_info_instance['id']);

  // Here you can do your foreach to assign values to your fields inside your field collection.
  $element_key = 0;
  $form_state['values']['field_COLLECTION_NAME'][LANGUAGE_NONE][$element_key]['entity'] = $field_collection_item;
  $form_state['values']['field_COLLECTION_NAME'][LANGUAGE_NONE][$element_key]['entity']->field_FIRST_SUB_FIELD[LANGUAGE_NONE][0]['value'] = 'ALVALUE 1';
  $form_state['values']['field_COLLECTION_NAME'][LANGUAGE_NONE][$element_key]['entity']->field_SECOND_SUB_FIELD[LANGUAGE_NONE][0]['value'] = 'ALVALUE 1';

  $element_key = 1;
  $form_state['values']['field_COLLECTION_NAME'][LANGUAGE_NONE][$element_key]['entity'] = $field_collection_item;
  $form_state['values']['field_COLLECTION_NAME'][LANGUAGE_NONE][$element_key]['entity']->field_FIRST_SUB_FIELD[LANGUAGE_NONE][0]['value'] = 'ALVALUE 2';
  $form_state['values']['field_COLLECTION_NAME'][LANGUAGE_NONE][$element_key]['entity']->field_SECOND_SUB_FIELD[LANGUAGE_NONE][0]['value'] = 'ALVALUE 2';

  // Do not miss to add & in your form validate function (&$form, &$form_state).
  // Also, we might consider using form_set_value instead of assign value directly.

  // UPDATE: 20170813 - CORRECT WAY:
  $field_collection = entity_create('field_collection_item', array('field_name' => 'field_COLLECTION_NAME'));
  $element_key = 0;
  $form_state['values']['field_COLLECTION_NAME'][LANGUAGE_NONE][$element_key]['entity'] = $field_collection;
  $form_state['values']['field_COLLECTION_NAME'][LANGUAGE_NONE][$element_key]['entity']->field_FIRST_SUB_FIELD[LANGUAGE_NONE][0]['value'] = 'ALVALUE 1';
  $form_state['values']['field_COLLECTION_NAME'][LANGUAGE_NONE][$element_key]['entity']->field_SECOND_SUB_FIELD[LANGUAGE_NONE][0]['value'] = 'ALVALUE 1';

  // 20170809
  // Do not use module weights to change the order of execution for a hook implementation!
  // Instead of that use hook_module_implements_alter to modify the order of execution.

  // Did you know you can use uuid_features module to export content using Features.

  // Remember: "if (TRUE == $var)" preferred over "if ($var == TRUE)" in PHP.

  // 20170813
  // Services hook request and response.
  // Implement hook_services_request_preprocess_alter().
  // Implement hook_services_request_postprocess_alter().

  // It's good to write something to help you know the exactly execution time.
  global $custom_time_measure;
  // This line in hook_services_request_preprocess_alter.
  $custom_api_time_measure['start'] = microtime(true);

  // And this line in hook_services_request_postprocess_alter.
  $custom_time_measure['end'] = microtime(true);

  // -------.
  // You can implement this hook to alter the Error response.
  function hook_rest_server_execute_errors_alter(&$error, $controller, $arguments) {
    $responseArray = array();
    $responseArray['status']['code'] = '1'.$error['code'];
    $responseArray['status']['message'] = $error['body_data'];
    $error['body_data'] = $responseArray;
  }

  // 20170813
  // Drupal workflow get state id sid by state name.
  $name = 'pending';
  $sid = db_query("SELECT sid FROM {workflow_states} WHERE name = :name", array(':name' => $name))->fetchObject()->sid;

  // -------
  // Update: 20170821
  // Correct way:
  $sid = ($state = WorkflowState::loadByName('derde') ) ? $state->sid : '';
  // Source: https://www.drupal.org/node/2760913
  // -------

// Drupal workflow Get sid by state machine name state_name.
function CUSTOM_workflow_sid($name) {
  // @TODO: Cache result of this query.
  $workflow_state = db_query("SELECT sid FROM {workflow_states} WHERE name = :name", array(':name' => $name))->fetchObject();
  if (isset($workflow_state->sid)) {
    return $workflow_state->sid;
  }
  else {
    return FALSE;
  }
}

  // 20170817
  // Check if user has nodes on specific content type.
  // @TODO: Use count instead of select field name.
  $has_nodes = db_query('SELECT nid FROM {node} WHERE (type = :type) AND uid = :uid', array(
    ':type' => 'CONTENT_TYPE_NAME',
    'uid' => 'USER_UID',
  ))->fetchField();
  if ($has_nodes) {
    // Do something.
  }

  // 20170820
  // Show form_id in all forms for admin.
  $form['CUSTOM_form_id'] = array(
    '#markup' => t('Form ID: @form_id', array('@form_id' => $form_id)),
    '#weight' => 10000,
    '#access' => user_access('CUSTOM view form_id'),
  );

  // 20170821
  // Add header or footer to views programmatically.
  // Drupal hook views to add header.
  // using template_preprocess_views_view
  function TEMPLATE_preprocess_views_view(&$vars) {
    if (isset($vars['view']) && isset($vars['view']->name) && $vars['view']->name == 'VIEW_NAME' && $vars['view']->current_display == 'DISPLAY_NAME') {
      $vars['header'] ='SOMETHING HTML';
    }
  }

  // 20170822
  // Get count nodes in specific state.
  function count_nodes_in_workflow_state($state_name) {
    // @TODO: Cache this result and add parameter (TRUE/FALSE) to ignore cache.
    $sid = ($state = WorkflowState::loadByName($name) ) ? $state->sid : FALSE;
    $state = workflow_state_load_single($sid);
    $result = new stdClass();
    $result->total = $state->count();
    return $result;
  }

  // 20170822
  // Override view field programmatically using hook_views_pre_render().
  // Rewrite view field using hook programmatically.
  // Best way to use hook instead of tpl file of the field.
/**
 * Implements hook_views_pre_render().
 */
function HOOK_views_pre_render(&$view) {
  // Check if it is our targeted view display.
  if (($view->name == 'VIEW_MACHINE_NAME') && ($view->current_display == 'DISPLAY_NAME')) {
    $view->style_plugin->render_fields($view->result);
    foreach ($view->style_plugin->rendered_fields as $index => &$rendered_result) {
      // Add HTML markup on rendered field.
      $rendered_result['FIELD_NAME'] = 'QWQ';
      // You can print this array $rendered_result to see all fields.
    }
  }
}

  // 20170824
  // Delete view column or override values using hook.
/**
 * Implements template_preprocess_views_view_table().
 * https://api.drupal.org/api/views/theme%21theme.inc/function/template_preprocess_views_view_table/7.x-3.x
 */
function template_preprocess_views_view_table(&$vars) {
  // @TODO: You should use $variables['view']->name and $variables['view']->current_display to apply this only one specific view.
  // Let's assume your field name is node status.
  // Remove header label.
  if (isset($vars['header']) && isset($vars['header']['status']) {
    unset($vars['header']['status']);
  }

  // Remove row columns.
  foreach($vars['rows'] as $key => $row) {
    if (isset($vars['rows']) && isset($vars['rows'][$key]) && isset($vars['rows'][$key]['status'])) {
      unset($vars['rows'][$key]['status']);
      unset($vars['result'][$key]->node_status);
    }
  }
  // You can always print_r($vars['rows']) to know what is exact field name that you need to delete.
  // print_r($vars['result']).
  // print_r($vars['header']).
}

  // For more: https://gist.github.com/derhasi/1501628

// 20170827
/**
 * Implements template_preprocess_page().
 *
 * Hide No front page content has been created yet.
 * Hide node view/edit tabs in some cases.
 */
function template_preprocess_page(&$variables) {
  // Hide view and edit tabs in case of profile and current user can manage it.
  $content_types = array('FIRST_CONTENT_TYPE', 'SECOND_CONTENT_TYPE');
  if (isset($variables['node']) && !empty($variables['node']) && in_array($variables['node']->type, $content_types) && !user_access('bypass node access')) {
    $to_be_removed = array('node/%/edit', 'node/%/view');
    foreach ($variables['tabs'] as $group_key => $tab_group) {
      if (is_array($tab_group)) {
        foreach ($tab_group as $key => $tab) {
          if (isset($tab['#link']['path']) && in_array($tab['#link']['path'], $to_be_removed)) {
            unset($variables['tabs'][$group_key][$key]);
          }
        }
      }
    }
  }
}

  // 20170828
  // Drupal workflow form remove current state button.
  // Remove unnecessary action button in Node View page when it is showing as the current state label.
    /**
     * Implements hook_form_form_id_alter().
     * Alter transition form to remove current state button.
     */
    function MYMODULE_form_workflow_transition_form_alter(&$form, &$form_state, $form_id) {

      // Get current state to remove current state button.
      $current_sid = $form['workflow']['workflow_sid']['#default_value'];
      unset($form['workflow']['workflow_sid']['#options'][$current_sid]);

      // By default workflow button label became (Update workflow) if the options
      // count equal one. So, We will use the state label name instead of
      // (Update workflow).
      // Check if option count equal one.
      if (is_array($form['workflow']['workflow_sid']['#options']) && (count($form['workflow']['workflow_sid']['#options']) == 1)) {
        $submit_label = current($form['workflow']['workflow_sid']['#options']);
        $form['workflow']['actions']['submit']['#value'] = $submit_label;
      }
    }

  // 20170910
  // Render workflow transition form if you enable workflow field module with workflow_extensions module.
  $node = node_load(1111);

  $workflow_field = 'field_WORKFLOW_FIELD_NAME';
  $bundle = $node->type;
  $workflow = workflow_get_workflows_by_type($bundle, 'node');
  $field = _workflow_info_field($workflow_field, $workflow);
  $entity_type = 'node';
  $instance = field_info_instance($entity_type, $workflow_field, $bundle);
  if (module_exists('workflow')) {
    module_load_include('inc', 'workflow', 'workflow.deprecated');
  }

  $workflow_transition_form = drupal_get_form('workflow_transition_form', $field, $instance, $entity_type, $node);
  $workflow_transition_form['nid']['#value'] = $node->nid;
  $workflow_transition_form['#node'] = $node;
  $workflow_transition_form['#wf'] = workflow_load_by_name('fm_profiles_workflow');
  $workflow_transition_form['workflow']['workflow_sid']['#default_value'] = $workflow_transition_form['workflow']['workflow_sid']['#value'];
  $workflow_transition_form['workflow']['workflow_sid']['#title'] = '';
  // Hide workflow comment.
  hide($workflow_transition_form['workflow']['workflow_comment']);

  // If there are no more buttons we will correct the button label.
  $submit_label = current($workflow_transition_form['workflow']['workflow_sid']['#options']);
  $workflow_transition_form['workflow']['actions']['submit']['#value'] = $submit_label;

  // Call needful function to replace with button.
  _workflow_extensions_replace_with_buttons($workflow_transition_form, 'workflow_sid');

  // Fixing the button key name with the button value.
  foreach ($workflow_transition_form['workflow']['buttons'] as $button_key => $button_value) {
    if (is_array($button_value)) {
      unset($workflow_transition_form['workflow']['buttons'][$button_key]);
      $workflow_transition_form['workflow']['buttons']['submit_to_' . $button_value['#to_state']] = $button_value;
      $workflow_transition_form['workflow']['buttons']['submit_to_' . $button_value['#to_state']]['#value'] = $workflow_transition_form['workflow']['workflow_sid']['#options'][$button_value['#to_state']];
    }
  }

  // Render the form.
  $form['fm_workflow_transition_form'] = array(
    '#markup' => $workflow_transition_form_output,
  );

  // 20170918
  // Get all node related to this organic group nid.
  $og_nid = 12;
  $query = new EntityFieldQuery();
  $query->entityCondition('entity_type', 'node')
    ->entityCondition('bundle', 'CONTENT_TYPE_NAME')
    ->propertyCondition('status', 1)
    ->fieldCondition('og_group_ref', 'target_id', $og_nid)
    ->propertyOrderBy('created', 'DESC')
    // Add DANGEROUS_ACCESS_CHECK_OPT_OUT since we need to bypass node access.
    // Please review: http://drupal.org/node/1597378 //.
    ->addTag('DANGEROUS_ACCESS_CHECK_OPT_OUT')
    ->range(0, 10);
  $result = $query->execute();
  if (isset($result['node']) && is_array($result['node'])) {
    foreach ($result['node'] as $record) {
      $node = node_load($record->nid);
      $total_durations = $node->field_project_duration[LANGUAGE_NONE][0]['value'] + $total_durations;
    }
  }

  // 20170919
  // Workflow get transition button label.
  // Getting label of specific transation from state to another specific state.
  $query = db_select('workflow_transitions', 't')
    ->fields('t', array('label'));
  $query->condition('t.sid', $from_sid);
  $query->condition('t.target_sid', $to_sid);
  $label = $query->execute()->fetchField();
  print $label;

  // 20170919
  // Mode: https://open.spotify.com/track/18iSRBd1hAUxFbGp3f4Oj0
  // Drupal workflow function to check if the user allowed to perform specific operation on specific workflow state.
  // This function more likely user_access but for workflow access operation.
  // NOTE: This snippet is not support if the uid is related to the Author!
/**
 * To check if the given user id can perform specific operation on this state.
 */
function MYCUSTOM_workflow_user_access($sid, $op, $uid = NULL) {
  if ($uid == NULL) {
    global $user;
    $uid = $user->uid;
  }

  // Allowed operations.
  $allowed_operations = array('view', 'update', 'delete');
  if (!in_array($op, $allowed_operations)) {
    return FALSE;
  }

  $user_roles = user_load($uid);
  if (isset($user_roles->roles)) {
    // Check all user roles.
    foreach ($user_roles->roles as $rid => $role_name) {
      if (MYCUSTOM_workflow_access($rid, $sid, 'grant_' . $op)) {
        // This user can access now.
        return TRUE;
      }
    }
  }
  else {
    // The user cannot be loaded.
  }

  return FALSE;
}

/**
 * To check if the given role id can perform specific operation.
 */
function MYCUSTOM_workflow_access($rid, $sid, $op) {
  $workflow_access = workflow_access_get_workflow_access_by_sid($sid);
  if (is_array($workflow_access)) {
    foreach ($workflow_access as $access) {
      // Check rid.
      if ($rid == $access->rid) {
        // Check operation.
        if ($access->{$op} == 1) {
          return TRUE;
        }
      }
    }
  }

  return FALSE;
}

$sid = CUSTOM_FUNCTION_TO_GET_SID('sent_to_audit');
MYCUSTOM_workflow_user_access($sid, 'update', $uid = NULL);


  // 20171203
  // Add anything after child form input.
  // You might need this when you want to add custom code as prefix or suffix for child form input like password_confirm element.
function TEMPLATE_preprocess_form_element(&$vars) {
  if (isset($vars['element']) && isset($vars['element']['#name'])) {
    switch ($vars['element']['#name']) {
      case 'pass[pass1]':
        $vars['element']['#children'] = $vars['element']['#children'] . 'SUFFIX';
        break;
    }
  }
}

// 20171204
/**
 * Get all required fields of given content type.
 */
function get_all_content_type_required_fields($content_type) {
  $options = array('target' => 'slave');
  $sql = "SELECT field_name
          FROM field_config_instance ci 
          WHERE ci.bundle = :content_type ";
  $result = db_query($sql, array(':content_type' => $content_type), $options);
  $fields = array();
  foreach ($result->fetchAll() as $key => $field) {
    $instance = field_info_instance('node', $field->field_name, $content_type);
    if ($instance['required'] == 1) {
      $fields[] = $field->field_name;
    }
  }
  return $fields;
}

// 20171207
// Howto set default value for container type hs_taxonomy Hierarchical select taxonomy programmatically.
// You should make the first element is parent. If you want to set the first only you can pass only one element. Also you can use default value as integer not as array.
$form['field_CUSTOM_NAME'][LANGUAGE_NONE]['#default_value'] = array(47, 39);

// I was testing on these values, but only one line was enough.
//  $form['field_service_taxonomy']['#value'] = array(47, 39);
//  $form['field_service_taxonomy']['und']['#entity']->field_service_taxonomy['und'][0] = array('tid' => 47);
//  $form['field_service_taxonomy']['und']['#entity']->field_service_taxonomy['und'][1] = array('tid' => 39);

// 20171207
// OG organic groups permissions issue always you need to check OG permissions.
// Sometimes when user want to add new node he can not see his group in the list. This most of the time because he does not have permission in his group as member to add this node.

  // 20171216
  // Load all nodes related to taxonomy term.
  $query = new EntityFieldQuery();
  $query->entityCondition('entity_type', 'node')
          ->entityCondition('bundle', 'CONTENT_TYPE_NAME')
          ->fieldCondition('field_TERM_REFERENCE', 'tid', $tid);
  $result = $query->execute();

 // Drupal 7 create image style scale and crop programmatically.
  // Check if this image style exists or not.
  $image_style_400x275 = image_style_load('400x275');
  if(isset($image_style_400x275) && !is_array($image_style_400x275)){
    $style = image_style_save(array('name' => '400x275'));
    $effect = array(
        'name' => 'image_scale_and_crop',
        'data' => array(
        'width' => 400,
        'height' => 275,
      ),
      'isid' => $style['isid'],
    );
    image_effect_save($effect);
    watchdog('custom', 'Image style 400x275 created.', array(), WATCHDOG_INFO);
  }else{
    watchdog('custom', 'Image style 400x275 already there.', array(), WATCHDOG_INFO);
  }

// 20171231
// Useful to run it inside any hook.
// By drpl .. Thanks Abdullah Bamelhes <3
$backtrace = debug_backtrace(DEBUG_BACKTRACE_PROVIDE_OBJECT | DEBUG_BACKTRACE_IGNORE_ARGS);
$variables = array('@backtrace' => json_encode($backtrace, JSON_PRETTY_PRINT));
watchdog('MODULE', 'Things happend, here\'s a backtrace:
@backtrace
', $variables, WATCHDOG_ERROR);

  // 20180314
  // Saving file from base64 string
  // Pass the filename to transliteration_clean_filename function to remove spaces and replace non-english characters.
  $filename = transliteration_clean_filename(time() . ' ' . $data['cadastral_survey_file']['filename']);
  $file_decoded = base64_decode($img['data']);
  $file_saved = file_save_data($file_decoded, 'public://' . $filename);
  $file_saved = (array) $file_saved;

  $node = node_load($nid);
  $node->field_image[LANGUAGE_NONE][count($node->field_image[LANGUAGE_NONE])] = $file_saved;
  node_save($node);

// 20180324
// Getting field date as current user timezone.
$date = new DateTime($node->field_test_date[LANGUAGE_NONE][0]['value'], new DateTimeZone($node->field_test_date[LANGUAGE_NONE][0]['timezone_db']));
$date->setTimezone(new DateTimeZone($user->timezone));
print $date->format('Y-m-d H:i:s');
// NOTE: sometimes the $user->timezone can be null. So you need to have a default value for that value.

// 20180401
// Show flag link.
print flag_create_link('FLAG_MACHINE_NAME', $node->nid); 

// Add flag.
$flag = flag_get_flag('FLAG_MACHINE_NAME');
$flag->flag('flag', $node->nid, user_load($user->uid), TRUE);

// Unflag.
$flag = flag_get_flag('FLAG_MACHINE_NAME');
$flag->flag('unflag', $node->nid, user_load($user->uid), TRUE);

// 20180408
// Error line: EntityMalformedException: Missing bundle property on entity of type ENTITY_MACHINE_NAME. in entity_extract_ids() (line 7932 of /includes/common.inc).
// Review this URL: https://drupal.stackexchange.com/questions/111610/how-to-debug-entitymalformedexception
// If this is a custom entity. Make sure the bundle has been set. Or make sure to not define a bundle if you don't need a bundles in hook_entity_info().

// 20180415
// Table theme
  $table = array(
    '#theme' => 'table',
    '#header' => array(
      array('data' => t('First title')),
      array('data' => t('Second title')),
    ),
    '#rows' => array(),
  );
  $table['#caption'] = t('@total records found', array('@total' => 123));

  $table['#rows'][] = array(
    array('data' => 'Text val 1'),
    array('data' => 'Text val 2'),
  );

  return array(
    'table' => $table,
    'pager' => array('#theme' => 'pager'),
  );

// 20180525
// Check if a specific phrase has been translated into targeted language.
  $phrase = 'Home';
  $langcode = 'ar'; // ar = Arabic language.
  $sql = 'SELECT t.translation
    FROM {locales_target} t
    JOIN {locales_source} s
      ON s.lid = t.lid
    WHERE s.source = :phrase AND t.language = :language';

  $results = db_query($sql, array(':phrase' => $phrase, 'language' => $langcode))->fetchAll();

// 20181025
// drupal manage private files access

/**
 * Implements hook_file_download_access().
 *
 * Restrect file access to owners only.
 */
function MYMODULE_file_download_access($file_item, $entity_type, $entity) {
  // Make sure the entity is one of certain content types.
  $content_types = array('page', 'article');
  if (in_array($entity->type, $content_types)) {
    // Check current user if he can access the node view page.
    if ('write your condition here') {
      return TRUE;
    }

    // Since this note is on the hook page on drupal.org:
    // (Note that denial may be overridden by another entity controller,
    // making this grant permissive rather than restrictive).
    // So, we will force the access denied here.
    drupal_access_denied();
    drupal_exit();
  }
}

// Select all jQuery
drupal_add_js("
  (function ($) {
    Drupal.behaviors.tableSelect = {
      attach: function (context, settings) {
        $('th.select-all').click(function (event) {
          $('th.select-all', context).closest('table').each(function(){
            var id_value = $(this).attr('id');
            $('#' + id_value + ' tbody :input').trigger('click');
	        });
        });
      }
    };
  })(jQuery);
    ", array(
    'type' => 'inline',
    'scope' => 'footer',
    'weight' => 5,
  ));
// 20201228
// Submitting the form with no validation. Ignore validation. skip form validation for a specific button.
$form['ignore'] = array(
  '#type' => 'submit',
  '#value' => t('Ignore validation'),
  // You need to have this line.
  '#limit_validation_errors' => [],
);
// 20201229
// Save paragraph programmatically
      $node = node_load(1);
      $paragraph = new ParagraphsItemEntity([
        'field_name' => 'field_CUSTOM_NODE_FIELD',
        'bundle' => 'PARAGRAPH_BUNDLE_NAME',
      ]);
      $paragraph->is_new = TRUE;
      $paragraph->setHostEntity('node', $node);
      $paragraph->field_CUSTOM_PARAGRAPH_FIELD[LANGUAGE_NONE][0]['value'] = 'VALUE';
      $paragraph->save();

// Load paragraph item programmatically.
$entity = entity_load('paragraphs_item', array($ITEM_ID));
$entity = reset($entity);
// 20201229
// Custom location field in a custom form.
$form['location'] = array(
    '#type' => 'location_element',
    '#title' => t('Location'),
    '#default_value' => NULL,
    '#collapsible' => TRUE,
    '#collapsed' => FALSE,
  );
// Show a virtual field on node full view mode.
    $vars['content']['field_virtual_field'] = array(
      '#title' => t('Field title'),
      '#access' => TRUE,
      '#theme' => 'field',
      '#label_display' => 'inline',
      '#view_mode' => 'full',
      '#items' => array(array('value' => '')),
      0 => array('#markup' => 'TEST VALUE'),
      '#weight' => 1,
    );

  // Color field inside field collection.
  $form['field_website_slide_buttons'][LANGUAGE_NONE][$key]['field_wsb_color'][LANGUAGE_NONE][0]['rgb']['#attached']['js'][$key2]['data']['color_field']['#div-field-wsb-color-und-0-field_website_slide_buttons-und-' . $key . '-rgb']['colors'][1] = '#000000';

  drupal_add_css('.field-name-field-website-slide-buttons .field-type-color-field-rgb .transparentBox{display:none}', 'inline');
  foreach ($form['field_website_slide_buttons'][LANGUAGE_NONE] as $key => $value) {
      // $form['field_website_slide_buttons'][LANGUAGE_NONE][$key]['field_wsb_color'][LANGUAGE_NONE][0]['rgb']['#attached']['js'][2]['data']['color_field']['#div-field-wsb-color-und-0-field_website_slide_buttons-und-0-rgb']['colors'][0] = '#000000';
      if (isset($form['field_website_slide_buttons'][LANGUAGE_NONE][$key]['field_wsb_color'][LANGUAGE_NONE][0]['rgb']['#attached']['js'])) {
        foreach($form['field_website_slide_buttons'][LANGUAGE_NONE][$key]['field_wsb_color'][LANGUAGE_NONE][0]['rgb']['#attached']['js'] as $key2 => $value2) {
          // Check if the structure is correct.
          if (isset($value2['data'])) {
            // $form['field_website_slide_buttons'][LANGUAGE_NONE][$key]['field_wsb_color'][LANGUAGE_NONE][0]['rgb']['#attached']['js'][$key2]['data']['color_field']['#div-field-wsb-color-und-0-field_website_slide_buttons-und-' . $key . '-rgb']['colors'][0] = '#000000';
            // $form['field_website_slide_buttons'][LANGUAGE_NONE][$key]['field_wsb_color'][LANGUAGE_NONE][0]['rgb']['#attached']['js'][$key2]['data']['color_field']['#div-field-wsb-color-und-0-field_website_slide_buttons-und-' . $key . '-rgb']['colors'][1] = '#000000';
          }
        }
      }
    }

  // drush command to remove all flood records.
  drush sql-query "TRUNCATE TABLE flood"
  drush sql-query --db-prefix "TRUNCATE TABLE {flood}"

Creating a related content view in Drupal 7:

Show related content based on shared Term-pages (from any given vocabularies).

Each term page will be recognized by the term ID (TID) hidden in the pages’ URL.

The process:

Basic stages:

  1. Create a “Content” view-block.
  2. Add a contextual filter: “Has taxonomy term ID”.
  3. Choose “provide a fixed value”.
  4. (From type): “Taxonomy term ID from URL“.

Checking:

• Uncheck “Load default filter from the term page”. • Check “Load default filter from node page, that’s good for related taxonomy blocks”.

• Check “Limit terms by a vocabulary”. • Check your desired vocabulary.

  1. Select “Filter to items that share any term”.

  2. Go down and check “Reduce duplicates”: This will several terms that relate to the same page – To appear. Only one will of them will.

https://www.daymuse.com/blogs/drupal-guide-related-content-term-views

Optional:

If you would like that the current node won’t appear in the list:

  1. Go to the view and add another, extra Contexutal filter.
  2. Give it content: NID.
  3. Select “Provide default value”.
  4. Set the “Type” to “Content ID from URL”.
  5. Go down in that window, click on “More”, and there check “Exclude”.

Note that this will exclude the current node in which the related is shown – From that very list.

It will do so by using the content ID which is a (hidden) part of the URL.

Source: https://drupal.stackexchange.com/a/205924/24113
  // Looking for security updates:
  drush up --security-only -n

  // Review improvements highlighted by the security review module:
  drush dl security_review --dev
  drush en -y security_review
  drush ev 'print json_encode(user_roles()) . "\n";'
  drush vset --format=json security_review_untrusted_roles '[1,2]'
  drush secrev --results

  // Looking for PHP enabled modules:
  drush pm-list --pipe --type=module --status=enabled | grep php

  // Looking for evidence of a compromise in your search results on Google:
  site:example.com viagra

  // Looking for code changes in Drupal core if Git is not installed:
  drush dl hacked diff
  drush en -y hacked diff
  drush hlp
  drush hd drupal
  drush hacked-diff drupal

  // Looking for evidence of a compromise in custom theme & modules.
  find ./ -type f -mtime -7 #List all files modified in the last 7 days

  // Looking for evidence of a compromise in the files directory:
  find sites/default/files/ -path "*.php"

  // Source: https://drupal.support/drupal-developer/article/linux-and-drush-commands-every-drupal-developer-needs-know-carry-out
  // Linux and Drush commands every Drupal developer needs to know to carry out a security audit

Apache Solr https://docs.websolr.com/docs/drupal-7-with-the-apachesolr-module
  // Source: http://semver.org/
  // Given a version number MAJOR.MINOR.PATCH, increment the:
  // - MAJOR version when you make incompatible API changes,
  // - MINOR version when you add functionality in a backwards-compatible manner.
  // - PATCH version when you make backwards-compatible bug fixes.

Drupal Query tag
https://drupal.stackexchange.com/questions/45785/entityfieldquery-inner-join
http://ifixdrupal.co.uk/performance/watchdog-notices
http://browse-tutorials.com/snippet/enable-or-disable-comments-using-nodesave-drupal-7
Recommended module in Squircle List:
Field_slideshow
Suggestion for Drupal website:
- The module description should have template so developers write description depending on this template it will be better than current way when every module has own template:
https://www.drupal.org/project/reg_with_pic
https://www.drupal.org/project/simplenews
https://www.drupal.org/project/linked_field
https://www.drupal.org/project/autocomplete_deluxe
https://www.drupal.org/project/content_taxonomy
https://www.drupal.org/project/hierarchical_select

VERY GOOD WEBSITE FOR DRUPAL SNIPPETS <3
http://dropbucket.org/

Always look into the helper module: http://cgit.drupalcode.org/helper/tree/lib

Some notes for Drupal

- Group style output in views theme with title h3 for (views-view-unformatted.tpl.php) and all nested templates to be in one separate div class. 20170328 - When using menu_block module and assign it to sidebar for example and going to browsing admin/structure/menu/manage/menu-NAME while you enable translation. Then sidebar menu will have both language since it take the menu items from cached result. 20170405
I'm putting this here so I remember for my daily use. If it helps you as well then even better :)
ملفات مرفقة: 

Share this post