Realm Object Server Setup In AWS Instance

Realm Object Server provides synchronisation of Realms between devices and provides authentication and access control services. Realm Object Server is a Node package which requires a Node project to run within.

Artboard.png

Prior knowledge


Mandatory to have some basic knowledge in linux commands which will help you to setup realm object server in AWS instance. Either you have AWS instance or CentOS instance to run below commands directly.

Ports

The Realm Object Server utilizes websocket connections over TCP to synchronize data. This means that you will need to make sure your firewall allows TCP communication over whichever ports your ROS is configured to use. By default, this is port 9080 for HTTP traffic. It is better securing your server by enabling HTTPs communication which is done over port 443.

Install Realm Object Server and Configure

Note:-  Don’t use root permission to run commands to setup ROS

  • #SSH to your instance
  • #Install NVM
    curl https://raw.githubusercontent.com/creationix/nvm/v0.25.0/install.sh | bash
    Note:- Close terminal and open once
  • #Install Node.js using NVM
    nvm install 8.11.3
  • #Install Node.js LTS
    curl –silent –location https://rpm.nodesource.com/setup_8.x | sudo bash –
    sudo yum -y install nodejs
  • #To compile and install native addons from npm
    sudo yum install gcc-c++ make
  • #Install realm-object-server using npm
    npm install -g realm-object-server
  • #Update realm-object-server to latest version
    npm install realm-object-server@latest
  • Note:- After installing ros you can check ros -V to find the version of ROS installed. If it throws error then you need to verify with some above steps.
  • #Go to html Directory
    cd  /var/www/html
  • #Create a new ROS project instance:
    ros init my-app
  • #Once my-app folder created go to my-app directory
    cd my-app
  • #Update feature token/access token in src/index.ts
  • #Start the server
    npm start

Running ROS in the Background

Once you are ready to go into production, you will want to daemonize your application project so that it runs in the background and automatically on server startup. It is  recommended using pm2 to maintain instances of Realm Object Server in production. PM2 is a battle tested process manager that allows your applications to stay alive forever and helps with mission critical administration during downtime.
  • #Install pm2
    sudo npm install pm2 -g
  • #From my-app directory run below command which will run ROS background
    pm2 start dist/index.js -n ros
  • #To check status of server running
    pm2 status
  • #To find your server logs file path
    pm2 describe 0
  • #To stop ROS
    pm2 stop ros
  • #To start ROS
    pm2 start ros

Once done you can browse your instance URL:9080 and it should look like this and in realm studio you will be able to login as well:

Screen Shot 2018-07-25 at 6.11.44 PM.png

References

https://docs.realm.io/platform/self-hosted/running-the-server

https://nodejs.org/en/download/package-manager/

https://www.liquidweb.com/kb/how-to-install-node-js-via-nvm-node-version-manager-on-centos-7

https://realm.io/

Advertisements

Setup of Lumen using Laravel Homestead vagrant box

Lumen is the stunningly fast micro-framework by Laravel. Lumen attempts to take the pain out of development by easing common tasks used in the majority of web projects, such as routing, database abstraction, queueing, and caching.

lumen

I believe if you can setup the software easily then development becomes very easy and less frustrating. If you are not aware of some terms like virtualbox, vagrant, homestead I will try to explain them first before we heading towards the setup.

Prior knowledge


Mandatory to have some basic knowledge in linux commands which will help you to setup lumen in your local machine.

What you will learn from this article


  • What is Virtual Box
  • What is Vagrant
  • What is Vagrant Box
  • Laravel Homestead
  • Lumen setup

What is Virtual box?

Virtual box provides an emulated environment which can load multiple guest Operating Systems (guest OS) under a single host operating-system (host OS). Each guest can be started, paused and stopped independently within its own virtual machine (VM). The host OS and guest OSs and applications can communicate with each other through a number of mechanisms including a common clipboard and a virtualized network facility. Guest VMs can also directly communicate with each other if configured to do so.

Ex – If you have windows machine and you want to setup Lumen in Linux environment. So here Windows OS is host and Linux OS is guest. Using above virtual box you can add guest OS in your host OS. Download the virtual box from here as per your OS. Read more about Virtual Box.

What is Vagrant?

As mentioned in virtual box paragraph, you can add multiple guest OSs. So Vagrant is a software through which you can manage virtual box environment. Once you configured vagrant and virtual box then it is easy to setup your environment and share the exact environment across your team either through vagrant box or vagrant file. Developer having same vagrant file just need to vagrant up without setting up the environment manually. Download the vagrant software here as per your OS. Read more about Vagrant.

What is Vagrant Box?

Vagrant box is a package of all software installed in your guest OS including OS. There are public and private vagrant boxes available, which you can just download and add to your virtual box. Public box means people have already packaged all the softwares, made a box and shared it publicly. Similarly if you just package all your softwares and make a box and share with your colleagues will be called private box. Discover more public boxes here. Read more about Vagrant box

Laravel Homestead

Laravel Homestead is an official, pre-packaged Vagrant box that provides you a wonderful development environment without requiring you to install PHP, a web server, and any other server software on your local machine. No more worrying about messing up your operating system! Vagrant boxes are completely disposable. If something goes wrong, you can destroy and re-create the box in minutes!

