Nasrul Hazim Bin Mohamad

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

CakePHP 2.x: Pagination Element

May
25

Being working on Bootstrap Pagination with CakePHP. Here the final one. Use it as you needed.

References:

  1. CakePHP 2.x Pagination
  2. Bootstrap Pagination
  3. CakeDC Users
<nav>
  	<ul class="pagination">	
  	<?php
		echo $this->Paginator->prev('< ' . __d('users', 'previous'), array('tag' => 'li'), null, array('disabledTag' => 'span', 'class' => 'disabled'));
		echo $this->Paginator->numbers(array(
			'separator' => '',
			'tag' => 'li',
			'currentTag' => 'span',
			'currentClass' => 'active'
		));
		echo $this->Paginator->next(__d('users', 'next') . ' >', array('tag' => 'li'), null, array('disabledTag' => 'span', 'class' => 'disabled'));
	?>
	</ul>
</nav>

Training – CakePHP Basic

Dec
26

MySQL: Save Arabic Characters / Words

Aug
13

Database / Table for Arabic Usage

  1. Charset – UTF-8
  2. Collation – utf8_unicode_ci

Example:


# Database
CREATE DATABASE `db_arabic`CHARACTER SET utf8 COLLATE utf8_unicode_ci;

# Table
CREATE TABLE `db_arabic`.`users`( `id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT, `name` VARCHAR(255), `created` DATETIME, `modified` DATETIME, PRIMARY KEY (`id`) ) CHARSET=utf8 COLLATE=utf8_unicode_ci; 

In CakePHP, make sure to set 'encoding' => 'utf8' in database.php.

You can have Arabic Lorem Ipsum at Multilanguage Lorem Ipsum Generator

For web page, please ensure to add meta tag, charset `utf-8′, as following:

&lt;meta charset=&quot;utf-8&quot; /&gt;

Reference: How to save Arabic Words Into MySQL Table

CakePHP: Running Shell Script with Cronjob

May
27

Create a Shell Script

Create a ScheduleShell.php in cakephp/app/Console/Command.

&lt;?php
class ScheduleShell extends Shell {
    function main() {
    	$this-&gt;out('Hello World');
    }
}
?&gt;

Add a cronjob

sudo crontab -e

I have a cronjob running every 5 minute for ScheduleShell.php

# cronjob run every 5 minute
*/5  *    *    *    * cd /var/www/html/cakephp/app &amp;&amp; Console/cake schedule

CakePHP: Upload File

Apr
18

The Model

&lt;?php

App::uses('AppModel', 'Model');

class Picture extends AppModel {
	public $useTable = 'picture';
	public $primaryKey = 'id';
	public $name = 'Picture';
	public $order = 'Picture.id ASC';

	protected $_displayFields = array(
		'id',
		'name',
		'link',
	);
}
?&gt;

The Database

CREATE TABLE `picture` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
  `link` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1

The View

&lt;?php
	echo $this-&gt;Form-&gt;create('Upload',array(
		'enctype' =&gt; 'multipart/form-data',
		'url' =&gt; array(
			'controller' =&gt; 'upload', 
			'action' =&gt; 'index'
		)
	));
	echo $this-&gt;Form-&gt;file('file');
	echo $this-&gt;Form-&gt;end(array(
		'label' =&gt; 'Submit',
		'class' =&gt; 'btn btn-success'
	));
?&gt;

The Controller

&lt;?php

App::uses('AppController', 'Controller');

class UploadController extends AppController { 
	public function index() {
                // in this example, we're trying to accept gif,jpeg and png

                $image = $this-&gt;request-&gt;data['Upload']['file'];

                $imageTypes = array(&quot;image/gif&quot;, &quot;image/jpeg&quot;, &quot;image/png&quot;);

                $uploadFolder = &quot;img&quot; . DS . &quot;photos&quot; . DS;

                $uploadPath = WWW_ROOT . $uploadFolder;

                $id = null;

                if(!empty($image['name']))
                {
                        $ext = substr(strtolower(strrchr($image['name'], '.')), 1); //get the extension

                        if(in_array($image['type'], $imageTypes))
                        {
                                $date = date_create();
                                $rand = rand(100000,999999);
                                $link = 'pic_' . date_format($date, 'U') . '_' . $rand . '.' . $ext;

                                move_uploaded_file($image['tmp_name'], $uploadPath . $link);

                                $this-&gt;Picture-&gt;create();
                                $this-&gt;Picture-&gt;set(array('name' =&gt; $image['name'], 'link' =&gt; $link));
                                $this-&gt;Picture-&gt;save();
                                $id = $this-&gt;Picture-&gt;id;
                                $this-&gt;Session-&gt;setFlash('Picture uploaded!');
                        }
                        else
                        {
                                $this-&gt;Session-&gt;setFlash('Only files with extension .gif, .png and .jpeg are allowed to be upload.');
                        }
                }

	}
}
?&gt;

CakePHP: PHPMailer Component – Using GMail SMTP

Apr
12

Requirements:

  1. CakePHP 2.x
  2. PHPMailer

Download PHPMailer & extract it to APP/vendors.

Add following lines in APP/vendors/phpmailer/class.phpmail.php line 542, in ELSE statement. This to ensure we have a secured domain through SSL / TLS.

// add a variable named SMTPSecure - SSL / TLS
var $SMTPSecure

// line 542 
if(!empty($this-&gt;SMTPSecure))
{
    $secure = $this-&gt;SMTPSecure . '://';
}

Create a component called EmailComponent in APP/app/Controller/Component

&lt;?php

App::uses('Component', 'Controller');
App::import('Vendor', 'phpmailer', array('file' =&gt; 'phpmailer'.DS.'class.phpmailer.php'));

class EmailComponent extends Component {

  public function send($to, $subject, $message) {
    $sender = &quot;from_you@you.com&quot;; // this will be overwritten by GMail

    $header = &quot;X-Mailer: PHP/&quot;.phpversion() . &quot;Return-Path: $sender&quot;;

    $mail = new PHPMailer();

    $mail-&gt;IsSMTP();
    $mail-&gt;Host = &quot;smtp.gmail.com&quot;; 
    $mail-&gt;SMTPAuth = true;
    $mail-&gt;SMTPSecure = &quot;ssl&quot;;
    $mail-&gt;Port = 465;
    $mail-&gt;SMTPDebug  = 2; // turn it off in production
    $mail-&gt;Username   = &quot;[yourGMailAccount]@gmail.com&quot;;  
    $mail-&gt;Password   = &quot;password&quot;;
    
    $mail-&gt;From = $sender;
    $mail-&gt;FromName = &quot;From Me&quot;;

    $mail-&gt;AddAddress($to);

    $mail-&gt;IsHTML(true);
    $mail-&gt;CreateHeader($header);

    $mail-&gt;Subject = $subject;
    $mail-&gt;Body    = nl2br($message);
    $mail-&gt;AltBody = nl2br($message);

    // return an array with two keys: error &amp; message
    if(!$mail-&gt;Send()) {
      return array('error' =&gt; true, 'message' =&gt; 'Mailer Error: ' . $mail-&gt;ErrorInfo);
    } else {
      return array('error' =&gt; false, 'message' =&gt;  &quot;Message sent!&quot;);
    }
  }
}

?&gt;

Create a controller, ExampleController.php to test out our EmailComponent

&lt;?php

App::uses('AppController', 'Controller');

class ExampleController extends AppController {
	public $components = array('Email');
	public function index() {
		// just to test out the sending email using SMTP is OK, create a method that will be able to access from public
		$to = '[someone@you.com]';
		$subject = 'Hi buddy, i got a message for you.';
		$message = 'Nothing much. Just test out my Email Component using PHPMailer.'
		$mail = $this-&gt;Email-&gt;send($to, $subject, $message);
		$this-&gt;set('mail',$mail);
		$this-&gt;render(false);
	}
}

When you navigate to http://localhost/APP/Example, the email should send to [someone@you.com]. Please do check the mailbox. 🙂

References:

  1. http://phpmailer.worxware.com/?pg=examplebgmail
  2. http://blog.teamtreehouse.com/sending-email-with-phpmailer-and-smtp
  3. http://book.cakephp.org/2.0/en/controllers/components.html#creating-a-component