<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>ServerGrove Blog &#187; symfony</title>
	<atom:link href="http://blog.servergrove.com/tag/symfony/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.servergrove.com</link>
	<description>VPS &#38; Shared Hosting, symfony, Zend Framework, Rails, Adobe Flex, Hosting News, Web Design Tips, Webhosting and more....</description>
	<lastBuildDate>Tue, 31 Aug 2010 19:26:16 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>PHP conferences update</title>
		<link>http://blog.servergrove.com/2010/08/31/php-conferences-update/</link>
		<comments>http://blog.servergrove.com/2010/08/31/php-conferences-update/#comments</comments>
		<pubDate>Tue, 31 Aug 2010 19:25:25 +0000</pubDate>
		<dc:creator>Pablo</dc:creator>
				<category><![CDATA[Conferences]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[symfony]]></category>

		<guid isPermaLink="false">http://blog.servergrove.com/?p=1326</guid>
		<description><![CDATA[There are some great conferences around the PHP world that are coming up or are being announced. Here is the list (if we missed one, please let us know) Open Source India &#8211; September 19-21, 2010 &#8211; Chennai, India PHP Matsuri &#8211; October 2-3, 2010 &#8211; Tokyo, Japan Symfony Day Cologne 2010 &#8211; October 8, [...]]]></description>
			<content:encoded><![CDATA[<p>There are some great conferences around the PHP world that are coming up or are being announced. Here is the list (if we missed one, please let us know)</p>
<ul>
<li><a href="http://osidays.com/">Open Source India</a> &#8211; September 19-21, 2010 &#8211; Chennai, India</li>
<li><a href="http://2010.phpmatsuri.net/page/what-is-php-matsuri">PHP Matsuri</a> &#8211; October 2-3, 2010 &#8211; Tokyo, Japan</li>
<li><a href="http://www.symfonyday.com/en/">Symfony Day Cologne 2010</a> &#8211; October 8, 2010 &#8211; Cologne, Germany</li>
<li><a href="http://zendcon.com/">ZendCon</a> &#8211; November 1-4, 2010, Santa Clara, California</li>
<li>Symfony Live San Francisco &#8211; February 2011, San Francisco, California</li>
<li>Symfony Live Paris &#8211; March 3-5, 2011 &#8211; Paris, France</li>
</ul>
<p><br style="clear: both"><br />
As always, if you work around PHP, we encourage you to participate of conferences which are an invaluable tool to enhance your skills and meet with fellow developers and colleagues.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.servergrove.com/2010/08/31/php-conferences-update/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Symfony + Git + Capistrano = Capifony</title>
		<link>http://blog.servergrove.com/2010/07/12/symfony-git-capistrano-capifony/</link>
		<comments>http://blog.servergrove.com/2010/07/12/symfony-git-capistrano-capifony/#comments</comments>
		<pubDate>Mon, 12 Jul 2010 16:12:06 +0000</pubDate>
		<dc:creator>Kim</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[symfony]]></category>
		<category><![CDATA[capify]]></category>
		<category><![CDATA[capistrano]]></category>

		<guid isPermaLink="false">http://blog.servergrove.com/?p=1224</guid>
		<description><![CDATA[Introduction Deploying applications to production/live servers is always a delicate task. The whole process needs to be quick to minimize downtime. Automating the deployment process helps running repetitive tasks minimizing the possibility human error. It is also a good idea to have a proven and easy way to rollback to a previous version if something [...]]]></description>
			<content:encoded><![CDATA[<h2>Introduction</h2>
<p>Deploying applications to production/live servers is always a delicate task. The whole process needs to be quick to minimize downtime. Automating the deployment process helps running repetitive tasks minimizing the possibility human error. It is also a good idea to have a proven and easy way to rollback to a previous version if something goes wrong.</p>
<p>Capistrano and more specifically Capifony can help with the automatic deployment of symfony projects.</p>
<h2>What is Capistrano?</h2>
<p>Capistrano is a time saving command line tool, written in Ruby, that helps you execute automated tasks on remote servers from your local environment. It also allows you to run symfony commands. Capistrano was built to help you administer all your servers from one place, running commands, installing software and keeping everything in sync. Oh&#8230; and of course it has a rollback mechanism.</p>
<p>It&#8217;s one of those tools Ruby developers have that we often wish we had in symfony, and now we do. Enter Capifony&#8230;</p>
<h2>Capistrano commands</h2>
<p>Capistrano has 2 base commands:</p>
<p>1. `capify &#8230;`;<br />
2. `cap &#8230;`.</p>
<p>Capify will create 2 files in a specified path (1st argument of `capify`):</p>
<p>1. `Capfile` &#8211; capistrano loader. It loads all basic libraries &#038; project config file;<br />
2. `config/deploy.rb` &#8211; project config file. Your configs &#038; variables setup for project placed here.</p>
<p>The second command, `cap`, actually runs capistrano tasks on the remote server with config from your `config/deploy.rb`.</p>
<p>A capistrano recipe is a package of tasks, grouped into namespaces. You can use embedded tasks or write your own (place them in your `config/deploy.rb`). Once a task is written you can run it with `cap` command under your project directory:</p>
<pre>cap namespace:task</pre>
<p>Deployment recipe<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;</p>
<p>As mentioned above, Capistrano is typically used to deploy Ruby On Rails applications. How does it work? Basically, capistrano must know 4 things:</p>
<p>1. addresses of your web, app &#038; db servers (most often it&#8217;s the same address);<br />
2. address of your source code control system repository (if you have one).</p>
<p>Keep in mind, that capistrano uses SSH to run remote tasks so you will need to have shell access to all your remote servers.</p>
<p>During the deploment process, Capistrano will maintain different files &#038; directories on server. It will create a `releases` directory that has dated directories with the actual copy of your code for each release. In addition, Capistrano symlinks your shared folders (common between releases) into release directories, so logs, assets &#038; other files keeps the same between deployments.</p>
<h2>What is Capifony?</h2>
<p>Capifony is a new RubyGem package, that extends Capistrano functionality so it can work with symfony PHP projects. In essence it&#8217;s a package of custom and extended original capistrano recipes.</p>
<h2>Demo project</h2>
<p>To fully understand how capifony works and what it does we need to create one simple symfony application and deploy it to our test server.</p>
<h3>Step 1: Install</h3>
<p>I assume that you already have Ruby &amp; RubyGems installed on your local environment (MacOS X has this out of the box &#8211; simply update gems with `sudo gem update –system`).</p>
<p>To install capifony and capistrano, simply run:</p>
<pre>gem install capifony</pre>
<p>This command will install capifony and it&#8217;s dependencies (capistrano for example) to your local host. NOTE: Your local host is the only place where you need to install capifony &amp; capistrano.</p>
<p>It&#8217;s also good practice to create and copy the SSH key to speed up the connections to your remote repositories.</p>
<p>Generate key with:</p>
<pre>ssh-keygen -t rsa
</pre>
<p>Next, copy your public key to remote server that you want to connect to (I am going to assume your SSH user is called `demoUser`):</p>
<pre>cat .ssh/id_rsa.pub | ssh demoUser@your.domain.com "cat &gt;&gt; .ssh/authorized_keys2"
</pre>
<p>Then just try to connect with:</p>
<pre>ssh demoUser@your.domain.com
</pre>
<p>If all goes well the remote server will just let you in without password prompt.</p>
<p>We then need to create the project repository on server, so let&#8217;s create one:</p>
<pre>
ssh demoUser@your.domain.com
sudo mkdir /var/repos
sudo chown demoUser !$
cd !$
mkdir demo.git
cd !$
git --bare init
</pre>
<h3>Step 2: Symfony project setup</h3>
<p>Lets create empty git repository for our new demo site (we will use git as SCM, but you can use subversion or any other source code manager that&#8217;s supported by capistrano):</p>
<pre>
cd /var/www
mkdir demo
cd !$
git init
touch .gitignore
</pre>
<p>Now add these lines to your `.gitignore` to exclude asset symlinks, databases config, cache, backups, uploads &amp; log folders from our git repository:</p>
<pre>
web/sf*
web/uploads/*
cache/*
plugins/.*
log/*
config/databases.yml
mkmf.log
.rsync*
backups/*
</pre>
<p>It&#8217;s time to add `.gitignore` to stage and make our initial commit:</p>
<pre>
git add .gitignore
git commit -m 'initial commit'
</pre>
<p>Finally we can generate skeleton for our demo project and commit it:</p>
<pre>
symfony generate:project demo
git add .
git commit -m 'symfony project created'
</pre>
<p>Now lets add the database schema to `config/doctrine/schema.yml`:</p>
<pre>
	---
	Topic:
	  actAs:
	    Timestampable:    ~
	  columns:
	    id:
	      type:           integer(4)
	      primary:        true
	      autoincrement:  true
	    title:
	      type:           string(256)
	      notnull:        true
	    content:
	      type:           clob
	      notnull:        true
</pre>
<p>And add some fixtures into `data/fixtures/fixtures.yml`:</p>
<pre>
	Topic:
	  topic1:
	    title:    First topic
	    content:  first topic content
	  topic2:
	    title:    Second topic
	    content:  second topic content
	  topic3:
	    title:    Third topic
	    content:  third topic content
</pre>
<p>Build database and model files:</p>
<pre>symfony doctrine:build --all --and-load --no-confirmation
</pre>
<p>And you need to generate the `frontend` application and put `main` module in it:</p>
<pre>
symfony generate:app frontend
symfony generate:module !$ main
</pre>
<p>To make this more interesting let&#8217;s put some logic for our application. Go to `apps/frontend/modules/main/actions/actions.class.php` and replace  the `executeIndex` function code with this:</p>
<pre>
/**
* Executes index action
*
* @param sfRequest $request A request object
*/
public function executeIndex(sfWebRequest $request)
{
   $this-&gt;topics = Doctrine::getTable('Topic')-&gt;findAll();
}
</pre>
<p>And the view. Go to `apps/frontend/modules/main/templates/indexSuccess.php` and add:</p>
<pre>
&lt;dl&gt;
  &lt;?php foreach ($topics as $topic): ?&gt;
    &lt;dt&gt;&lt;?php echo $topic-&gt;getTitle() ?&gt;&lt;/dt&gt;
    &lt;dd&gt;
        &lt;?php echo $topic-&gt;getContent() ?&gt;
    &lt;/dd&gt;
  &lt;?php endforeach; ?&gt;
&lt;/dl&gt;
</pre>
<p>Now if you open http://your.local.demo.host/frontend_dev.php/main in browser you will se definition list with our 3 topics.</p>
<p>Add changes to git:</p>
<pre>
git add .
git commit -m 'finished project'
</pre>
<h3>Stage 3: symfony library with project</h3>
<p>It&#8217;s good practice to include the dependent version of symfony in your project repository. You can do this in two ways:</p>
<p>1. Simply copy symfony library under `lib/vendor/symfony` directory &amp; commit it;</p>
<p>or </p>
<p>2. Submodule symfony library from another repository.</p>
<p>I like second way. To do this, we will submodule Vincent Jousse&#8217;s symfony 1.4 git mirror:</p>
<pre>
git submodule add http://github.com/vjousse/symfony-1.4.git lib/vendor/symfony
</pre>
<p>Don&#8217;t forget to fix symfony path in `config/ProjectConfiguration.class.php` (after both ways) from:</p>
<pre>
require_once '/opt/local/lib/php/symfony14/lib/autoload/sfCoreAutoload.class.php';
</pre>
<p>to</p>
<pre>require_once dirname(__FILE__) . '/../lib/vendor/symfony/lib/autoload/sfCoreAutoload.class.php';
</pre>
<p>And commit this:</p>
<pre>
git add .
git commit -m 'bundled symfony'
</pre>
<h3>Step 4: Push local project to remote git repository</h3>
<p>Remember our `demo.git` repository on `demoUser@your.domain.com` that we&#8217;ve created earlier? It&#8217;s time to push our project to it:</p>
<pre>
git remote add origin 	ssh://demoUser@your.domain.com/var/repos/demo.git
git push origin master:refs/heads/master
</pre>
<p>Now your project is pushed to remote repository, where anyone who has SSH access can push/pull it. Also, we will use this repository to deploy new versions with capistrano.</p>
<h3>Step 5: Config</h3>
<p>Now is the time to play with capifony itself. First of all, lets &#8220;capifony&#8221; our project:</p>
<pre>capifony .
</pre>
<p>Capifony created `Capfile` and `config/deploy.rb`. Go into `config/deploy.rb` and edit it&#8217;s variables. To set capistrano config variables, you need to call `set :var_name, &#8220;var_value&#8221;` instruction inside `deploy.rb`. Below is the list of main variables:</p>
<p>* `:application` &#8211; set your application name here (&#8220;demo&#8221; in our case);</p>
<p>* `:domain` &#8211; domain of our remote server. This variable will be auto-populated with `#{application}.com` (demo.com in our case). Place your server address here if it&#8217;s not `demo.com`. I set it to `#{application}.everzet.com`, because my test host is http://demo.everzet.com;</p>
<p>* `:deploy_to` &#8211; path, where we will deploy our application (in most cases `/var/www/#{domain}`);</p>
<p>* `:repository` &#8211; path to repository (`#{domain}:/var/repos/#{application}.git` in our case);</p>
<p>* `:scm` &#8211; source code management tool. In our case set it to `:git`, but it can be any of `accurev`, `bzr`, `cvs`, `darcs`, `subversion`, `mercurial`, `perforce`, `subversion` or even `none`;</p>
<p>* `:use_sudo` &#8211; set to `false`, because we doesn&#8217;t need sudo during our deployment process;</p>
<p>* `:deploy_via` &#8211; set it to `:remote_cache`, so deployments will last less time;</p>
<p>* `:git_enable_submodules` &#8211; set it to `1` if you have submodules in project (if you staged symfony as submodule for example);</p>
<p>Also add this line to `config/deploy.rb`:</p>
<pre>ssh_options[:forward_agent] = true
</pre>
<p>if you want to use your local SSH key instead of remote one for git checkout.</p>
<p>Your resulting `config/deploy.rb` is must be something like this:</p>
<pre>
set  :application,            "demo"
set  :domain,                 "#{application}.everzet.com"
set  :deploy_to,              "/var/www/#{domain}"

set  :scm,                    :git
set  :git_enable_submodules,  1
set  :repository,             "#{domain}:/var/repos/#{application}.git"
set  :deploy_via,             :remote_cache

role :web,                    domain
role :app,                    domain
role :db,                     domain, :primary =&gt; true

set  :use_sudo,               false
set  :keep_releases,          3
ssh_options[:forward_agent] = true
</pre>
<h3>Step 6: Deployment</h3>
<p>To start, we need to know 3 basic capistrano commands:</p>
<p>1. `cap deploy:setup` &#8211; create directories on server;<br />
2. `cap deploy:cold` &#8211; copy code, build database, make symlinks;<br />
3. `cap deploy` &#8211; copy code, make symlinks.</p>
<p>Now run:</p>
<pre>cap deploy:setup
</pre>
<p>This command will create the following folder structure on your server:</p>
<pre>
	`-- /var/www/demo.everzet.com
	  |-- releases
	  `-- shared
	    |-- log
	    `-- web
	      `-- uploads
</pre>
<p>After few deployments, folder structure will eventually become something like this:</p>
<pre>
	`-- /var/www/demo.everzet.com
	  |-- current (symlink)
	  |-- releases
	    |-- 20100512131539
	    |-- 20100509150741
	    `-- 20100509145325
	  `-- shared
	    |-- log
	    |-- config
	      `-- databases.yml
	    `-- web
	      `-- uploads
</pre>
<p>What does all this mean?</p>
<p>1. `releases` is folder, where all your releases sits. Every release is a timestamped folder under `releases` directory.</p>
<p>2. Every release has symlink to shared files and folders, placed in `shared` directory. This files &amp; folders stays same between deploys;</p>
<p>3. capistrano creates symlink to latest release, called `current`. This is your current project folder to work with (where to point web servers, crontabs etc.).</p>
<p>Now lets deploy our application for the first time:</p>
<pre>cap deploy:cold
</pre>
<p>If you&#8217;ve configured your remote server hosts right, you now can open http://your.remote.host/main &amp; see you symfony application there.</p>
<h3>Step 7: Deploy &amp; Rollback</h3>
<p>Now what if we change something, deployed it and it&#8217;s broke our site? Lets break something!</p>
<p>Open `apps/frontend/modules/main/actions/actions.class.php` and change</p>
<pre>$this-&gt;topics = Doctrine::getTable('Topic')-&gt;findAll();
</pre>
<p>to</p>
<pre>$this-&gt;topics = Doctrine::getTable('TopicS')-&gt;findAll();
</pre>
<p>Save it, commit it and push to remote repository:</p>
<pre>
git add .
git commit -m 'buggy change'
git push origin master
</pre>
<p>Now deploy this bug:</p>
<pre>
cap deploy
</pre>
<p>and try to open http://your.remote.host/main. Oh, no! Something broke. What to do? Simple! Run:</p>
<pre>
cap deploy:rollback
</pre>
<p>and capistrano will roll your server back to previous working version of project and you will be able to find, fix, push and deploy the bugfix later, without problems.</p>
<h2>Conclusion</h2>
<p>Capistrano is mighty tool that has served RoR developers for many years. Now the symfony world can use these best practices in their development workflow. It&#8217;s as simple as installing capifony gem.</p>
<p>If you want to add/request something or read further manuals &#8211; please, <a href="http://github.com/everzet/capifony">visit project repository on github</a>.</p>
<hr />
<h2>About the Author</h2>
<p><a href="http://blog.servergrove.com/wp-content/uploads/2010/07/konstantin.png"><img src="http://blog.servergrove.com/wp-content/uploads/2010/07/konstantin.png" alt="" title="konstantin" width="107" height="150" class="alignleft size-full wp-image-1254" style="margin-right: 10px;" /></a><a href="http://github.com/everzet">Konstantin Kudryashov</a> (aka everzet) is a web developer from Minsk, Belarus. Most of the time, he builds symfony applications. When he&#8217;s not &#8211; he maintains symfony bundles for TextMate, writes symfony plugins &amp; php libraries.<br />
<br style="clear: both" clear="all"></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.servergrove.com/2010/07/12/symfony-git-capistrano-capifony/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>symfony 1.3.5 and 1.4.5 released and available at ServerGrove</title>
		<link>http://blog.servergrove.com/2010/06/02/symfony-1-3-5-and-1-4-5-released-and-available-at-servergrove/</link>
		<comments>http://blog.servergrove.com/2010/06/02/symfony-1-3-5-and-1-4-5-released-and-available-at-servergrove/#comments</comments>
		<pubDate>Wed, 02 Jun 2010 15:39:28 +0000</pubDate>
		<dc:creator>Pablo</dc:creator>
				<category><![CDATA[Conferences]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[symfony]]></category>

		<guid isPermaLink="false">http://blog.servergrove.com/?p=1204</guid>
		<description><![CDATA[New versions of symfony framework have been released today. The 1.3.5 and 1.4.5 releases include a security vulnerability patch, updated dependencies of Propel and Lime, and a few bug fixes. Check out the blog post announcing the release for more details. We recommend all our customers (and non-customers as well) to update their projects with [...]]]></description>
			<content:encoded><![CDATA[<p>New versions of <a href="http://www.symfony-project.org">symfony framework</a> have been released today. The 1.3.5 and 1.4.5 releases include a security vulnerability patch, updated dependencies of Propel and Lime, and a few bug fixes. Check out <a href="http://www.symfony-project.org/blog/2010/05/31/symfony-1-3-5-and-1-4-5">the blog post announcing the release</a> for more details. We recommend all our customers (and non-customers as well) to update their projects with the latest releases.</p>
<p>Since we are talking about symfony, it is worthy to mention the announcement of a <a href="http://www.symfony-live.com/">Symfony Live Online Conference</a> which will cover updates on Symfony 2. The ticket to join the conference is only 20 euro (early bird pricing) or 30 euro, so there is no excuse to be part of this if symfony is your thing.</p>
<p>And one last note, as always, all these new versions are already available on all our servers. If you are a VPS customer, make sure to <a href="http://secure.servergrove.com/clients/knowledgebase.php?action=displayarticle&amp;id=126">update your local library</a> to get the latest and greatest. And happy symfony coding!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.servergrove.com/2010/06/02/symfony-1-3-5-and-1-4-5-released-and-available-at-servergrove/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MongoDB with PHP and symfony</title>
		<link>http://blog.servergrove.com/2010/04/28/mongodb-with-php-and-symfony/</link>
		<comments>http://blog.servergrove.com/2010/04/28/mongodb-with-php-and-symfony/#comments</comments>
		<pubDate>Wed, 28 Apr 2010 21:34:09 +0000</pubDate>
		<dc:creator>Pablo</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[symfony]]></category>
		<category><![CDATA[doctrine]]></category>
		<category><![CDATA[MongoDB]]></category>
		<category><![CDATA[NoSQL]]></category>

		<guid isPermaLink="false">http://blog.servergrove.com/?p=1151</guid>
		<description><![CDATA[pre {font-size: 12px; padding-bottom: 15px} Introduction There has been a lot of talk about document databases and how applicable they are for Web 2.0 application development. There are a bunch of projects in the &#8220;NoSQL&#8221; realm that are making a lot of noise, CouchDB, Cassandra, and MongoDB are the ones that are most mentioned. MongoDB [...]]]></description>
			<content:encoded><![CDATA[<style>pre {font-size: 12px; padding-bottom: 15px}</style>
<h2>Introduction</h2>
<p>There has been a lot of talk about document databases and how applicable they are for Web 2.0 application development. There are a bunch of projects in the &#8220;<a href="http://en.wikipedia.org/wiki/NoSQL">NoSQL</a>&#8221; realm that are making a lot of noise, <a href="http://couchdb.apache.org/">CouchDB</a>, <a href="http://cassandra.apache.org/">Cassandra</a>, and MongoDB are the ones that are most mentioned. <a href="http://www.mongodb.org/">MongoDB</a> is a scalable document database, which is also open source.</p>
<p>Part of our business is to develop internal applications and  support customers, so we dedicate a good amount of time to research, test and learn new technologies. We have been following this whole movement and decided to give MongoDB a try.</p>
<p>What has really taken our attention regarding MongoDB is its simplicity, yet how powerful it is. It lowers the barrier to develop DB-driven applications even more.</p>
<p>In MongoDB there are no tables and rows. You have collections and documents instead. And collections can contain any type of document, it is not limited by the columns or fields like a table. In some scenarios, this is a really big plus. Yet, some people, mostly those born and raised with RDBMS will be scared to death due to the lack of schema and rigid structures. As always, if you plan ahead and do your homework and design your entities properly, you will be fine.</p>
<p>Since collections can have different types of documents, let&#8217;s say, an array, you can update the document with more fields in the array. In the RDBM world to do this, you have to change your schema, making application upgrades one of the biggest pains.</p>
<h2>Using MongoDB and PHP</h2>
<p>To get started with MongoDB and PHP, you need to download and install the server. From the website you can <a href="http://www.mongodb.org/display/DOCS/Downloads">download packages</a> for your preferred OS or you can download the source and compile it. Installation is really simple. Once you have the files in your computer, to start the server all you have to do is run the daemon, ie.:</p>
<pre># /usr/local/mongodb/bin/mongod</pre>
<p>MongoDB will start and initialize its DB storage.</p>
<p>Now you can connect with the mongo command line client or other clients like <a href="http://www.apple.com/downloads/macosx/development_tools/mongohub.html">MongoHub</a>, <a href="http://www.phpmoadmin.com/">PHPMOAdmin</a> among <a href="http://www.mongodb.org/display/DOCS/Admin+UIs">others</a>.</p>
<p>To connect to MongoDB from PHP, you will need to install the mongo pecl extension. On Mac OS X or Linux, run:</p>
<pre># pecl install mongo</pre>
<p>Then add the following line to php.ini and restart your web server:</p>
<pre>extension=mongo.so</pre>
<p>The PHP.net site has <a href="http://us.php.net/manual/en/mongo.tutorial.php">a very good tutorial</a> on how to get started with MongoDB and PHP. Basically, to store something in MongoDB you follow these simple steps:</p>
<pre>// connect to the default DB server, localhost
$connection = new Mongo(); 

// select a DB
$db = $connection-&gt;dbname;

// get a collection, if it does not exist, it will get created
$collection = $db-&gt;users;

// insert a document
$collection-&gt;insert( $doc );</pre>
<p>That&#8217;s it! No table creation, nice! For more information on how to retrieve data, go to the <a href="http://us.php.net/manual/en/mongo.tutorial.php">PHP.net tutorial</a>.<br />
MongoDB stores data in a binary JSON format. If you are familiar with JavaScript, you will know JSON. When you store a PHP object, when it is time to get the data from the DB, you will get an array instead. For many uses, this is OK, but some times, for more complex solutions, objects are necessary. Fortunately there is a solution already!</p>
<h2>Enter ODM (Object Document Mapper)</h2>
<p><a href="http://github.com/jwage/odm">ODM</a> is a new project created by <a href="http://github.com/jwage">Jon Wage</a>, a core developer of the popular <a href="http://www.doctrine-project.org/">Doctrine ORM</a>. The Doctrine\ODM namespace will be the home to PHP 5.3 object mappers for Document based storage systems like MongoDB. Currently only the Doctrine\ODM\MongoDB code has been implemented and it will map PHP objects with MongoDB documents. So when you store PHP objects in MongoDB and you need to retrieve them, you will get back PHP objects. Not only that, but it also helps with relations between objects. The project home page includes a basic usage manual and a full working example.</p>
<p>What&#8217;s really nice about this solution is how unintrusive it is. Your classes are pure PHP classes without having to extend other classes. The only requirement is that you map your properties using one of the support metadata drivers. In this example we use the AnnotationDriver:</p>
<pre>namespace Entities;

/** @Entity */
class User
{
    /** @Field */
    private $id;

    /** @Field */
    private $username;

    /** @Field */
    private $password;

    /** @Field(embedded="true", targetEntity="Entities\Phonenumber", type="many", cascadeDelete="true") */
    private $phonenumbers = array();

    /** @Field(embedded="true", targetEntity="Entities\Address", type="many") */
    private $addresses = array();

    /** @Field(reference="true", targetEntity="Entities\Profile", type="one") */
    private $profile;

    /** @Field(reference="true", targetEntity="Entities\Account", cascadeDelete="true") */
    private $account;

    public function getId()
    {
        return $this-&gt;id;
    }

    public function getUsername()
    {
        return $this-&gt;username;
    }

    public function setUsername($username)
    {
        $this-&gt;username = $username;
    }

    public function getPassword()
    {
        return $this-&gt;password;
    }

    public function setPassword($password)
    {
        $this-&gt;password = md5($password);
    }

    public function getAddresses()
    {
        return $this-&gt;addresses;
    }

    public function addAddress(Address $address)
    {
        $this-&gt;addresses[] = $address;
    }

    public function setProfile(Profile $profile)
    {
        $this-&gt;profile = $profile;
    }

    public function getProfile()
    {
        return $this-&gt;profile;
    }

    public function setAccount(Account $account)
    {
        $this-&gt;account = $account;
    }

    public function getAccount()
    {
        return $this-&gt;account;
    }

    public function getPhonenumbers()
    {
        return $this-&gt;phonenumbers;
    }

    public function addPhonenumber(Phonenumber $phonenumber)
    {
        $this-&gt;phonenumbers[] = $phonenumber;
    }
}</pre>
<p>Take a look at the DocBlocks and how we map the properties to the document.</p>
<p>Once you defined your entities, the usage is super simple:</p>
<pre>require '/path/to/doctrine/lib/Doctrine/Common/ClassLoader.php';

use Doctrine\Common\ClassLoader,
      Doctrine\Common\Annotations\AnnotationReader,
      Doctrine\ODM\MongoDB\Mongo,
      Doctrine\ODM\MongoDB\Configuration,
      Doctrine\ODM\MongoDB\Mapping\Driver\AnnotationDriver,
      Doctrine\ODM\MongoDB\Mapping\Driver\YamlDriver,
      Doctrine\ODM\MongoDB\EntityManager;

$classLoader = new ClassLoader('Doctrine\ODM', __DIR__ . '/../lib');
$classLoader-&gt;register();

$classLoader = new ClassLoader('Doctrine', '/path/to/doctrine/lib');
$classLoader-&gt;register();

$classLoader = new ClassLoader('Entities', __DIR__);
$classLoader-&gt;register();

$config = new Configuration();

$reader = new AnnotationReader();
$reader-&gt;setDefaultAnnotationNamespace('Doctrine\ODM\MongoDB\Mapping\Driver\\');
$config-&gt;setMetadataDriverImpl(new AnnotationDriver($reader, __DIR__ . '/Entities'));

$em = EntityManager::create(new Mongo(), $config);

$user = new User();
$user-&gt;username = 'jwage';
$user-&gt;password = 'changeme';

$user-&gt;profile = new Profile();
$user-&gt;profile-&gt;firstName = 'Jonathan';
$user-&gt;profile-&gt;lastName = 'Wage';

$user-&gt;account = new Account();
$user-&gt;account-&gt;name = 'Test Account';

$em-&gt;persist($user);
$em-&gt;flush();</pre>
<p>For more information, visit the <a href="http://github.com/jwage/odm">project home page</a>.  Please note that this project is in very early stages of development, so things may change.</p>
<h2>MongoDB, ODM and symfony</h2>
<p>We will demonstrate how to use MongoDB with ODM and symfony.<a href="http://symfony-reloaded.org/"> Symfony 2</a> is still in alpha stage, so even though it would be a perfect fit with ODM, we will stick with <a href="http://www.symfony-project.org/">symfony 1.4</a> for now. For this part of the article, you will need to know a little bit of symfony.</p>
<p>1. If you don&#8217;t have a symfony project, go ahead and create it with ./symfony generate:project myproject</p>
<p>2. Download Doctrine2 (you will need the new class autoloader) and ODM into myproject/lib/vendor</p>
<p>3. Add the class auotoloader to the config/ProjectConfiguration.class.php file:</p>
<pre>require_once __DIR__.'/../lib/vendor/symfony/lib/autoload/sfCoreAutoload.class.php';
sfCoreAutoload::register();

require __DIR__.'/../lib/vendor/doctrine2/lib/Doctrine/Common/ClassLoader.php';

use Doctrine\Common\ClassLoader, Doctrine\ODM\MongoDB\EntityManager;

class ProjectConfiguration extends sfProjectConfiguration
{
  public function setup()
  {
    $classLoader = new ClassLoader('Doctrine\ODM', __DIR__ . '/../lib/vendor/odm/lib');
    $classLoader-&gt;register();

    $classLoader = new ClassLoader('Doctrine\ODM', __DIR__ . '/../lib/vendor/doctrine2/lib');
    $classLoader-&gt;register();

    $classLoader = new ClassLoader('Entities', __DIR__.'/../lib');
    $classLoader-&gt;register();

  }
}</pre>
<p>4. Create your classes in lib/Entities, ie. lib/Entities/Server.php:</p>
<pre>namespace Entities;
use Doctrine\ODM\MongoDB\Mapping\ClassMetadata;

class Server
{
  private $id;
  private $hostname;
  private $ipAddress;
  private $status = 0;

    public function getId()
    {
        return $this-&gt;id;
    }

    public function getHostname()
    {
        return $this-&gt;hostname;
    }
    public function setHostname($hostname)
    {
        $this-&gt;hostname = $hostname;
    }
   public function getIpAddress()
    {
        return $this-&gt;ipAddress;
    }
    public function setIpAddress($ip)
    {
        $this-&gt;ipAddress = $ip;
    }

  public function  __toString()
  {
    return $this-&gt;hostname;
  }

}</pre>
<p>5. Now you can perform your operations, just to keep it simple, we will add the code to the actions.inc.php:</p>
<pre>use Doctrine\ODM\MongoDB\EntityManager, Doctrine\ODM\MongoDB\Mongo, Entities\Server;
class defaultActions extends sfActions
{
 public function executeInex(sfWebRequest $request)
  {
    $em = EntityManager::create(new Mongo());

    $s = new Server();
    $s-&gt;setIpAddress('192.168.0.1');
    $s-&gt;setHostname('abc.example.com');
    $em-&gt;persist($s);
    $em-&gt;flush();
    $query = $em-&gt;createQuery('Entities\Server');
    $servers = $query-&gt;execute();
    $this-&gt;servers = $servers;
  }</pre>
<p>And your indexSuccess.php has nothing special about ODM:</p>
<pre>Servers:
&lt;ul&gt;
&lt;?php foreach( $servers as $s): ?&gt;
 &lt;li&gt;&lt;?php echo esc_entities($s);?&gt;&lt;/li&gt;
&lt;?php endforeach; ?&gt;
&lt;/ul&gt;</pre>
<p>Hopefully with this preview, you can see the power of MongoDB when joined by ODM and symfony.</p>
<p>Special thanks to Jon Wage for leading the development of this project and his contribution to this article.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.servergrove.com/2010/04/28/mongodb-with-php-and-symfony/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>Interesting symfony plugins: sfSyncContentPlugin</title>
		<link>http://blog.servergrove.com/2010/04/26/interesting-symfony-plugins-sfsynccontentplugin/</link>
		<comments>http://blog.servergrove.com/2010/04/26/interesting-symfony-plugins-sfsynccontentplugin/#comments</comments>
		<pubDate>Mon, 26 Apr 2010 20:42:08 +0000</pubDate>
		<dc:creator>Pablo</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[symfony]]></category>
		<category><![CDATA[plugins]]></category>

		<guid isPermaLink="false">http://blog.servergrove.com/?p=1143</guid>
		<description><![CDATA[With the amount of plugins published in the symfony site, many great plugins get lost in the maze. With this series of posts, we would like to bring some attention to plugins we use every day or that we think are essential for any symfony developer. sfSyncContentPlugin Deploying symfony applications is always a key part [...]]]></description>
			<content:encoded><![CDATA[<p>With the amount of plugins published in the symfony site, many great plugins get lost in the maze. With this series of posts, we would like to bring some attention to plugins we use every day or that we think are essential for any symfony developer.</p>
<h2>sfSyncContentPlugin</h2>
<p>Deploying symfony applications is always a key part of developing and maintaining websites that run on symfony. It is always a recommended practice to do development on a local environment or dedicated development server. It is also recommended to have a QA/staging server that is as close as possible to your production server. Using this well proven method you can spot problems and bugs before everybody else sees or experiences them, you know, those bugs that &#8220;only&#8221; happen in production, don&#8217;t tell me that it never happened to you, I won&#8217;t believe you.</p>
<p>Anyway, making changes in a live site is not only not recommended, it should never be done!</p>
<p>When developing and testing symfony applications, a lot of times you need to have a copy of the live data. Or you may have a staging server where you make changes before pushing them to a live site in a production server. symfony already provides a way to deploy code changes to a remote server, but what about uploaded and data files? And database content?</p>
<p>Since we discovered and started using it, we can&#8217;t live without the <a href="http://www.symfony-project.org/plugins/sfSyncContentPlugin">sfSyncContentPlugin plugin</a> by Tom Boutell and Alex Gilbert, also developers of <a href="http://www.apostrophenow.com/">Apostrophe CMS</a>. This plugin helps with all the tasks and needs described above. Using it is quite simple. All you need to do is define your servers in config/properties.ini like this:</p>
<pre>[qa]
  host=qa.example.com
  port=22
  user=user
  dir=/var/www/mysite

[prod]
  host=www.example.com
  port=22
  user=user
  dir=/var/www/mysite

[staging]
  host=staging.example.com
  port=22
  user=user
  dir=/var/www/mysite</pre>
<p>Make sure to use SSH keys to authenticate to your remote servers, so you don&#8217;t get asked again and again for passwords. Then  just run the following symfony tasks:</p>
<pre>
# Migrate files and DB from development to qa
./symfony project:sync-content frontend dev to qa@qa

# Migrate files and DB to production (always make a backup of production before doing this!)
./symfony project:sync-content frontend dev to prod@prod

# Migrate files and DB from QA into development
./symfony project:sync-content frontend dev from prod@prod
</pre>
<p>Files and DB content are copied accordingly, almost magically. It saves so much time, but please make sure you understand and check the order that you apply in the symfony task. With the power this plugin provides, is very easy, by mistake, to overwrite production data, so again, always make a backup!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.servergrove.com/2010/04/26/interesting-symfony-plugins-sfsynccontentplugin/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Interesting symfony plugins: sfPropelMigrationsLightPlugin</title>
		<link>http://blog.servergrove.com/2010/04/06/interesting-symfony-plugins-sfpropelmigrationslightplugin/</link>
		<comments>http://blog.servergrove.com/2010/04/06/interesting-symfony-plugins-sfpropelmigrationslightplugin/#comments</comments>
		<pubDate>Tue, 06 Apr 2010 21:18:50 +0000</pubDate>
		<dc:creator>Pablo</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[symfony]]></category>
		<category><![CDATA[plugins]]></category>
		<category><![CDATA[propel]]></category>

		<guid isPermaLink="false">http://blog.servergrove.com/?p=1129</guid>
		<description><![CDATA[You probably have read about all the buzz surrounding Doctrine these days. Its support for migrations (the ability to upgrade/downgrade the database schema) is pretty awesome. However, migrating to Doctrine from Propel 1.4 can be challenging on a large scale project. Don&#8217;t fret, it turns out that there is a cool little plugin that provides [...]]]></description>
			<content:encoded><![CDATA[<p>You probably have read about all the buzz surrounding <a href="http://www.doctrine-project.org/">Doctrine</a> these days. Its support for migrations (the ability to upgrade/downgrade the database schema) is pretty awesome. However, migrating to Doctrine from <a href="http://propel.phpdb.org/trac/">Propel 1.4</a> can be challenging on a large scale project. Don&#8217;t fret, it turns out that there is a cool little plugin that provides migrations for those that are locked in the Propel world. As described in the plugin page, the <a href="http://www.symfony-project.org/plugins/sfPropelMigrationsLightPlugin">sfPropelMigrationsLightPlugin</a> allows to &#8220;Easily change the database structure without losing any data.&#8221;</p>
<p>The main difference between Doctrine&#8217;s migrations and sfPropelMigrationsLightPlugin is that you have to write the code to alter your tables, where as Doctrine can generate these by looking at the differences in the local schema file and the DB. The plugin page describes the use which is fairly simple: create the migration class, add the code to the up() and down() methods and finally run the migrate task (ie. <code>symfony migrate frontend 42)</code></p>
<p>Automating the deployment process is an important part of delivering software and avoiding problems. This plugin surely helps in this regard and we recommend its use if you are using Propel. And remember to always backup before you migrate anything!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.servergrove.com/2010/04/06/interesting-symfony-plugins-sfpropelmigrationslightplugin/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Installing Apostrophe CMS on shared hosting</title>
		<link>http://blog.servergrove.com/2010/03/24/installing-apostrophe-cms-on-shared-hosting/</link>
		<comments>http://blog.servergrove.com/2010/03/24/installing-apostrophe-cms-on-shared-hosting/#comments</comments>
		<pubDate>Wed, 24 Mar 2010 16:32:45 +0000</pubDate>
		<dc:creator>Pablo</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Shared Hosting]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[symfony]]></category>
		<category><![CDATA[apostrophe]]></category>

		<guid isPermaLink="false">http://blog.servergrove.com/?p=1072</guid>
		<description><![CDATA[Here is a quick guide to get Apostrophe CMS, up and running on our Shared hosting servers. We are going to assume that you either have Apostrophe running on your local development environment, or that you will install the sandbox version that you can download from the site. Installing the Apostrophe Sandbox First of all, [...]]]></description>
			<content:encoded><![CDATA[<p>Here is a quick guide to get <a href="http://www.apostrophenow.com/">Apostrophe CMS</a>, up and running on our <a href="http://servergrove.com/sharedhosting">Shared hosting</a> servers.</p>
<p>We are going to assume that you either have Apostrophe running on your local development environment, or that you will install the <a href="http://trac.apostrophenow.org/wiki/ManualInstallation#WaystoDownloadtheApostropheSandboxProject">sandbox version</a> that you can download from the site.</p>
<h3>Installing the Apostrophe Sandbox</h3>
<p>First of all, login to your Control Panel account and make sure you have SSH enabled for your domain. This can be done in the Setup section of the domain.</p>
<div id="attachment_1075" class="wp-caption alignnone" style="width: 510px"><a href="http://blog.servergrove.com/wp-content/uploads/2010/03/ssh.png"><img class="size-full wp-image-1075" title="ssh" src="http://blog.servergrove.com/wp-content/uploads/2010/03/ssh.png" alt="Enabling SSH" width="500" /></a><p class="wp-caption-text">Enabling SSH</p></div>
<p>Next, in the Control Panel, go ahead and create your database and database user. Go to <em>Databases</em> under your domain and add a new database and then a new username.</p>
<p>Next, connect with your SSH client go to /symfony_projects directory and execute:</p>
<p><code>svn co http://svn.apostrophenow.org/sandboxes/asandbox/branches/1.3 asandbox</code></p>
<p>Once it finished executing all the SVN checkouts, you will have a complete Apostrophe installation in asandbox. Go into asandbox directory and create copies of the needed configuration files:</p>
<p><code>cd asandbox<br />
cp config/databases.yml.sample config/databases.yml<br />
cp config/properties.ini.sample config/properties.ini<br />
</code><br />
Edit config/databases.yml and configure the database connection with the database/username created in the previous step. Make sure to change dbname, host, username and password to match your account.</p>
<pre>all:
  doctrine:
    class:        sfDoctrineDatabase
    param:
       dsn:        mysql:dbname=ademo;host=sg108.servergrove.com
       username: ademo
       password: yourpassword</pre>
<p>Run the following symfony tasks:</p>
<p><code>./symfony cc<br />
./symfony plugin:publish-assets<br />
./symfony doctrine:build --all<br />
./symfony doctrine:data-load<br />
</code></p>
<p>This will create the default database and load the default configuration. You can also setup a default demo by running:</p>
<p><code>./symfony apostrophe:demo-fixtures</code></p>
<p>And finally run:</p>
<p><code>./symfony project:permissions<br />
</code></p>
<p>Before you are done there is a very important step. You need to configure the web server to use your Apostrophe installation. Go into the control panel and into the Maestro section. Select the asandbox project and go to Setup WebServer and click OK.</p>
<div id="attachment_1076" class="wp-caption alignnone" style="width: 510px"><a href="http://blog.servergrove.com/wp-content/uploads/2010/03/maestro1.png"><img class="size-full wp-image-1076" title="Setting up Apostrophe with Maestro" src="http://blog.servergrove.com/wp-content/uploads/2010/03/maestro1.png" alt="" width="500" /></a><p class="wp-caption-text">Setting up Apostrophe with Maestro</p></div>
<div id="attachment_1077" class="wp-caption alignnone" style="width: 510px"><a href="http://blog.servergrove.com/wp-content/uploads/2010/03/maestro2.png"><img class="size-full wp-image-1077" title="Setting up Apostrophe with Maestro" src="http://blog.servergrove.com/wp-content/uploads/2010/03/maestro2.png" alt="" width="500" /></a><p class="wp-caption-text">Setting up Apostrophe with Maestro</p></div>
<p>At this point, your Apostrophe installation has to be working, so go ahead and load your site</p>
<div id="attachment_1078" class="wp-caption alignnone" style="width: 510px"><a href="http://blog.servergrove.com/wp-content/uploads/2010/03/asandbox1.png"><img class="size-full wp-image-1078" title="Apostrophe demo running" src="http://blog.servergrove.com/wp-content/uploads/2010/03/asandbox1.png" alt="" width="500" /></a><p class="wp-caption-text">Apostrophe demo running</p></div>
<h3>Installing Apostrophe from your development environment</h3>
<p>If you have Apostrophe running in your development environment there are many common steps with the sandbox installation. First, enable SSH and create the database and database user in the Control Panel as described above. Then import a SQL dump of your database and import it using the DB WebAdmin in the Control Panel.</p>
<p>Next, upload your Apostrophe project into symfony_projects. You can upload the files using a FTP client or you can checkout your SVN repository or clone your GIT repository using the SSH client. Edit databases.yml so the connection information matches the shared hosting server settings as done in the sandbox installation above.</p>
<p>Next, run the following commands</p>
<p><code>./symfony cc<br />
./symfony plugin:publish-assets<br />
./symfony project:permissions<br />
</code></p>
<p>And finally, use Maestro as described in the sandbox installation to setup the web server to use Apostrophe project. It is that simple!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.servergrove.com/2010/03/24/installing-apostrophe-cms-on-shared-hosting/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Important symfony security update released</title>
		<link>http://blog.servergrove.com/2010/02/25/important-symfony-security-update-released/</link>
		<comments>http://blog.servergrove.com/2010/02/25/important-symfony-security-update-released/#comments</comments>
		<pubDate>Fri, 26 Feb 2010 02:09:44 +0000</pubDate>
		<dc:creator>Pablo</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[symfony]]></category>
		<category><![CDATA[doctrine]]></category>
		<category><![CDATA[security]]></category>

		<guid isPermaLink="false">http://blog.servergrove.com/?p=1034</guid>
		<description><![CDATA[The symfony core team released new versions of three branches (1.2, 1.3 and 1.4) fixing a security vulnerability in the Doctrine admin generator. The new versions are 1.2.12, 1.3.3 and 1.4.3. All our servers have been upgraded but if you are using the admin generator in your site, it is important that you clear the [...]]]></description>
			<content:encoded><![CDATA[<p>The symfony core team released new versions of three branches (1.2, 1.3 and 1.4) <a href="http://www.symfony-project.org/blog/2010/02/25/security-release-1-2-12-1-3-3-and-1-4-3">fixing a security vulnerability in the Doctrine admin generator</a>. The new versions are 1.2.12, 1.3.3 and 1.4.3.</p>
<p>All our servers have been upgraded but if you are using the admin generator in your site, it is important that you clear the symfony cache. On shared hosting you can do so by login to the Control Panel and using Maestro. On a VPS, through SSH and as root run the following command: &#8220;cd /usr/local/php; git pull&#8221; and then clear your symfony cache.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.servergrove.com/2010/02/25/important-symfony-security-update-released/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>symfony CMS review series: Apostrophe</title>
		<link>http://blog.servergrove.com/2010/02/25/symfony-cms-review-series-apostrophe/</link>
		<comments>http://blog.servergrove.com/2010/02/25/symfony-cms-review-series-apostrophe/#comments</comments>
		<pubDate>Thu, 25 Feb 2010 13:49:08 +0000</pubDate>
		<dc:creator>Pablo</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[symfony]]></category>
		<category><![CDATA[apostrophe]]></category>
		<category><![CDATA[cms]]></category>
		<category><![CDATA[diem]]></category>
		<category><![CDATA[sympal]]></category>

		<guid isPermaLink="false">http://blog.servergrove.com/?p=1010</guid>
		<description><![CDATA[A big topic during Symfony Live 2010 was the need of quality web applications developed using symfony. CMS (content management system) applications are core to modern web development and until recently, even just 6 months ago or so, there were few available options built in symfony. Projects like SimpleCMS and Sympal had been started and [...]]]></description>
			<content:encoded><![CDATA[<p>A big topic during Symfony Live 2010 was the need of quality web applications developed using symfony. CMS (content management system) applications are core to modern web development and until recently, even just 6 months ago or so, there were few available options built in symfony. Projects like SimpleCMS and <a href="http://www.sympalphp.org/">Sympal</a> had been started and while they showed potential, they were still in the early stages of development.</p>
<p>This scenario has changed quite a bit in the past month. At the time of this post, there are three major open source CMS applications: <a href="http://www.apostrophenow.com/">Apostrophe</a>, <a href="http://diem-project.org/">Diem</a> and <a href="http://www.sympalphp.org/">Sympal</a>. We expect a fair number of these apps to be installed on our platform so we decided to dig in and test them out. As with any application, no CMS can fit everybody&#8217;s needs and workflow, so we don&#8217;t think there is one CMS that will rule them all. The idea is not to find the best CMS, but to highlight the strengths and weakness of each option and comment on any places where we see room for improvement. Of course, these projects are relatively new, so I am sure there will be plenty of room for improvement and with time and contributions from developers and designers things will get better. We encourage anyone with an interest in any of these projects to join in the discussion and leave comments below and ask the current developers if they need contributors (I think I already know the answer to that!). I am also sure there are plenty of other CMS systems developed with symfony that have not been released open source and would be nice if companies can contribute back to the community by releasing them into the public. In case we missed something be sure to let us know.</p>
<p>We will review the applications in alphabetical order and will  start with Apostrophe developed by the fine folks at <a href="http://punkave.com/">P&#8217;unk Avenue</a>.</p>
<p><strong>Apostrophe</strong></p>
<div id="attachment_1013" class="wp-caption alignnone" style="width: 560px"><a href="http://blog.servergrove.com/wp-content/uploads/2010/02/a.jpg"><img class="size-full wp-image-1013" title="a" src="http://blog.servergrove.com/wp-content/uploads/2010/02/a.jpg" alt="" width="550" height="419" /></a><p class="wp-caption-text">Apostrophe&#39;s site</p></div>
<p><strong>Getting started</strong></p>
<p>Apostrophe can be found at <a href="http://www.apostrophenow.com/">http://www.apostrophenow.com/</a>. The website is clean and simple and they provide <a href="http://demo.apostrophenow.com/">a full-feature demo</a> and this video to help get the feel for the application.</p>
<p><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="400" height="300" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="src" value="http://vimeo.com/moogaloop.swf?clip_id=7172499&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=&amp;fullscreen=1" /><embed type="application/x-shockwave-flash" width="400" height="300" src="http://vimeo.com/moogaloop.swf?clip_id=7172499&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=&amp;fullscreen=1" allowscriptaccess="always" allowfullscreen="true"></embed></object></p>
<p><a href="http://vimeo.com/7172499">Apostrophe CMS Screencast (EMAP)</a> from <a href="http://vimeo.com/user1850492">Apostrophe</a> on <a href="http://vimeo.com">Vimeo</a>.</p>
<p><strong>Concepts and key features</strong></p>
<ul>
<li>pages: Apostrophe places content in pages. These pages are dynamically created through a nice, clean and concise UI. You can define the template for each page, allowing to have different layouts for your home page, internal and special pages. When you add a page, breadcrumbs, menus and sitemap get updated automatically which can save lots of time and prevent broken links.</li>
<li>slots: A page has areas for content called slots. These slots can contain very diverse data. By default several slot types are provided: rich text, slideshow, video, image, RSS feed, PDF, button, plain text and raw HTML. We will go into more details later on.</li>
<li>media: Out of the box, you get a media manager which allows you to add images, videos and documents into a library that then can be used to locate and link from your pages and slots.</li>
<li>history of changes: when you make a change in a slot, let&#8217;s say a rich text, the change gets stored in a history log which can then be accessed for review. You can also revert back to a previous version of the content, which is super-useful. It also works on other slot types, like in the RSS feed it keeps track of the changes in the URL, although it does not show the URL for each revision which would be very handy.</li>
<li>Ajax-enabled UI: The admin elements of the system are displayed and loaded only when you need them. In the demo and installed sandbox, which provides a sample site as starting point, the buttons and menus do not obstruct the general flow of the page, and do not distort the view. It will be interesting to see how it works with other type of sites and more custom CSS layouts.</li>
<li>search-enabled: Apostrophe uses Zend_Search to index content and provide search functionality out of the box. The index is stored in the filesystem by default.</li>
</ul>
<div id="attachment_1020" class="wp-caption alignnone" style="width: 560px"><a href="http://blog.servergrove.com/wp-content/uploads/2010/02/a5.jpg"><img class="size-full wp-image-1020" title="a5" src="http://blog.servergrove.com/wp-content/uploads/2010/02/a5.jpg" alt="" width="550" height="333" /></a><p class="wp-caption-text">History of changes</p></div>
<p><strong>Installation</strong></p>
<p>You have a few different options to install Apostrophe: sandbox, svn checkout and plugin installation.</p>
<p>The <a href="http://trac.apostrophenow.org/wiki/ManualInstallation">installation document</a> is very good, with enough explanation for each required step. We picked to download the sandbox tarball, which includes the symfony project skeleton, all the plugins and dependencies needed and a sample site ready to be used. This is probably the quickest way to get started in your own server. It literally took about 5 minutes to download the file, uncompress it, create the needed configuration files (sample files for both config/databases.yml and config/properties.ini are provided), create the database and load the fixtures, and finally run a series of symfony tasks to make sure files can be written by the web server.</p>
<p>I created a virtual host entry in our Apache:</p>
<pre>
&lt;VirtualHost *:80&gt;
 DocumentRoot /Users/user/Sites/asandbox/web
 ServerName asandbox.local

&lt;Directory /Users/user/Sites/asandbox/web&gt;
AllowOverride All
&lt;/Directory&gt;

&lt;/VirtualHost&gt;
</pre>
<p>Notice the AllowOverride directive in the Directory block. This is very important to make sure the .htaccess file included in the web directory gets used by Apache to assure full functionality  of the CMS features.</p>
<p>Then I added the asandbox.local to the /etc/hosts file and restarted Apache.</p>
<p><strong>First impressions</strong></p>
<p>When loading the site for the first time, I got a nice page with some sample content.</p>
<div id="attachment_1014" class="wp-caption alignnone" style="width: 560px"><a href="http://blog.servergrove.com/wp-content/uploads/2010/02/a2.jpg"><img class="size-full wp-image-1014" title="a2" src="http://blog.servergrove.com/wp-content/uploads/2010/02/a2.jpg" alt="" width="550" height="314" /></a><p class="wp-caption-text">Sample site</p></div>
<p>In the top-right corner there is a Login button. When you click on it a nice login form appears and the default login is admin/demo. Upon logging in, the page refreshes and now you get to see all the admin elements, including a menu on the top of the page which gives you access to configure and add pages, media, reorganize your site structure and manage users and permissions.</p>
<p>Editing a page allows to set basic things like name, access level, template, editing permissions and page engine (more on this later).</p>
<div id="attachment_1017" class="wp-caption alignnone" style="width: 560px"><a href="http://blog.servergrove.com/wp-content/uploads/2010/02/a3.jpg"><img class="size-full wp-image-1017" title="a3" src="http://blog.servergrove.com/wp-content/uploads/2010/02/a3.jpg" alt="" width="550" height="314" /></a><p class="wp-caption-text">Editing page</p></div>
<p>The media manager allows you to add images from your computer, videos from Youtube and others using embed code, and PDF documents.</p>
<p>Reorganizing the site structure of the site is done by dragging pages in a tree component which is very cool and simple to use. This in turn, updates the breadcrumbs and menus automatically.</p>
<div id="attachment_1018" class="wp-caption alignnone" style="width: 560px"><a href="http://blog.servergrove.com/wp-content/uploads/2010/02/a4.jpg"><img class="size-full wp-image-1018" title="a4" src="http://blog.servergrove.com/wp-content/uploads/2010/02/a4.jpg" alt="" width="550" height="314" /></a><p class="wp-caption-text">Reorganizing site</p></div>
<p>When you want to add content to a page, you need to add a slot to the section of the page you want. If you need to add some rich text, you use the analogous slot type and a WYSIWYG (FCKeditor) is shown in place. Upon saving, the editor is hidden and the content displayed. If you need to create a slideshow, you add the slot, then select the images from the media library and done! Displaying news from a remote site is super easy, just add a RSS feed slot, enter the URL and see the articles fill up the page. And of course, <a href="http://trac.apostrophenow.org/wiki/ManualDevelopersGuide">you can create your own slots</a>.</p>
<p><strong>Help for everybody</strong></p>
<p>The team behind Apostrophe made sure everybody, from developers, editors to designers have at least some kind of documentation to refer to. So if you are a designer and need to customize the layout or work with templates, make sure to read the <a href="http://trac.apostrophenow.org/wiki/ManualDesignersGuide">Designer&#8217;s guide</a>. There are also <a href="http://trac.apostrophenow.org/wiki/ManualEditorsGuide">editor&#8217;s</a> and <a href="http://trac.apostrophenow.org/wiki/ManualDevelopersGuide">developer&#8217;s</a> guides.</p>
<p><strong>Installing Apostrophe on shared hosting</strong></p>
<p>Running symfony applications on shared hosting can sometimes be challenging but installing Apostrophe using <a href="http://servergrove.com/maestro" target="_blank">Maestro</a> can happen in a matter of minutes! There is no doubt we are kicking some hosting butt here. If you want to run Apostrophe on our shared hosting servers, we recommend that you upload the entire project directory (ie. the sandbox directory) into the symfony_projects folder and use Maestro to setup the web server for you. This is a simple process and helps you avoid having to mess with modrewrite rules and so on. Just make sure you do not override the .htaccess file as Apostrophe already provides one for you.</p>
<p><strong>Installing Apostrophe on VPS servers</strong></p>
<p>VPS servers customers have full access to their environment so there are no special steps required if you want to install Apostrophe in a VPS. Just make sure you follow the instructions provided in the installation manual.</p>
<p><strong>Closing notes</strong></p>
<p>A lot of thought, time and effort has been put in Apostrophe. The first stable version was released just before Symfony Live. The system allows you to have a CMS-enabled site running in matter of minutes, which is something most developers of small sites need. Since it is developed on top of symfony and as a plugin, you can use it along other symfony applications and you can extend its functionality to add custom features, a key part of today&#8217;s needs.</p>
<p>We want to congratulate and thank <a href="http://punkave.com/">P&#8217;unk Avenue</a> for releasing this CMS as an open source project. Make sure to <a href="http://window.punkave.com/">follow their blog</a> for updates and if you want to contribute don&#8217;t hesitate to <a href="http://groups.google.com/group/apostrophenow">join the google group</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.servergrove.com/2010/02/25/symfony-cms-review-series-apostrophe/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Heading to Symfony Live 2010</title>
		<link>http://blog.servergrove.com/2010/02/13/heading-to-symfony-live-2010/</link>
		<comments>http://blog.servergrove.com/2010/02/13/heading-to-symfony-live-2010/#comments</comments>
		<pubDate>Sun, 14 Feb 2010 00:10:32 +0000</pubDate>
		<dc:creator>Pablo</dc:creator>
				<category><![CDATA[Conferences]]></category>
		<category><![CDATA[symfony]]></category>
		<category><![CDATA[sflive2010]]></category>

		<guid isPermaLink="false">http://blog.servergrove.com/?p=970</guid>
		<description><![CDATA[Next week we will be present at Symfony Live 2010, the second edition of this conference where symfony developers meet to learn and network. We are very excited to not only be present but also  sponsor supporting the symfony community. If you can&#8217;t make it to Paris, keep checking this blog for daily updates or [...]]]></description>
			<content:encoded><![CDATA[<p>Next week we will be present at <a href="http://www.symfony-live.com/">Symfony Live 2010</a>, the second edition of this conference where symfony developers meet to learn and network. We are very excited to not only be present but also  sponsor supporting the symfony community.</p>
<p>If you can&#8217;t make it to Paris, keep checking this blog for daily updates or<a title="@servergrove" href="http://twitter.com/servergrove"> follow us on twitter</a> for  more frequent notes.  In the case you will be present, please say hi and introduce yourself, we are looking forward to meet clients and developers.</p>
<p>à bientôt!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.servergrove.com/2010/02/13/heading-to-symfony-live-2010/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
