Code Hinting & Autocompletion for CodeIgniter in PHPStorm

Finally, moving back and forth between models, views and controllers is just too distracting and time consuming. I had to find another way to navigate my way between codes. I tweeted asking about alternative IDEs in Mac OS X to achieve this. Turns out there is a way! I got a tip from @LuisFAlonso (THANK YOU!) to check out instructions from a blog here. I followed the instructions and restarted PHPStorm afterwards. [Read More]

Jajan for Android Open Sourced at Github

Jajan for Android is now Open Sourced at Github a few hours ago. I personally hope that by looking at the source code provided, more and more developers will sync to the tune of how easy it is to create an Android application. I wrote most of the codes 7 August 2011 in under 4 hours. Using ready made libraries already available within Android and also other third party libraries, it helped to ease the complications. [Read More]

Hacking CodeIgniter for Persistent Timestamped Cache with Memcache

I’ve got myself a long title for a blog post this time. This post is exactly what the title says. Been twisting my head figuring out how to bypass CodeIgniter’s internal to hack CodeIgniter’s ability to do a persistent timestamped cache of generated HTML contents using Memcached. I couldn’t find any other way to speed up cached HTML content serving within the framework, so after a long talk with @chazzuka, I made the choice to skip framework. [Read More]

HandlerSocket Client Library for CodeIgniter

These past weeks, I’ve been amazed by the amazing performance offered by HandlerSocket right out of the box. You’d amaze yourself after reading a blog post by Yoshinori Matsunobu about the topic, he managed to get 750 thousands queries per second!

Well I wanted to try it on my own and see how it goes. Here’s a CodeIgniter library intended just for that!

[gist]

<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
/**
* HandlerSocket Library for CodeIgniter
*
* To use this class, please use HandlerSocket's PHP extension available at
* http://code.google.com/p/php-handlersocket/
*
* @package CodeIgniter Library
* @subpackage HandlerSocket
* @category Database
* @author Batista R. Harahap <batista@bango29.com>
* @link http://www.bango29.com
* @license MIT License - http://www.opensource.org/licenses/mit-license.php
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
class Hsock {
protected static $CI;
protected static $conn;
/**
* HandlerSocket Constructor
*
* Initialize with $write = TRUE to connect to HandlerSocket's write Port
*
* @access public
* @param bool write
* @return none
*/
function __construct($write = FALSE) {
$this->CI =& get_instance();
if($write) {
$port =& $this->CI->config->item('hsock_port_write');
} else {
$port =& $this->CI->config->item('hsock_port_read');
}
$this->conn = new HandlerSocket(
$this->CI->config->item('hsock_host'),
$port
);
}
/**
* Open a MySQL table index for query
*
* The parameter $index_id is a free select of any integer, use as if it was the connection ID
*
* @access public
* @param int index_id
* @param string db_name
* @param string table_name
* @param string where_index_name
* @param mixed table_select_fields
* @return bool
*/
function open_index($index_id, $db_name, $table_name, $where_index_name, $table_select_fields) {
if(!is_array($table_select_fields))
throw new HandlerSocketException("Table Fields must be an array while opening index");
$table_select_fields = implode(",", $table_select_fields);
$open = $this->conn->openIndex(
$index_id,
$db_name,
$table_name,
$where_index_name,
$table_select_fields
);
if($open) {
return $open;
} else {
return FALSE;
}
}
/**
* Execute a single query for an opened index
*
* @access public
* @param int index_id
* @param string operand
* @param mixed where_value_fields
* @param int limit
* @param int offset
* @return bool
*/
function execute_single($index_id, $operand, $where_value_fields, $limit = -1, $offset = 0) {
if(!is_array($where_value_fields))
throw new HandlerSocketException("WHERE Value Fields must be an array while executing single query");
$where_value_fields = implode(',', $where_value_fields);
$exec = $this->conn->executeSingle(
$index_id,
$operand,
$where_value_fields,
$limit,
(int)$offset
);
if(!empty($exec)) {
return $exec;
} else {
return FALSE;
}
}
/**
* Execute a multiple query for an opened index
*
* @access public
* @param mixed queries
* @return bool
*/
function execute_multi($queries = array()) {
if(!is_array($queries))
throw new HandlerSocketException("Queries must be an array while executing multi query");
$exec = $this->conn->executeMulti($queries);
if(!empty($exec))
return $exec;
else
return FALSE;
}
/**
* Execute an insert query to an open index's MySQL table
*
* @access public
* @param int index_id
* @param mixed column_values
* @return bool
*/
function execute_insert($index_id, $column_values = array()) {
return $this->conn->executeInsert($index_id, $column_values);
}
/**
* Get errors for queries
*
* @access public
* @return mixed
*/
function get_error() {
return $this->conn->getError();
}
}
/* End of file Hsock.php */
/* Location: application/libraries/ */
view raw Hsock.php hosted with ❤ by GitHub
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
/**
* HandlerSocket Config for CodeIgniter - Please autoload the config!
*
* To use this class, please use HandlerSocket's PHP extension available at
* http://code.google.com/p/php-handlersocket/
*
* @package CodeIgniter Config
* @subpackage HandlerSocket
* @category Database
* @author Batista R. Harahap <batista@bango29.com>
* @link http://www.bango29.com
* @license MIT License - http://www.opensource.org/licenses/mit-license.php
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
if(!defined('HSOCK_WRITE_MODE') && !defined('HSOCK_READ_MODE')) {
define('HSOCK_WRITE_MODE', TRUE);
define('HSOCK_READ_MODE', FALSE);
}
$config['hsock_host'] = '127.0.0.1';
$config['hsock_port_read'] = 9998;
$config['hsock_port_write'] = 9999;
/* End of file hsock.php */
/* Location: application/config/ */
view raw hsock.php hosted with ❤ by GitHub
[/gist]

