Squids my favorites

One of my best maritim meat is the squid, few days ago i cooked a recipe with risotto, egs, curry and squids and was delicious. Check here and tell me if you like it squids recipe

calamari

Calamari

Wall songs app for facebook

Im sure that all the songs you are share on the facebook are lost in the timeline. Now you can listen all your wall songs in a very cool facebook app WallSongs.

Wall Songs on Facebook

Zend Framework 2 Assets loader module

I recently released a module for zend framework 2, a module which helps you to automatically load assets like css, js, images and other types. All assets are filtred with JsMin, Packer, Less etc. and cached to a file and to browser by sending headers for caching. Take a look on the repository from github website.

PHP Dependency Injection

Simple but powerfull dependency injector based on phpdoc. It maps classes and instances into a injector instance. To inject classes and instances into a object instance just call the $injector->injectInto($instance);. This is a very simple aproach but when is used in a application si very powerfull.

class A {}
class B {}
class C { public $name; }

//THE BOOTSTRAP PART
$injector = Injector::getInstance();
$injector->mapClass("A");
$injector->mapSingleton("B");

$c = new C();
$c->name = "C Class";

$injector->mapInstance($c);

class YourClass
{
	/**
	 * @var B
	 */
	public $b_class;

	/**
	 * @var C
	 */
	public $c_class;

	public function init()
	{
	//use here $this->c_class and b_class
	}
}

$yc = new YourClass();

$injector->injectInto($yc);

$yc->init();

The injector takes all public properties and check the @var phpdoc param, if params match a class maped in the injector the value is passed to the property. Dependincy injection reduces significantly the the code you write, you dont need to create or pass instances for all classes just put it in the injector map set the php doc and thats all.

Click on the show source to view the injector class. If you have some questions just leave me a comment.

<?php

/**
 * Injector map item
 *
 * @autor		Albulescu Cosmin <albulescu.cosmin@gmail.com>
 * @version		1.0
 */
class Injector_Item
{

	/**
	 * The classname
	 * @var string
	 */
	public $class;

	/**
	 * The class is singleton
	 * @var boolean
	 */
	public $singleton;

	/**
	 * Holds instance name
	 * @var mixed
	 */
	public $instance;

	/**
	 * Array with params of constructing class
	 * @var array
	 */
	public $params;

	/**
	 * New injector map item
	 * @param string $class
	 * @param boolean $singleton
	 * @param object $instance
	 * @param array $params
	 */
	public function __construct($class, $singleton = false, $instance = null, $params = array())
	{
		$this->class = $class;
		$this->singleton = $singleton;
		$this->instance = $instance;
		$this->params = $params;
	}
}

/**
 * Injector manager
 *
 * @autor		Albulescu Cosmin <albulescu.cosmin@gmail.ro>
 * @version		1.0
 */
class Injector
{
	private static $_instance = null;

    /**
     * @return Injector
     */
    public static function getInstance()
    {
        if (null === self::$_instance)
        {
            self::$_instance = new self();
        }

        return self::$_instance;
    }

    private $map = array();

    /**
     * Map singleton class
     * @param string $class
     * @throws Exception
     */
    public function mapSingleton($class)
    {
    	if(!is_string($class))
    	{
    		throw new Exception("Class name must be a string");
    	}

    	$this->map[$class] = new Injector_Item($class, true);
    }

    /**
     * Map a class
     * @param string $class
     * @throws Exception
     */
    public function mapClass($class, $params = array())
    {
    	if(!is_string($class))
    	{
    		throw new Exception("Class name must be a string");
    	}

    	$this->map[$class] = new Injector_Item($class, false, null, $params);
    }

    /**
     * Map a object instance
     * @param object $instance
     * @throws Exception
     */
    public function mapInstance($instance)
    {
    	if(!is_object($instance))
    	{
    		throw new Exception("Instance must be an object " .gettype($instance). " given");
    	}

    	$item = new Injector_Item(get_class($instance), true, $instance);

    	$this->map[get_class($instance)] = $item;
    }

