Nasrul Hazim Bin Mohamad

PHP-CS-Fixer Configuration

Feb
11

Assalamualaikum / Hi,

Today, just a quick sharing on my PHP-CS-Fixer setup in my Laravel application.

First, you need PHP CS Fixer. You can go through the installation steps here.

Then, I’ve added an alias for my PHP-CS-Fixer alias csfix="php-cs-fixer fix".

Now my PHP-CS-Fixer config file, following are the setup in my Laravel application.

Once done, I just need to run csfix (since I’ve add an alias for the it).

Hope that will be helpful to keep things standardised across your Laravel application.

Thanks,
Nas

WordPress: ORM Model Class

Feb
17

Object Relational Mapping or ORM is something that WordPress is missing, but that doesn’t mean we can’t create an abstract Model that act similar to ORM behavior.

Here are the first version to implement the ORM in WordPres – far from completions.

<?php 

abstract class Model {

	static $table_name = '';

	public static function table() {
		global $wpdb;

		return $wpdb->prefix.static::$table_name;
	}
	
	public static function all($conditions = '') {

		if(!empty(self::table())) {
			global $wpdb;

			$sql = "SELECT * FROM ".self::table() . $conditions;

			return $wpdb->get_results($sql);
		}

		return false;
	}

	public function row($conditions = '') {

		if(!empty(self::table())) {
			global $wpdb;

			$sql = "SELECT * FROM ".self::table() . $conditions;

			return $wpdb->get_row($sql);
		}

		return false;
	}

	public function findById($id) {
		global $wpdb;

		$sql = "SELECT * FROM ".self::table() . " WHERE id = '".$id."'";

		return $wpdb->get_row($sql);
	}

	public static function find($type, $parameters) {
		if(empty($type)) {
			$type = 'all';
		}

		$conditions = isset($parameters['conditions']) ? (' WHERE ' . join(' AND ',$parameters['conditions'])) : null;

		if($type == 'all') {
			return self::all($conditions);
		} else if($type == 'row') {
			return self::row($conditions);
		}

		return false;
	}

	public static function create($data) {
		global $wpdb;

		if($wpdb->insert(self::table(),$data)) {
			$id = $wpdb->insert_id;

			$data = self::findById($id);

			return $data;	
		}

		return false;		
	}

	public static function update($data, $where, $format = null, $where_format = null) {
		global $wpdb;

		return $wpdb->update( self::table(), $data, $where, $format, $where_format );
	}

	public static function delete($data) {
		global $wpdb;

		return $wpdb->delete( self::table(), $data );	
	}
}

Here are the implementation:

<?php

// make sure to include the abstract class first before extending the Model Class

class State extends Model {
	static $table_name = 'states';
}

The usage:

<?php

// include the State class in your plugin first

$states = State::all(); // fetch all available states
$state = State::findById(1); // find state with id = 1
$deleted = State::delete(['id' => 1]); // delete state record with id = 1

More features to add in – to have columns properties, what to hide, what to show, column alias and many more. But this is my first attempt to make the WordPress Plugin Development much easier (an attempt to replicate any famous PHP framework such Laravel, CakePHP and so on. Prefer to have something like Eloquent ORM)

Y2016

Dec
18

Year 2016, InsyaAllah, next year to be a year of sharing knowledge of what I’ve learnt so far. Following are the trainings I would like to conduct:

1. Mobile Apps Development with jQuery Mobile
2. Mobile Apps Development with Intel XDK (incoming)
3. API Development with Slim Framework (incoming)
4. PHP Basic / Advanced
5. Web Development with CakePHP 3 (incoming)
6. Web Development with Laravel 5 (incoming)
7. Web Development with Yii Framework 2 (incoming)
8. WordPress for Developers – Beginner Level
9. WordPress Theme Development
10. WordPress Plugin Development