You will get all simple steps to install Laravel Homestead from this link https://laravel.com/docs/5.6/homestead and follow all the instructions as mentioned.

I just want to add few more simple steps which I found developers might get confused during Homestead box setup. Open homestead link https://laravel.com/docs/5.6/homestead in another tab and read my below points to get better understanding.

Point 1:

Screen Shot 2018-07-21 at 3.58.37 PM

Here if the above command throws error then run this command:

vagrant box add laravel/homestead https://vagrantcloud.com/laravel/boxes/homestead-7/versions/0.2.1/providers/virtualbox.box

Mainly you need to find the laravel homestead box and download it if vagrant box add laravel/homestead does not work.

Point 2:

Screen Shot 2018-07-21 at 4.09.56 PM
Screen Shot From Laravel Site

After running above command inside a directory type ls to list out the files got created. Here you will find Vagrantfile also got created. Don’t change the vagrant file content at all or replace it with you any existing Vagrantfiles.

2.png

Point 3:

Screen Shot 2018-07-21 at 4.50.53 PM.png
Screen Shot From Laravel Site

Here inside Homestead.yaml file map: ~/code means the folder which will be synced from your host machine. This directory name can be anything where all of your project resides. You can think of /var/www/html folder as well where we keep all of our project directories.

And to: /home/vagrant/code means the folder of your vagrant machine will have all the files available in mapped folder from your host machine. So no need to change this path. Let me share scree shot of my synced folders between vagrant and my host machine.

Screen Shot 2018-07-21 at 5.03.57 PM
Folder of Host Machine
4.png
Folder created during git clone as mentioned in Laravel site
3.png
Vagrant Folders

You can find out the folders got synced between host and vagrant box.

Point 4:

When you will do vagrant up inside the directory where you run init.sh file make sure you see the message about your folders got synced like below.

6.jpg5.jpg

Point 5:

Screen Shot 2018-07-21 at 5.29.07 PM.png

The ip 192.168.10.10 it gets generated by Homestead and you will find the ip on top of your Homestead.yaml file. So don’t change this IP as well. Use this ip in your /etc/hosts to link to the domain you will use to browse your project.

Lumen setup:

Once your folders get synced then install lumen inside your map: directory in your host machine. In my case it is ~/code. Follow https://lumen.laravel.com/docs/5.6 to install lumen in your directory which will be synced automatically to vagrant box. After I installed lumen when I typed lumen new blog it created project blog having lumen framework structure and all necessary files needed for Lumen.

Screen Shot 2018-07-21 at 5.35.57 PM.png

Ultimately I need to point the domain to this public folder, so this point will be like this:

Screen Shot 2018-07-21 at 5.38.36 PM.png

Here in my case it will be to: /home/vagrant/code/blog/public because /home/vagrant/code = ~/code and then after I need to point blog/public.

Once you cross verify all these things then browse your domain and it should work and you are done with setup 🙂

Please feel free to ask questions if you have any.

Thanks for your time to go through the article.

Thanks!

References:

https://laravel.com/docs/5.6/homestead

https://lumen.laravel.com/docs/5.6

https://www.virtualbox.org/wiki/Downloads

https://www.virtualbox.org/wiki/Downloads

https://www.vagrantup.com/docs/virtualbox/

https://www.vagrantup.com/intro/index.html

Node.js async await vs promise vs callback

Normally Node.js invokes functions asynchronously. Node.js async await, promise and callback comes into picture when you want to execute one function after completion of another function execution.

All these features are introduced one by one in Node.js different version release. Before Node version 7.6, the callbacks were the only way provided by Node to run one function after another.

We will see all three concepts taking real case scenario:

Three Tomatoes with Shadows --- Image by © Royalty-Free/Corbis

Requirement is If you have sufficient balance then you can purchase. All examples below written can not be directly executed rather used here to show concept difference.

Ex:

let placeAnOrderAndDeliver = function(name, address) {
  // Send the item to Dear 'name' staying at this 'address'
}

let showWarningOrError = function(statusCode, error) {
  // Show warning message or error message if no sufficient balance
  // Or if any error happened
}

let checkSufficientBalanceInAccount = function(
    userName, password, balanceNeeded, callback) {
  if (logInCredentialValidated) {
    if (balanceInMyAccount > balanceNeeded) {
      callback(true);
    } else {
      callback(false);
    }
  } else {
    callback(false);
  }
}

let purchaseItem = function(itemName, itemCost) {
  try {
    checkSufficientBalanceInAccount('testUser', 'testPassword', itemCost,
        function(response) {
          if (response) {
            placeAnOrderAndDeliver('Name', 'Address');
          } else {
            showWarningOrError('402', 'Insufficient balance!')
          }
        })
  } catch (error) {
    showWarningOrError('400', error.message)
  }
}

Problem of above way is, for multiple callbacks it gets messy and cause lot of troubles.

Later promise and function chaining introduced in Node.js version:

So if you will refactor above functions into promise and function chaining, it will look like this:

let placeAnOrderAndDeliver = function(name, address) {
  // Send the item to Dear 'name' staying at this 'address'
}

