Playing with websockets, angularjs and socket.io

I’m a big fan of websockets. I’ve got various post about them (here, here). Last months I’m working with angularjs projects and because of that I wanna play a little bit with websockets (with socket.io) and angularjs.

I want to build one angular service.
[sourcecode language=”js”]
angular.module(‘io.service’, []).
factory(‘io’, function ($http) {
var socket,
apiServer,
ioEvent,
watches = {};

return {
init: function (conf) {
apiServer = conf.apiServer;
ioEvent = conf.ioEvent;

socket = io.connect(conf.ioServer);
socket.on(ioEvent, function (data) {
return watches.hasOwnProperty(data.item) ? watches[data.item](data) : null;
});
},

emit: function (arguments) {
return $http.get(apiServer + ‘/request’, {params: arguments});
},

watch: function (item, closure) {
watches[item] = closure;
},

unWatch: function (item) {
delete watches[item];
}
};
});
[/sourcecode]

And now we can build the application
[sourcecode language=”js”]
angular.module(‘myApp’, [‘io.service’]).

run(function (io) {
io.init({
ioServer: ‘http://localhost:3000’,
apiServer: ‘http://localhost:8080/api’,
ioEvent: ‘io.response’
});
}).

controller(‘MainController’, function ($scope, io) {
$scope.$watch(‘question’, function (newValue, oldValue) {
if (newValue != oldValue) {
io.emit({item: ‘question’, newValue: newValue, oldValue: oldValue});
}
});

io.watch(‘answer’, function (data) {
$scope.answer = data.value;
$scope.$apply();
});
});
[/sourcecode]

And this’s the html
[sourcecode language=”html”]
<!doctype html>
<html>

<head>
<title>ws experiment</title>
</head>

<body ng-app="myApp">

<div ng-controller="MainController">

<input type="text" ng-model="question">
<hr>
<h1>Hello {{answer}}!</h1>
</div>

<script src="assets/angular/angular.min.js"></script>
<script src="//localhost:3000/socket.io/socket.io.js"></script>

<script src="js/io.js"></script>
<script src="js/app.js"></script>

</body>
</html>
[/sourcecode]

The idea of the application is to watch one model’s variable (‘question’ in this example) and each time it changes we will send the value to the websocket server and we’ll so something (we will convert the string to upper case in our example)

As you can read in one of my previous post I don’t like to send messages from the web browser to the websocket server directly (due do to authentication issues commented here). I prefer to use one server (a Silex server in this example)

[sourcecode language=”php”]
include __DIR__ . ‘/../../vendor/autoload.php’;

use Silex\Application;
use Symfony\Component\HttpFoundation\Request;

$app = new Application([‘debug’ => true]);
$app->register(new G\Io\EmitterServiceProvider());

$app->get(‘/request’, function (Application $app, Request $request) {

$params = [
‘item’ => $request->get(‘item’),
‘newValue’ => strtoupper($request->get(‘newValue’)),
‘oldValue’ => $request->get(‘oldValue’),
];

try {
$app[‘io.emit’]($params);
$params[‘status’] = true;
} catch (\Exception $e) {
$params[‘status’] = false;
}

return $app->json($params);
});

$app->run();
[/sourcecode]

You can see the code within my github account.

Upgrading Cordova-Android apps outside Google Play Store with angularjs

Recent months I’ve working with enterprise mobile applications. This apps are’t distributed using any marketplace, so I need to handle the distributions process. With Android you can compile your apps, create your APK files and distribute them. You can send the files by email, use a download link, send the file with bluetooth, or whatever. With iOS is a bit different. You need to purchase one Enterprise license, compile the app and distribute your IPA files using Apple’s standards.

OK, but this post is not about how to distribute apps outside the markets. This post is about one big problem that appears when we need to upgrade our apps. How do the user knows that there’s a new version of the application and he needs to upgrade? When we work inside Google Play Store we don’t need to worry about it, but if we distribute our apps manually we need do something. We can send push notifications or email to the user to inform about the new version. Let me show you how I’m doing it.

My problem isn’t only to let know to the user about a new version. Sometimes I also need to ensure that the user runs the last version of the app. Imagine a critical bug (solved in the last release) but the user don’t upgrade.

First we need to create a static html page where the user can download the APK file. Imagine that this is the url where the user can download the last version of the app:

[sourcecode language=”bash”]
http://192.168.1.1:8888/app.apk
[/sourcecode]

We can check the version of the app against the server each time the user opens the application, but this check means network communication and it’s slow. We need to reduce the communication between client and server to the smallest expression and only when it’s strictly necessary. Check the version each time can be good in a desktop application, but it reduces the user experience with mobile apps. My approach is slightly different. Normally we use token based authentication within mobile apps. That’s means we need to send our token with all request. If we send the token, we also can send the version.

In a angular app we can define the version and the path of our apk using a key-value store.

[sourcecode language=”js”]
.value(‘config’, {
version: 4,
androidAPK: "http://192.168.1.1:8888/app.apk&quot;
})
[/sourcecode]

Now we need to add version parameter to each request (we can easily create a custom http service to append this parameter to each request automatically, indeed)

