Friday, March 13, 2015

AngularJS + NodeJS + Yoeman + Bower + Grunt

Here comes to new experience with frontend development! AngularJS provide very detail tutorial in setup but I still having error in running npm install. The first step is always difficult as we are fresh and know nothing of it.

But no worry, let's get it clear what is AngularJS before we start to use it!

What is AngularJS?
  1. AngularJS is a structural framework for dynamic web apps. It lets you use HTML as your template language and lets you extend HTML's syntax to express your application's components clearly and succinctly. Angular's data binding and dependency injection eliminate much of the code you would otherwise have to write.
Then get a basic idea from http://www.w3schools.com/angular where they show you AJS directive is are HTML attribute with an ng prefix and some example of AJS expression and AJS controller. Trust me that http://www.w3schools.com/ really provide good tutorial for beginner. After understand the basic syntax, we won't feel like looking at alien code anymore. :D


What is NodeJS and npm?
  1. Node.js® is a platform built on Chrome's JavaScript runtime for easily building fast, scalable network applications. Node.js uses an event-driven, non-blocking I/O model that makes it lightweight and efficient, perfect for data-intensive real-time applications that run across distributed devices.
  2. npm is a package manager for JavaScript, and is the default for Node.js. As of Node.js version 0.6.3, npm is bundled and installed automatically with the environment. npm runs through the command line and manages dependencies for an application.

Step by step setup AngularJS workplace:
  1. Get your workplace ready with git, and node installed.
    1. Install GIT to your workplace if you haven't install.
    2. Open Git Shell and check availability of node, npm via the following command:
      • node --version
      • npm --version
  2. Click HERE to redirect you to to node installer website, download and run the application.
  3. Now you're able to start with the AngularJS tutorial from https://docs.angularjs.org/tutorial.
Who is Yeoman?
He is your computer man who live in npm package repository, sound lovely yea. Yeoman actually is web's scaffolding tools for modern webapps. The lovely part is with one or two command, Yeoman can write entire boilerplate code for your entire web application.

How to install Yeoman?
npm install -g yo


Yeoman also work with other tools -> grunt, gulp, bower for improving your productivity.
Next, go thru this tutorial to learn how to instruct your yeoman to work for you. ^^ VOla!