let showWarningOrError = function(statusCode, error) {
  // Show warning message or error message if no sufficient balance
  // Or if any error happened
}

let checkSufficientBalanceInAccount = new Promise((resolve, reject) => {
  let successMsg = {
    status: '200',
    message: 'Successful transaction!'
  };

  let failureMsg = {
    status: '449',
    message: 'Unsuccessful transaction!'
  };

  let failureLoginMsg = {
    status: '401',
    message: 'Invalid credential!'
  };

  if (logInCredentialValidated) {
    if (balanceInMyAccount > balanceNeeded) {
      resolve(successMsg);
    } else {
      reject(failureLoginMsg);
    }
  } else {
    reject(failureMsg);
  }
});

let purchaseItem = function(itemName, itemCost) {
  try {
    checkSufficientBalanceInAccount('testUser', 'testPassword', itemCost).
        then((response) => {
          placeAnOrderAndDeliver('Name', 'Address');
        }).
        catch((reason) => {
          showWarningOrError(reason.status, reason.message);
        });
  }
  catch (error) {
    showWarningOrError('400', error.message);
  }
};

In this way code looks more clear and easily understandable. You can chain multiple functions by adding multiple .then

In Node v8 await gets released to deal with promise and chaining. Here no need to write .then, Simply you need to call prefix await before the function name and call next function usually you call the function. Unless await function executes the next function will not be executed.

Example using async/await:

let placeAnOrderAndDeliver = function(name, address) {
  // Send the item to Dear 'name' staying at this 'address'
}

let showWarningOrError = function(statusCode, error) {
  // Show warning message or error message if no sufficient balance
  // Or if any error happened
}

let checkSufficientBalanceInAccount = new Promise((resolve, reject) => {
  let successMsg = {
    status: '200',
    message: 'Successful transaction!'
  };

  let failureMsg = {
    status: '449',
    message: 'Unsuccessful transaction!'
  };

  let failureLoginMsg = {
    status: '401',
    message: 'Invalid credential!'
  };

  if (logInCredentialValidated) {
    if (balanceInMyAccount > balanceNeeded) {
      resolve(successMsg);
    } else {
      reject(failureLoginMsg);
    }
  } else {
    reject(failureMsg);
  }
});

let purchaseItem = async function(itemName, itemCost) {
  try {
    await checkSufficientBalanceInAccount('testUser', 'testPassword', itemCost);
    placeAnOrderAndDeliver('Name', 'Address');
  }
  catch (error) {
    showWarningOrError('400', error.message);
  }
};

If you will compare promise based example and async/await based example then you will find last function is the main difference where “let purchaseItem = async function” you can see async keyword before function keyword. Because await should be used inside async function.

Another difference is functions are called in an order, where function called after await function will not execute unless await function completes.

That is all about basic usage and main differences. If you want to know more about promise and async/await go through these references links:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise

Hope you like it!

Thanks for your time to go through this.

Use of realm object in realm Event handler

Before describing the deep concept of handling realm event handler changes, if you want to know about realm then please go through these links https://realm.io/ and https://realm.io/docs/javascript/latest/once.

Realm Platform:

They provide new standard in data synchronisation. Realm helps companies build engaging mobile applications with minimal development time. The Realm Platform enables any development team, no matter the size, to include difficult-to-build features like two‑way data sync and realtime collaboration. Devote more time to what makes your app truly unique and less time to maintaining services.

Realm object database is a simple alternative to SQLite and Core Data and proudly open source.

I can just share the benefits of realm database quickly:Screen Shot 2018-06-23 at 10.06.14 AM

Now let’s discuss about handling event handler changes:

This is an important and awesome feature which you will not find in any other mobile DB like sqlite, Oracle Lite, Tiny DB etc.

Once you setup realm database and connect to realm DB using Node JS then for any changes in database, the event fires for that change and you can capture that event change in callback.  If you have multiple databases or individual database for each user then you can set the path to register the event change for those databases.

So for each operation(Insertion, Modification and Delete) in database there will be event fired and in callback of that you can do your operation in Node Js. For example if there is data insertion in realm DB through mobile then in Node Js server you can catch the data and insert that data to MySql or move to AWS SQS or play with it.

A sample index.js file might look something like this. This example listens for changes to a user-specific private Realm at the virtual path /~/myuserDB. It will look for updated Coupon objects in these Realms, verify their coupon code if it wasn’t verified yet, and write the result of the verification into the isValid property of the Coupon object.

'use strict';
var Realm = require('realm'); 

// the URL to the Realm Object Server
var SERVER_URL = '//127.0.0.1:9080';

// The regular expression you provide restricts the observed Realm files to only the subset you
// are actually interested in. This is done in a separate step to avoid the cost
// of computing the fine-grained change set if it's not necessary.
var NOTIFIER_PATH = '^/([^/]+)/myUserDB$';

//declare admin user
let adminUser = undefined