Those status incoming, it’s the one I’m preparing the syllabus & materials, summarizing the process, and so on. Hope more things can be share other than mentioned above such as the tools I’ve used along the process of the development – Sublime Text 3, SQLYog, Putty, Git and so on

PHP: Convert Image to Base64 Encoding

Dec
11

Simple Image class, convert image to Base64 encoding.

class Image {
	public static function toBase64($image_location) {
		$image_path = $image_location;
		$image_type = pathinfo($image_path, PATHINFO_EXTENSION);
		$image_data = file_get_contents($image_path);
		$image_base64 = 'data:image/' . $image_type . ';base64,' . base64_encode($image_data);

		return $image_base64;
	}
}

Usage:

$b64 = Image::toBase64('https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png');
Base64

Base64

PHP: Detect If It’s IE

Nov
07

IE 11

IE 11

if  (preg_match('~MSIE|Internet Explorer~i', $_SERVER['HTTP_USER_AGENT']) || (strpos($_SERVER['HTTP_USER_AGENT'], 'Trident/7.0; rv:11.0') !== false)) {
    header('Location: https://www.google.com/chrome/browser/desktop/');
}

PHP: Simple Captcha

Oct
12

A simple Captcha using PHP

Demo: Captcha Demo
Source code: Simple Catcha

simple-captcha

simple-captcha

WordPress: Message Class

Sep
20

A simple class for displaying admin messages – error, notice and successful.


class Message {
	public static function error($message) {
		return '<div class="error"><p>'.$message.'</p></div>';
	}

	public static function success($message) {
		return '<div class="updated"><p>'.$message.'</p></div>';
	}

	public static function notice($message) {
		return '<div class="update-nag">'.$message.'</div>';
	}
}

/** 
 * Usage
 **/
Message::error('Hutang 2.6Bil! Bayar!');
Message::notice('Kacing! (PM: eh..cam bunyi duit masuk je');
Message::success('PM: Hasil derma orang bagi. Syukur lahhhh..boleh byr hutang');
wp-admin-message-error

wp-admin-message-error

wp-admin-message-notice

wp-admin-message-notice

wp-admin-message-success

wp-admin-message-success

How to Include PHP ActiveRecord in WordPress as Global Feature

Sep
12

This post for developers who used to ORM/ActiveRecord and not familiar with WordPress Query (like me) and want the ORM/ActiveRecord to be available in WordPress.

As per post’s title, this post regarding how you can include PHP ActiveRecord for global use – let say you have multiple plugins that use PHP ActiveRecord, you can’t load same PHP ActiveRecord classes / redeclared classed in an application or system – to be precise in PHP.

So the solution is to add in PHP ActiveRecord in {wordpress_installation}/wp-includes

Configurations

  1. Download PHP ActiveRecord and extract to {wordpress_installation}/wp-includes
  2. Create a new file in {wordpress_installation}/wp-includes/php-activerecord/ called AR.php and use the codes below
    <?php
    
    class AR {
    	static $conn;
    	static $model_directories;
    
    	public static function add_model_directories($list) {
    		if(!is_array($list)) {
    			return false;
    		}
    
    		if(!is_array(self::$model_directories)) {
    			self::$model_directories = array();
    		}
    
    		foreach ($list as $key => $value) {
    			if(!in_array($value, self::$model_directories)) {
    				self::$model_directories[] = $value;
    			}
    		}
    
    		return true;
    	}
    }
    
    function ar_init() {
    	$connections = array(
    		'development' => 'mysql://'.DB_USER.':'.DB_PASSWORD.'@'.DB_HOST.'/'.DB_NAME,
    	);
    
    	AR::$conn = ActiveRecord\Config::instance();
    	AR::$conn->set_model_directory(AR::$model_directories);
    	AR::$conn->set_connections($connections);
    }
    
  3. Update ActiveRecord\Config class in php-activerecord/lib/Config.php for method set_model_directory and get_model_directory. This to ensure we can include multiple model directories from multiple plugins.:
    	public function set_model_directory($dir)
    	{
    		if( is_array($dir) ) {
    			foreach( $dir as $k => $path ) {
    				if( !file_exists($path ) ) {
    					throw new ConfigException('Invalid or non-existent model directory: '.$path);
    				}
    			}
    		} else if( $dir  && !file_exists( $dir) ) {
    			throw new ConfigException('Invalid or non-existent model directory: '. $dir);
    		}
    
    		$this->model_directory = $dir;
    	}
    
    	public function get_model_directory()
    	{
    		return $this->model_directory;
    	}
    
  4. Include ActiveRecord.php and AR.php in {wordpress_installation}/wp-settings.php after Line 155:
    require( ABSPATH . WPINC . '/php-activerecord/ActiveRecord.php' );
    require( ABSPATH . WPINC . '/php-activerecord/AR.php' );
    
  5. Add the following codes after Line 241 to initialize PHP ActiveRecord:
    /**
     * Initialize PHP ActiveRecord
     */
    ar_init();
    

