Thursday, February 5, 2015

Notes In Resolving Conflict on GIT Rebase

So after doing git rebase master from a featured branch or some other branch you get a conflict.

Here are some notes on resolving.
  • After getting the conflict, you will be redirected to temporary branch where you have to resolve your conflict.
  • Resolve your conflicts as usual removing <<<<<<, ======, >>>>>>>> and doing your manual merges
  • After resolving do a git add .
  • Do not commit but after doing git add do git rebase --continue or git will complain about having no resolution to your conflict
  • The rebase should go as usual

Tuesday, November 4, 2014

Access SSL Enabled URL via Curl

Sometimes you may have problems accessing URL that are SSL enabled. The solution is to simply set the flags below:


    $ch = curl_init();
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
To output and debug the problem you can:
curl_setopt($ch, CURLOPT_VERBOSE, TRUE);
curl_setopt($ch, CURLOPT_STDERR, fopen('php://temp', 'rw+'));
$result = curl_exec($ch);
curl_close($ch);

if ($result === FALSE) {
    printf("cUrl error (#%d): %s
\n", curl_errno($curlHandle),
           htmlspecialchars(curl_error($curlHandle)));
}

rewind($verbose);
$verboseLog = stream_get_contents($verbose);

print_r($verboseLog);

Monday, April 14, 2014

How to Fix SSHFS Mounts Not Writable by PHP

Problem:
When accessing a php file in the browser that uses is_writable(), is_dir(),... etc of a mounted directory through sshfs, PHP sometimes cannot detect the mounted directory so the functions above always returns false.

1.) Steps to resolve:
$> sudo adduser $USER fuse
$> ls -l /etc/fuse.conf
$> sudo chmod a+r /etc/fuse.conf

2.) Edit fuse.conf and enable user_allow_other
$> sudo vim /etc/fuse.conf

3.) Connect with allow_user
sshfs -o allow_other,uid=1000,gid=33 user@192.168.1.101:/path/to/mounted/mydir mydir

Sunday, January 12, 2014

install fastcgi

sudo apt-get update && sudo apt-get install libapache2-mod-fastcgi sudo a2enmod fastcgi

Monday, January 6, 2014

Composer Update/Install

Dont install require-dev packages (--no-dev), prefer the distribution packages (--prefer-dist), maximum verbosity (-vvv), show profiles such as memory usage and time (--profile)
php composer.phar update --no-dev --prefer-dist -vvv --profile

Tuesday, November 26, 2013

Tip: How to Add Timestamp With CURRENT_DATETIME in Doctrine 2 ORM

Assuming that your database profiler is Mysql:
    /**
     * @ORM\Column(type="datetime", nullable=false)
     * @ORM\Version
     * @var string
     */
    protected $creationTimestamp;

The above declaration should produce:
CREATE TABLE mytable (creationTimestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL);
The trick is adding @Version which converts the type 'datetime' to 'timestamp'. Remember that this is only for MySql profiler.

Wednesday, November 20, 2013

How to use ZF2's Curl Http Adapter with Header information

Just sharing some of my painful WTF experiences using ZF2's Curl Http client adapter so you wont have to deal with my headaches.

Basically I am trying to send a CURL_HTTPHEADER with these params.
This is what it should look like straight php:

$c = curl_init('http://url');
curl_setopt($c, CURLOPT_POST, 1);
curl_setopt($c, CURLOPT_POSTFIELDS, $data);
curl_setopt($c, CURLOPT_HTTPHEADER, array(
    'Content-type: application/json',
    'Authorization: Bearer 1jo41324knj23o'
));
Simple enough right? Well I was assuming the same thing using ZF2's Curl Adapter:
$client = new Client('http://url');
$client->setMethod('post');

$adapter = new Curl()
$adapter->setCurlOption(CURLOPT_POST, 1);
$adapter->setCurlOption(CURLOPT_POSTFIELDS, $data);
$adapter->setCurlOption(CURLOPT_HTTPHEADER, array(
    'Content-type: application/json',
    'Authorization: Bearer 1jo41324knj23o'
));
Well the thing is this will not work because the headers and data are being set exclusively by write() in the client object as you will see in the source:
// inside Curl::write()
// line 374 Curl.php
curl_setopt($this->curl, CURLOPT_HTTPHEADER, $curlHeaders);