    /**
     * Get mapped instance of an object
     * @param string $class
     * @return mixed
     */
    public function getMappedInstance($class)
    {
    	if($this->hasMap($class))
    	{
    		$item = $this->map[ $class ];

    		if($item->singleton)
    		{
    			if(!$item->instance)
    			{
    				$item->instance = new $class;
    			}

    			return $item->instance;
    		}
    		else
    		{
	    		$r = new ReflectionClass( $item->class );

				if($r->hasMethod("__construct"))
				{
					$instance = $r->newInstance( $item->params );
				}
				else
				{
					$instance = $r->newInstance();
				}

				return $instance;
    		}
    	}

    	return null;
    }

    /**
     * Check if class mapped
     * @param string $class
     * @return boolean
     */
    public function hasMap($class)
    {
    	return array_key_exists($class, $this->map);
    }

    /**
     * Create new instance of a class with injected properties
     * @param string $class
     * @param array $params
     * @return mixed|NULL
     */
    public function newInstance($class, $params = array())
    {
    	if(class_exists($class,true))
    	{
    		$r = new ReflectionClass($class);

			if($r->hasMethod("__construct"))
			{
				$instance = $r->newInstance($params);
			}
			else
			{
				$instance = $r->newInstance();
			}

			$this->injectInto($instance);

			return $instance;
    	}

    	return null;
    }

    /**
     * Inject dependinces into a object instances
     * @param object $instance
     */
    public function injectInto($instance)
    {
    	$r = new ReflectionClass($instance);
    	$properties = $r->getProperties(ReflectionProperty::IS_PUBLIC);

    	foreach($properties as $property)
    	{
    		$doc = $property->getDocComment();

    		$doc =  trim(preg_replace('/\r|\r\n *\* */', '', $doc));

    		$lines = explode("\n", $doc);

    		//remove start and and of comment block
    		array_shift($lines);
    		array_pop($lines);

    		$propertyName = $property->getName();

    		foreach($lines as $line)
    		{
    			preg_match_all('/@([a-z]+)\s+(.*?)\s*(?=$|@[a-z]+\s)/s', $line, $matches);

    			if(count($matches) >=3 && count($matches[1]) && count($matches [2]))
    			{
	    			$info = array_combine($matches[1], $matches[2]);

	    			if(isset($info['var'])) {
	    				if($this->hasMap($info['var'])) {
	    					$instance->$propertyName = $this->getMappedInstance($info['var']);
	    				}

	    				break;//stop iterating, var found and injected if has a reference
	    			}
    			}
    		}
    	}
    }

    /**
     * Clear the map
     */
    public function clearMap()
    {
    	$this->map = array();
    }
}

Check this tool i found, play facebook wall shared music

Today i found very usefull facebook application, Wall play.

Wall play scan all your shared video music and put it in one player.

Facebook wall play

Using nodejs to read counter strike server info

NodeJs is a very powerfull tool for creating server side applications. Nodejs is a event-driven I/O JavaScript environment based on V8, wich is the engine for the chrome browser and is very fast, . This article shows how to read counter strike server info trought udp protocol wich the server runs. On default the server runs on the port 27015, and to read the info you need to send some pakets for the what you need: the server details, the players list or the server rules.

var Packet = {
	ping : [0xFF,0xFF,0xFF,0xFF,0x69],
	challenge : [0xFF,0xFF,0xFF,0xFF,0x56,0x00,0x00,0x00,0x00],
	details : [0xFF,0xFF,0xFF,0xFF, 0x54, 0x53, 0x6F, 0x75, 0x72, 0x63, 0x65, 0x20, 0x45, 0x6E, 0x67, 0x69, 0x6E, 0x65, 0x20, 0x51, 0x75, 0x65, 0x72, 0x79, 0x00],
	players : [0xFF,0xFF,0xFF,0xFF,0x55],
	rules : [0xFF,0xFF,0xFF,0xFF,0x56]
};