// The handleChange callback is called for every observed Realm file whenever it
// has changes. It is called with a change event which contains the path, the Realm,
// a version of the Realm from before the change, and indexes indication all objects
// which were added, deleted, or modified in this change
var handleChange = async function (changeEvent) {
  // Extract the user ID from the virtual path, assuming that we're using
  // a filter which only subscribes us to updates of user-scoped Realms.
  var matches = changeEvent.path.match("^/([^/]+)/([^/]+)$");
  var userId = matches[1];

  var realm = changeEvent.realm;
  var coupons = realm.objects('Coupon');
  var couponIndexes = changeEvent.changes.Coupon.insertions;

  for (let couponIndex of couponIndexes) {
    var coupon = coupons[couponIndex];
    if (coupon.isValid !== undefined) {
      var isValid = verifyCouponForUser(coupon, userId);
      // Attention: Writes here will trigger a subsequent notification.
      // Take care that this doesn't cause infinite changes!
      realm.write(function() {
        coupon.isValid = isValid;
      });
    }
  }
}

function verifyCouponForUser(coupon, userId) {
    //logic for verifying a coupon's validity
}

// register the event handler callback
async function main() {
    adminUser = await Realm.Sync.User.login(`https:${SERVER_URL}`, 'realm-admin', '')
    Realm.Sync.addListener(`realms:${SERVER_URL}`, adminUser, NOTIFIER_PATH, 'change', handleChange);
}

main()

Note: In above code var realm = changeEvent.realm; where realm is the object which contains all rows, values which was changed in DB and other informations as well. So in event handler file no need to open realm to get realm object or to do any DB operation. You can use above realm object through out the event handler file carefully.

In past we did same mistake when dealing with realm object. Like

Realm.open({schema: [Car, Person]})
  .then(realm => {
    // ...use the realm instance here
  })
  .catch(error => {
    // Handle the error here if something went wrong
  });

So you no need to open realm in Event handler file unless you need it. As you can see the object realm already available var realm = changeEvent.realm;  globally.

For any DB operation like insertion, modification and delete operation you can use above realm object.

References:

https://realm.io/docs/javascript/latest/
https://academy.realm.io/posts/realm-sf-tim-oliver-event-handling-realm-object-server/https://docs.realm.io/platform/using-synced-realms/server-side-usage/data-change-events

Hope you like the post and stay tuned for my next post about “deep analysisof handling event handler for each DB operations”.

Thanks!

Importance Of Logging In MySql

Enable logging in MySql is necessary to manage your server and helps in analyzing performance and investigating problems.

Most of the time when we find any issues in our web application or when user complains about the performance then only we print our query and run that query in MySql server to analyse what is wrong.

Prevention is better than cure.


Important Log Types In MySql:

  • The error log
  • The query log
  • The slow query log

The error log:

If you enable error log in MySql server it keeps record of each error occurs in the MySql server. You can check MySql configuration file(Ex: my.cnf in /etc/mysql  in Ubuntu) whether error log is enabled or not.

    # Error log - should be very few entries.
    log_error = /var/log/mysql/error.log

Once you change the configuration restart MySql server to reflect the changes made for error  log and then find your MySql errors in var/log/mysql/error.log.

The query log:

The query log is very important log also as it tracks every query executed in your MySql Server for your application. It also displays details about which clients are connected to the server and what these clients are doing.

We always emphasise on slow queries but redundant/multiple queries are worse than slow queries.

If you have slow query running for your application then it needs to be refactored for your application for better performance. But if you are not aware of how many queries are running for the feature for your application or there might be chance that duplicate queries are executing through different functions for same feature but you have never got chance to check.

Then query log helps to find out all queries are running for your feature so you can identify redundant query or multiple queries which can be optimised.

Enable query log(Ex: my.cnf in /etc/mysql  in Ubuntu) –

    general_log_file        = /var/log/mysql/mysql.log
    general_log             = 1

After enable the query log make sure to restart your MySql server to reflect the changes. Once you are done then you can just read/var/log/mysql/mysql.log or use the command tail -f /var/log/mysql/mysql.log and browse your feature in application to see how many queries are getting executed for that feature.

The slow query log:

The slow query log lists all queries that takes more than amount of time mentioned in long_query_time variable in configuration file. You can modify long_query_time according to your requirement. Please check the configuration for this setting:

    # Here you can see queries with especially long duration
    #log_slow_queries	= /var/log/mysql/mysql-slow.log
    #long_query_time = 2
    #log-queries-not-using-indexes

Any query that takes longer than long_query_time will be listed in mysql-slow.log file.

Conclusion:

Use the MySql logs to make your application efficient and robust.

Stay tuned for more type of logs in MySql.

Thanks for your valuable time to read the blog and if you like don’t forget to like and share the blog. Comments are always welcome 🙂


 

 

Improve the way of writing functions!

Even though we write lot of functions daily we hardly pay attention how to improve our functions.

FUNCTIONS SHOULD DO ONE THING. THEY SHOULD DO IT WELL. THEY SHOULD DO IT ONLY.

Doing Many Things At A Time!

Before giving attention to write an effective function you need to know what are the main points you need to take into considerations.

  • Small!
  • Blocks and Indenting
  • Do One Thing
  • Reading Code from Top to Bottom: The Stepdown Rule 
  • Use Descriptive Names
  • Function Arguments
  • Duplication

Small!

Function should be small. If you are thinking how small they can be, then I would say 2 lines or 3 lines or 4 lines long but these number of lines are not fixed though. You may consider these line numbers as a checkpoint like if your function has many lines make sure your function is not doing so many things.

