PHP version update (7.2 to 7.4 )

Please go through this  https://www.php.net/supported-versions.php

This is to inform you that PHP ending their security support for the version PHP 7.2 on 30 November 2020.We are using this version since last 3 year for most of our live websites.
So we need to upgrade the versions in local to PHP 7.4 for new website development and requirements.please install php 7.4 as per your requirements from below steps in Ubuntu 16.04 & 18.04
sudo apt-get update
sudo apt -y install software-properties-common
sudo add-apt-repository ppa:ondrej/php
sudo apt-get update
sudo apt -y install php7.4
For switching the php versions as per your project requirements use below command
sudo a2dismod php7.2 (to disable)
sudo a2enmod php7.4  (to enable ) 
sudo service apache2 restart
to revert back to 7.2  use
sudo a2dismod php7.4 
sudo a2enmod php7.2 
sudo service apache2 restart
Also Please install the php7.4 extensions

sudo apt install php7.4-common php7.4-mysql php7.4-xml php7.4-xmlrpc php7.4-curl php7.4-gd php7.4-imagick php7.4-cli php7.4-dev php7.4-imap php7.4-mbstring php7.4-opcache php7.4-soap php7.4-zip php7.4-intl -y

Next Post and Prev Post Finding From Post ids

Post Ids for all post including current post id

        foreach ($view_result as $entity) {
          $posts[$entity->nid->value] = $entity->nid->value; 
        }

         //call next and prev
         $pager = getAdjacentPost($posts,$currentpostId);

Function for adjacent post

function getAdjacentPost($posts,$currentpostID){
    $adjecentLinks = array();
    while (!in_array(key($posts), [$currentpostID])) {
        next($posts);
    }
    if (current($posts) !== false) {
        $nextPostId = next($posts);
        $adjecentLinks['next'] = $nextPostId;
        
    }
    reset($posts);
    while (!in_array(key($posts), [$currentpostID])) {
        next($posts);
    }
    if (current($posts) !== false) {
        $prevPostId = prev($posts);
        $adjecentLinks['prev'] = $prevPostId;
        
    }
  return($adjecentLinks);
}

 

Drupal 8 Entity Query Taxonamy

public function getMatterCategories($languageCode,$parentCatId){
        $result=[];
        $vocabulary = 'matter_category';
        $query = \Drupal::entityQuery('taxonomy_term');
        $query->condition('vid', $vocabulary);
        $query->sort('weight');
        $tids = $query->execute();
        $terms = \Drupal\taxonomy\Entity\Term::loadMultiple($tids);
        $termList = array();

        foreach($terms as $term) {
            if($term->hasTranslation($languageCode)){
                $parentArraKey = [];
                $tid = $term->id();
                $translated_term = \Drupal::service('entity.repository')->getTranslationFromContext($term, $languageCode);
                $storage = \Drupal::service('entity_type.manager')
                  ->getStorage('taxonomy_term');
                $parents = $storage->loadParents($tid);
                $termName = $term->id();
                $parentArraKey = array_keys($parents);
                if($parentCatId){
                  if($parentArraKey[0] == $parentCatId){
                    $result[]= [
                      'id'=>$tid,
                      'name'=>$translated_term->getName(),
                      'image'=>($translated_term->field_image->entity)?file_create_url($translated_term->field_image->entity->uri->value):''
                    ];
                  }
                }else{
                  if(!$parentArraKey){
                    $result[]= [
                      'id'=>$tid,
                      'name'=>$translated_term->getName(),
                      'image'=>($translated_term->field_image->entity)?file_create_url($translated_term->field_image->entity->uri->value):''
                    ];
                  }
                }
            }
        }
        return $result;
    }

 