For every information wich server can serve you need to send a packet from above and you will receive the binary data. To read more about the counter strike server queries click here.

Here is the code to take a look and next i will explain much more about it.


var util = require('util');
var DGram = require('dgram');
var EventEmitter = require('events').EventEmitter;

var Packet = {
	ping : [0xFF,0xFF,0xFF,0xFF,0x69],
	challenge : [0xFF,0xFF,0xFF,0xFF,0x56,0x00,0x00,0x00,0x00],
	details : [0xFF,0xFF,0xFF,0xFF, 0x54, 0x53, 0x6F, 0x75, 0x72, 0x63, 0x65, 0x20, 0x45, 0x6E, 0x67, 0x69, 0x6E, 0x65, 0x20, 0x51, 0x75, 0x65, 0x72, 0x79, 0x00],
	players : [0xFF,0xFF,0xFF,0xFF,0x55],
	rules : [0xFF,0xFF,0xFF,0xFF,0x56]
};

var XBuffer = function(data)
{
	this.data = data;
	this.position = 0;
}

XBuffer.prototype.readString = function()
{
	var string = '';

	while(this.data[this.position] != 0x00)
	{
		string += String.fromCharCode(this.data[this.position]);
		this.position++;

		if(this.position > this.data.length)
			break;
	}

	//skip  0x00
	this.position++;

	return string;
}
XBuffer.prototype.skip = function(n)
{
	n = n || 1;
	this.position += n;
}
XBuffer.prototype.available = function()
{
	return Math.max(this.data.length - this.position, 0);
}
XBuffer.prototype.read = function(n)
{
	var b = new Buffer(n);
	n = n || 1;
	for(var i=0; i < n; i++)
	{
		b[i] = this.data[this.position+n];
		this.position++;
	}

	return new XBuffer(b);
}
XBuffer.prototype.readByte = function()
{
	var value = this.data[this.position];
	this.position++;
	return String.fromCharCode(value);
}
XBuffer.prototype.lookAhead = function(n)
{
	var tempPos = this.position;
	var buff = this.read(n);
	this.position=tempPos;
	return buff;
}

XBuffer.prototype.readUInt8 = function()
{
	var value = this.data.readUInt8(this.position);
	this.position++;
	return value;
}
XBuffer.prototype.readInt8 = function()
{
	var value = this.data.readInt8(this.position);
	this.position++;
	return value;
}
XBuffer.prototype.readInt16LE = function()
{
	var value = this.data.readInt16LE(this.position);
	this.position+=2;
	return value;
}
XBuffer.prototype.readInt16BE = function()
{
	var value = this.data.readInt16BE(this.position);
	this.position+=2;
	return value;
}
XBuffer.prototype.readInt32LE = function()
{
	var value = this.data.readInt32LE(this.position);
	this.position+=4;
	return value;
}
XBuffer.prototype.readFloatLE = function()
{
	var value = this.data.readFloatLE(this.position);
	this.position+=4;
	return value;
}
XBuffer.prototype.toString = function()
{
	return "[XBuffer " + this.data + "]";
}

function parseRules( data )
{
	var d = {};
	var b = new XBuffer(data);

	b.skip(5);

	var count = b.readInt16LE();

	if (count == 65535)
	{
		b.skip();
		count = b.readInt16LE();
	}

	d.num_rules = count;

	while(b.available())
	{
		d[b.readString()]=b.readString();
	}

	return d;
}

function parseDetails( data )
{
	b = new XBuffer(data);
	var d = {};

	b.skip(4);

	d.type =  b.readInt8();

	if (d.type == 0x6D)
		d.address =  b.readString();
	else
		d.protocol= b.readInt8();

	d.hostname =  b.readString();
	d.map =  b.readString();
	d.game_dir =  b.readString();
	d.game_desc =  b.readString();

	if (d.type != 0x6D) d.steamappid = b.readInt16LE();

	d.num_players= b.readInt8();
	d.max_players= b.readInt8();

	if (d.type == 0x6D) d.protocol = b.readInt8();
	else               d.num_bots = b.readInt8();

	d.dedicated = b.readByte();
	d.os		= b.readByte();
	d.password		= b.readInt8();
	d.secure		= b.readInt8();
	d.version		= b.readInt8();

	return d;
}