// line 380 Curl.php
if ($method == 'POST') {
    curl_setopt($this->curl, CURLOPT_POSTFIELDS, $body);
}

// line 398 Curl.php
if (isset($this->config['curloptions'])) ...
    foreach ((array) $this->config['curloptions'] as $k => $v) ...
 
Notice at line 398 that this is where the remaining curl parameters gets set. This means that CURLOPT_HTTPHEADER and CURLOPT_POSTFIELDS have already been defined so our usage from above will not work (Maybe there is a CURL flag to overwrite this, I just don't know at the moment). So how do you make this work? You have to pass your definitions in the Client object:
$client = new Client('http://url');
$client->setMethod('post');
$client->setRawBody($data);
$client->setHeaders(array(
    'Content-Type: application/json',
    'Authorization: Bearer 1jo41324knj23o',
));
$client->setAdapter(new Curl());
$client->send();
Now the write() method will pull from these params when assembled

Saturday, November 16, 2013

Automagic Mod_Vhost_Alias for Vagrant precise PHP

Just sharing my Apache vhost to enable automatic virtual hosting for my development environment.
This will enable anything you put to '/vagrant/www/*' a vhost with a public directory. Useful if you are working with frameworks that redirects everything to public/index.php (e.g. Zend Framework)
A directory like:
vagrant/
    www/
        mysite/
            public/
        myothersite/
            public/

Will automatically setup:
1. http://mysite.local
2. http://myothersite.local

And here is the configuration:
<Virtualhost *:80>
    VirtualDocumentRoot "/vagrant/www/%-2+/public"
    ServerName vhosts.local
    ServerAlias *.local
    UseCanonicalName Off
    LogFormat "%V %h %l %u %t \"%r\" %s %b" vcommon

    ErrorLog  /var/log/apache2/local-error_log
    CustomLog /var/log/apache2/local-access_log common

    <Directory ~ "/vagrant/www/[a-z0-9_]+/public">
        Options Indexes FollowSymLinks MultiViews
        AllowOverride All
        Order Allow,Deny
        Allow from all

        <IfModule mod_rewrite.c>
            RewriteEngine On
            RewriteBase /
            RewriteCond %{REQUEST_FILENAME} -s [OR]
            RewriteCond %{REQUEST_FILENAME} -l [OR]
            RewriteCond %{REQUEST_FILENAME} -d
            RewriteRule ^.*$ - [NC,L]
            RewriteCond %{REQUEST_URI}::$1 ^(/.+)(.+)::\2$
            RewriteRule ^(.*) - [E=BASE:%1]
            RewriteRule ^(.*)$ %{ENV:BASE}index.php [NC,L]
        </IfModule>
    </Directory>
</Virtualhost>

Monday, November 4, 2013

How to use ZF2's Service Manager Factories with Constructor Based Objects Returning New Instances

Say you have a manufacturer that produces books and you have multiple new instances of books with different title being manufactured. How would you do this via the Service Manager?

Your book factory accepts a title in its constructor.
class Book
{
    protected $title;

    public function __construct($title)
    {
        $this->title = $title;
    }
}
Now the trick is inside the factory. You need to return a closure inside of a closure like bellow in order to pass a new '$title' and a new instance of book. 
//module.php
'factories' => array(
    'BookFactory' => function ($sm) {
        return function ($title) {
             return new Book($title);
        }
    }
),
In your Manufacturer object.
class BookManufacturer implements ServiceLocatoryAwareInterface
{
    protected $title = array('Lord of the Rings', 'Wheel of Time');

    public function manufacture($qty)
    {
       $bookFactory = $this->getServiceLocator()->get('BookFactory');

       $books = array();
       for ($i = 0; $i <= $qty; ++$i) {
           $books[] = $bookFactory($this->title[rand(0, count($this->title) - 1)]);
       }

       return $books;
    }
}
Or simplified example where you just want a new instance of Book.
// controller
$bookFactory = $this->getServiceLocator()->get('BookFactory');
$book1 = $bookFactory('Lord of the Rings');
$book2 = $bookFactory('Wheel of Time');

var_dump($book1); // new instance of Book with 'Lord of the rings title'
var_dump($book2); // new instance of Book with 'Wheel of time Title'
Does this smells like functional programming?

Friday, November 1, 2013

Saturday, September 21, 2013

How to Pass the ServiceManager to Forms and Taking Advantage of the init()

Seems pretty easy and its also documented in the ZF2 docs but I think its worth repeating here.

In short, when creating forms by extending the Form object it is a good practice to create your elements inside the init() method.

namespace class\name\space;
class MyForm extends Form implements ServiceLocatorAwareInterface
{
    protected $serviceLocator;

    public function __construct()
    {
        $this->setName('MyForm');
    }

    public function init()
    {
        $this->add(array(
            'type' => 'MyCustomFieldset', // You are not using a class name space,
            'name' => 'custom_fieldset',
        ));

        $this->add(array(
            'type' => 'Select',
            'name' => 'custom_select',
            'options' => array(
                'value_options' => $this->getSelections(), // you can access methods via the ServiceManager now!
            ),
        ));
    }

    public function getSelections()
    {
         $mainServiceManager = $this->getServiceLocator()->getServiceLocator();
         
         return $mainServiceManager->get('someService')
                                   ->someMethodThatCreateSelectionArray();
    }

    public function getServiceLocator()
    {
        return $this->serviceLocator;
    }

    public function setServiceLocator(ServiceLocator $serviceLocator)
    {
        $this->serviceLocator = $serviceLocator;
    }
}
As you see from above, you have access now to the ServiceManager. You can even use $this->getSelections(). You will not be able to do that inside the __construct()!

Of course, you have to set this up inside Module.php via the Form Element Manager
//Module.php

public function getFormElementConfig()
{
    return array(
        'invokables' => array(
            'MyForm' => 'class\name\space\MyForm',
            'MyCustomFieldset' => 'class\name\space\MyFieldset',
        )
    );
}
To access the form, simply pull it from the Form Element Manager
// some controller
public function indexAction()
{
    $form = $this->getServiceLocator()->get('FormElementManager')->get('MyForm');
    return ViewModel(array(
        'form' => $form,
    ))
}

Saturday, September 7, 2013

How to Create a Custom ZF2 ServiceManager Plugin?

If you want to discover how a ServiceManager Plugin gets initialized go here:
http://www.franzdeleon.me/2013/09/how-does-servicemanager-plugin-get.html

So how do we register our own custom ServiceManager Plugin?

1.) First create a Plugin Manager:

use Zend\ServiceManager\AbstractPluginManager;
class CustomPluginManager extends AbstractPluginManager
{
    public function validatePlugin($plugin)
    {
        if (!$plugin instanceof CustomeInterface) {
            throw new ErrorException('Wrong intance of plugin');
        }
    }
}
2.) Then create a ServiceManager Factory that returns an instance of your just created CustomPluginManager:

use Zend\Mvc\Service\AbstractPluginManagerFactory;
class CustomManagerFactory extends AbstractPluginManagerFactory
{
    const PLUGIN_MANAGER_CLASS = 'Namespace\to\CustomPluginManager';
    public function createService(ServiceLocatorInterface $serviceLocator)
    {
        $plugins = parent::createService($serviceLocator);
        return $plugins;
    }
}
3.) Now lets define an interface for our plugin config:

interface CustomPluginProviderInterface
{
    public function getCustomPlugin();
}

4.) Then we need to put this all together by registering our CustomPlugin plugin in Module.php. We first need to register our Factory:

//inside Module.php
public function getServiceConfig()
{
    return array(
        'factories' => array(
            'customPluginManager' => 'namespace\to\CustomManagerFactory',
        ),
    )
}
5.) In order for the Plugin to be created as a plugin manager, we need to register it to the Service Listener. We do this via init() method. It is important to put this inside init() as this is called before the MVC bootstrapping.

