<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"><title>Devnotes</title><link href="http://foxfoo.com" rel="alternate"></link><link href="http://foxfoo.com/feeds/all.atom.xml" rel="self"></link><id>http://foxfoo.com</id><updated>2012-02-15T00:00:00Z</updated><entry><title>The purpose of the Internet</title><link href="http://foxfoo.com/the-purpose-of-the-internet.html" rel="alternate"></link><updated>2012-02-15T00:00:00Z</updated><author><name>John Doe</name></author><id>tag:foxfoo.com,2012-02-15:/the-purpose-of-the-internet.html/</id><summary type="html">&lt;p&gt;What is the purpose of the Internet?
This quostion is not being able to even for those who use it everyday,
and know its nature very well.
When back in the days people started to connect computers
from academic, government and bussiness networks into one world wide web,
they focused the most on its role as a communication instrument.
But what is the communication then?
People are communicating to each other since the the begining of our history.
Homo Sapiens unlike other species, has the language,
which happened to be the main tool for interacting to each other.
Language or speaking in general, was developed over the ability to make
sounds using the mouth, it is often complemented with body language,
facial expressions, gestures.
The only thing used for communication was only human body.&lt;/p&gt;
&lt;p&gt;But this was not enough, as it only allowed to communicate with someone
who is in direct sight or close enough to hear what others say.
The more people communicated, the more they became dependent on this.
Communication allowed people to collaborate,-
to work more productively in order to achieve their common goals together.
Which had a signifficant impact on developing communication amongst them.
And this lead to the rise of society, which is like one big organism.
Having its own collective conciuosness and intrinsic values.
It is not easy for us to percieve society as a whole,
same like one single cell of the body is not aware about the organism,
which is formed from miriads of other cells like it.
But still each and every of us is a part of it.
A part of something bigger and probably more important than we individually.
We started to live as a one big organism.
Which is an environment for us to live.
Our duty is in turn to support organism itself,
to make it work better and not to harm it.
Because healthier the society is,
the better conditions are for us to live within.
So we come to the purpose of every of us as a part of society,
which obviously is to benefit to society,
in order to attain better conditions to ourselves.&lt;/p&gt;
&lt;p&gt;Our brain works in the way, that makes us to feel a need of cognition.
We want to percieve the world we are living in better,
(this probably is a result of natural selection:
those who want to understand things better are more intelligent,
this means that they have better chances to survive)
So we naturally want to understand society better,
this is why we want to communicate to each other,
because other people are also a parts of the same organism as we are.
To intaract with other members we use language.
But during the time,
humans also learned to use tools to accomplish various tasks.
Because our body alone is limited.
Also there were tools for communication introduced.
Based on language, there was created writing, which allowed to record
the words on the piece of a material.
There also were smoke signals, coal drawings on the cave wall, drums,
which evolved to modern means of communications as mail,
telephone, radio, and recently the Internet.
It seems that it has been growing unrestrained for last decades.
Now one thisd of population is using it and the number is growing.
It allows us to collaborate in many ways, I am not going to name all the appliances here, because I suppose everybody knows it.
But the main idea is that the Internet is important and useful
not just for everyone of us, but for the sociaty as a whole.
So the Internet is not to satisfy the needs for some particular people,
but rather to make the world better, which in turn would benefit for us all.&lt;/p&gt;
&lt;p&gt;&lt;img alt="image0" src="pictures/slaves-in-egypt.jpg" /&gt;&lt;/p&gt;
&lt;p&gt;People worrking together to make the world better&lt;/p&gt;
</summary><category term="internet"></category><category term="society"></category></entry><entry><title>Site to play durak online</title><link href="http://foxfoo.com/site-to-play-durak-online.html" rel="alternate"></link><updated>2011-12-26T00:00:00Z</updated><author><name>John Doe</name></author><id>tag:foxfoo.com,2011-12-26:/site-to-play-durak-online.html/</id><summary type="html">&lt;p&gt;Durak is a card game very popular in Eastern Europe.
I like this card game, therefore i decided to build a site
in which one could play Durak online against other people.
It was surprising that such popular game did not have good website to play it
online, well there were some, but they was ugly, hardly playable and poor.
So my goal was to build better site.
This was challenging task, but I started to plan it thoroughly.
First prototype of it emerged in 2008. I have built it using cakephp and ajax.
It neither was easy to play nor good looking. But it was at least playable.
By having this prototype version, I was able to analyze in details
main aspects of building web site including both usability
and technical inplementation.
And this was the very first step of building
&lt;a class="reference external" href="http://durak24.com"&gt;The best Durak card game online&lt;/a&gt; website.&lt;/p&gt;
&lt;p&gt;First of all i found that i have very limited resources.
Time was limited, because, I could work on the project on my spare time only.
And unfortunately i do not have much spare time.
So I decided to go with only essential features,
to use good frameworks and tools and do not try to reinvent a bycycle.&lt;/p&gt;
&lt;p&gt;The second limited resource was servers. Durak is interactive game,
so clients to wery much queries to the server,
so server should be capable to process all these requests.
Also server had to host a website itself.&lt;/p&gt;
&lt;p&gt;Given those two limitations I designed an application architecture,
that was meant to impose rapid development
and to be able to be ran on cheap servers.
My decission was to move as much logic as is possible to the client.
And client software to be coded in javascript using jQuery.
Another decission vas to separate website server from the server
in which all the interactions in between players happening.
I decided to make website itself in Symfony2 web application framework
to accelerate the development and to host a website in a cheap PHP web hosting.
And to use another Game Server which I built on Google Appengine platform
using python language.
It was easy to start with but it was far not cheap.
But developing with Python is very fast.
However later I had to escape AppEngine due to its increasing pricing,
so I ported the Game Server from Python to good old java servlets,
that could be deployed at every host that supports WAR application hosting.
The porting took only couple of days,
and I called my new server software Uncloud,
because I was upset by AppEngine cloud technology pricing and hosted it in
&lt;a class="reference external" href="ttp://www.jvmhost.com/?affid=11"&gt;JVMHost&lt;/a&gt;
(Yes, this is referal link,
but please note that I am very content by this service,
so I would really reccomend it for everyone).
But I think to develop it in Python at first then to port it to Java
can be good idea sometimes, as it was in my case.
The truth is: developing in python is fast.
But java servlets have one important feature -
the application state can be saved without using any database
or other external storing mechanisms,
]I could all the player and game states store just to Application context,
instead using any permanent persistence, so the Uncloud server got even faster.&lt;/p&gt;
&lt;p&gt;So, we now have some sort of service oriented system model,
and a natural question to arrise here would be
&amp;quot;How do these components interact to each other?&amp;quot;. See this picture:&lt;/p&gt;
&lt;p&gt;&lt;img alt="image0" src="pictures/how-durak24-works.png" /&gt;&lt;/p&gt;
&lt;p&gt;This is how services interact when user enters the game.&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;Client makes request to the Website, asking to join the game.&lt;/li&gt;
&lt;li&gt;Website communicates to Uncloud, ant tells Uncloud to accept requests
from the Client.&lt;/li&gt;
&lt;li&gt;Website responds to client with credentials, required to connect to Uncloud&lt;/li&gt;
&lt;li&gt;Client makes JSONP request to Uncloud not independently from Website,
up from this time, client only communicates dirrectly to Uncloud.&lt;/li&gt;
&lt;li&gt;Uncloud responds to Client.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Steps 4-5 are repeated as long as player stays in the game.
Three components could be found, that is Client Software, Website server and Uncloud server.&lt;/p&gt;
&lt;p&gt;This architecture well balanced load between servers and client. Website is only responsible For serving pages and user authentification. Game interactions are shared between Uncloud and Client Software. Uncloud returns only simple JSON, so all html rendering is done on Client Software. Hosting is relatively cheap, and is sufficient for game to run nice and smoothly.&lt;/p&gt;
&lt;p&gt;How does it all look you might wonder?
See this video or visit
&lt;a class="reference external" href="http://durak24.com"&gt;durak24.com&lt;/a&gt; website.&lt;/p&gt;
&lt;iframe width="760" height="545" src="http://www.youtube.com/embed/KlUZHoNGWTE" frameborder="0" allowfullscreen&gt;&lt;/iframe&gt;</summary></entry><entry><title>Howto Facebook Connect in Symfony2</title><link href="http://foxfoo.com/howto-facebook-connect-in-symfony2.html" rel="alternate"></link><updated>2011-11-27T00:00:00Z</updated><author><name>John Doe</name></author><id>tag:foxfoo.com,2011-11-27:/howto-facebook-connect-in-symfony2.html/</id><summary type="html">&lt;p&gt;To implement Facebook Connect leveraging awesome Symfony2 Auth system
I had a little bit difficult,
mostly because I could not found good guide how to do it in documentation,
nor somewhere on the Internet. So that I have finally have figured this out,
here is brief of what I have exactly done.
I am not confident 100% about this solution,
maybe there could be better and more elegant one, but at least this works.
But if someone has something to add, I would really like to know it.&lt;/p&gt;
&lt;p&gt;Symfony2 distribution contains demo application,
with an example of username/password authentication.
We will build our application on top of that,
additionally providing a way to login using Facebook.&lt;/p&gt;
&lt;p&gt;First add Facebook Connect button:
First of all we need to define our Facebook Application credentials
(get them by registering new app in Facebook), wee will use them everywhere.&lt;/p&gt;
&lt;p&gt;app/config/parameters.ini:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
facebookAppId=your-app-id
facebookAppSecret=your-app-secret
&lt;/pre&gt;
&lt;p&gt;Then we need to pass them to the output of our application, therefore we will make DemoController::indexAction to return AppId, that in turn will be set to template.&lt;/p&gt;
&lt;p&gt;src/Acme/DemoBundle/Controllers/DemoController.php&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="x"&gt;// ...&lt;/span&gt;
&lt;span class="x"&gt;public function indexAction()&lt;/span&gt;
&lt;span class="x"&gt;{&lt;/span&gt;
&lt;span class="x"&gt;    return array(&amp;#39;facebookAppId&amp;#39; =&amp;gt;&lt;/span&gt;
&lt;span class="x"&gt;    $this-&amp;gt;container-&amp;gt;getParameter(&amp;#39;facebookAppId&amp;#39;));&lt;/span&gt;
&lt;span class="x"&gt;}&lt;/span&gt;
&lt;span class="x"&gt;// ...&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And in template add Facebook Connect button&lt;/p&gt;
&lt;p&gt;src/Acme/DemoBundle/Resources/views/Demo/index.html.twig:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&amp;lt;fb:login-button v=&amp;quot;2&amp;quot; size=&amp;quot;xlarge&amp;quot; onlogin=&amp;quot;onFacebookConnect();&amp;quot;&amp;gt;
    Login with Facebook
&amp;lt;/fb:login-button&amp;gt;
&amp;lt;div id=&amp;quot;fb-root&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;


&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;
window.fbAsyncInit = function() {
    FB.init({
        appId      : &amp;#39;{{ facebookAppId }}&amp;#39;,
        status     : true,
        cookie     : true,
        xfbml      : true
    });

    FB.Event.subscribe(&amp;#39;auth.login&amp;#39;, function(response) {
        window.location.reload();
    });
};

function onFacebookConnect() {
    window.location.reload();
}

(function(d){
    var js, id = &amp;#39;facebook-jssdk&amp;#39;; if (d.getElementById(id)) {return;}
    js = d.createElement(&amp;#39;script&amp;#39;); js.id = id; js.async = true;
    js.src = &amp;quot;//connect.facebook.net/en_US/all.js&amp;quot;;
    d.getElementsByTagName(&amp;#39;head&amp;#39;)[0].appendChild(js);
}(document));
&amp;lt;/script&amp;gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And do not forget add required namespaces to html element:&lt;/p&gt;
&lt;p&gt;src/Acme/DemoBundle/Resources/views/layout.html.twig:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="nt"&gt;&amp;lt;html&lt;/span&gt; &lt;span class="na"&gt;xmlns:fb=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;http://www.facebook.com/2008/fbml&amp;quot;&lt;/span&gt;
      &lt;span class="na"&gt;xmlns:og=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;http://opengraphprotocol.org/schema/&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This is all ok Facebook should now authenticate users.
And to set cookie to our application.
Next we are going to extract user data from Facebook using the cookie,
And authenticate user to our application if everything goes correct.&lt;/p&gt;
&lt;p&gt;First let us model data structure for our user:&lt;/p&gt;
&lt;p&gt;src/Acme/DemoBundle/Facebook/FacebookUser.php&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class="k"&gt;namespace&lt;/span&gt; &lt;span class="nx"&gt;Acme\DemoBundle\Facebook&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nx"&gt;Symfony\Component\Security\Core\User\UserInterface&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;FacebookUser&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;__construct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$data&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;username&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$data&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;first_name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getUsername&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getId&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;__toString&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;serialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Make changes to our configuration&lt;/p&gt;
&lt;p&gt;app/config/security.yml:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="l-Scalar-Plain"&gt;security&lt;/span&gt;&lt;span class="p-Indicator"&gt;:&lt;/span&gt;
    &lt;span class="l-Scalar-Plain"&gt;...&lt;/span&gt;
    &lt;span class="l-Scalar-Plain"&gt;firewalls&lt;/span&gt;&lt;span class="p-Indicator"&gt;:&lt;/span&gt;
        &lt;span class="l-Scalar-Plain"&gt;...&lt;/span&gt;
        &lt;span class="l-Scalar-Plain"&gt;secured_area&lt;/span&gt;&lt;span class="p-Indicator"&gt;:&lt;/span&gt;
            &lt;span class="l-Scalar-Plain"&gt;pattern&lt;/span&gt;&lt;span class="p-Indicator"&gt;:&lt;/span&gt;    &lt;span class="l-Scalar-Plain"&gt;^/demo/secured/&lt;/span&gt;
            &lt;span class="l-Scalar-Plain"&gt;form_login&lt;/span&gt;&lt;span class="p-Indicator"&gt;:&lt;/span&gt;
                &lt;span class="l-Scalar-Plain"&gt;check_path&lt;/span&gt;&lt;span class="p-Indicator"&gt;:&lt;/span&gt; &lt;span class="l-Scalar-Plain"&gt;/demo/secured/login_check&lt;/span&gt;
                &lt;span class="l-Scalar-Plain"&gt;login_path&lt;/span&gt;&lt;span class="p-Indicator"&gt;:&lt;/span&gt; &lt;span class="l-Scalar-Plain"&gt;/demo/secured/login&lt;/span&gt;
            &lt;span class="l-Scalar-Plain"&gt;logout&lt;/span&gt;&lt;span class="p-Indicator"&gt;:&lt;/span&gt;
                &lt;span class="l-Scalar-Plain"&gt;path&lt;/span&gt;&lt;span class="p-Indicator"&gt;:&lt;/span&gt;   &lt;span class="l-Scalar-Plain"&gt;/demo/secured/logout&lt;/span&gt;
                &lt;span class="l-Scalar-Plain"&gt;target&lt;/span&gt;&lt;span class="p-Indicator"&gt;:&lt;/span&gt; &lt;span class="l-Scalar-Plain"&gt;/demo/&lt;/span&gt;
            &lt;span class="c1"&gt;# Add this to call facebook authentication listener&lt;/span&gt;
            &lt;span class="c1"&gt;# in this secured area&lt;/span&gt;
            &lt;span class="l-Scalar-Plain"&gt;facebook&lt;/span&gt;&lt;span class="p-Indicator"&gt;:&lt;/span&gt; &lt;span class="l-Scalar-Plain"&gt;~&lt;/span&gt;
&lt;span class="nn"&gt;...&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;New factory wil be responsible for creation of objects for Facebook Authentication&lt;/p&gt;
&lt;p&gt;src/Acme/DemoBundle/Resources/config/security_factories.xml:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="nt"&gt;&amp;lt;container&lt;/span&gt; &lt;span class="na"&gt;xmlns=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;http://symfony.com/schema/dic/services&amp;quot;&lt;/span&gt;
           &lt;span class="na"&gt;xmlns:xsi=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot;&lt;/span&gt;
           &lt;span class="na"&gt;xsi:schemaLocation=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;http://symfony.com/schema/dic/services&lt;/span&gt;
&lt;span class="s"&gt;                               http://symfony.com/schema/dic/services/services-1.0.xsd&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;services&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;service&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;security.authentication.factory.facebook&amp;quot;&lt;/span&gt;
                 &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Acme\DemoBundle\Facebook\FacebookFactory&amp;quot;&lt;/span&gt;
                 &lt;span class="na"&gt;public=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;false&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;tag&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;security.listener.factory&amp;quot;&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/service&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/services&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/container&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;So we have to create Factory class:&lt;/p&gt;
&lt;p&gt;src/Acme/DemoBundle/Facebook/FacebookFactory.php:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class="k"&gt;namespace&lt;/span&gt; &lt;span class="nx"&gt;Acme\DemoBundle\Facebook&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nx"&gt;Symfony\Component\DependencyInjection\ContainerBuilder&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nx"&gt;Symfony\Component\DependencyInjection\Reference&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nx"&gt;Symfony\Component\DependencyInjection\DefinitionDecorator&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nx"&gt;Symfony\Component\Config\Definition\Builder\NodeDefinition&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nx"&gt;Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory\SecurityFactoryInterface&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nx"&gt;Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory\AbstractFactory&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="o"&gt;/**&lt;/span&gt;
 &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;The&lt;/span&gt; &lt;span class="nx"&gt;factory&lt;/span&gt; &lt;span class="nx"&gt;is&lt;/span&gt; &lt;span class="nx"&gt;where&lt;/span&gt; &lt;span class="nx"&gt;you&lt;/span&gt; &lt;span class="nx"&gt;hook&lt;/span&gt; &lt;span class="nx"&gt;into&lt;/span&gt; &lt;span class="nx"&gt;the&lt;/span&gt; &lt;span class="nx"&gt;security&lt;/span&gt; &lt;span class="nx"&gt;component&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;telling&lt;/span&gt; &lt;span class="nx"&gt;it&lt;/span&gt; &lt;span class="nx"&gt;the&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="nx"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;your&lt;/span&gt; &lt;span class="nx"&gt;provider&lt;/span&gt; &lt;span class="k"&gt;and&lt;/span&gt; &lt;span class="nx"&gt;any&lt;/span&gt; &lt;span class="nx"&gt;configuration&lt;/span&gt;
 &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt; &lt;span class="nx"&gt;available&lt;/span&gt;
 &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="nx"&gt;it&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
 &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;FacebookFactory&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;SecurityFactoryInterface&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ContainerBuilder&lt;/span&gt; &lt;span class="nv"&gt;$container&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$config&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                           &lt;span class="nv"&gt;$userProvider&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$defaultEntryPoint&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$providerId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;security.authentication.provider.facebook.&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;$id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nv"&gt;$providerDD&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;DefinitionDecorator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                          &lt;span class="s1"&gt;&amp;#39;facebook.security.authentication.provider&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="nv"&gt;$container&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;setDefinition&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$providerId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$providerDD&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;replaceArgument&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Reference&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$userProvider&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

        &lt;span class="nv"&gt;$listenerId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;security.authentication.listener.facebook.&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;$id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nv"&gt;$listenerDD&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;DefinitionDecorator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                              &lt;span class="s1"&gt;&amp;#39;facebook.security.authentication.listener&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nv"&gt;$listener&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$container&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;setDefinition&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$listenerId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$listenerDD&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$providerId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$listenerId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$defaultEntryPoint&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getPosition&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;pre_auth&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getKey&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;facebook&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;addConfiguration&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;NodeDefinition&lt;/span&gt; &lt;span class="nv"&gt;$node&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And we can see services used by this factory:
facebook.security.authentication.listener and facebook.security.authentication.provider
So we must inject them to our dependency container them too:&lt;/p&gt;
&lt;p&gt;src/Acme/DemoBundle/Resources/config/services.xml:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="cp"&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; ?&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;container&lt;/span&gt; &lt;span class="na"&gt;xmlns=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;http://symfony.com/schema/dic/services&amp;quot;&lt;/span&gt;
    &lt;span class="na"&gt;xmlns:xsi=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot;&lt;/span&gt;
    &lt;span class="na"&gt;xsi:schemaLocation=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;http://symfony.com/schema/dic/services&lt;/span&gt;
&lt;span class="s"&gt;                        http://symfony.com/schema/dic/services/services-1.0.xsd&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;services&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;service&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;twig.extension.acme.demo&amp;quot;&lt;/span&gt;
                 &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Acme\DemoBundle\Twig\Extension\DemoExtension&amp;quot;&lt;/span&gt;
                 &lt;span class="na"&gt;public=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;false&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;tag&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;twig.extension&amp;quot;&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;argument&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;service&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;twig.loader&amp;quot;&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/service&amp;gt;&lt;/span&gt;

        &lt;span class="nt"&gt;&amp;lt;service&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;acme.demo.listener&amp;quot;&lt;/span&gt;
                 &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Acme\DemoBundle\ControllerListener&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;tag&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;kernel.event_listener&amp;quot;&lt;/span&gt;
                 &lt;span class="na"&gt;event=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;kernel.controller&amp;quot;&lt;/span&gt;
                 &lt;span class="na"&gt;method=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;onKernelController&amp;quot;&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;argument&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;service&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;twig.extension.acme.demo&amp;quot;&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/service&amp;gt;&lt;/span&gt;

        &lt;span class="nt"&gt;&amp;lt;service&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;facebook.security.authentication.provider&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Symfony\Component\Security\Core\Authentication\Provider\AnonymousAuthenticationProvider&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;public=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;false&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;argument&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/service&amp;gt;&lt;/span&gt;

        &lt;span class="nt"&gt;&amp;lt;service&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;facebook.security.authentication.listener&amp;quot;&lt;/span&gt;
          &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;”Acme\DemoBundle\Facebook\FacebookListener&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;public=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;false&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;argument&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;service&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;security.context&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;argument&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;service&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;security.authentication.manager&amp;quot;&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;argument&amp;gt;&lt;/span&gt;%facebookAppId%&lt;span class="nt"&gt;&amp;lt;/argument&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;argument&amp;gt;&lt;/span&gt;%facebookAppSecret%&lt;span class="nt"&gt;&amp;lt;/argument&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/service&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/services&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/container&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;To comply with Auth framework we need to define authentication token.&lt;/p&gt;
&lt;p&gt;src/Acme/DemoBundle/Facebook/FacebookUserToken.php:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class="k"&gt;namespace&lt;/span&gt; &lt;span class="nx"&gt;Acme\DemoBundle\Facebook&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nx"&gt;Symfony\Component\Security\Core\Authentication\Token\AbstractToken&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="o"&gt;/**&lt;/span&gt;
 &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;A&lt;/span&gt; &lt;span class="nx"&gt;token&lt;/span&gt; &lt;span class="nx"&gt;represents&lt;/span&gt; &lt;span class="nx"&gt;the&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="nx"&gt;authentication&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="nx"&gt;present&lt;/span&gt; &lt;span class="nx"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;the&lt;/span&gt; &lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
 &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;Once&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="nx"&gt;request&lt;/span&gt; &lt;span class="nx"&gt;is&lt;/span&gt; &lt;span class="nx"&gt;authenticated&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;the&lt;/span&gt; &lt;span class="nx"&gt;token&lt;/span&gt; &lt;span class="nx"&gt;retains&lt;/span&gt; &lt;span class="nx"&gt;the&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="err"&gt;`&lt;/span&gt;&lt;span class="nx"&gt;s&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;and&lt;/span&gt; &lt;span class="nx"&gt;delivers&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="nx"&gt;across&lt;/span&gt; &lt;span class="nx"&gt;the&lt;/span&gt; &lt;span class="nx"&gt;security&lt;/span&gt; &lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
 &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;FacebookUserToken&lt;/span&gt; &lt;span class="k"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;AbstractToken&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nv"&gt;$accessToken&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;setAccessToken&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$accessToken&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;accessToken&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$accessToken&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getAccessToken&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;accessToken&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getCredentials&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This token will be used by listener. And here is the listener itself&lt;/p&gt;
&lt;p&gt;src/Acme/DemoBundle/Facebook/FacebookListener.php:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class="k"&gt;namespace&lt;/span&gt; &lt;span class="nx"&gt;Acme\DemoBundle\Facebook&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nx"&gt;Symfony\Component\HttpFoundation\Response&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nx"&gt;Symfony\Component\HttpKernel\Event\GetResponseEvent&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nx"&gt;Symfony\Component\Security\Http\Firewall\AbstractAuthenticationListener&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nx"&gt;Symfony\Component\Security\Http\Firewall\ListenerInterface&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nx"&gt;Symfony\Component\Security\Core\Exception\AuthenticationException&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nx"&gt;Symfony\Component\Security\Core\SecurityContextInterface&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nx"&gt;Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nx"&gt;Symfony\Component\Security\Core\Authentication\Token\TokenInterface&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nx"&gt;Symfony\Component\HttpFoundation\Request&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nx"&gt;Symfony\Component\Security\Http\Logout\LogoutHandlerInterface&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nx"&gt;Symfony\Component\HttpFoundation\RedirectResponse&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nx"&gt;Symfony\Component\Security\Core\Authentication\Token\AnonymousToken&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="o"&gt;/**&lt;/span&gt;
 &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;The&lt;/span&gt; &lt;span class="nx"&gt;listener&lt;/span&gt; &lt;span class="nx"&gt;is&lt;/span&gt; &lt;span class="nx"&gt;responsible&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="nx"&gt;fielding&lt;/span&gt; &lt;span class="nx"&gt;requests&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="nx"&gt;the&lt;/span&gt; &lt;span class="nx"&gt;firewall&lt;/span&gt;
 &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;and&lt;/span&gt; &lt;span class="nx"&gt;calling&lt;/span&gt; &lt;span class="nx"&gt;the&lt;/span&gt; &lt;span class="nx"&gt;authentication&lt;/span&gt; &lt;span class="nx"&gt;provider&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
 &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;FacebookListener&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;ListenerInterface&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="nv"&gt;$securityContext&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="nv"&gt;$authenticationManager&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;__construct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;SecurityContextInterface&lt;/span&gt; &lt;span class="nv"&gt;$securityContext&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                &lt;span class="nx"&gt;AuthenticationManagerInterface&lt;/span&gt; &lt;span class="nv"&gt;$authenticationManager&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                &lt;span class="nv"&gt;$appId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$appSecret&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;securityContext&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$securityContext&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;authenticationManager&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$authenticationManager&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;appId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$appId&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;appSecret&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$appSecret&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;handle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;GetResponseEvent&lt;/span&gt; &lt;span class="nv"&gt;$event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$request&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$event&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;getRequest&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;null&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;securityContext&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;getToken&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nv"&gt;$cookie&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;getFacebookCookie&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$cookie&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nv"&gt;$token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;FacebookUserToken&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="nv"&gt;$token&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;setAccessToken&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$cookie&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;access_token&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;


            &lt;span class="nv"&gt;$content&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="nb"&gt;file_get_contents&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                    &lt;span class="s1"&gt;&amp;#39;https://graph.facebook.com/me?access_token=&amp;#39;&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;
                    &lt;span class="nv"&gt;$token&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;getAccessToken&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$content&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="nv"&gt;$userData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;json_decode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$content&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="nv"&gt;$user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;FacebookUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$userData&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="nv"&gt;$token&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;setUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$user&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;securityContext&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;setToken&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$token&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getFacebookCookie&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$args&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;array&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nb"&gt;isset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$_COOKIE&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;fbs_&amp;#39;&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;appId&lt;/span&gt;&lt;span class="p"&gt;]))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nb"&gt;parse_str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$_COOKIE&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;fbs_&amp;#39;&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;appId&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;\\&amp;quot;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nv"&gt;$args&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nb"&gt;ksort&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$args&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nv"&gt;$payload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$args&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nv"&gt;$key&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$key&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;sig&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="nv"&gt;$payload&lt;/span&gt; &lt;span class="o"&gt;.=&lt;/span&gt; &lt;span class="nv"&gt;$key&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;=&amp;#39;&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="nv"&gt;$value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;md5&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$payload&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;appSecret&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="nv"&gt;$args&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;sig&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$args&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now you should be able to authenticate to demo app with facebook,
and you should see this in secured are when authenticated by Facebook:&lt;/p&gt;
&lt;p&gt;&lt;img alt="image0" src="pictures/user-authenticated-to-symfony2-by-facebook.png" /&gt;&lt;/p&gt;
</summary><category term="facebook"></category><category term="symfony2"></category><category term="php"></category></entry><entry><title>How to deploy a web application to FTP server using Apache Ant</title><link href="http://foxfoo.com/how-to-deploy-a-web-application-to-ftp-server-using-apache-ant.html" rel="alternate"></link><updated>2011-11-24T00:00:00Z</updated><author><name>John Doe</name></author><id>tag:foxfoo.com,2011-11-24:/how-to-deploy-a-web-application-to-ftp-server-using-apache-ant.html/</id><summary type="html">&lt;p&gt;As far as I have seen the most popular method
to transfer PHP web application to remote server is FTP.
This post is not about whether it is good or bad practice,
but I would rather try explain how to automatize this procedure
using Apache Ant.
Actually Ant is the tool which Java developers use everyday.
But you do not have to work with Java projects to use this handy tool.
So what is Ant?
In simple words just run scripted tasks defined in XML,
for a sake of automatizing things.&lt;/p&gt;
&lt;p&gt;Would not it be nice to be able to upload application files to ftp
and clean cache by only running a single command?
Of course, but how to do it?
Here is how – a simple script
that you just put into the root of your web application&lt;/p&gt;
&lt;dl class="docutils"&gt;
&lt;dt&gt;ant.xml::&lt;/dt&gt;
&lt;dd&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="nt"&gt;&amp;lt;project&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;my symfony2 website&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;default=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;upload&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;basedir=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;.&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

  &lt;span class="c"&gt;&amp;lt;!-- Include config file containing FTP credentials --&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;property&lt;/span&gt; &lt;span class="na"&gt;file=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;build.properties&amp;quot;&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;

  &lt;span class="c"&gt;&amp;lt;!-- This target will do all required job --&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;target&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;upload&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="c"&gt;&amp;lt;!-- Clean cache of web application on ftp server --&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;ftp&lt;/span&gt; &lt;span class="na"&gt;action=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;delete&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;server=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;${ftp.server}&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;userid=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;${ftp.user}&amp;quot;&lt;/span&gt;
         &lt;span class="na"&gt;password=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;${ftp.password}&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;remotedir=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;${ftp.dir}/app/cache&amp;quot;&lt;/span&gt;
         &lt;span class="na"&gt;verbose=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;true&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;passive=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;yes&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;fileset&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;include&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;**/*&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/fileset&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/ftp&amp;gt;&lt;/span&gt;

    &lt;span class="c"&gt;&amp;lt;!--&lt;/span&gt;
&lt;span class="c"&gt;    Upload three directories to their respective locations on ftp server&lt;/span&gt;
&lt;span class="c"&gt;    --&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;ftp&lt;/span&gt; &lt;span class="na"&gt;server=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;${ftp.server}&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;userid=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;${ftp.user}&amp;quot;&lt;/span&gt;
         &lt;span class="na"&gt;password=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;${ftp.password}&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;remotedir=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;${ftp.dir}/app&amp;quot;&lt;/span&gt;
         &lt;span class="na"&gt;binary=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;yes&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;verbose=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;false&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;passive=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;yes&amp;quot;&lt;/span&gt; &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;fileset&lt;/span&gt; &lt;span class="na"&gt;dir=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;app&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;include&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;**/*&amp;quot;&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;exclude&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;cache/&amp;quot;&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="c"&gt;&amp;lt;!--Everything but the cache --&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/fileset&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/ftp&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;ftp&lt;/span&gt; &lt;span class="na"&gt;server=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;${ftp.server}&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;userid=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;${ftp.user}&amp;quot;&lt;/span&gt;
         &lt;span class="na"&gt;password=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;${ftp.password}&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;remotedir=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;${ftp.dir}/src&amp;quot;&lt;/span&gt;
         &lt;span class="na"&gt;binary=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;yes&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;verbose=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;false&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;passive=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;yes&amp;quot;&lt;/span&gt; &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;fileset&lt;/span&gt; &lt;span class="na"&gt;dir=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;src&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;include&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;**/*&amp;quot;&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/fileset&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/ftp&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;ftp&lt;/span&gt; &lt;span class="na"&gt;server=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;${ftp.server}&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;userid=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;${ftp.user}&amp;quot;&lt;/span&gt;
         &lt;span class="na"&gt;password=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;${ftp.password}&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;remotedir=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;${ftp.dir}/public_html&amp;quot;&lt;/span&gt;
         &lt;span class="na"&gt;binary=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;yes&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;verbose=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;false&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;passive=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;yes&amp;quot;&lt;/span&gt; &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;fileset&lt;/span&gt; &lt;span class="na"&gt;dir=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;web&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;include&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;**/*&amp;quot;&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/fileset&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/ftp&amp;gt;&lt;/span&gt;
    &lt;span class="c"&gt;&amp;lt;!--&lt;/span&gt;
&lt;span class="c"&gt;    Note how the last task here uploaded contents&lt;/span&gt;
&lt;span class="c"&gt;    of our local web directory&lt;/span&gt;
&lt;span class="c"&gt;    to the public_html on the server,- this is because Symfony2 default&lt;/span&gt;
&lt;span class="c"&gt;    directory structure is not the same as the structure on my server --&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/target&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/project&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;and settings defined in build.properties:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
#Ftp settings
ftp.server=server.url
ftp.user=username
ftp.password=password
ftp.dir=/dir
&lt;/pre&gt;
&lt;p&gt;The script with deploying instructions is now ready,
but we need to install Ant itself&lt;/p&gt;
&lt;p&gt;Install Apache Ant with Ftp task on Ubuntu
As and everything on ubuntu it installs like:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
# sudo apt-get install ant
&lt;/pre&gt;
&lt;p&gt;But this is not sufficient to run ftp task,
so we have to install libcommons-net-java:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
# sudo apt-get install libcommons-net-java
&lt;/pre&gt;
&lt;p&gt;By doing this file /usr/share/java/commons-net.jar
and /usr/share/java/oro.jar should be created.
It is now possible to execute FTP tasks by running command:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
$ ant -lib /usr/share/java/commons-net.jar:/usr/share/java/oro.jar
&lt;/pre&gt;
&lt;p&gt;By linking this file to where Ant is installed:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
$ sudo ln -s /usr/share/java/commons-net.jar /usr/share/ant/lib
$ sudo ln -s /usr/share/java/oro.jar /usr/share/ant/lib
&lt;/pre&gt;
&lt;p&gt;we can achieve that we do not have to add the lib as a parameter,
so we could simply run:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
$ ant
&lt;/pre&gt;
&lt;p&gt;in order to execute upload task&lt;/p&gt;
&lt;p&gt;Install Apache Ant with Ftp task on Windows 7&lt;/p&gt;
&lt;p&gt;In windows this might not be so trivial
as first you have to download Ant [&lt;a class="reference external" href="http://ant.apache.org/"&gt;http://ant.apache.org/&lt;/a&gt;] and extract it.&lt;/p&gt;
&lt;p&gt;Search in start menu for “Edit system environment variables” and open it.
Add new system variable ANT_HOME with value of “C:ant”
(or something regarding to where you extracted ant binaries).
Also adjust “Path” variable – add aditional path “%ANT_HOME%\bin” to it.&lt;/p&gt;
&lt;p&gt;Download commons-net [&lt;a class="reference external" href="http://commons.apache.org/net/download_net.cgi"&gt;http://commons.apache.org/net/download_net.cgi&lt;/a&gt;]
and jakarta-oro [&lt;a class="reference external" href="http://archive.apache.org/dist/jakarta/oro/"&gt;http://archive.apache.org/dist/jakarta/oro/&lt;/a&gt;] jars
and place them into C:antlib.&lt;/p&gt;
&lt;p&gt;But when you run ant you will get an error,
it complains about some permission denied.
This is good windows firewall standing on the way,-
turn it off by this command:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
netsh advfirewall set global StatefulFTP disable
&lt;/pre&gt;
&lt;p&gt;Try to run upload script and it should work.&lt;/p&gt;
&lt;p&gt;Run Apache Ant Ftp task within Eclipse&lt;/p&gt;
&lt;p&gt;All you have to do in Eclipse Preferences is in
Ant -&amp;gt; Runtime -&amp;gt; Classpath to Ant home entries
add jars commons-net and jakarta-oro.
After doing this you should be able to run Ant within Eclipse like this:&lt;/p&gt;
&lt;p&gt;&lt;img alt="image0" src="pictures/ant-in-eclipse.png" /&gt;&lt;/p&gt;
&lt;p&gt;To run it press Alt + Shift + X Q&lt;/p&gt;
</summary><category term="ant"></category><category term="ftp"></category></entry><entry><title>Using WordPress as a library in your project</title><link href="http://foxfoo.com/using-wordpress-as-a-library-in-your-project.html" rel="alternate"></link><updated>2011-11-24T00:00:00Z</updated><author><name>John Doe</name></author><id>tag:foxfoo.com,2011-11-24:/using-wordpress-as-a-library-in-your-project.html/</id><summary type="html">&lt;p&gt;What do I mean by “using WordPress as a library”? Usually, when building WordPress based project one takes vanilla WordPress source, and then applies various adjustments on it. To shape WordPress to your needs, you have to cut the original sources in several places.&lt;/p&gt;
&lt;p&gt;wordpress_distribution:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
|- wp-admin         # administration module, most likely not to be edited
|- wp-content       # directory where user themes and plugins dwell
|- wp-includes      # probably not to be edited
|- index.php
|- wp-config.php    # config created by user
+- wp-blah-blah.php # other distribution files that should not be edited
&lt;/pre&gt;
&lt;p&gt;So making an application implies a need to make a lot of changes
in different places in a source tree.
And this is far away from what I mean of “usage as a library”,
so how is third party source code used like a library?
Here I name few examples: Smarty, Doctrine, NuSoap.
All these products are just put in a corner of your project,
and their files do not blend with files edited by your own.
This makes easier things easier when upgrading the library, –
just replace the directory with sources.
And in general it adds clarity to the code.
So the problem is that WordPress has to be adjusted in many places
inside its source tree.
But can we move all these points where changes should be done
to the separate directory. Of course we can,
and this post is about how to do it.
And the principles stated here actualy applies not only to WordPress,
but actually to many other CMS and frameworks.&lt;/p&gt;
&lt;p&gt;First of all after studying WordPress source code,
I have found that wp-config.php,
does not have to be in the root WordPress distribution directory,
but also in the directory that is one level up of it.
This means that we can create directory called “blog”,
let it be the root directory of our project.
Inside it we have wordpress directory.
And this is good – we already moved config file out.
The next thing is to move wp-content out of WordPress.
Actually we do not move this directory out just make copy of it –
and it will be the directory,
where major customizations of our blog will happen.
So inside “blog” directory, we create “app” directory, –
this is where we keep files changed by us.
Nevertheless we will make this directory our application root.
Inside this root there will be directory wp-content and favicon.ico image.
And if is needed also .htaccess.
Now in our blog we have two directories “wordpress”,
which is immutable source code of WordPress, and directory “app”,
which contains nothing but only our customizations.
Now we have to setup a virtual host for WordPress
so that document root would be situated in app directory.
And when HTTP request comes to it,
then the request tries to get to the file which is in the directory,
but if not, then go to corresponding file in “wordpress” directory.
To achieve that we have to configure vhost in a certain way.
We will rely on Apache directive “AliasMatch”.&lt;/p&gt;
&lt;dl class="docutils"&gt;
&lt;dt&gt;Here is how it goes::&lt;/dt&gt;
&lt;dd&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="nt"&gt;&amp;lt;VirtualHost&lt;/span&gt; &lt;span class="s"&gt;*:80&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nb"&gt;ServerAdmin&lt;/span&gt; my@email.com
    &lt;span class="nb"&gt;ServerName&lt;/span&gt; blog.dev
    &lt;span class="nb"&gt;DocumentRoot&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;/home/user/blog/app&amp;quot;&lt;/span&gt;
    &lt;span class="nb"&gt;ErrorLog&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;/home/user/blog.dev-error.log&amp;quot;&lt;/span&gt;
    &lt;span class="nb"&gt;LogLevel&lt;/span&gt; &lt;span class="k"&gt;notice&lt;/span&gt;
    &lt;span class="nb"&gt;CustomLog&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;/home/user/blog.dev.dev-access.log&amp;quot;&lt;/span&gt; combined
    &lt;span class="nt"&gt;&amp;lt;Directory&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;/home/user/blog/app&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nb"&gt;Options&lt;/span&gt; Indexes FollowSymLinks Includes ExecCGI
        &lt;span class="nb"&gt;AllowOverride&lt;/span&gt; &lt;span class="k"&gt;All&lt;/span&gt;
        &lt;span class="nb"&gt;Order&lt;/span&gt; allow,deny
        &lt;span class="nb"&gt;Allow&lt;/span&gt; from &lt;span class="k"&gt;all&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/Directory&amp;gt;&lt;/span&gt;
    &lt;span class="nb"&gt;AliasMatch&lt;/span&gt; &lt;span class="sx"&gt;/wp-&lt;/span&gt;(.*).php &lt;span class="sx"&gt;/home/user/blog/wordpress/wp-&lt;/span&gt;$1.php
    &lt;span class="nb"&gt;AliasMatch&lt;/span&gt; &lt;span class="sx"&gt;/index.php&lt;/span&gt; &lt;span class="sx"&gt;/home/user/blog/wordpress/index.php&lt;/span&gt;
    &lt;span class="nb"&gt;AliasMatch&lt;/span&gt; &lt;span class="sx"&gt;/wp-admin/&lt;/span&gt;(.*) &lt;span class="sx"&gt;/home/user/blog/wordpress/wp-admin/&lt;/span&gt;$1
&lt;span class="nt"&gt;&amp;lt;/VirtualHost&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;That is it, we now have directory structure like this:
wordpress_distribution:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
|- wordpress # do not touch it unless upgrading WordPress
|- app       # Here aoof files that we edit
+- wp-config # application config, editable
&lt;/pre&gt;
&lt;p&gt;Of course this setup applies to development version,
and we have to merge these directories when deployed on live,
to return to original WordPress directory structure.
But we solved our problem,-
in development environment we use WordPress as a library.&lt;/p&gt;
</summary><category term="wordpress"></category><category term="apache"></category></entry><entry><title>What is telepathy</title><link href="http://foxfoo.com/what-is-telepathy.html" rel="alternate"></link><updated>2011-08-15T00:00:00Z</updated><author><name>John Doe</name></author><id>tag:foxfoo.com,2011-08-15:/what-is-telepathy.html/</id><summary type="html">&lt;p&gt;In fiction stories the creatures of extraterrestrial cultures
has been using telepathy as an instrument
of their daily communication centuries ago,
so this is not a new thing, and possibly it is mature and robust mean
of information exchanging among individuals.
Well you might say,
what sort of information source can one consider
fictional stories about aliens? Relax, OK?
Jules Verne has made an insight of a spacecraft
100 years before such was really built.
So telepathy is also possible even though it is not known yet.
But is it right to accept it as the truth
just because it is being possible? Of course not.&lt;/p&gt;
&lt;p&gt;Indeed telepathy is very simple,
and not so magical as it seems to be.
Modern telepathy actually is so called “all-truth-saying” policy.
It is good old verbal communication, people use the same “normal” language,
and they appear to speak also quite “normally”.
But the difference is that telepaths do not lie to each others.
Absolutely not. And also try to tell each other every little thing they can.
Telepaths believe that every fact concealed from others is vulnerability,
every secret you might have may stab you.
They say that it prevents them from doing anything bad
or cheating to each other. It also helps to understand each other better.&lt;/p&gt;
&lt;p&gt;There are still not much telepaths,
and their communities tend to live isolated from rest of the people.
They believe that they are on the upper level
of existence than ordinary people,
like ordinary people are on the upper level then are animals,
and animals in turn are upper to plants.
Well if we get back to the extraterrestrial cultures,
mentioned in the beginning of this post,
it has been noticed that the aliens also claim
that humans are not yet ready to use telepathy.
Telepaths believe that they together are one collective consciousness
and they are charged for its well being.
They try to live in peace with nature and to respect the laws of the Universe.&lt;/p&gt;
&lt;p&gt;In my personal opinion more and more people will turn to telepaths
in the nearest future.
And I hope someday we all live in peace and harmony
without need to lie to each other.
I am glad I can see a tendency in IT field,-
technologies gives us an opportunity to get close to each other,
and help us to express our needs better,- which was not easy before,
because of being afraid of telling “personal secrets” to anyone.
People are learning to share their private information in social networks,
internet gives us an opportunity to put away pressure of our secrets.
And does it in easy way.&lt;/p&gt;
&lt;p&gt;&lt;img alt="image0" src="pictures/telepaths-chatting.jpg" /&gt;&lt;/p&gt;
&lt;p&gt;Group of young telepaths having a conversation.&lt;/p&gt;
</summary><category term="telepathy"></category></entry><entry><title>Setup Debian server in Virtualbox</title><link href="http://foxfoo.com/setup-debian-server-in-virtualbox.html" rel="alternate"></link><updated>2011-05-28T00:00:00Z</updated><author><name>John Doe</name></author><id>tag:foxfoo.com,2011-05-28:/setup-debian-server-in-virtualbox.html/</id><summary type="html">&lt;p&gt;The thing is that I like to keep my computer clean.
I especially do not want to install web servers in to my computer.
Laptop should not act as server.
I try to resist temptation to install and test random software on it,
because it could mess things up, but sometimes I have no choice.
As a software developer,
I often have to test and to work with a lot of software.
To install and remove, then install and remove something again happens usually.
Many servers and libraries with their specific versions
and dependencies must be hosted on my single workstation.
No surprising this leads to conflicts and disorder.&lt;/p&gt;
&lt;p&gt;Fortunately there is an effective way
to isolate those different installed items from each other,
and of course to keep my computer clean.
As you might guess I am talking about virtualization.
I use Ubuntu and my favorite virtualization software is Virtualbox
for its ease of use and rich feature feature set.
And it also is free.
This article describes instructions of how to install Debian
as a guest operating system in Virtualbox which runs in Ubuntu host.
I have chosen Debian,
because it is possible to install very base version of Debian,
which contain only what is needed and has a small footprint.&lt;/p&gt;
&lt;p&gt;There is a special Debian flavor, to instal the very basic components of OS.
It is called netinst and can be found at:
&lt;a class="reference external" href="http://www.debian.org/CD/netinst/"&gt;http://www.debian.org/CD/netinst/&lt;/a&gt; – ISO file is only 180MB.
Now download the netinst CD image for i386 architecture.&lt;/p&gt;
&lt;p&gt;Install Debian in to virtual machine&lt;/p&gt;
&lt;p&gt;Open the VirtualBox, press “New” button in window toolbar,
the New Virtual Machine Wizard starts. Click on the “Next” button.
Wizard asks to name the new virtual machine, and to select OS type.
I name mine new virtual machine as “Debian PHP”
(I will use this virtual machine to host PHP systems),
and Operating system and version are of course “Linux” ad “Debian”.
Go to the next step:
it asks how many RAM will be allocated for virtual machine,-
stick with recommended 384MB.
The next question is how to create a virtual disk.
Check the “Boot Hard Disk” and select “Create new hard disk”.
It will open another wizard in ths wizard –
“Create New Virtual Disk” just go next.
In the next question answer “Dynamicaly expanding storage”.
The next question is Virtual Disk Location and Size,
I leave default name, and select size of 2GB only,-
because I do not want this virtal machine
to spread and eat all free space on my computer.
Both wizards can now be finished.&lt;/p&gt;
&lt;p&gt;Open settings window of the new created VM.
In Storage page click Empty cd drive
(which is next to IDE Controller in the Storage Tree).
Click CD icon in Attributes section to setup virtual CD/DVD drive.
Then choose the downloaded Debian CD ISO file as a disk.
Virtual machine is ready to be started.&lt;/p&gt;
&lt;p&gt;Virtual machine boots from CD, starts the install.
It first asks for language, English is ok.
I choose locale en_US.UTF-8 and keyboard layout American English.
In next question I set hostname to “debian-php”
and stick with default domain name.
Then enter the root password, and create new user.
Asked about partitioning, choose default “Guided – use entire disk”.
Some people are uncertain in this step,
as setup says that it is going to wipe the disk,
but it will not delete the disk of your computer,
it talks about your new created virtual disk,
which lives in one file actualy. I select to keep all files in one partition.
Then finnish the partitioning with writing changes to disk.
Install starts. It takes some time.
During the process it asks some qustions for configuring apt,
for instance what are proxy if any, and select apt mirror nearest to you.
When “Software selection” dialog appears I select&lt;/p&gt;
&lt;p&gt;Web server
File server
Mail server
SQL server
SSH server
Standard system utilities&lt;/p&gt;
&lt;p&gt;Setup will ask for workgroup name for Samba server, I choose default WORKGROUP.
Before finishing setup will ask where install grub, choose default.
Setup is finished.&lt;/p&gt;
&lt;p&gt;Configure networking&lt;/p&gt;
&lt;p&gt;During virtual machine creation,
VirtualBox created virtual network adapter using NAT.
Which enables virtual machine access internet. But it bypass host machine,
so connection from host to virtual machine can not be established.&lt;/p&gt;
&lt;p&gt;We will use another network adapter to access virtual machine from host.
When virtual machine is stopped
edit it’s settings not to use installation iso anymore,
and add one more network adapter, choose it’s type to “host only network”.
This new adapter will be used to comunicate with your virtual machine
from your host.
You can now start virtual machine again, when it starts,
see if vboxnet0 adapter can be seen on host,
just check ipconfig output for something similar to this:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
vboxnet0 Link encap:Ethernet HWaddr 0a:00:27:00:00:00
inet addr:192.168.56.1 Bcast:192.168.56:.255 Mask:255.255.255.0
inet6 addr: fe80::800:27ff:fe00:0/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:24 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:3808 (3.8 KB)
&lt;/pre&gt;
&lt;p&gt;See what inet addr is given to host’s adapter to the network
in which virtual machine also is accessible.
Now in edit virtual machine’s /etc/network/interfaces file,
so that connection to host could be made thru eth1 network interface.&lt;/p&gt;
&lt;p&gt;The file alredy contains network interfaces defined:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
# The loopback network interface
auto lo
iface lo inet loopback

# The primary network interface
allow-hotplug eth0
iface eth0 inet dhcp
so we add also interface for host only networking adapter:

# The host network interface
auto eth1
iface eth1 inet static
address 192.168.56.2
netmask 255.255.255.0
&lt;/pre&gt;
&lt;p&gt;Note ip is 192.168.56.2, because vboxnet0 ip is 192.168.56.1 so,
both IPs are on the same network. Restart the Debian virtual machine.
You can now ssh to it:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
$ ssh devel&amp;#64;192.168.56.2
&lt;/pre&gt;
&lt;p&gt;On host machine add line:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
devel-php 192.168.56.2
&lt;/pre&gt;
&lt;p&gt;So,
you do not have to type ip but access the virtual machine via its hostname:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
$ ssh devel&amp;#64;debian-php
&lt;/pre&gt;
&lt;p&gt;And virtual machine is able to access internet.
Nevertheless you do not have to run Virtualbox GUI:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
$ nohup VBoxHeadless -s &amp;quot;Debian PHP&amp;quot; &amp;amp;
&lt;/pre&gt;
&lt;p&gt;will start virtual machine in background.
Few seconds later you should be able to ssh into it.&lt;/p&gt;
&lt;p&gt;Configure Samba share&lt;/p&gt;
&lt;p&gt;Let us now host sample php project on our server.
In devel user home create a directory named projects.
This directory is to be shared to host machine via Samba.
In file /etc/samba/smb.conf make sure that options has such values set.
And in the end of file add:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
[Projects]
comment = Directory for hosted php projects
path = /home/devel/projects
browseable = yes
read only = no
guest ok = yes
valid users = devel
&lt;/pre&gt;
&lt;p&gt;Reload samba:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
# /etc/init.d/samba reload
&lt;/pre&gt;
&lt;p&gt;In Ubuntu host Finder window press CTRL + L,
and type in to location bar: &lt;a class="reference external" href="smb://debian-php/Projects"&gt;smb://debian-php/Projects&lt;/a&gt;
Enter devel user and its password. Shared directory opens,
now you can bookmark it in Finder.&lt;/p&gt;
&lt;p&gt;Configure virtual hosts&lt;/p&gt;
&lt;p&gt;In shared directory create a new directory test,
and index.php file in it – it will be our first project.
In index.php add code:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
&amp;lt;?php phpinfo();
&lt;/pre&gt;
&lt;p&gt;Now back in debian login as root user
and create file /etc/apache2/sites-available/projects with content:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
ServerName test.dev
DocumentRoot /home/devel/projects/test
ErrorLog /home/devel/logs/test-error.log
LogLevel notice
CustomLog /home/devel/logs/test-access.log combined
&lt;/pre&gt;
&lt;p&gt;Enable it:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
# a2ensite projects
&lt;/pre&gt;
&lt;p&gt;and reload Apache:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
# /etc/init.d/apache2 restart
&lt;/pre&gt;
&lt;p&gt;Login again to debian virtual machine with devel user
and create directory logs with writing permissions for everyone.&lt;/p&gt;
&lt;p&gt;then in Ubuntu host machine add one more hostname for test site:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
192.168.56.2 test.dev
&lt;/pre&gt;
&lt;p&gt;That is it! Try to connect to URL &lt;a class="reference external" href="http://test.dev"&gt;http://test.dev&lt;/a&gt; with web browser.&lt;/p&gt;
</summary><category term="virtualization"></category><category term="debian"></category><category term="linux"></category><category term="php"></category></entry><entry><title>Howto install Redmine on Ubuntu 11.04</title><link href="http://foxfoo.com/howto-install-redmine-on-ubuntu-1104.html" rel="alternate"></link><updated>2011-05-14T00:00:00Z</updated><author><name>John Doe</name></author><id>tag:foxfoo.com,2011-05-14:/howto-install-redmine-on-ubuntu-1104.html/</id><summary type="html">&lt;p&gt;When I decided to try Redmine,
I found it difficult to install on Ubuntu 11.04.
Actualy it is very easy,
although all tutorials which I have found on internet,
seemed some-how too much complicated.&lt;/p&gt;
&lt;p&gt;But the procedure is indeed very simple, first just install redmine package:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
sudo apt-get install redmine
&lt;/pre&gt;
&lt;p&gt;When install asks whether to setup database automaticaly, ansver “yes”.&lt;/p&gt;
&lt;p&gt;Then install passenger,-
this is appache module allowing to run rails applications on it:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
sudo apt-get install libapache2-mod-passenger
&lt;/pre&gt;
&lt;p&gt;Now just make sure that required apache modules are enabled:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
sudo a2enmod passenger rewrite
&lt;/pre&gt;
&lt;p&gt;I like to create virtual host for each web application that i am running, I want to do the same with Redmine also.
Create a virtual host config file at /etc/apache2/sites-available/redmine with such content:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&amp;lt;VirtualHost *:80&amp;gt;
    ServerName redmine.dev
    DocumentRoot &lt;span class="s2"&gt;&amp;quot;/usr/share/redmine/public&amp;quot;&lt;/span&gt;
    PassengerResolveSymlinksInDocumentRoot on
    Options Indexes ExecCGI FollowSymLinks
&amp;lt;/VirtualHost&amp;gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now this virtual host must be enabled:&lt;/p&gt;
&lt;p&gt;sudo a2ensite redmine
And, of course, hostname redmine.dev should be defined in /etc/hosts :&lt;/p&gt;
&lt;p&gt;127.0.0.1   redmine.dev
And lastly just restart the apache:&lt;/p&gt;
&lt;p&gt;sudo apache2ctl restart
Thats it! Redmine is now on &lt;a class="reference external" href="http://redmine.dev"&gt;http://redmine.dev&lt;/a&gt; – simple..&lt;/p&gt;
</summary><category term="redmine"></category><category term="ubuntu"></category><category term="linux"></category></entry><entry><title>How to forward all requests from domain to a subdirectory</title><link href="http://foxfoo.com/how-to-forward-all-requests-from-domain-to-a-subdirectory.html" rel="alternate"></link><updated>2011-02-16T00:00:00Z</updated><author><name>John Doe</name></author><id>tag:foxfoo.com,2011-02-16:/how-to-forward-all-requests-from-domain-to-a-subdirectory.html/</id><summary type="html">&lt;p&gt;Say there is a web host running Apache,
and we have an application which we want to deploy on it.
Somehow we do not want to upload all application files right to document root,
but we rather create a directory dedicated for uploading files.
But we still want to access the application
as if it was uploaded to document root.
We are going to leverage ModRewrite to rewrite requesting urls
to point to subdirectory instead of document root unobtrusively.&lt;/p&gt;
&lt;p&gt;Maybe the solution stated here is not the best,
and possibly there is a better one, but it still works for me.
Actually I have figured it out when setting this WordPress based blog.
I could, of course, upload WordPress files to public_html,
but the problem is
that I already have some applications deployed in subdirectories on this host.
Those other applications are accessed by their subdomains,-
the hosting is configured to keep ther document roots
in the main document root, this is where the problem comes from.
And in WordPress distribution there are many files and directories,
which would mix with directories of those other applications.
It would be better and cleaner to keep WordPress in its own directory,
just like other applications.&lt;/p&gt;
&lt;p&gt;So I put uploaded my blog application to _wordpress subdirectory.
and created .htaccess file in public_html, that contains:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="c"&gt;# All that begins with any letter but not &amp;quot;_&amp;quot; forwarded to wordpress&lt;/span&gt;
&lt;span class="nb"&gt;RewriteRule&lt;/span&gt; ^[^_] http://www.foxfoo.com/_wordpress%{REQUEST_URI} [NC,L]

&lt;span class="c"&gt;# Root to index.php&lt;/span&gt;
&lt;span class="nb"&gt;RewriteRule&lt;/span&gt; ^$ http://www.foxfoo.com/_wordpress/index.php [NC,L]
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;It of course would be nice to, if it was possible to type just:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="nb"&gt;RewriteRule&lt;/span&gt; ^.*$ http://www.foxfoo.com/_wordpress%{REQUEST_URI} [NC,L]
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;That will not work.
Simply because requesting &lt;a class="reference external" href="http://www.foxfoo.com/_wordpress/smth"&gt;http://www.foxfoo.com/_wordpress/smth&lt;/a&gt;
would also be rewrited, and still match the pattern,
so it could be rewrited once again. That of course would cause forever loop,
therefore Apache just responds with code 500 to prevent this.
What we did is just to find pattern that does not match the url rewrited URI,
but match requested one.
This solution obviously relies on assumption
that WordPress will not be called by URI starting with “_”, as I said,
this is not the most elegant solution, but while it is sufficient for me,
I will not keep looking for a better one, but if you know, please share it.&lt;/p&gt;
</summary><category term="apache"></category></entry></feed>