Below example is from clean code book can be taken as reference:

    public static String renderPageWithSetupsAndTeardowns(
        PageData pageData, boolean isSuite) throws Exception {
        if (isTestPage(pageData)) {
            includeSetupAndTeardownPages(pageData, isSuite);
        }
        return pageData . getHtml();
    }

Blocks and Indenting

Blocks within if statements, else statements, while statements, and so on should be one line long. Probably that line should be a function call. Not only does this keep the enclosing function small, but it also adds documentary value because the function called within the block can be a nicely descriptive name.

This also implies that function should not be large enough to hold nested structures. Therefore, the indent level of a function should not be greater than one or two. This, of course makes the functions easier to read and understand.

Do One Thing

Your function may have one line of code but doing many things at that line is not a efficient and optimised function.

For Ex:

return level4 != null ? GetResources().Where(r => (r.Level2 == (int)level2) && (r.Level3 == (int)level3) && (r.Level4 == (int)level4)).ToList() : level3 != null ? GetResources().Where(r => (r.Level2 == (int)level2) && (r.Level3 == (int)level3)).ToList() : level2 != null ? GetResources().Where(r => (r.Level2 == (int)level2)).ToList() : GetAllResourceList();

Similarly another example:

function build_address_list_for_zip($zip) {
    $query = "SELECT * FROM ADDRESS WHERE zip = $zip";
    $results = perform_query($query);
    $addresses = array();
    while ($address = fetch_query_result($results)) {
        $addresses[] = $address;
    }

    // now create a nice looking list of
    // addresses for the user
    return $html_content;
}

In this function you are fetching record from database and generating html content and rendering it. So it can be split into two functions:

function fetch_addresses_for_zip($zip) {
    $query = "SELECT * FROM ADDRESS WHERE zip = $zip";
    $results = perform_query($query);
    $addresses = array();
    while ($address = fetch_query_result($results)) {
        $addresses[] = $address;
    }
    return $addresses;
}

function build_address_list_for_zip($zip) {
    $addresses = fetch_addresses_for_zip($zip);

    // now create a nice looking list of
    // addresses for the user
    return $html_content;
}

Reading Code from Top to Bottom: The Stepdown Rule

We normally read like a top-down narrative. So when you are calling function inside another function definition then make sure to define the calling function below the function where it is called instead on top of that function:

Ex:

function getStudentInformation() {
    $this->getName($studentId);
    $this->getAge($studentId);
}

function getName($studentId){
    // return student name
}

function getAge($studentId){
    // return student age
}

It should not be like this:

function getName($studentId){
    // return student name
}

function getAge($studentId){
    // return student age
}

function getStudentInformation() {
    $this->getName($studentId);
    $this->getAge($studentId);
}

Use Descriptive Names

Don’t be afraid to make a name long. A long descriptive name is better than a short name which is difficult to understand.

A long descriptive name is better than a long descriptive comment.

Use a naming convention that allows multiple words to be easily read in the function names, and then make use of those multiple words to give the function name that says what it does.

Don’t be afraid to spend time choosing a name. Indeed, you should try several different names and read the code with each in place. As modern IDEs like Visual Studio, PhpStorm, JetStorm makes it trivial to change function names easily.

Function Arguments

The ideal number of arguments for a function is zero (niladic). Next comes one (monadic), followed closely by two (dyadic). Three arguments (triadic) should be avoided where possible. More than three (polyadic) requires very special justification—and then shouldn’t be used anyway.

If your function is having more number of arguments then your function is doing one thing at a time. So check your code and split the functions doing one thing at a time.

Duplication

Duplication may be the root of all evil in software. Many principles and practices have been created for the purpose of controlling or eliminating it.

If you are writing large functions doing many things then there is more chance of having code duplication in different functions doing same thing which can be refactored by creating small functions. That small function can be invoked in different functions.


Conclusion:-

So check the above points to write an effective and efficient function which is easy for maintenance and can be tested well.

Hope you enjoy reading the blog and please like and share if you like it and what can be improved don’t hesitate to comment 🙂

Stay tune for more on clean and quality code writing.

References:-  

Robert C.Martin Series: Clean Code Book

https://stackoverflow.com/questions/475675/when-is-a-function-too-long

Caching using zend framework(1sT sTEP tOWARDS zERO tO hERO)

In this blog we will discuss how to cache your whole project. When we run our project, php interpreter enters into the public/index.php file and after interpreted the project source code, again it comes out through index.php file.

ppt

 

As in above image we can see index.php is entry point and exit point so if we will start Caching and end Caching in index.php file then our whole project will be cached. We will see how it can be possible through demo.

DEMO

1st Step: 

You should have created project using zend framework. Here we are using zend framework 1.12 for easy understanding. If you want to install framework and create project so check these 2 links.

1. https://www.digitalocean.com/community/tutorials/how-to-install-zend-framework-on-an-ubuntu-12-04-vps

2. http://framework.zend.com/manual/1.12/en/learning.quickstart.create-project.html

2nd Step:

Create clone of the project from https://github.com/tbiswal/quickstart which we will use for demo.