How to Use in Your Plugin

  1. Create your WordPress Plugin (you can use wppb.me)
  2. Open up your WordPress Plugin main file and add in the following code in order to include your model directory in AR class:
    AR::add_model_directories(array(
    	PLUGIN_PATH . 'includes' . DIRECTORY_SEPARATOR . 'models'
    ));
    
  3. Now create a sample model file which extend ActiveRecord\Model in your plugin’s model directory. Following are the sample codes:
    <?php
    
    class GTState extends ActiveRecord\Model {
    	static $table_name = 'gt_states';
    }
    
  4. Now you’re ready to use the GTState class in your view / controller.

I hope this trick will speed up the development progress.

Sorry WordPress Developers, I need a little hack to develop fast with PHP ActiveRecord, because I’m a beginner with WordPress, more things to learn.

References

  1. Load Multiple Model Directories
  2. PHP ActiveRecord Wiki

Training: Web Mobile Application Development (Basic / Intermediate) – INTIM – August 2015

Aug
16

Training: Web Mobile Application Development (Basic / Intermediate)

Location: INTAN Kampus Wilayah Timur (INTIM), Kemaman, Terengganu

Date: 17th – 20th August 2015

Slide: http://bit.ly/training-web-mobile-application-development

Training Materials:

  1. Web Mobile Application Starter Kit – https://bit.ly/training-mobile-app-starter-kit
  2. Basic Android Configuration – https://bit.ly/training-mobile-app-android-config
  3. API Template – https://bit.ly/training-api-template

Important Articles:

  1. HTTP Methods for Restful Services – http://bit.ly/htpp-nethods-for-restful-services
  2. Android Configuration – http://bit.ly/android-config-xml
  3. Chrome Device Mode – http://bit.ly/chrome-device-mode

 

Web Services: Slim Framework + Eloquent(Laravel)

May
02

Setting up the Restful API is easy with Slim Framework & Eloquent(Laravel). Here are the steps:

  1. Install required components via composer – Slim Framework + Eloquent(Laravel)
  2. Create a database called web_services and create users table.
  3. Setting up Eloquent
  4. Setting up Routes
  5. Final Touch
Web Service Restful API

Web Service Restful API

Install the necessary components using composer – create a composer.json and save it in a working directory and run composer install.

{
    "name": "Web Services",    
    "require": {
        "php": ">=5.3.0",
        "slim/slim": "2.*",
        "slim/views": "0.1.*",
        "illuminate/database": "5.0.*",
        "illuminate/events": "5.0.*"
    },
    "autoload": {
        "classmap": [
            "models"
        ]
    }
}

We’re creating a simple web services for Users – Simple CRUD. Create a database called web_services and run the following SQL statement to create user table.

CREATE TABLE `users` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
  `email` varchar(255) DEFAULT NULL,
  `phone` varchar(45) DEFAULT NULL,
  `created_at` datetime DEFAULT NULL,
  `updated_at` datetime DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