// inside Module.php
public function init(ModuleManager $moduleManager)
{
    $sm = $moduleManager->getEvent()->getParam('ServiceManager');
    $serviceListener = $sm->get('ServiceListener');
    $serviceListener->addServiceManager(
        'customPluginManager',
        'custom_plugin_config',
        'namespace\to\CustomPluginProviderInterface',
        'getCustomPluginConfig'
    );
}
6.) Now you can register to your custom plugin from other modules!
// in some other Module.php
public function getCustomPluginConfig()
{
    return array(
        'invokables' => array(
            'AclService' => 'namespace/to/AclService'
        )
    )
}
7.) Then you can call it for example inside a controller:
 
// inside controller.php in some other module
public function someAction()
{
    $aclService = $this->getServiceLocator()->get('customPluginManager')->get('AclService');
}

That is pretty much it!

Reference:
http://raing3.gshi.org/2013/05/26/creating-custom-plugin-manager-in-zend-framework-2/

How Does a ServiceManager Plugin gets Initialized?

Hopefully this post will explain and answer this question.

For this example, I will trace the initialization of the FilterManager Plugin.
For those who are not familiar with the plugin functionality of ZF2, it is basically an extension of the Service Manager that you can use for organization and other things.

As an example, you are calling a plugin manager when you do something like below:

// from Controller
$stringTrimFilter = $this->getServiceLocator()->get('FilterManager')->get('stringTrim');

// from inside a View. basePath is a View Helper Plugin
$this->basePath('/some/uri');

Now lets get down to business. So how does a plugin gets created and initialized?

1.) We will start from the ModuleManagerFactory for simplicity's sake. In the ModuleManagerFactory (https://github.com/zendframework/zf2/blob/master/library/Zend/Mvc/Service/ModuleManagerFactory.php) the Service Listener Factory gets initialized. (see line 38 and called on 44)

2.) In the Service Listener Factory (https://github.com/zendframework/zf2/blob/master/library/Zend/Mvc/Service/ServiceListenerFactory.php) a bunch of Plugin Factories gets initialized also.

One of the plugin factories that gets initialized is the FilterManager factory which looks like this. See line 54:

'FilterManager' => 'Zend\Mvc\Service\FilterManagerFactory',

3.) Lets go to the FilterManagerFactory (https://github.com/zendframework/zf2/blob/master/library/Zend/Mvc/Service/FilterManagerFactory.php).The class is basically a ServiceManager Factory implementation class.

4.) The FilterManagerFactory file extends AbstractPluginManagerFactory (https://github.com/zendframework/zf2/blob/master/library/Zend/Mvc/Service/AbstractPluginManagerFactory.php) which is basically an implementation of FactoryInterface.php. That means we are instantiating an object. What object?

5) The FilterManagerFactory will INSTANTIATE and RETURN an instance of FilterPluginManager (https://github.com/zendframework/zf2/blob/master/library/Zend/Filter/FilterPluginManager.php) see line 17:

const PLUGIN_MANAGER_CLASS = 'Zend\Filter\FilterPluginManager';

6.) Now an instance of FilterPluginManager is created. It is important to note that FilterPluginManager extends AbstractPluginManager (https://github.com/zendframework/zf2/blob/master/library/Zend/ServiceManager/AbstractPluginManager.php) which is basically an own ServiceManager class!

The FilterPluginManager class also invokes a bunch of ZF2 filters. The class also gets mapped to the service key "FilterManager" key. Take a look at step 2 again.

Moreover this class implements the abstract method validatePlugin() which is used to validate the actual plugin object that you will inject to this manager like for example, StringTrim!

    public function validatePlugin($plugin)
    {
        if ($plugin instanceof FilterInterface) {
            // we're okay
            return;
        }
        if (is_callable($plugin)) {
            // also okay
            return;
        }
        throw new Exception\RuntimeException(sprintf(
            'Plugin of type %s is invalid; must implement %s\FilterInterface or be callable',
            (is_object($plugin) ? get_class($plugin) : gettype($plugin)),
            __NAMESPACE__
        ));
    }

7.) Now we are back in the ModuleManagerFactory (see step 1). Since we now have an instance of the FilterPluginManager via the key FilterManager, this instance is added to the Service Listener (see line 76 of ModuleManagerFactory.php) or below:

$serviceListener->addServiceManager(
    'FilterManager',
    'filters',
    'Zend\ModuleManager\Feature\FilterProviderInterface',
    'getFilterConfig'
 );

8.) Lets take a look at the FilterProviderInterface (https://github.com/zendframework/zf2/blob/master/library/Zend/ModuleManager/Feature/FilterProviderInterface.php) which difines the method getFilterConfig(). What is this method again? This is where you register your custom filters remember in Module.php?
public function getFilterConfig()
{
    return array(
        'factories' => array(
            'customFilter' => function ($sm) {
                // create your filter...
            }
        ),         
    )
}

9.) Thats pretty much the workflow and registration of a ServiceManager Plugin. Now you can call it like this:

$stringTrimFilter = $this->getServiceLocator()->get('FilterManager')->get('stringTrim');
// or your custom filter
$customfilter = $this->getServiceLocator()->get('FilterManager')->get('customFilter');

Tuesday, August 27, 2013

TIP: How to Immitate init() inside Controllers in ZF2

For ZF1 users there is the convenient init() method that you can use on every controller but in ZF2 the init() does not exist anymore for design purposes.

There are sometimes advantages though of having an init() type functionality inside the constructor. For example, checking the ACL.

A little background. One of the problems of working directly inside the constructor in ZF2 is because the dispatch event has not occured yet, you cannot grab important objects like controller plugins so doing the bellow wont work.
// assume we are inside a controller
public function __construct()
{
    $this->redirect()->toRoute('someroute'); // I will not work!
}
Solution:
There are tons of ways to do this but I find this a little easier:
class IndexController extends AbstractActionController
{
    public function __construct()
    {
        $resource = $this->getResourceId();
        $this->getEventManager()->attach('dispatch', function ($e) use ($resource) {
            $controller = $e->getTarget(); // this will return your controller instance

            // there is no ACL plugin ok! I created that!
            if (!$controller->acl()->isAllowed('me', $resource)) {
                // now i can use controller plugins!
                return $controller->redirect()->toRoute('authenticate');
            }     
        });
    }

    public function getResourceId()
    {
        return 'some_resource';
    }
}
Reference:
http://mwop.net/blog/2012-07-30-the-new-init.html

TIP: How to Retrieve and Register Custom Controller Plugins

You can think of controller plugins as action helpers in ZF1.
In order to retrieve the list of plugins including custom plugins you created.

Create a custom plugin:
//module.php
class Module
{
    public function getControllerPluginConfig()
    {
        return array(
            'factories' => array(
                'MyCustomAclPlugin' => function ($sm) {
                    $supahService = $sm->getServiceLocator()->get('superService');
                    return new MyCustomAclService($supahService);
                },
            )
        );
    }
}
Now to use it:
// pretend we are in a controller that extands AbstractActionController
public function indexAction() {
    var_dump($this->getPluginManager()->getRegisteredServices());
    // array('mycustomaclplugin', ...);

    // using our plugin
    $this->mycustomaclplugin()->someMethod();
}

Routing URI With Forward Appended Slashes in ZF2

You may sometimes want to route forward appended URIs to its last corresponding action.

For example:

http://www.sample.com/mycontroller/login/ (WILL NOT route to login action)
http://www.sample.com/mycontroller/login (WILL ROUTE to login action)
http://www.sample.com/mycontroller/ (WILL NOT ROUTE to index action)
http://www.sample.com/mycontroller (WILL ROUTE to index action)

And assume this Route setting for above:

array(
    'mycontroller' => array(
        'type'    => 'Segment',
        'options' => array(
            'route'    => '/mycontroller',
            'defaults' => array(
                'controller' => 'SomeModule\Controller\MyController',
                'action'     => 'index',
            ),
        ),
        'may_terminate' => true,
        'child_routes' => array(
            'login' => array(
                'type'    => 'Segment',
                'options' => array(
                    'route'    => '/login',
                    'defaults' => array(
                        'controller' => 'SomeModule\Controller\MyController',
                        'action'     => 'login',
                    ),
                ),
                'may_terminate' => true,
            ),
        ),
    ),
);