Drupal 8 Entity Query Conditions

    $query = \Drupal::entityQuery('entity_name');
    //field value condition check
    $query->condition('financial_status','accept');
    //field value array condition check
    $query->condition('financial_payment_status',['completed'],'IN');
    //condition with date format (d/m/y)
    if($params['start-date']){
      $befordate = $params['start-date'].' 23:59:59';
      $query->condition('changed',strtotime($befordate),'>=');
    }
    if($params['end-date']){
      $enddate = $params['end-date'].' 23:59:59';
      $query->condition('changed',strtotime($enddate),'<='); 
    }
    //search condition with name
    if($search)
       $query->condition('name', "%" . $search . "%", 'LIKE');
    //Or Conditon check with name or user name searching
    if($matter_search){
      $group = $query->orConditionGroup()
       ->condition('chat_matter_Id.entity.name', "%" . $matter_search . "%", 'LIKE')
       ->condition('chat_matter_Id.entity.user_id.entity.field_first_name', "%" . $matter_search . "%", 'LIKE');
      $query->condition($group);
    }
    //condition not equal a value
    $query->condition('financial_type','fees','!=');
    //today created items filter
    $query->condition('created', array(strtotime('today'), strtotime('today 23:59:59')), 'BETWEEN');
    //condition for item status is published
    $query->condition('status', 1);
    //sort list by created time
    $query->sort('created', 'DESC');
    //result range for pager
    if($offset && $limit){
     $start_limit = ($offset - 1) * $limit;
     $query->range($start_limit, $limit);
    }
    $entity_ids = $query->execute();
    if (!empty($entity_ids)) {
      $Entity = \Drupal::entityTypeManager()->getStorage('entity_name')->loadMultiple($entity_ids);
      foreach ($Entity as $node) {
        $data = [];
        $data['matter_id'] = $node->financial_matter_Id->entity->id->value;
        
        $payments[] = $data;
      }
    }

 

CSV Export (Html table format)

Html format

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<button id="export">export</button>

<table class="dataTable">
  <tr>
    <th>Company</th>
    <th>Contact</th>
    <th>Country</th>
  </tr>
  <tr>
    <td>Alfreds Futterkiste</td>
    <td>Maria Anders</td>
    <td>Germany</td>
  </tr>
  <tr>
    <td>Centro comercial Moctezuma</td>
    <td>Francisco Chang</td>
    <td>Mexico</td>
  </tr>
  <tr>
    <td>Ernst Handel</td>
    <td>Roland Mendel</td>
    <td>Austria</td>
  </tr>
  <tr>
    <td>Island Trading</td>
    <td>Helen Bennett</td>
    <td>UK</td>
  </tr>
  <tr>
    <td>Laughing Bacchus Winecellars</td>
    <td>Yoshi Tannamuri</td>
    <td>Canada</td>
  </tr>
  <tr>
    <td>Magazzini Alimentari Riuniti</td>
    <td>Giovanni Rovelli</td>
    <td>Italy</td>
  </tr>
</table>

javascript

$('#export').click(function() {
  var titles = [];
  var data = [];

  /*
   * Get the table headers, this will be CSV headers
   * The count of headers will be CSV string separator
   */
  $('.dataTable th').each(function() {
    titles.push($(this).text());
  });

  /*
   * Get the actual data, this will contain all the data, in 1 array
   */
  $('.dataTable td').each(function() {
    data.push($(this).text());
  });
  
  /*
   * Convert our data to CSV string
   */
  var CSVString = prepCSVRow(titles, titles.length, '');
  CSVString = prepCSVRow(data, titles.length, CSVString);

  /*
   * Make CSV downloadable
   */
  var downloadLink = document.createElement("a");
  var blob = new Blob(["\ufeff", CSVString]);
  var url = URL.createObjectURL(blob);
  downloadLink.href = url;
  downloadLink.download = "data.csv";

  /*
   * Actually download CSV
   */
  document.body.appendChild(downloadLink);
  downloadLink.click();
  document.body.removeChild(downloadLink);
});

   /*
* Convert data array to CSV string
* @param arr {Array} - the actual data
* @param columnCount {Number} - the amount to split the data into columns
* @param initial {String} - initial string to append to CSV string
* return {String} - ready CSV string
*/
function prepCSVRow(arr, columnCount, initial) {
  var row = ''; // this will hold data
  var delimeter = ','; // data slice separator, in excel it's `;`, in usual CSv it's `,`
  var newLine = '\r\n'; // newline separator for CSV row

  /*
   * Convert [1,2,3,4] into [[1,2], [3,4]] while count is 2
   * @param _arr {Array} - the actual array to split
   * @param _count {Number} - the amount to split
   * return {Array} - splitted array
   */
  function splitArray(_arr, _count) {
    var splitted = [];
    var result = [];
    _arr.forEach(function(item, idx) {
      if ((idx + 1) % _count === 0) {
        splitted.push(item);
        result.push(splitted);
        splitted = [];
      } else {
        splitted.push(item);
      }
    });
    return result;
  }
  var plainArr = splitArray(arr, columnCount);
  // don't know how to explain this
  // you just have to like follow the code
  // and you understand, it's pretty simple
  // it converts `['a', 'b', 'c']` to `a,b,c` string
  plainArr.forEach(function(arrItem) {
    arrItem.forEach(function(item, idx) {
      row += item + ((idx + 1) === arrItem.length ? '' : delimeter);
    });
    row += newLine;
  });
  return initial + row;
}