[sourcecode language=”js”]
$http.get(‘http://192.168.1.1:8888/api/doSomething&#8217;, {params: {_version: config.version}})
.success(function (data) {
alert("OK");
})
.error(function (err, status) {
switch (status) {
case 410:
$state.go(‘upgrade’);
break;
}
});
[/sourcecode]

We can create a simple backend to take care of the version and throws an HTTP exception (one 410 HTTP error for example) if versions doesn’t match. Here you can see a simple Silex example:

[sourcecode language=”php”]
<?php

include __DIR__ . "/../vendor/autoload.php";

use Silex\Application;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\HttpException;

$app = new Application([
‘debug’ => true,
‘version’ => 4,
]);

$app->after(function (Request $request, Response $response) {
$response->headers->set(‘Access-Control-Allow-Origin’, ‘*’);
});

$app->get(‘/api/doSomething’, function (Request $request, Application $app) {
if ($request->get(‘_version’) != $app[‘version’]) {
throw new HttpException(410, "Wrong version");
} else {
return $app->json(‘hello’);
}
});

$app->run();
[/sourcecode]

As you can see we need to take care about CORS

With this simple example we can realize if user has a wrong version within each server request. If version don’t match we can, for example redirect to an specific route to inform that the user needs to upgrade the app and provide a link to perform the action.

With Android we cannot create a link to APK file. It doesn’t work. We need to download the APK (using FileTransfer plugin) and open the file using webintent plugin.

The code is very simple:

[sourcecode language=”js”]
var fileTransfer = new FileTransfer();
fileTransfer.download(encodeURI(androidUrl),
"cdvfile://localhost/temporary/app.apk",
function (entry) {
window.plugins.webintent.startActivity({
action: window.plugins.webintent.ACTION_VIEW,
url: entry.toURL(),
type: ‘application/vnd.android.package-archive’
}, function () {
}, function () {
alert(‘Failed to open URL via Android Intent.’);
console.log("Failed to open URL via Android Intent. URL: " + entry.fullPath);
});
}, function (error) {
console.log("download error source " + error.source);
console.log("download error target " + error.target);
console.log("upload error code" + error.code);
}, true);
[/sourcecode]

And basically that’s all. When user self-upgrade the app it closes automatically and he needs to open it again, but now with the correct version.

Talk about SOLID and Symfony at the deSymfony 2014 conference.

Last saturday I attended to the deSymfony conference in Barcelona. A great opportunity to meet again with the PHP and Symfony community in Spain. This year the conference accepted my talk about SOLID and Symfony. Here you can see the slides of the talk (slides in spanish):

The conference was perfect. Barcelona is an incredible city and the conference place (10 minutes walking from the Sagrada Familia), was incredible too. Great talks. But the best, as always, the coffe breaks with the conversations with the Symfony and PHP community from Valencia, Zaragoza, Madrid, Barcelona, …

That’s me in action speaking about SOLID principles and Symfony:
Bo90AasCMAAdHL8 (photo source)

But the best of my speech was in the opposite direction. Many thanks to all of you 🙂

20140531_152345

Token based authentication with Silex Applications

Imagine this simple Silex application:

[sourcecode language=”php”]
use Silex\Application;

$app = new Application();

$app->get(‘/api/info’, function (Application $app) {
return $app->json([
‘status’ => true,
‘info’ => [
‘name’ => ‘Gonzalo’,
‘surname’ => ‘Ayuso’
]]);
});

$app->run();
[/sourcecode]

What happens if we want to use a security layer? We can use sessions. Sessions are the “standard” way to perform authentication in web applications, but when our application is a PhoneGap/Cordova application that uses a Silex server as API server, sessions aren’t the best way. The best way now is a token based authentication. The idea is simple. First we need a valid token. Our API server will give us a valid token if we send valid credentials in a login form. Then we need to send the token with each request (the same way than we send the session cookie with each request).

With Silex we can check this token and validate.

[sourcecode language=”php”]
use Silex\Application;

$app = new Application();

$app->get(‘/api/info’, function (Application $app) {
$token = $app->get(‘_token’);

// here we need to validate the token …

return $app->json([
‘status’ => true,
‘info’ => [
‘name’ => ‘Gonzalo’,
‘surname’ => ‘Ayuso’
]]);
});

$app->run();
[/sourcecode]

It isn’t an elegant solution. We need to validate the token within all routes and that’s bored. We also can use middlewares and validates the token with $app->before(). We’re going to build something like this, but with a few variations. First I want to keep the main application as clean as possible. Validation logic must be separated from application logic, so we will extend Silex\Application. Our main application will be like this:

[sourcecode language=”php”]
use G\Silex\Application;

$app = new Application();

$app->get(‘/api/info’, function (Application $app) {
return $app->json([
‘status’ => true,
‘info’ => [
‘name’ => ‘Gonzalo’,
‘surname’ => ‘Ayuso’
]]);
});

$app->run();
[/sourcecode]

Instead of Silex\Application we’ll use G\Silex\Application.

[sourcecode language=”php”]
namespace G\Silex;

use Silex\Application as SilexApplication;
use G\Silex\Provider\Login\LoginBuilder;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;

class Application extends SilexApplication
{
public function __construct(array $values = [])
{
parent::__construct($values);

LoginBuilder::mountProviderIntoApplication(‘/auth’, $this);

$this->after(function (Request $request, Response $response) {
$response->headers->set(‘Access-Control-Allow-Origin’, ‘*’);
});
}
}
[/sourcecode]

Our new G\Silex\Application is a Silex\Application enabling CORS. We also mount a Service provider.

The responsibility of our API server will be check the token of every request and to provide one way to get a new token. To get a new token we will create a route “/auth/validateCredentials”. If a valid credentials are given, new token will be send to client.

Our Service provider has two parts: a service provider and a controller provider.

To mount both providers we will use a LoginBuilder class:
[sourcecode language=”php”]
namespace G\Silex\Provider\Login;

use Silex\Application;

class LoginBuilder
{
public static function mountProviderIntoApplication($route, Application $app)
{
$app->register(new LoginServiceProvider());
$app->mount($route, (new LoginControllerProvider())->setBaseRoute($route));
}
}
[/sourcecode]

Our Controller provider:

[sourcecode language=”php”]
namespace G\Silex\Provider\Login;

use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
use Symfony\Component\HttpFoundation\Request;
use Silex\ControllerProviderInterface;
use Silex\Application;

class LoginControllerProvider implements ControllerProviderInterface
{
const VALIDATE_CREDENTIALS = ‘/validateCredentials’;
const TOKEN_HEADER_KEY = ‘X-Token’;
const TOKEN_REQUEST_KEY = ‘_token’;

private $baseRoute;

public function setBaseRoute($baseRoute)
{
$this->baseRoute = $baseRoute;

return $this;
}

public function connect(Application $app)
{
$this->setUpMiddlewares($app);

return $this->extractControllers($app);
}

private function extractControllers(Application $app)
{
$controllers = $app[‘controllers_factory’];

$controllers->get(self::VALIDATE_CREDENTIALS, function (Request $request) use ($app) {
$user = $request->get(‘user’);
$pass = $request->get(‘pass’);
$status = $app[LoginServiceProvider::AUTH_VALIDATE_CREDENTIALS]($user, $pass);

return $app->json([
‘status’ => $status,
‘info’ => $status ? [‘token’ => $app[LoginServiceProvider::AUTH_NEW_TOKEN]($user)] : []
]);
});

return $controllers;
}

private function setUpMiddlewares(Application $app)
{
$app->before(function (Request $request) use ($app) {
if (!$this->isAuthRequiredForPath($request->getPathInfo())) {
if (!$this->isValidTokenForApplication($app, $this->getTokenFromRequest($request))) {
throw new AccessDeniedHttpException(‘Access Denied’);
}
}
});
}

private function getTokenFromRequest(Request $request)
{
return $request->headers->get(self::TOKEN_HEADER_KEY, $request->get(self::TOKEN_REQUEST_KEY));
}

private function isAuthRequiredForPath($path)
{
return in_array($path, [$this->baseRoute . self::VALIDATE_CREDENTIALS]);
}

private function isValidTokenForApplication(Application $app, $token)
{
return $app[LoginServiceProvider::AUTH_VALIDATE_TOKEN]($token);
}
}
[/sourcecode]

And our Service provider:
[sourcecode language=”php”]
namespace G\Silex\Provider\Login;

use Silex\Application;
use Silex\ServiceProviderInterface;

class LoginServiceProvider implements ServiceProviderInterface
{
const AUTH_VALIDATE_CREDENTIALS = ‘auth.validate.credentials’;
const AUTH_VALIDATE_TOKEN = ‘auth.validate.token’;
const AUTH_NEW_TOKEN = ‘auth.new.token’;

public function register(Application $app)
{
$app[self::AUTH_VALIDATE_CREDENTIALS] = $app->protect(function ($user, $pass) {
return $this->validateCredentials($user, $pass);
});

$app[self::AUTH_VALIDATE_TOKEN] = $app->protect(function ($token) {
return $this->validateToken($token);
});

$app[self::AUTH_NEW_TOKEN] = $app->protect(function ($user) {
return $this->getNewTokenForUser($user);
});
}

public function boot(Application $app)
{
}

private function validateCredentials($user, $pass)
{
return $user == $pass;
}

private function validateToken($token)
{
return $token == ‘a’;
}

private function getNewTokenForUser($user)
{
return ‘a’;
}
}
[/sourcecode]

Our Service provider will have the logic to validate credentials, token and it must be able to generate a new token:

[sourcecode language=”php”]
private function validateCredentials($user, $pass)
{
return $user == $pass;
}

private function validateToken($token)
{
return $token == ‘a’;
}

private function getNewTokenForUser($user)
{
return ‘a’;
}
[/sourcecode]

As we can see the logic of the example is very simple. It’s just an example and here we must to perform our logic. Probably we need to check credentials with our database, and our token must be stored somewhere to be validated later.

You can see the example in my github account. In another post we will see how to build a client application with angularJs to use this API server.

Yet another Database Abstraction layer with PHP and DBAL

I’m not a big fan of ORMs. I feel very confortable working with raw SQLs and because of that I normally use DBAL (or PDO in old projects). I’ve got one small library to handle my dayly operations with databases and today I’ve written this library

First of all imagine one DBAL connection. I’m using a sqlite in-memomy database in this example but we can use any database supported by DBAL (aka “almost all”):

[sourcecode language=”php”]
use Doctrine\DBAL\DriverManager;

$conn = DriverManager::getConnection([
‘driver’ => ‘pdo_sqlite’,
‘memory’ => true
]);
[/sourcecode]

We can also create one DBAL connection from a PDO connection. It’s usefull to use DBAL within legacy applications instead of creating a new connection (remember that DBAL works over PDO)

[sourcecode language=”php”]
use Doctrine\DBAL\DriverManager;

$conn = DriverManager::getConnection([‘pdo’ => new PDO(‘sqlite::memory:’)]);
[/sourcecode]

Now we set up the database for the example
[sourcecode language=”php”]
$conn->exec("CREATE TABLE users (
userid VARCHAR PRIMARY KEY NOT NULL ,
password VARCHAR NOT NULL ,
name VARCHAR,
surname VARCHAR
);");
$conn->exec("INSERT INTO users VALUES(‘user’,’pass’,’Name’,’Surname’);");
$conn->exec("INSERT INTO users VALUES(‘user2′,’pass2′,’Name2′,’Surname2’);");
[/sourcecode]

Our table “users” has two records. Now we can start to use our library.

First we create a new instance of our library:
[sourcecode language=”php”]
use G\Db;

$db = new Db($conn);
[/sourcecode]

Now a simple query from a string:
[sourcecode language=”php”]
$data = $db->select("select * from users");
[/sourcecode]

Sometimes I’m lazy and I don’t want to write the whole SQL string and I want to perform a select * from table:
[sourcecode language=”php”]
use G\Sql;
$data = $db->select(SQL::createFromTable("users"));
[/sourcecode]

Probably we need to filter our Select statement with a WHERE clause:
[sourcecode language=”php”]
$data = $db->select(SQL::createFromTable("users", [‘userid’ => ‘user2’]));
[/sourcecode]

And now something very intersting (at least for me). I want to iterate over the recordset and maybe change it. Of course I can use “foreach” over $data and do whatever I need, but I preffer to use the following sintax:
[sourcecode language=”php”]
$data = $db->select(SQL::createFromTable("users"), function (&$row) {
$row[‘name’] = strtoupper($row[‘name’]);
});
[/sourcecode]

For me it’s more readable. I iterate over the recordset and change the row ‘name’ to uppercase. Here you can see what is doing my “select” function:

[sourcecode language=”php”]
/**
* @param Sql|string $sql
* @param \Closure $callback
* @return array
*/
public function select($sql, \Closure $callback = null)
{
if ($sql instanceof Sql) {
$sqlString = $sql->getString();
$parameters = $sql->getParameters();
$types = $sql->getTypes();
} else {
$sqlString = $sql;
$parameters = [];
$types = [];
}

$statement = $this->conn->executeQuery($sqlString, $parameters, $types);
$data = $statement->fetchAll();
if (!is_null($callback) && count($data) > 0) {
$out = [];
foreach ($data as $row) {
if (call_user_func_array($callback, [&$row]) !== false) {
$out[] = $row;
}
}
$data = $out;
}

return $data;
}
[/sourcecode]

And finally transactions (I normally never use autocommit and I like to handle transactions by my own)

[sourcecode language=”php”]
$db->transactional(function (Db $db) {
$userId = ‘temporal’;

$db->insert(‘users’, [
‘USERID’ => $userId,
‘PASSWORD’ => uniqid(),
‘NAME’ => ‘name3’,
‘SURNAME’ => ‘name3’
]);

$db->update(‘users’, [‘NAME’ => ‘updatedName’], [‘USERID’ => $userId]);
$db->delete(‘users’, [‘USERID’ => $userId]);
});
[/sourcecode]

The “transactional” function it’s very simmilar than DBAL’s transactional function

[sourcecode language=”php”]
public function transactional(\Closure $callback)
{
$out = null;
$this->conn->beginTransaction();
try {
$out = $callback($this);
$this->conn->commit();
} catch (\Exception $e) {
$this->conn->rollback();
throw $e;
}

return $out;
}
[/sourcecode]

I change a little bit because I like to return a value within the closure and allow to do things like that:
[sourcecode language=”php”]
$status = $db->transactional(function (Db $db) {
$userId = ‘temporal’;

$db->insert(‘users’, [
‘USERID’ => $userId,
‘PASSWORD’ => uniqid(),
‘NAME’ => ‘name3’,
‘SURNAME’ => ‘name3’
]);

$db->update(‘users’, [‘NAME’ => ‘updatedName’], [‘USERID’ => $userId]);
$db->delete(‘users’, [‘USERID’ => $userId]);

return "OK"
});
[/sourcecode]

The other functions (insert, update, delete) only bypass the calls to DBAL’s funcitons:
[sourcecode language=”php”]
private $conn;

public function __construct(Doctrine\DBAL\Connection $conn)
{
$this->conn = $conn;
}

public function insert($tableName, array $values = [], array $types = [])
{
$this->conn->insert($tableName, $values, $types);
}

public function delete($tableName, array $where = [], array $types = [])
{
$this->conn->delete($tableName, $where, $types);
}

public function update($tableName, array $data, array $where = [], array $types = [])
{
$this->conn->update($tableName, $data, $where, $types);
}
[/sourcecode]

And that’s all. You can use the library with composer and download at github.

BTW I’ve test the new Sensiolabs product (SensioLabs Insight) to analyze the code and verify good practices and I’ve got the Platinum medal #yeah!

Auto injecting dependencies in PHP objects

I must admit I don’t really know what’s the correct title for this post. Finally I use “Auto injecting dependencies in PHP objects”. I know it isn’t very descriptive. Let me explain it a little bit. This time I want to automate the Hollywood Principle (“Don’t call us, we’ll call you”). The idea is simple. Imagine one “controller”

[sourcecode language=”php”]
class Controller
{
public function hi($name)
{
return "Hi $name";
}
}
[/sourcecode]

We can easily automate the “hi” action

[sourcecode language=”php”]
$controller = new Controller();
echo $controller->hi("Gonzalo");
[/sourcecode]

Or maybe if we are building a framework and our class name and action name depends on user-input:
[sourcecode language=”php”]
$class = "Controller";
$action = "hi";
$arguments = [‘name’ => "Gonzalo"];

echo call_user_function_array([new $class, $action], arguments);
[/sourcecode]

But imagine that we want to allow something like that:

[sourcecode language=”php”]
class Controller
{
public function hi($name, Request $request)
{
return "Hi $name " .$request->get(‘surname’);
}
}
[/sourcecode]

Now we need to inject Request object within our action “hi”, but not always. Only when user set a input variable with the type “Request”. Imagine that we also want to allow this kind of injection in the constructor too. We can need to use Reflection to create our instance and to call our action. Sometimes I need to work with custom frameworks and legacy PHP applications. I’ve done it in a couple of projects, but now I want to create a library to automate this operation.

The idea is to use a Dependency Injection Container (Pimple in my example) and retrieve the dependency from container (if it’s available). I cannot use “new” keyword to create the instance and also I cannot call directly the action.

One usage example is:
[sourcecode language=”php”]
class Foo
{
public function hi($name)
{
return "Hi $name";
}
}

class Another
{
public function bye($name)
{
return "Bye $name";
}
}

class Bar
{
private $foo;

public function __construct(Foo $foo, $surname = null)
{
$this->foo = $foo;
$this->surname = $surname;
}

public function hi(Another $another, $name)
{
return $this->foo->hi($name . " " . $this->surname) . ‘ ‘ . $another->bye($name);
}
}

$container = new Pimple();
$container[‘name’] = "Gonzalo2";

$builder = new G\Builder($container);

$bar = $builder->create(‘Bar’, [‘surname’ => ‘Ayuso’]);
var_dump($builder->call([$bar, ‘hi’]));

var_dump($bar->hi(new Another(), ‘xxxxx’));
[/sourcecode]

Our library tries to retrieve the dependecy from the DIC. If it cannot do it, it creates the a new instance.
The whole “magic” is in the Builder class. You can see the library in my github account.

Playing with HTML5. Building a simple pool of WebWokers

Today I’m playing with the HTML5’s WebWorkers. Since our JavaScript code runs within a single thread in our WebBrowser, heavy scripts can lock the execution of our code. HTML5 gives us one tool called WebWorkers to allow us to run different threads within our Application.

Today I’m playing with one small example (that’s just an experiment). I want to create a pool of WebWebworkers and use them as a simple queue.
The usage of the library is similar than the usage of WebWorkers. The following code shows how to start the pool with 10 instances of our worker “js/worker.js”

[sourcecode language=”javascript”]
// new worker pool with 10 instances of the worker
var pool = new WorkerPool(‘js/worker.js’, 10);

// register callback to worker’s onmessage event
pool.registerOnMessage(function (e) {
console.log("Received (from worker): ", e.data);
});
[/sourcecode]

“js/worker.js” is a standard WebWorker. In this example our worker perform XHR request to a API server (in this case one Silex application)

[sourcecode language=”javascript”]
importScripts(‘ajax.js’);

self.addEventListener(‘message’, function (e) {
var data = e.data;

switch (data.method) {
case ‘GET’:
getRequest(data.resource, function(xhr) {
self.postMessage({status: xhr.status, responseText: xhr.responseText});
});
break;
}
}, false);
[/sourcecode]

WebWorkers runs in different scope than a traditional browser application. Not all JavaScript objects are available in the webworker scpope. For example we cannot access to “window” and DOM elements, but we can use XMLHttpRequest. In our experimente we’re going to preform XHR requests from the webworker.

The library creates a queue with the variable number of workers:

[sourcecode language=”javascript”]
var WorkerPool;

WorkerPool = (function () {
var pool = {};
var poolIds = [];

function WorkerPool(worker, numberOfWorkers) {
this.worker = worker;
this.numberOfWorkers = numberOfWorkers;

for (var i = 0; i < this.numberOfWorkers; i++) {
poolIds.push(i);
var myWorker = new Worker(worker);

+function (i) {
myWorker.addEventListener(‘message’, function (e) {
var data = e.data;
console.log("Worker #" + i + " finished. status: " + data.status);
pool[i].status = true;
poolIds.push(i);
});
}(i);

pool[i] = {status: true, worker: myWorker};
}

this.getFreeWorkerId = function (callback) {
if (poolIds.length > 0) {
return callback(poolIds.pop());
} else {
var that = this;
setTimeout(function () {
that.getFreeWorkerId(callback);
}, 100);
}
}
}

WorkerPool.prototype.postMessage = function (data) {
this.getFreeWorkerId(function (workerId) {
pool[workerId].status = false;
var worker = pool[workerId].worker;
console.log("postMessage with worker #" + workerId);
worker.postMessage(data);
});
};

WorkerPool.prototype.registerOnMessage = function (callback) {
for (var i = 0; i < this.numberOfWorkers; i++) {
pool[i].worker.addEventListener(‘message’, callback);
}
};

WorkerPool.prototype.getFreeIds = function () {
return poolIds;
};

return WorkerPool;
})();
[/sourcecode]

The API server is a simple Silex application. This application also enables cross origin (CORS). You can read about it here.

[sourcecode language=”php”]
use Silex\Application;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;

$app = new Application();

$app->get(‘/hello’, function () use ($app) {
error_log("GET /hello");
sleep(2); // emulate slow process
return $app->json([‘method’ => ‘GET’, ‘response’ => ‘OK’]);
});

$app->after(function (Request $request, Response $response) {
$response->headers->set(‘Access-Control-Allow-Origin’, ‘*’);
});

$app->run();
[/sourcecode]

You can see the whole code in my github account.

Here one small screencast to see the application in action.

How to run a Web Server from a PHP application

Normally we deploy our PHP applications in a webserver (such as apache, nginx, …). I used to have one apache webserver in my personal computer to play with my applications, but from time to now I preffer to use PHP’s built-in webserver for my experiments. It’s really simple. Just run:

[sourcecode language=”bash”]
php -S 0.0.0.0:8080
[/sourcecode]
and we’ve got one PHP webserver at our current directory. With another languages (such as node.js, Python) we can start a Web Server from our application. For example with node.js:

[sourcecode language=”javascript”]
var http = require(‘http’);
http.createServer(function (req, res) {
res.writeHead(200, {‘Content-Type’: ‘text/plain’});
res.end(‘Hello World\n’);
}).listen(8080, ‘0.0.0.0’);
console.log(‘Server running at http://0.0.0.0:8080&#8217;);
[/sourcecode]

With PHP we cannot do it. Sure? That assertion isn’t really true. We can do it. I’ve just create one small library to do it in two different ways. First running the built-in web server and also running one React web server.

I want to share the same interface to start the server. In this implementation we will register one callback to handle incomming requests. This callback will accept a Symfony\Component\HttpFoundation\Request and it will return a Symfony\Component\HttpFoundation\Response. Then we will start our server listening to one port and we will run our callback per Request (a simple implementeation of the reactor pattern)

We will create a static factory to create the server
[sourcecode language=”php”]
namespace G\HttpServer;
use React;

class Builder
{
public static function createBuiltInServer($requestHandler)
{
$server = new BuiltInServer();
$server->registerHandler($requestHandler);

return $server;
}

public static function createReactServer($requestHandler)
{
$loop = React\EventLoop\Factory::create();
$socket = new React\Socket\Server($loop);

$server = new ReactServer($loop, $socket);
$server->registerHandler($requestHandler);

return $server;
}
}
[/sourcecode]

Each server (BuiltIn, and React) has its own implementation.

And basically that’s all. We can run a simple webserver with the built-in server
[sourcecode language=”php”]
use G\HttpServer\Builder;
use Symfony\Component\HttpFoundation\Request;

Builder::createBuiltInServer(function (Request $request) {
return "Hello " . $request->get(‘name’);
})->listen(1337);
[/sourcecode]

Or the same thing but with React
[sourcecode language=”php”]
use G\HttpServer\Builder;
use Symfony\Component\HttpFoundation\Request;

Builder::createReactServer(function (Request $request) {
return "Hello " . $request->get(‘name’);
})->listen(1337);
[/sourcecode]

As you can see our callback handles one Request and returns one Response (The typical HttpKernel), because of that we also can run one Silex application:
With built-in:
[sourcecode language=”php”]
use G\HttpServer\Builder;
use Symfony\Component\HttpFoundation\Request;

$app = new Silex\Application();

$app->get(‘/’, function () {
return ‘Hello’;
});

$app->get(‘/hello/{name}’, function ($name) {
return ‘Hello ‘ . $name;
});

Builder::createBuiltInServer(function (Request $request) use ($app) {
return $app->handle($request);
})->listen(1337);
[/sourcecode]

And the same with React:
[sourcecode language=”php”]
use G\HttpServer\Builder;
use Symfony\Component\HttpFoundation\Request;

$app = new Silex\Application();

$app->get(‘/’, function () {
return ‘Hello’;
});

$app->get(‘/hello/{name}’, function ($name) {
return ‘Hello ‘ . $name;
});

Builder::createReactServer(function (Request $request) use ($app) {
return $app->handle($request);
})->listen(1337);
[/sourcecode]

As an exercise I also have created one small benchmark (with both implementations) with apache ab running 100 request with a 10 request at the same time. Here you can see the outcomes.

  builtin react
Simple response    
ab -n 100 -c 10 http://localhost:1337/
Time taken for tests 0.878 seconds 0.101 seconds
Requests per second (mean) 113.91 [#/sec] 989.33 [#/sec]
Time per request (mean) 87.791 [ms] 10.108 [ms]
Time per request (mean across all concurrent requests) 8.779 [ms] 1.011 [ms]
Transfer rate 21.02 [Kbytes/sec] 112.07 [Kbytes/sec]
Silex application
ab -n 100 -c 10 http://localhost:1337/
Time taken for tests 2.241 seconds 0.247 seconds
Requests per second (mean) 44.62 [#/sec] 405.29 [#/sec]
Time per request 224.119 [ms] 24.674 [ms]
Time per request (mean across all concurrent requests) 22.412 [ms] 2.467 [ms]
Transfer rate 10.89 [Kbytes/sec] 75.60 [Kbytes/sec]
ab -n 100 -c 10 http://localhost:1337/hello/gonzalo
Time taken for tests 2.183 seconds 0.271 seconds
Requests per second (mean) 45.81 [#/sec] (mean) 369.67 [#/sec]
Time per request (mean) 218.290 [ms] (mean) 27.051 [ms]
Time per request (mean across all concurrent requests) 21.829 [ms] 2.705 [ms]
Transfer rate 11.54 [Kbytes/sec] 71.84 [Kbytes/sec]

Built-in web server is not suitable for production environments, but React would be a useful tool in some cases (maybe not good for running Facebook but good enough for punctual situations).

Library is available at github and also you can use it with composer

Playing with event dispatcher and Silex. Sending logs to a remote server.

Today I continue playing with event dispatcher and Silex. Now I want to send a detailed log of our Kernel events to a remote server. We can do it something similar with Monolog, but I want to implement one working example hacking a little bit the event dispatcher. Basically we’re going to create one Logger class (implementing PSR-3 of course)

[sourcecode language=”php”]
namespace G;

use Psr\Log\LoggerInterface;
use Psr\Log\LogLevel;

class Logger implements LoggerInterface
{
private $socket;

public function __construct($socket)
{
$this->socket = $socket;
}

function __destruct()
{
@fclose($this->socket);
}

public function emergency($message, array $context = array())
{
$this->sendLog($message, $context, LogLevel::EMERGENCY);
}

public function alert($message, array $context = array())
{
$this->sendLog($message, $context, LogLevel::ALERT);
}

public function critical($message, array $context = array())
{
$this->sendLog($message, $context, LogLevel::CRITICAL);
}

public function error($message, array $context = array())
{
$this->sendLog($message, $context, LogLevel::ERROR);
}

public function warning($message, array $context = array())
{
$this->sendLog($message, $context, LogLevel::WARNING);
}

public function notice($message, array $context = array())
{
$this->sendLog($message, $context, LogLevel::NOTICE);
}

public function info($message, array $context = array())
{
$this->sendLog($message, $context, LogLevel::INFO);
}

public function debug($message, array $context = array())
{
$this->sendLog($message, $context, LogLevel::DEBUG);
}

public function log($level, $message, array $context = array())
{
$this->sendLog($message, $context, $level);
}

private function sendLog($message, array $context = array(), $level = LogLevel::INFO)
{
$data = serialize([$message, $context, $level]);
@fwrite($this->socket, "{$data}\n");
}
}
[/sourcecode]

As you can see our Logger class send logs to a remote server, with a socket passed within the constructor.
We also need one Service Provider called LoggerServiceProvider to integrate our Logger instance into our Silex application.

[sourcecode language=”php”]
namespace G;

use Silex\Application;
use Silex\ServiceProviderInterface;

class LoggerServiceProvider implements ServiceProviderInterface
{
private $socket;

public function __construct($socket)
{
$this->socket = $socket;
}

public function register(Application $app)
{
$app[‘remoteLogger’] = $app->share(
function () use ($app) {
return new Logger($this->socket);
}
);
}

public function boot(Application $app)
{
}
}
[/sourcecode]

And now the last part is our Silex application:

[sourcecode language=”php”]
use G\LoggerServiceProvider;
use G\Silex\Application;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel;
use Symfony\Component\HttpKernel\Event;

$app = new Application();
$app->register(new LoggerServiceProvider(stream_socket_client(‘tcp://localhost:4000’)));

$app->on(HttpKernel\KernelEvents::REQUEST, function (Event\GetResponseEvent $event) use ($app) {
$app->getLogger()->info($event->getName());
}
);

$app->on(HttpKernel\KernelEvents::CONTROLLER, function (Event\FilterControllerEvent $event) use ($app) {
$app->getLogger()->info($event->getName());
}
);

$app->on(HttpKernel\KernelEvents::TERMINATE, function (Event\PostResponseEvent $event) use ($app) {
$app->getLogger()->info($event->getName());
}
);

$app->on(HttpKernel\KernelEvents::EXCEPTION, function (Event\GetResponseForExceptionEvent $event) use ($app) {
$app->getLogger()->critical($event->getException()->getMessage());
}
);

$app->get(‘/’, function () {
return ‘Hello’;
});

$app->run();
[/sourcecode]

As we can see the event dispacher send each event to a remote server (in this example: tcp://localhost:4000). Now we only need a tcp server to handle those sockets. We can use different tools and libraries to do that. In this example we’re going to use React.

[sourcecode language=”php”]
use React\EventLoop\Factory;
use React\Socket\Server;

$loop = Factory::create();
$socket = new Server($loop);

$socket->on(‘connection’, function (\React\Socket\Connection $conn){
$unique = uniqid();
$conn->on(‘data’, function ($data) use ($unique) {
list($message, $context, $level) = \unserialize($data);
echo date("d/m/Y H:i:s")."::{$level}::{$unique}::{$message}" . PHP_EOL;
});
});

echo "Socket server listening on port 4000." .PHP_EOL;
echo "You can connect to it by running: telnet localhost 4000" . PHP_EOL;

$socket->listen(4000);
$loop->run();
[/sourcecode]

Now we only need to start our servers:
our silex one

[sourcecode]
php -S 0.0.0.0:8080 -t www
[/sourcecode]

and the tcp server
[sourcecode]
php app/server.php
[/sourcecode]
One screencast showing the prototype in action:

You can see the full code in my github account.

Sending automated emails with PHP, Swiftmailer and Twig

I’m the one of hosts of a Coding Dojo in my city called Katayunos. Katayunos is the mix of the word Kata (coding kata) and “Desayuno” (breakfast in Spanish). A group of brave programmers meet together one Saturday morning and after having breakfast we pick one coding kata and we practise TDD and pair programming. It’s something difficult to explain to non-geek people (why the hell we wake up early one Saturday morning to do this) but if you are reading this post probably it sounds good:).

My work as host is basically pick the place and encourage people to join to the Coding Dojo. One way of doing this (besides twitter buzz) is take my address book and send one bulk email to all of them inviting to join us. I don’t like this kind of mails. They look like spam, so I prefer to send a personalized email. This email has a common part (the place location, the hour, the event description, …) and the personalized part. I can do it manually, the list isn’t so huge, but definitely that’s not cool. Because of that I have done a little script to perform this operation. I can do a simple PHP script but we are speaking about announcing a event about TDD, SOLID and things like that, so I must use the “right way”. Let’s start.

I manage my list of contacts within a spreadsheet. In this spreadsheet I have the name, the email and a one paragraph with the personalized part to each one of my contact. I can easily export this spreadsheet to a csv document like this:

[sourcecode]
Peter Parker, spiderman@gmail.com, "Lorem ipsum dolor sit amet, …"
Clark Kent, superman@gmail.com, "consectetur adipisicing elit, …"
Juan López Fernández, superlopez@gmail.com, "sed do eiusmod tempor incididunt .."
[/sourcecode]

So first of all I need to parse this file.

[sourcecode language=”php”]
class Parser
{
private $data;

public function createFromCsvFile($path)
{
$handle = fopen($path, "r");
while (($data = fgetcsv($handle)) !== false) {
$this->data[] = [
‘name’ => trim($data[0]),
’email’ => trim($data[1]),
‘body’ => isset($data[2]) ? trim($data[2]) : null,
];
}
}

public function getData()
{
return $this->data;
}
}
[/sourcecode]

Easy. Now I want to send this parsed array by email. Because of that I will include Swiftmailer in my composer.json file.

My email will also be one template and one personalized part. We will use Twig to manage the template.

[sourcecode language=”bash”]
"require": {
"swiftmailer/swiftmailer": "v5.0.2",
"twig/twig": "v1.13.2",
}
[/sourcecode]

Now we will create a class to wrap the needed code to send emails

[sourcecode language=”php”]
class Mailer
{
private $swiftMailer;
private $swiftMessage;

function __construct(Swift_Mailer $swiftMailer, Swift_Message $swiftMessage)
{
$this->swiftMailer = $swiftMailer;
$this->swiftMessage = $swiftMessage;
}

public function sendMessage($to, $body)
{
$this->swiftMessage->setTo($to);
$this->swiftMessage->setBody(strip_tags($body));
$this->swiftMessage->addPart($body, ‘text/html’);

return $this->swiftMailer->send($this->swiftMessage);
}
}
[/sourcecode]

Our Mailer class sends mails. Our Parser class parses one csv file. Now we need something to join those two classes: the Spammer class. Spammer class will take one parsed array and it will send one by one the mails using Mailer class.

[sourcecode language=”php”]
class Spammer
{
private $twig;
private $mailer;

function __construct(Twig_Environment $twig, Mailer $mailer)
{
$this->twig = $twig;
$this->mailer = $mailer;
}

public function sendEmails($data)
{
foreach ($data as $item) {
$to = $item[’email’];
$this->mailer->sendMessage($to, $this->twig->render(‘mail.twig’, $item));
}
}
}
[/sourcecode]

Ok with this three classes I can easily send my emails. This script is a console script and we also want pretty console colours and this kind of stuff. symfony/console to the rescue. But I’ve a problem now. I want to write one message when one mail is sent and another one when something wrong happens. If I want to do that I need to change my Spammer class. But my Spammer class does’t know anything about my console Command. If I inject the console command into my Spammer class I will violate the Demeter law, and that’s a sin. What can we do? Easy: The mediator pattern. We can write one implementation of mediator pattern but we also can use symfony/event-dispatcher, a well done implementation of this pattern. We change our Spammer class to:

[sourcecode language=”php”]
use Symfony\Component\EventDispatcher\EventDispatcher;

class Spammer
{
private $twig;
private $mailer;
private $dispatcher;

function __construct(Twig_Environment $twig, Mailer $mailer, EventDispatcher $dispatcher)
{
$this->twig = $twig;
$this->mailer = $mailer;
$this->dispatcher = $dispatcher;
}

public function sendEmails($data)
{
foreach ($data as $item) {
$to = $item[’email’];
try {
$this->mailer->sendMessage($to, $this->twig->render(‘mail.twig’, $item));
$this->dispatcher->dispatch(MailEvent::EVENT_MAIL_SENT, new MailEvent\Sent($to));
} catch (\Exception $e) {
$this->dispatcher->dispatch(MailEvent::EVENT_SENT_ERROR, new MailEvent\Error($to, $e));
}
}
}
}
[/sourcecode]

Now can easily build of console command class:

[sourcecode language=”php”]
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\EventDispatcher\EventDispatcher;

class SpamCommand extends Command
{
private $parser;
private $dispatcher;

protected function configure()
{
$this->setName(‘spam:run’)
->setDescription(‘Send Emails’);
}

protected function execute(InputInterface $input, OutputInterface $output)
{
$output->writeln("Sending mails …");
$this->dispatcher->addListener(MailEvent::EVENT_MAIL_SENT, function (MailEvent\Sent $event) use ($output) {
$output->writeln("<info>Mail sent to</info>: <fg=black;bg=cyan>{$event->getTo()}</fg=black;bg=cyan>");
}
);

$this->dispatcher->addListener(MailEvent::EVENT_SENT_ERROR, function (MailEvent\Error $event) use ($output) {
$output->writeln("<error>Error sending mail to</error>: <fg=black;bg=cyan>{$event->getTo()}</fg=black;bg=cyan> Error: " . $event->getException()->getMessage());
}
);

$this->spammer->sendEmails($this->parser->getData());
$output->writeln("End");
}

public function setSpammer(Spammer $spammer)
{
$this->spammer = $spammer;
}

public function setParser(Parser $parser)
{
$this->parser = $parser;
}

public function setDispatcher(EventDispatcher $dispatcher)
{
$this->dispatcher = $dispatcher;
}
}
[/sourcecode]

With all this parts we can build our script. Our classes are decoupled. That’s good but setting up the dependencies properly can be hard. Because of that we will use symfony/dependency-injection. With symfony DIC we can set up our dependency tree within a yaml file:

Our main services.yml
[sourcecode]
imports:
– resource: conf.yml
– resource: mail.yml
– resource: twig.yml

parameters:
base.path: .

services:
parser:
class: Parser
calls:
– [createFromCsvFile, [%mail.list%]]

mailer:
class: Mailer
arguments: [@swift.mailer, @swift.message]

spam.command:
class: SpamCommand
calls:
– [setParser, [@parser]]
– [setDispatcher, [@dispatcher]]
– [setSpammer, [@spammer]]

spammer:
class: Spammer
arguments: [@twig, @mailer, @dispatcher]

dispatcher:
class: Symfony\Component\EventDispatcher\EventDispatcher
[/sourcecode]

I like to separate the configuration files to reuse those files between projects and to make them more readable.

One for twig:

[sourcecode]
parameters:
twig.path: %base.path%/templates
twig.conf:
auto_reload: true

services:
twigLoader:
class: Twig_Loader_Filesystem
arguments: [%twig.path%]

twig:
class: Twig_Environment
arguments: [@twigLoader, %twig.conf%]
[/sourcecode]

another one for swiftmailer:

[sourcecode language=”xml”]
services:
swift.message:
class: Swift_Message
calls:
– [setSubject, [%mail.subject%]]
– [setFrom, [%mail.from.mail%: %mail.from.name%]]

swift.transport:
class: Swift_SmtpTransport
arguments: [%mail.smtp.host%, %mail.smtp.port%, %mail.smtp.encryption%]
calls:
– [setUsername, [%mail.smtp.username%]]
– [setPassword, [%mail.smtp.password%]]

swift.mailer:
class: Swift_Mailer
arguments: [@swift.transport]
[/sourcecode]

and the last one for the configuration parameters:

[sourcecode]
parameters:
mail.do.not.send.mails: false

mail.list: %base.path%/mailList.csv
mail.subject: mail subject
mail.from.name: My Name
mail.from.mail: my_email@mail.com

mail.smtp.username: my_smtp_username
mail.smtp.password: my_smtp_password
mail.smtp.host: smtp.gmail.com
mail.smtp.port: 465
mail.smtp.encryption: ssl
[/sourcecode]

Now we can build our script.

[sourcecode language=”php”]
use Symfony\Component\Console\Application;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;

$container = new ContainerBuilder();
$loader = new YamlFileLoader($container, new FileLocator(__DIR__ . ‘/conf’));
$loader->load(‘services.yml’);

$container->setParameter(‘base.path’, __DIR__);

$application = new Application();
$application->add($container->get(‘spam.command’));
$application->run();
[/sourcecode]n

And that’s all. My colleagues of the next Katayuno will be invited in a “SOLID” way :).
Source code is available in my github account.

BTW: Do you want to organize one Katayuno in your city? It’s very easy. Feel free to contact me for further information.