Amazon SES with Sendmail as Relay

Over and over, sendmail keeps getting whacked out of configuration and it’s puzzling why this keeps happening. I followed everything at Amazon SES' instruction here with no luck. So to set things straight once for all, here are the steps to make the changes permanent. Open up sendmail.mc typically located at /etc/mail Add FEATURE(`mailertable')dnl below where all the FEATURE() codes are Add the lines below at the end of file MAILER_DEFINITIONS Maws-email, P=/etc/aws/ses-send-email. [Read More]

OAUTHnesia for PHP

It’s 2012 now and Urbanesia is publishing a new OAUTHnesia client for Urbanesia’s API. This time it’s for PHP. Why it took so long to actually finish a PHP version is because we gave up on a third party library that is too complicated to do simple things. So without further ado, the codes are available below.

<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
/**
* OAUTHnesia for PHP Class
*
* @package OAUTHnesia
* @subpackage PHP
* @category OAUTH Client
* @author Batista R. Harahap <tista@urbanesia.com>
* @link http://www.bango29.com
* @license MIT License - http://www.opensource.org/licenses/mit-license.php
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
class Oauthnesia {
var $cons_key = "";
var $cons_sec = "";
var $user_key = "";
var $user_sec = "";
var $API_URL = "http://api1.urbanesia.com/";
var $api_uri = "";
function __construct($conf) {
if(empty($conf))
throw new Oauthnesia_Exception("Empty configuration array");
if(empty($conf['consumer_key']))
throw new Oauthnesia_Exception("Please initialize with Consumer Key");
if(empty($conf['consumer_secret']))
throw new Oauthnesia_Exception("Please initialize with Consumer Secret");
if( (empty($conf['user_key']) && !empty($conf['user_secret'])) || (!empty($user_key) && !empty($user_sec)) )
throw new Oauthnesia_Exception("Both User Tokens must be initialized");
$this->API_URL = !empty($conf['api_base_url']) ? $conf['api_base_url'] : $this->API_URL;
$this->cons_key = $conf['consumer_key'];
$this->cons_sec = $conf['consumer_secret'];
$this->user_key = !empty($conf['user_key']) ? $conf['user_key'] : '';
$this->user_sec = !empty($conf['user_secret']) ? $conf['user_secret'] : '';
}
function request($uri = "", $post = "", $get = "", $with_user_key = false) {
if(empty($uri))
throw new Oauthnesia_Exception("API URI must be initialized");
if(!is_string($uri))
throw new Oauthnesia_Exception("API URI must be a String object");
if(!is_string($post))
throw new Oauthnesia_Exception("API POST Requests must be a String object");
if(!is_string($get))
throw new Oauthnesia_Exception("API GET Requests must be a String object");
if(!is_bool($with_user_key))
throw new Oauthnesia_Exception("User Key Signing flag must be boolean");
$this->api_uri = $uri;
// Add default POST requirements for Urbanesia
$def_post = $this->get_default_post($with_user_key);
// Merge POST with default POST
if(empty($post))
$post = $def_post;
else
$post .= "&" . $def_post;
// Encode POST and GET for OAUTH
$post = $this->encode_for_oauth($post);
$get = $this->encode_for_oauth($get);
// Encode the whole GET + POST
$requestify = $this->sortify($post ."&". $get);
// Base Signature
$base_sig = $this->get_base_sig($requestify);
// Sign the request with Consumer/User Secret
$oauth_sig = hash_hmac("SHA1", $base_sig, $this->cons_sec . "&" . $this->user_sec, TRUE);
$oauth_sig = base64_encode($oauth_sig);
$oauth_sig = str_replace("=", "%3D", $oauth_sig);
$oauth_sig = str_replace("+", "%2B", $oauth_sig);
$oauth_sig = "?oauth_signature=" . $oauth_sig;
$url = $this->API_URL . $this->api_uri . $oauth_sig . "&" . $get;
return $this->send_request($url, $post);
}
function xauth($username, $password) {
if(empty($username))
throw new Oauthnesia_Exception("No username specified for xAuth");
if(empty($password))
throw new Oauthnesia_Exception("No password specified for xAuth");
$this->api_uri = "oauth/access_token";
// Add default POST requirements for Urbanesia
$def_post = $this->get_default_post(FALSE);
// Xauth Default POST
$xpost = "&x_auth_username={$username}&x_auth_password={$password}&x_auth_mode=client_auth";
// Merge POST with Xauth
$post = $this->encode_for_oauth($def_post . $xpost);
// Base Signature
$base_sig = $this->get_base_sig($post);
// Sign the request with Consumer/User Secret
$oauth_sig = hash_hmac("SHA1", $base_sig, $this->cons_sec . "&" . $this->user_sec, TRUE);
$oauth_sig = base64_encode($oauth_sig);
$oauth_sig = str_replace("=", "%3D", $oauth_sig);
$oauth_sig = str_replace("+", "%2B", $oauth_sig);
$oauth_sig = "?oauth_signature=" . $oauth_sig;
$url = $this->API_URL . $this->api_uri . $oauth_sig;
$result = $this->send_request($url, $post);
$r =& $result['response'];
if(
!empty($r->result) &&
!empty($r->result->oauth_token_key) &&
!empty($r->result->oauth_token_secret) &&
!empty($r->result->first_name) &&
!empty($r->result->last_name) &&
!empty($r->result->account_id)
) {
return $r->result;
} else {
return FALSE;
}
}
function send_request($url, $post) {
if(empty($url) || empty($post))
throw new Oauthnesia_Exception("Empty URL/POST request for CURL");
$c = curl_init();
curl_setopt($c, CURLOPT_USERAGENT, "OAUTHnesia for PHP v1.0");
curl_setopt($c, CURLOPT_CONNECTTIMEOUT, 1);
curl_setopt($c, CURLOPT_TIMEOUT, 5);
curl_setopt($c, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($c, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($c, CURLOPT_FOLLOWLOCATION, TRUE);
curl_setopt($c, CURLOPT_URL, $url);
curl_setopt($c, CURLOPT_POST, TRUE);
curl_setopt($c, CURLOPT_POSTFIELDS, $post);
$response = curl_exec($c);
$code = curl_getinfo($c, CURLINFO_HTTP_CODE);
$info = curl_getinfo($c);
$mem = memory_get_usage(TRUE);
$return = array(
'response' => json_decode($response),
'code' => $code,
'info' => $info,
'memory' => round($mem/1024/1024, 2) . " MB"
);
return $return;
}
function get_base_sig($req) {
return "POST&" . rawurlencode($this->API_URL . $this->api_uri) . "&"
. rawurlencode($req);
}
function sortify($body) {
$arr = explode("&", $body);
$arr = array_filter($arr);
array_multisort($arr);
return implode("&", $arr);
}
function encode_for_oauth($var) {
$vars = explode("&", $var);
$vars = array_filter($vars);
array_multisort($vars);
$return = "";
for($i=0, $j=0, $max=count($vars); $i<$max; $i++) {
if($j === 1)
$return .= "&";
$tmp = explode("=", $vars[$i]);
$return .= rawurlencode($tmp[0]) . "=" . rawurlencode($tmp[1]);
$j = 1;
}
return $return;
}
function get_default_post($with_user_key = false) {
if($with_user_key === TRUE && empty($this->user_key))
throw new Oauthnesia_Exception("Trying to make a request signed with User Secret without initializing with User Secret");
$post = "oauth_consumer_key=" . $this->cons_key
. "&oauth_nonce=" . $this->get_nonce()
. "&oauth_signature_method=HMAC-SHA1"
. "&oauth_timestamp=" . mktime()
. "&oauth_version=1.0"
. "&safe_encode=1";
if($with_user_key)
return $post . "&oauth_token=" . $this->user_key;
else
return $post;
}
function get_nonce() {
return md5(microtime(TRUE));
}
function safe_encode($data) {
if (is_array($data)) {
return array_map(array($this, 'safe_encode'), $data);
} else if (is_scalar($data)) {
return str_ireplace(
array('+', '%7E'),
array(' ', '~'),
rawurlencode($data)
);
} else {
return '';
}
}
}
class Oauthnesia_Exception extends Exception {}
view raw OAUTHnesia.php hosted with ❤ by GitHub

The Improbability of The Impossible

How many strands of thread does it take to keep us from being naked everyday? A whole lot for sure! How do you somehow collect all those strands and weave them into a single united strands that we wear everyday? Easy, a needle, strands with enough length and a significant amount of time and energy should suffice. So what’s the substance connecting all the dots? Technology. Dissecting and subordinating the impossible usually starts with HOW. [Read More]

Mobile Products & Handhelds Landscape

It’s been a few weeks after the whole world said their good byes to Steve Jobs, the iconic leader any startup/company should aspire to have. Everyone was in awe for what he did but mostly for what he didn’t do I suppose. He shaped the mobile landscape as we know today and for the years to come. I believe strongly that mobile developers are candidly smart but also stupid at the same time, this includes myself. [Read More]

Create Your Own Android Splash Screen and Boot Animation

So far my experience compiling my own version of Android using CyanogenMod 7.1 here is as sharp as it can be. I’m running it smoothly on my Nexian Journey and it’s time to do some changes to CM’s default theme to show my own. Either creating the splash screen or the boot animation, each of the tasks have its own complication. I’m gonna start off by creating a boot animation. [Read More]