function parsePlayers( buffer )
{
	var b = new XBuffer( buffer );

	var players=[];

	b.skip(5);

	var playersn = b.readUInt8();

	for(var i=0; i < playersn; i++)
	{
		players.push({
			id : b.readUInt8(),
			name : b.readString(),
			score : b.readInt32LE(),
			time : b.readFloatLE()
		});
	}

	return players;
}

var Protocol = function(ip, port)
{
	this.ip = ip;
	this.port = port;
	this.client = DGram.createSocket("udp4");

	if(false === (this instanceof Protocol)) {
        return new Protocol(ip, port);
    }

	EventEmitter.call(this);
}

util.inherits(Protocol, EventEmitter);

Protocol.prototype.request = function()
{
	var self = this;

	var data = {};

	self.dgramRequest(new Buffer(Packet['ping']), function(challData,rinfo){
		if(challData[4] == 0x6A)
		{
			//pong received

			//request details
			self.dgramRequest(new Buffer(Packet['details']), function( detailsData, rinfo1){

				//parse server details
				try {
					data.details = parseDetails( detailsData );
				}catch(e){
					self.emit("exception", e);
				}

				//request the server details
				self.dgramRequest( new Buffer(Packet['players']), function(playersData, rinfo2){

					//parse players data and ad it to the data object
					try {
						data.players = parsePlayers( playersData );
					}catch(e) {
						self.emit("exception", e);
					}

					self.dgramRequest( new Buffer(Packet['rules']), function(rulesData, rinfo3){

						//parse server rules
						try {
						data.rules = parseRules( rulesData );
						} catch(e) {
							self.emit("exception", e);
						}

						//dispatch event
						self.emit("success", data);
					});

				});
			});

		}
		else
		{
			//no pong received, server is down
			self.emit("offline");
		}
	});

}

function preprocess( data )
{
	//used if you need to filter data from the server
	return data;
}

Protocol.prototype.dgramRequest = function( buffer, callback )
{
	var self = this;

	var offlineTimeout;

	var _internalCallback = function(data, rinfo)
	{
		data = preprocess( data );

		clearTimeout(offlineTimeout);

		if(callback)
		setTimeout(callback,0, data, rinfo);

		self.client.removeListener("message", _internalCallback);
	}

	offlineTimeout = setTimeout(function(){
		self.emit("offline");
	}, 2000);

	this.client.on("message", _internalCallback);

	this.client.send(buffer, 0, buffer.length, parseInt(this.port), this.ip, function(err, bytes) {
	  if(err){	console.log("Fail to broadcase packet to " + self.ip); }
	});

}

exports.Protocol = Protocol;

As you see there is required the dgram package wich is used for udp communications. UDP uses a simple transmission model without implicit handshaking dialogues for providing reliability, ordering, or data integrity. Thus, UDP provides an unreliable service and datagrams may arrive out of order, appear duplicated, or go missing without notice.

In this code are two objects the XBuffer and Protocol, XBuffer simply increase the reading pointer when reading data, and the Protocol send all pakets, filter data and dispatched as event.

Example of requesting info from the server

self.dgramRequest( new Buffer(Packet['players']), function(playersData, rinfo2) {
//your code here
} );

The function gramRequest is used to make syncron request to the server, send the packet and wait for response. If the response not apear for 2 senconds will trigger the offline event

The requests are sent one after another, parsed for a human readable format and pushed to the data object, when all complete is dispatched the success event ( self.emit(“success”, data); )

For every kind of received info i used functions to parse the binary data, for example, the player data is parsed with parsePlayers function. See the code comments for see how its work.