3rd Step:

As we are caching whole project so we will follow #Zend_Cache_Frontend_Output method.

4th Step:

Create directory called cache inside public directory and give full read write permission to cache directory.

5th Step:

Add below code in mentioned files:-

1. quickstart/public/index.php

Add this code before $application->bootstrap()->run();


// auto loader
require_once 'Zend/Loader/Autoloader.php';
$autoloader = Zend_Loader_Autoloader::getInstance();
$autoloader->setFallbackAutoloader(true);

// config
$config = new Zend_Config_Ini(APPLICATION_PATH . '/configs/application.ini', 'production');
$registry = Zend_Registry::getInstance();
$registry->set('config', $config);

// Setup caching option
$frontendOptions = array(
    'lifetime' => 7200, // cache lifetime of 2 hours
    'automatic_serialization' => true
);
$backendOptions = array(
    'cache_dir' => 'cache/' // Directory where to put the cache files
);
$cache = Zend_Cache::factory('Output',
    'File',
    $frontendOptions,
    $backendOptions
);
$registry->set('appCacheObj', $cache);

$appCache = Zend_Registry::get('appCacheObj');

$cacheId = 'myCacheId'.str_replace("/", "_", $_SERVER['REQUEST_URI']);

if(strpos($cacheId, ".php") !== -1) {
    $cacheId = explode(".php", $cacheId)[0];
}

//Clear cache for dynamic page
if($_SERVER['REQUEST_URI'] == "/guestbook/sign") {
    $appCache->remove($cacheId);
}

//Cache start
if($appCache->start($cacheId)) {
    exit;
}

After $application->bootstrap()->run(); add below line:


    //Cache end
    if(!is_null($appCache)){
        $appCache->end();
    }

2. Add below code inside end of the public function save() of models/GuestbookMapper.php file:-


//Clear cache on save action to show new data to user instead of cached data
$appCache = Zend_Registry::get('appCacheObj');
$appCache->clean(Zend_Cache::CLEANING_MODE_ALL);

When you will browse http://quickstart.local/guestbook/sign you will get the page like below.

ppt2

You can check the cache directory which contains the cached files. After click on Sign Guestbook it will clear the cache 1st and then it will create new cached files.

FYI : So for your project you have to clear cache on any save action so that user will get new fetched records otherwise you can show data from cached records.

After completing all the above step when you will browse your project you will find that each page of your application is cached. Only the cached record will be cleaned if you click on any save action. So enjoy 🙂

/*Hope you will love it */

cACHING uSING zEND fRAMEWORK(zERO tO hERO)

In my previous post we have seen simple caching using plain PHP. Here we will learn how to implement caching using Framework. We will use ZendFramework-1.12.3. You might wonder that why I am using very old version framework for caching. Don’t worry I will make you zero to hero in caching step by step. In this version caching is very easy to understand also easy to implement. So let’s start!!

Analysis:

Note: You can also refer manual and for demo you can refer my blog.

Zend_Cache provides a generic way to cache any data. Caching in Zend Framework is operated by frontends while cache records are stored through backend adapters (File, Sqlite, Memcache…) through a flexible system of IDs and tags. Using those, it is easy to delete specific types of records afterwards (for example: “delete all cache records marked with a given tag”).

The core of the module (Zend_Cache_Core) is generic, flexible and configurable. Yet, for your specific needs there are cache frontends that extend Zend_Cache_Core for convenience: Output, File, Function and Class.

Example #1 Getting a Frontend with Zend_Cache::factory()

Zend_Cache::factory() instantiates correct objects and ties them together. In this first example, we will use Core frontend together with File backend.


    $frontendOptions = array(
        'lifetime' => 7200, // cache lifetime of 2 hours
        'automatic_serialization' => true
    );

    $backendOptions = array(
        'cache_dir' => './tmp/' // Directory where to put the cache files
     );

    // getting a Zend_Cache_Core object
    $cache = Zend_Cache::factory('Core',
        'File',
        $frontendOptions,
        $backendOptions
    );

Note: Frontends and Backends Consisting of Multiple Words Some frontends and backends are named using multiple words, such as ‘ZendPlatform’. When specifying them to the factory, separate them using a word separator, such as a space (‘ ‘), hyphen (‘-‘), or period (‘.’).

Example #2 Caching a Database Query Result

Now that we have a frontend, we can cache any type of data (we turned on serialization). for example, we can cache a result from a very expensive database query. After it is cached, there is no need to even connect to the database; records are fetched from cache and unserialized.


    // $cache initialized in previous example
    // see if a cache already exists:
    if( ($result = $cache->load('myresult')) === false ) {

        // cache miss; connect to the database

        $db = Zend_Db::factory( [...] );

        $result = $db->fetchAll('SELECT * FROM huge_table');

        $cache->save($result, 'myresult');

        } else {

            // cache hit! shout so that we know
            echo "This one is from cache!\n\n";

    }

    print_r($result);

Example #3 Caching Output with Zend_Cache Output Frontend

We ‘mark up’ sections in which we want to cache output by adding some conditional logic, encapsulating the section within start() and end() methods (this resembles the first example and is the core strategy for caching).