To make the forward appended slashes default to the last action in the URI:
array(
    'mycontroller' => array(
        'type'    => 'Segment',
        'options' => array(
            'route'    => '/mycontroller',
            'defaults' => array(
                'controller' => 'SomeModule\Controller\MyController',
                'action'     => 'index',
            ),
        ),
        'may_terminate' => true,
        'child_routes' => array(
            'default' => array(
                'type'    => 'Segment',
                'options' => array(
                    'route'    => '/[:action][/]',
                    'constraints' => array(
                        'action'     => '[a-zA-Z][a-zA-Z0-9_-]+',
                    ),
                    'defaults' => array(
                        'controller'    => 'SomeModule\Controller\MyController',
                        'action'        => 'index',
                    ),
                ),
                'may_terminate' => true,
            ),
            'login' => array(
                'type'    => 'Segment',
                'options' => array(
                    'route'    => '/login[/]',
                    'defaults' => array(
                        'controller' => 'SomeModule\Controller\MyController',
                        'action'     => 'login',
                    ),
                ),
                'may_terminate' => true,
            ),
        ),
    ),
);

Notice that I added a "default" child route so that I will not have to worry if a I added a new action and forget to create a route for it. Also notice the "[/]" which means that forward slashes are optional now and that's basically it. You just have to add "[/]" in each route of a Segment type.

http://www.sample.com/mycontroller/login/ (WILL ROUTE to login action)
http://www.sample.com/mycontroller/login (WILL ROUTE to login action)
http://www.sample.com/mycontroller/ (WILL ROUTE to index action)
http://www.sample.com/mycontroller (WILL ROUTE to index action)

If you dont want a default fallback route, you can do just so.
array(
    'mycontroller' => array(
        'type'    => 'Segment',
        'options' => array(
            'route'    => '/mycontroller[/]',
            'defaults' => array(
                'controller' => 'SomeModule\Controller\MyController',
                'action'     => 'index',
            ),
        ),
        'may_terminate' => true,
        'child_routes' => array(
            'login' => array(
                'type'    => 'Segment',
                'options' => array(
                    'route'    => '/login[/]',
                    'defaults' => array(
                        'controller' => 'SomeModule\Controller\MyController',
                        'action'     => 'login',
                    ),
                ),
                'may_terminate' => true,
            ),
        ),
    ),
);
Notice that I added "[/]" in the parent route because we removed the default child fallback route.
Now your route with forward slashes should work.

Monday, August 26, 2013

ZF2's MVC Event Trigger Sequence

Below is the trigger sequence of Zend Frameworks 2's MVC Event.

1.) MvcEvent::EVENT_BOOTSTRAP
    returns: Zend\Mvc\Application

    a.) MvcEvent::EVENT_ROUTE
        Returns: Zend\Mvc\Application

    b.) MvcEvent:EVENT_DISPATCH
        Returns: Zend\Mvc\Controller\AbstractController

    c.) MvcEvent:EVENT_RENDER
        Returns: Zend\Mvc\Application

    d.) MvcEvent:EVENT_FINISH
        Returns: Zend\Mvc\Application

You will usually attach to an event inside onBootstrap($e) in Module.php
//Module.php
namespace SomeModule;
use Zend\Mvc\MvcEvent;