function parsePlayers( buffer )
{
        //create the xbuffer object with received buffer
	var b = new XBuffer( buffer );

	var players=[];
        //skip 5 unused bytes
	b.skip(5);
        //read a 2 bytes int wich is the number of the players
	var playersn = b.readUInt8();
        //make a loop to players length
	for(var i=0; i < playersn; i++)
	{
		players.push({
			id : b.readUInt8(), // read 2 bytes of int with the id of the player
			name : b.readString(), //read n bytes ending with 0x00 wich is the player name
			score : b.readInt32LE(), //read 4 bytes int with user score
			time : b.readFloatLE() //read 4 bytes float with user playing time
		});
	}

	return players;
}

Mini example to use this code

var Protocol = require("./communication.js").Protocol;

var protocol = new Protocol(server.ip, server.port);

protocol.on("success", function(data){
 //use data
});
protocol.request();

I hope this article helps you, and if you have some questions leave me a message.

Fist video for gatestebine.ro

Im very proud to announce the video section for my website with recipes. Take a look at the first video and tell me what you think about.

Gatesti bine?

Daca ﵩ place sa gatesti si vrei sa arati lumii si prieteniilor ce capodopere faci ﮠarta culinara, intra pe gatestebine.ro si publicati retetele.

Retete culinare, comunitate bucatari, gastronomie

Yahoo messenger in php

One of my articles was Yahoo Messenger Client with Action Script 3 now i will show you how to write a yahoo messenger application in php. The script flow its exactly like code from action script because its connect to the same yahoo messenger protocol. For binary working i used a zend package ( Zend_Io ). The implementation of yahoo messenger in php its very simple, use only minimal 6 base classes.

  1. ChallengeResponseV16 – Used to make the authentification
  2. Network – Used to communicate trought the socket
  3. Packet – Keeps human readable packet info
  4. PacketBody - Keeps human readable packet body info
  5. Protocol – Builds packets, make login and other yahoo messenger protocol implementation
  6. Service – Keeps constants with services provided by protocol

Try the yahoo messenger in php or download the source code

Web application versioning when using Zend Framework

This is a simple way to versioning a zend framework application using just two files, a ini file that keeps the current version and a proxy/model file wich load the current version from the ini file and test the user passed version for a new feature. The ini file is splited in three states: production, testing and development.


[production]

; 1.1.1 -
; 1.2.0 - From this we add video section
; 1.0.0 - First release of the site

version = "1.0.0";

[testing : production]

version = "1.0.0";

[development : production]

version = "1.0.0";

The good think about this is that you can set a version for each stage of application. While application is in development mode, just set a constant for enviroement and current version will be that from development block. The class wich handle this operations is a very simple singleton class with “version” method.


define('APPLICATION_ENV', 'development');

class Proxy_Version
{
	private static $_instance = null;

	private $versions;

    /**
     * Singleton instance
     * @abstract
     * @return Proxy_Version
     */
    public static function getInstance()
    {
        if (null === self::$_instance)
        {
            self::$_instance = new self();
        }

        return self::$_instance;
	}

	private function __construct()
	{
		$this->versions = new Zend_Config_Ini('version.ini', APPLICATION_ENV);
	}

    public static function version( $version = null )
    {
        self::getInstance();

    	$currentVersion = self::$versions->version;

    	$userVersion = false;//if you have stored in db the version for each user

    	if( $userVersion !== false )
    	{
    		$currentVersion = $userVersion;
    	}

    	if($version)
    	{
    		return version_compare($currentVersion, $version, ">=");
    	}

    	return $currentVersion;
    }
}

Also if you look closer in this class you can set a user version, for example when you want to let a limited numbers of users to test the next version of the application. To be more easy to use you can apply a shortcut in a view helper and access it with $this->version().


//context of version 1.0

if($this->version("1.2"))
{
//content of version 1.2
}

//context of version 1.0

echo $this->version();

Or you can set a shortcut in a abstract zend controller action and load views depentds of version method.


//controller class
//....
public function indexAction()
{
  if($this->version("1.2"))
    $this->render("index_1.2.phtml");
}
//....

Proudly powered by White Label SEO.