Inside, output your data as usual – all output will be cached when execution hits the end() method. On the next run, the whole section will be skipped in favor of fetching data from cache (as long as the cache record is valid).

$frontendOptions = array(
    'lifetime' => 30, // cache lifetime of 30 seconds
    'automatic_serialization' => false // this is the default anyways
);

$backendOptions = array('cache_dir' => './tmp/');

$cache = Zend_Cache::factory('Output',
    'File',
    $frontendOptions,
    $backendOptions
);

// we pass a unique identifier to the start() method
if(!$cache->start('mypage')) {
    // output as usual:
    echo 'Hello world! ';
    echo 'This is cached ('.time().') ';
    $cache->end(); // the output is saved and sent to the browser
}

echo 'This is never cached ('.time().').';

Simple Demo: I assume that you have installed zend framework 1.12. Here we will use concept of Example #3 for caching. We will use File as backend adapter to store cache records. So create a directory called “cache” inside public folder with read write permission.

Step 1: Add below code in public/index.php before $application->bootstrap() ->run();


    // auto loader
    require_once 'Zend/Loader/Autoloader.php';
    $autoloader = Zend_Loader_Autoloader::getInstance();
    $autoloader->setFallbackAutoloader(true);

    // registry
    $registry = Zend_Registry::getInstance();

    $frontendOptions = array(
        'lifetime' => 7200, // cache lifetime of 2 hours
        'automatic_serialization' => true
    );

    $backendOptions = array(
        'cache_dir' => 'cache/' // Directory where to put the cache files
    );

    $cache = Zend_Cache::factory('Output',
        'File',
        $frontendOptions,
        $backendOptions
    );
    $registry->set('appCacheObj', $cache);

Step 2: Add below code in indexAction() inside indexController.php


    $appCache = Zend_Registry::get('appCacheObj');
    $cacheId = 'myBigLoop';
    //If cache record is not present then caching will be started from this code
    if($appCache->start($cacheId)) {
        exit;
    }
    $data = '';
    for ($i = 0; $i < 10000; $i++) {
        $data = $data . $i." ";
    }
    $this->view->data = $data;

Step 3: Add below code in index.phtml inside view folder.


<?php
$appCache = Zend_Registry::get('appCacheObj');
    echo $this->data;

//Caching will be ended here
if(!is_null($appCache)){$appCache->end();}
?>

Before caching:

When you will browse your index page( EX: http://localhost/quickstart/public/index.php) 1st time you will get the result 0 to 10000 as output. Now if you will check your cache directory you will find Binary file named “zend_cache—myBigLoop” where myBigLoop was your cacheId. If you will check the time taken to get your output it will be at least more than 70ms.

before_caching

After caching:

When you will browse index page next time you will get your output from cached files. The time taken to generate output will be 3-4 times faster than previous result.

after_caching

For time being you can delete your cached record manually from cache folder and experiment on it. We will deal with little complex demo in my next blog and also we will clear cached record through code.

Reference:

http://framework.zend.com/manual/1.12/en/manual.html

/*Hope you will love it */

Get Images in 16 : 9 Format

After lots of searching in Goggle, Stack exchange finally I am able to generate images in 16:9 format for youtube, dailymotion and vimeo. So lets have a look how can we simply get the thumb images from dailymotion, vimeo and youtube API.

Dailymotion

Step 1:
From the http://www.dailymotion.com/us if you will click on any video you will get the url in this format for that video:

http://www.dailymotion.com/video/<video_id>

Ex: Here is my url http://www.dailymotion.com/video/x267cnn_pree-two-feet-shy-indmusic-in-the-great-outdoors_music

Step 2:
To get the thumb image in 16:9 format, request dailymotion API in this format:

https://api.dailymotion.com/video/<video_id>?fields=thumbnail_360_url&thumbnail_ratio=widescreen

Ex: https://api.dailymotion.com/video/x267cnn_pree-two-feet-shy-indmusic-in-the-great-outdoors_music?fields=thumbnail_360_url&thumbnail_ratio=widescreen

Step 3:
In Step 2 you will get response like this: {“thumbnail_360_url”:”http:\/\/s2.dmcdn.net\/HphZA\/640×360-E1L.jpg”}

Reconstruct the thumbnail_360_url:
EX: http://s2.dmcdn.net/HPhZA/640×360-E1L.jpg

Image:

640x360-E1L

  640×360(16:9)



Vimeo

Step 1:
Get the vimeo video URL. Ex: http://vimeo.com/831365

Step 2:
To get data about a specific video, use the following url:

http://vimeo.com/api/v2/video/video_id.output

video_id : The ID of the video you want information for. output Specify the output type. VIMEO currently offer JSON, PHP, and XML formats.

So getting this URL http://vimeo.com/api/v2/video/831365.xml:


<videos>
  <video>
    [skipped]
    <thumbnail_small>http://i.vimeocdn.com/video/52914011_100x75.jpg</thumbnail_small>
    <thumbnail_medium>http://i.vimeocdn.com/video/52914011_200x150.jpg</thumbnail_medium>
    <thumbnail_large>http://i.vimeocdn.com/video/52914011_640.jpg</thumbnail_large>
   [skipped]
  </video>
</videos>

Parse this for every video to get the thumbnail.

Here’s approximate code in PHP:


<?php
  $videoid = 831365;

  $hash = unserialize(file_get_contents("http://vimeo.com/api/v2/video/$videoid.php"));

  $hash = $hash[0]['thumbnail_large'];

  $pieces = explode("_", $hash);

  echo "Your Image is here: " . $pieces[0] . "_640x360.jpg";
?>

O/P:
Your Image is here: http://i.vimeocdn.com/video/52914011_640x360.jpg

Image:-

52914011_640x360

     640×360(16:9)


Youtube

Step 1:
Get the youtube video url. Ex: http://www.youtube.com/watch?v=10OTg6lD4Jc

Step 2:
Request youtube API for 16:9 format:

http://img.youtube.com/vi/<video_id>/mqdefault.jpg or http://img.youtube.com/vi/<video_id>/maxresdefault.jpg

Ex(Medium quality image):
http://img.youtube.com/vi/10OTg6lD4Jc/mqdefault.jpg

Image:

mqdefault

320×180(16:9)

Ex(High quality image):
http://img.youtube.com/vi/10OTg6lD4Jc/maxresdefault.jpg

7788_91393518121913073

 1280×720(16:9)

References:
http://stackoverflow.com/questions/25740034/show-dailymotion-video-and-thumbnail-in-correct-169-format
http://stackoverflow.com/questions/2068344/how-do-i-get-a-youtube-video-thumbnail-from-the-youtube-api
http://stackoverflow.com/questions/1361149/get-img-thumbnails-from-vimeo

/* Hope You will love it */

CACHING

What is caching?

Caching is an area of a computer’s memory devoted to temporarily storing recently used information. The content, which includes HTML pages, images, files and Web objects, is stored on the local hard drive in order to make it faster for the user to access it, which helps improve the efficiency of the computer and its overall performance.

Most caching occurs without the user knowing about it. For example, when a user returns to a Web page they have recently accessed, the browser can pull those files from the cache instead of the original server because it has stored the user’s activity. The storing of that information saves the user time by getting to it faster, and lessens the traffic on the network.

Caching Mechanism:

Drawing21

Very Simple Example to learn caching in PHP:

Step One: Create the top-cache.php file:

We need to create two files. Here’s the first one: Create a new file named top-cache.php and paste the code below in it.

<?php
  $url = $_SERVER["SCRIPT_NAME"];
  $break = Explode('/', $url);
  $file = $break[count($break) - 1];
  $cachefile = 'cached-'.substr_replace($file ,"",-4).'.html';
  $cachetime = 18000; //in seconds

  // Serve from the cache if it is younger than $cachetime
  if (file_exists($cachefile) && time() - $cachetime < filemtime($cachefile)) {
      echo "<!-- Cached copy, generated ".date('H:i', filemtime($cachefile))." -->\n";
      include($cachefile);
      exit;
  }
  ob_start(); // Start the output buffer
?>

So, what this code does? The first 5 lines create the cached file name according to the current php file. So, if you’re using a file named index.php, the cached file will be named cached-index.html.

Line 6 creates a $cachetime(in seconds) variable which determines the life of the cache. You can experiment by changing the time.

Lines 9 to 13 are a conditional statement which look for a file named $cachefile. If the file is found, a comment is inserted (line 10) and the $cachefile file is included. Then, the exit statement stops the execution of the script and the file is sent to the client brother. Which means that if a static file is found, no php code is interpreted by the server.

Line 14 creates a buffer, if the $cachefile file isn’t found. That’s all for the top-cache.php file.

Step two: Create the bottom-cache.php file:

Now, create a second php file, named bottom-cache.php and paste the code below in it.

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

If a file named $cachefile isn’t found on your server, this code is executed and create the file, so next time the page will be called, the $cachefile static file will be served to the client browser instead of executing the whole PHP file.

Step three: Include cache files on your page
Now that you have created the two necessary files, you simply have to include them on the php page you wish to cache. As you probably guessed, the top-cache.php file must be included in the beginning of your php page and the bottom-cache.php at the end, as shown below:

You can save this page as index.php.

<?php
  include('top-cache.php');

  // Your regular PHP code goes here.
  //You can uncomment the code and test it.
  /*
  for($i=1;$i<=100000;$i++) {
    echo "Hello world";
  }
  */

  include('bottom-cache.php');
?>

Now if you test the cache on a slow page, you’ll be amazed by how faster the page is.

Note: Give full read and write permission to the directory where you will put the above 3 files. For Windows OS no need to give file permission.
Ex: If this is my folder structure in ubuntu():

cac

Then you should give the read and write permission to caching folder.

When you will browse the page after uncommenting the code in step three “http://localhost/caching/index.php” for very 1st time you will see it will take time around 50-70ms. Next time you will see it will show the result in 17 to 25 ms. Its amazing.

Before caching(time taken 63 ms):

before

After Caching(time taken 18 ms):

after

Reference:

http://en.wikipedia.org/wiki/Cache_(computing)

http://www.catswhocode.com/blog/how-to-create-a-simple-and-efficient-php-cache

http://www.citrix.com/glossary/caching.html

/*Hope you will love it*/