p/s: There might be blocker while install you run grunt serve, here is some helpful guideline:

  1. npm install -g generator-angular 
  2. yo angular 
  3. bower install angular-ui 
  4. npm install grunt-contrib-compass 
  5. reinstall ruby gem installer (http://rubyinstaller.org/downloads/) with checked all checkbox 
  6. on ruby console - gem install sass 
  7. on ruby console - gem install compass 
  8. grunt test 
  9. grunt serve 
  10. grunt 

Other Good Reference Website:
https://docs.angularjs.org/tutorial
http://www.ng-newsletter.com/posts/beginner2expert-how_to_start.html
http://campus.codeschool.com/courses/shaping-up-with-angular-js/intro
http://angular-tips.com/blog/2013/08/watch-how-the-apply-runs-a-digest/
http://www.ng-newsletter.com/posts/directives.html





Wednesday, March 11, 2015

Yii2: How to Handle Fatal Error.

Fatal error happen when your program process over the php memory limit, or longer process time. It will cause your program to abort or stop the existing process. Without proper handle this issue, the page might look unprofessional.

Here is the tutorial:

Step 1. Prepare file (lib/error.handler.php) with the following code:

function fatalErrorHandler()
{
  // Where yii_log function located
  require_once( __DIR__.DIRECTORY_SEPARATOR.'backend.lib.php'); 
  
  //to get last error message
  $error = error_get_last(); 

  // To track fatal run-time errors
  If ($error['type'] == E_ERROR){

    // to log error note and send email alert.
    yii_log($error, 'error'); 

    // temporary key for jquery to validate 
    echo '<div style="display:none" id="fatal-error">true</div>'; 
     }
   }

  register_shutdown_function('fatalErrorHandler');

Step 2. Include the following code in (config/web.php and config/console.php)

include_once(dirname(__FILE__).DIRECTORY_SEPARATOR.'../lib/error.handler.php');

Step 3. Prepare file (lib/backend.lib.php) with the following code:

function yii_log($message, $level, $exit = FALSE) {
  $message = is_array($message) ? $message['message'] : $message;
  $message = date('Y-m-d H:i:s', time()). ' ' . substr((string)microtime(), 1, 8) . ' - ' . $message;
  switch (strtolower($level)) {
    case 'error':
      Yii::error($message);
      break;
    case 'warning':
      Yii::warning($message);
      break;      
    case 'info':
      Yii::info($message);
      break;
    case 'trace':
    default:
      Yii::trace($message);
      break;
  }
  // Yii::log($message, $level);
  Yii::getLogger()->flush();

  // also alert via email
  send_email_alert($message);
  if($exit) {
    exit();
  }
}

function send_email_alert($message) {
  $from = get_no_reply_email();
  $sendTo = get_alert_email();
  $app_name = Yii::$app->name;

  $headers="From: {$from}\r\nReply-To: {$from}";
  mail($sendTo, $app_name . ' Alert', $message, $headers);

}

Step 4. Prepare Ajax file (check_error.js) checking

$(document).ready(function() {
if ($("#fatal-error").length) {
    //$("upload-csv-form").before('
File: '+decodeURIComponent(getCookie('csvfile')).match(/"(.+)"/)[1]+' import was failed!
'); var filename = decodeURIComponent(getCookie('csvfile')).match(/"(.+)"/)[1]; var postData = { csvfile: filename}; if (typeof yii.getCsrfToken != 'undefined' && yii.getCsrfToken() != '' ) { postData[yii.getCsrfParam()] = yii.getCsrfToken(); } $.ajax({ url: '/member/updatestatus', data: postData, type: 'POST', dataType: 'jason', success: function(){ } }); $("pre").replaceWith('
Importing of '+filename+' did not complete successfully because of a server side error (no memory, performance issues or connection issues).
'); } });
function getCookie(cname) {
var name = cname + "=";
var ca = document.cookie.split(';');
    for(var i=0; i<ca.length; i++) {
        var c = ca[i];
        while (c.charAt(0)==' ') c = c.substring(1);
        if (c.indexOf(name) == 0) return c.substring(name.length,c.length);
    }

Step 5. Register js file in view file
$this->registerJsFile($this->getAssetManager()->getPublishedUrl('@app/themes/dashboard').'/js/check_error.js', ['position' => $this::POS_END]);

Thursday, December 18, 2014

Yii: Check Column Exists before Create Column with Migration Script

You need only 3 simple step to Create Column via Migration Script.

Step 1:
- Create Migration Script with yiic command:
- Goto project and run the following command


protected/yiic migrate create alter_table_column


Step 2:
- Go to folder path protected/migrations and look for file name mxxxxxx_xxxxx_alter_table_column.php
- Add the following command in function up.


public function up()
 {
  $table = Yii::app()->db->schema->getTable('table_name');
  if(!isset($table->columns['column_name'])) {
      // Column doesn't exist then create column
   $this->addColumn('table_name', 'column_name', 'int(11) NOT NULL');
  }
 }

Step 3:
- Run migration script with the following command:


protected/yiic migrate 


~ EOF. Thanks for Reading. ~

Monday, November 10, 2014

PHP Packing Solution - How to divide items equally

This tutorial concept is actually come from stackoverflow where the solution was suggested in ruby script but I had translate it in PHP script.

$list_of_bags = array(11, 41, 31, 15, 15, 66, 67, 34, 20, 42, 22, 25);
# total weight of all bags
$weight_of_bags = array_sum($list_of_bags);
# how many containers do we have at our disposal?
$number_of_containers = 4;
# How much should one container weight?
$weight_per_container = $weight_of_bags / $number_of_containers;
# We make an array containing an empty array for each container
$containers[] = array();

$total = 0;

# For each bag
foreach ($list_of_bags as $bag) {
    for($i=0; $i<$number_of_containers; $i++){

        $total = (isset($containers[$i])) ? array_sum($containers[$i]) : 0;
        if($total + $bag < $weight_per_container){
            $containers[$i][] = $bag;
            break;
        }
    }
}

# output all containers with the number of items and total weight
foreach ($containers as $index=>$container) {
   echo "container $index has ";
   echo count($container);
   echo " ";
   echo "items and weigths: ";
   echo array_sum($container);
   echo "
";
}
Output:
container 0 has 3 items and weigths: 83
container 1 has 3 items and weigths: 96
container 2 has 2 items and weigths: 87
container 3 has 2 items and weigths: 76
container 4 has 2 items and weigths: 47

Wednesday, November 5, 2014

PHP Recursive Function

Tutorial by: Adam Lim


For example we need to create calculation as below:
5 => (5*2)+(4*2)+(3*2)+(2*1)+(1*1)

It can be resolved by for loop as below:

$total=0;
for($i=5; $i=0; $i--){
  $total += $i * 2;
}


To create a recursive function, it should as follow:

function test($int){
  if($int>0){
    echo $int.<br>;
    return(($int*2) + test($int-1));     // call back self function to continue loop
  }else{
    return 0;
  }
}

echo test(5);

Output:
5
4
3
2
1
30

DEMO

Dynamic Photo Framing API

Today bonus is to introduce photo framing api(apisilo.com) for framing industry. It is easy to use as you just need to pass four parameters which is art, frametop, framebtm, and framesize.

Parameter values and file format:
art - Photo or the artwork you wish to frame (only jpg, gif, png file format)
frametop - small piece of frame image, please see sample. (only jpg, gif, png file format)
framebtm - small piece of frame image, please see sample. (only jpg, gif, png file format)
framesize - integer value that you wish to control frame thickness.

How to use it:

Use with jquery getJSON to call API

$.getJSON("http://frame.apisilo.com/index.php?jsoncallback=?",
    {
      art: "http://www.tourismeoutaouais.com/blogue/wp-content/uploads/2014/10/halloween2-620x350.jpg",
      frametop: "http://www.imagemagick.org/Usage/thumbnails/blackthin_btm.gif",
      framebtm: "http://www.imagemagick.org/Usage/thumbnails/blackthin_btm.gif",
      framesize:"50"
    },
    function(data) {
        var str = data['result'];
        var finalData = str.replace(/\\/gi, '');

        $("#framed_artwork").attr("src",finalData);
    });

Append the result in framed_artwork as following:
<img id="framed_artwork" src="sample.jpg" />


DEMO