class Module
{
    public function onBootstrap($e)
    {
        $e->getName(); // returns MvcEvent::EVENT_BOOTSTRAP
        $e->getTarget(); // returns Zend\Mvc\Application

        // retrieves the Event Manager within Bootstrap
        $em = $e->getApplication()->getEventManager();

        $em->attach(MvcEvent::EVENT_ROUTE, function ($e) {
             $e->getName(); // returns MvcEvent::EVENT_ROUTE
             $e->getTarget(); // returns Zend\Mvc\Application
        }

        $em->attach(MvcEvent::EVENT_DISPATCH, function ($e) {
             $e->getName(); // returns MvcEvent::EVENT_DISPATCH
             $e->getTarget(); // returns Zend\Mvc\Controller\AbstractController
        }

        $em->attach(MvcEvent::EVENT_RENDER, function ($e) {
             $e->getName(); // returns MvcEvent::EVENT_RENDER
             $e->getTarget(); // returns Zend\Mvc\Application
        }

        $em->attach(MvcEvent::EVENT_FINISH, function ($e) {
             $e->getName(); // returns MvcEvent::EVENT_FINISH
             $e->getTarget(); // returns Zend\Mvc\Application
        }
    }
}
It is only normal to return Zend\Mvc\Application as the object itself is being manipulated in the application process.

Thursday, August 22, 2013

REPOST: Setting up PHP to connect to a MS SQL Server using PDO_ODBC in Ubuntu

For those who are not familiar of ODBC like I was, its basically an API that lets you connect to other databases. PDO has its ODBC driver which in turn ODBC has its own also. To connect to MS SQL Server, we are using FreeTDS which is a library that lets you accomplish this.

sudo apt-get install freetds-bin freetds-common tdsodbc odbcinst php5-odbc unixodbc
sudo cp /usr/share/tdsodbc/odbcinst.ini /etc/
sudo apache2ctl restart

Connect using PDO in PHP:
$c = new PDO('odbc:Driver=FreeTDS; Server=hostname_or_ip; Port=port; Database=database_name; UID=username; PWD=password;');
Note: You will not see any reference of FreeTDS (the odbc driver) in the ODBC section of your PHP Info so don't weird out.

Reference:
https://secure.kitserve.org.uk/content/accessing-microsoft-sql-server-php-ubuntu-using-pdo-odbc-and-freetds

Tuesday, August 13, 2013

REPOST: Show and Compare Committed Files Using LOG and DIFF in Subversion

Show commited files for revision 63.

Syntax:
svn log --verbose -r <rev>
Example:
svn log --verbose -r 63

Show difference by comparing actual files. For example, show line by line difference between revision 64 against 63.

Syntax:
svn diff -r<rev-of-commit>:<rev-of-commit - 1>
Example:
svn diff -r64:63

Show the actual file version at the specific revision number:

Syntax:
svn cat -r <rev> <file> | less
Example 
svn cat -r 64 ./some_file.php | less

Reference:
http://stackoverflow.com/questions/6296284/svn-list-files-committed-for-a-revision

Monday, August 12, 2013

My take on Mocks VS Stubs

I sometimes get confused on the difference between a mock and a stub. Actually I still get confused from time to time but I'll spit out my thoughts right now.

Example:
class Math
{
    public function add($arg1, $arg2)
    {
        if (!is_numeric($arg1) || !is_numeric($arg2)) {
            throw new Exception('cannot add non numerics');
        }
        return $arg1 + $arg2;
    }
}

class Person
{
    public function getTotalItems(Math $math, $shoes, $shirts)
    {
        return $math->add($shoes, $shirts);
    }
}

Mock Unit Test:
public function getTotalItemsTest()
{
    $mockMath = $this->getMockBuilder('Math')
                     ->setMethods(array('add'))
                     ->getMock();
    $mockMath->expects($this->once())
             ->method('add')
             ->with($this->isType('numeric'), $this->isType('numeric'))
             ->will($this->returnCallback(function ($arg1, $arg2) {
                 return $arg1 + $arg2;
             }));

    $total = $person->getTotalItems($mockMath, 2, 3);
    $this->assertEquals(5, $total);
}

Stub Unit Test:
public function getTotalItemsTest()
{
    $stubMath = $this->getMockBuilder('Math')
                     ->setMethods(array('add'))
                     ->getMock();
    $stubMath->expects($this->any())
             ->method('add')
             ->will($this->returnValue(5));

    $total = $person->getTotalItems($stubMath, 2, 3);
    $this->assertEquals(5, $total);
}

This is not the best example but you get the groove? When you mock an object, you set an "expectation" for the object method you are mocking. In the case above, we are checking that add() only accepts numerical inputs. Usually, a dead give away is we are using with() to set our expectation. In contrast to a stub, we are just returning straight the result.

Note that the callback for a mock does not matter. I just use it for verbosity.