LAMP Setup commands line by line

sudo apt-get update
sudo apt-get install apache2
sudo systemctl restart apache2
sudo apt-get install curl
sudo apt-get install mysql-server
sudo mysql_secure_installation

sudo apt-get install vim
sudo vim /etc/apache2/mods-enabled/dir.conf

    DirectoryIndex index.php index.html index.cgi index.pl index.xhtml index.htm

sudo service apache2 restart
To Install PHP 7.2 
sudo apt-get install php libapache2-mod-php php-mysql

sudo apt-get install php-pear php7.2-curl php7.2-dev php7.2-mbstring php7.2-zip php7.2-mysql php7.2-dom php7.2-gd
sudo apt-get update
sudo apt-get install phpmyadmin php-mbstring php-gettext
sudo apt-get install zip
sudo phpenmod mbstring
sudo ln -s /etc/phpmyadmin/apache.conf /etc/apache2/conf-available/phpmyadmin.conf
sudo ln -s /usr/share/phpmyadmin /var/www/html/phpmyadmin
sudo a2enmod rewrite
sudo systemctl restart apache2

Image to base 64 format in javascript

    <form><input type="file" name="image"></form>

    //add the following javascript for encoding

    var imgFile = document.querySelector('input[type=file]');
    var reader = new FileReader();

    imgFile.addEventListener('change', function (event) {
      reader.readAsDataURL(imgFile.files[0]);
    });

    reader.addEventListener('load', function () {
      var imageData = reader.result;
      console.log(imageData);
    }, false);

PHP Cache

When working on PHP websites made from scratch and without a framework, speed can often be an issue. Caching is extremely useful in order to speed up PHP webpages.

  • file cache
  • memcached/redis
  • APC

Each used for slightly different goal.

File cache is usually something that you utilize when you can pre-render files or parts of them. It is used in templating solutions, partial views (mvc), css frameworks. That sort of stuff.

Memcached and redis are both more or less equal, except redis is more of a noSQL oriented thing. They are used for distributed cache ( multiple servers , same cached data ) and for storing the sessions, if you have cluster of webservers.

APC is good for two things: opcode cache and data cache. Faster then memcached, but works for each server separately.


Bottom line is : in a huge project you will use all of them. Each for a different task.

how to make a simple PHP caching system for your web pages.

Page Caching

1.create a first file for caching (first-cache.php)



$url = $_SERVER["SCRIPT_NAME"];
$break = Explode('/', $url);
$file = $break[count($break) - 1];
$cachefile = 'cached-'.substr_replace($file ,"",-4).'.html';
$cachetime = 18000;
// Serve from the cache if it is younger than $cachetime
if (file_exists($cachefile) && time() - $cachetime < filemtime($cachefile)) {
echo "\n";
readfile($cachefile);
exit;
}
ob_start(); // Start the output buffer
?>
  • The first five lines create the cached file name according to the current PHP file
  • Line six creates a $cachetime variable, which determines the life of our simple cache (Cachefile time).
  • Lines nine to thirteen are a conditional statement which looks for a cache file named $cachefile. If the file is found, a comment is inserted (line ten) and the $cachefile file is included. Then, the exit statement stops the execution of the script and the file is sent to the client browser. This means that if a static file is found, no PHP is interpreted by the server.
  • Line 14 creates a buffer if the $cachefile file isn’t found.

2.create another new PHP file (second-cache.php)


// Cache the contents to a cache file
$cached = fopen($cachefile, 'w');
fwrite($cached, ob_get_contents());
fclose($cached);
ob_end_flush(); // Send the output to the browser

If a cached file named $cachefile (first-cache.php) isn’t found on your server, this code will be executed and will create the cache file itself.

3.Include Cache Files On Your Page

the first-cache.php file must be included at the beginning of your PHP page and the second-cache.php at the end, as shown below:

include('first-cache.php'); 
// Your regular PHP code goes here
include('second-cache.php');

As a result, next time the page will be requested, the $cachefile static file will be served to the client browser instead of executing the whole PHP file.

What is OpCode Cache?

An OpCode cache is a performance-enhancing extension that caches the result of the PHP code compilation to bytecode. Throughout PHP’s lifetime, there have been a number of OpCode caches available, mostly depending on the used PHP version.

How Do I Enable OpCode Cache?

As available OpCode caches depend on the PHP version used on your server, please get in touch with your web hosting provider to see how to enable OpCode caching on your site.