Next, setting up the Eloquent. Create a database.php in config folder(Please create this folder in the working directory) folder.

$database = [
    'driver'    => 'mysql',
    'host'      => 'localhost',
    'database'  => 'web_services',
    'username'  => 'root',
    'password'  => '',
    'charset'   => 'utf8',
    'collation' => 'utf8_unicode_ci',
    'prefix'    => '',
];

use IlluminateDatabaseCapsuleManager as Capsule;

$capsule = new Capsule;

$capsule->addConnection($database);

// Set the event dispatcher used by Eloquent models... (optional)
use IlluminateEventsDispatcher;
use IlluminateContainerContainer;
$capsule->setEventDispatcher(new Dispatcher(new Container));

// Make this Capsule instance available globally via static methods... (optional)
$capsule->setAsGlobal();

// Setup the Eloquent ORM... (optional; unless you've used setEventDispatcher())
$capsule->bootEloquent();

Once we’re done with Eloquent, next we going to set up the routes for Users CRUD operations. Save your time, copy & paste the following codes and save it in config/routes.php.

<?php

$app->get('/api/users', function () {
    echo User::all()->toJson();
});

$app->get('/api/users/:id',  function($id) {
	try {
		echo User::find($id)->toJson();
	} catch (Exception $e) {
		echo '{"error":{"text":'. 'Unable to get the web service. ' . $e->getMessage() .'}}';
	}
});

$app->get('/api/users/search/:query', function($query) {
	echo User::where('name', '=', $query)->get()->toJson();
});

$app->post('/api/users/add', function() use ($app) {
    try {
        $user = new User;

        $user->name = $app->request()->post('name');
        $user->phone = $app->request()->post('phone');
        $user->email = $app->request()->post('email');

        if($user->save()) {
            echo '{"message":"Successfully add new user"}';
        } else {
             echo '{"message":"Failed to add new user"}';
        }
    } catch (Exception $e) {
        echo '{"error":{"text":'. 'Unable to get the web service. ' . $e->getMessage() .'}}';
    }

});

$app->put('/api/users/update/:id', function($id) use ($app) {
    try {
        $user = User::find($id);

        $user->name = $app->request()->post('name');
        $user->phone = $app->request()->post('phone');
        $user->email = $app->request()->post('email');

        if($user->save()) {
            echo '{"message":"Successfully update user info"}';
        } else {
             echo '{"message":"Failed update user info"}';
        }   
    } catch (Exception $e) {
        echo '{"error":{"text":'. 'Unable to get the web service. ' . $e->getMessage() .'}}';
    }
    
});

$app->delete('/api/users/:id', function($id) {
	$user = User::find($id);
	
    if($user->delete()) {
        echo '{"message":"Successfully delete user"}';
    } else {
         echo '{"message":"Failed to delete user"}';
    }
});

OK, here the final touch! 2 things to do, one the index.php and the other one is .htaccess. Here the index.php. Please take note, we require the header("Access-Control-Allow-Origin: *");, to ensured that we can access this Restful API from other domains. There might be security issues. Comments are welcomed.

<?php
try {
	header("Access-Control-Allow-Origin: *");
	require 'vendor/autoload.php';
	require 'config/database.php';
	require 'config/initialize.php';
} catch (Exception $e) {
	echo '{"error":{"text":'. 'Unable to start up the web service. ' . $e->getMessage() .'}}';
}

The .htaccess.

RewriteEngine On

# Some hosts may require you to use the `RewriteBase` directive.
# If you need to use the `RewriteBase` directive, it should be the
# absolute physical path to the directory that contains this htaccess file.
#
# RewriteBase /

RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [QSA,L]

Source code available at: Web Service(Restful API)

I Have 3 demo available:

  1. Web Service App
  2. Web Service Demo
  3. Web Service Mobile Demo