Celebrating Symfony2 With One Free Project

Symfony2 was released this past Thursday.  This marks a huge advancement in the framework with tons of new features, better programming patterns, and much better performance.  Symfony2 is now the most popular PHP project on GitHub and contributors are helping better it each day.

Since we are so excited for this release, we are going to take on one small free project for the person or company who submits the best idea and reason for their project.  We’ll be picking the free project within one week of today. Shoot us an email with your project and reason you’d like it done for free.

Congrats to the entire Symfony2 team and we look forward to helping out with it!

Scaling HerCampus.com

Over the past month we’ve been working with Her Campus (HerCampus.com) to help them with issues they were having. When we started talking with Her Campus, we learned that they had different types of issues ranging from some Drupal based ones to actual server level problems. They were having some trouble keeping up to traffic demands, and if a traffic spike occurred their current infrastructure wasn’t sufficient.

After looking at their setup, we noted quite a few areas in which we could improve performance. The old setup was a fairly standard setup, a frontend server using Apache to handle HTTP requests and then a second server which was their MySQL database server. The servers were a 4 gig and 8 gig server respectively.

It was clear Apache was adding unneeded overhead, and wasn’t the best solution for them. We revamped their setup significantly. We switched them to Nginx + PHP-FPM. We immediately saw great improvement on from this change alone. However we wanted to get them to a single server, and to be able to handle traffic spikes with a single server.

We ended up doing the following:

  • Switch from Apache -> Nginx+PHP-FPM
  • Update all MyISAM tables to INNODB tables, and upgrade their MySQL to 5.1
  • Tune MySQL settings to fit their requirements
  • Update several tables adding indexes, reducing query time from in one case 34 seconds to 0.02 seconds.
  • Add the Boost Module to their setup
  • Update several of the view queries to be better written, added caching to each query.
  • Use ImageCache and sub-domains to load assets

After these updates we were able to move them from their two servers (8 gig and 4 gig) to a single server(4 gig). We have also reduced load times significantly. Their server loads dropped from 4-5 on average to 0.25. Recently they had an article on the Huffington Post and didn’t have any problems handling the 4x traffic spike they saw. At points we were seeing according to ChartBeat over 600 people on the site at once. The single server handled this without problems.

The updated infrastructure will give them a savings of about 75% from their previous setup. It also gives the users on the site a much faster and reliable experience.

We look forward to helping Her Campus with their continuing expansion of their site and user base!

Redirect outbound traffic over specific IP

Recently one of our clients decided to white label their product.  With that we had to setup the server to use multiple IPs as the application requires you communicate over SSL and we needed a SSL per domain.  We did not want to buy a UCC(a multiple domain)  SSL certificate as right now it wasn’t required for the small number of white labels. After we added the additional IP we had the issue that the application which connects to off site MySQL servers, was sometimes going over the new IPs and then getting denied accessed.

We knew the solution was with iptables so after some digging and testing, we came up with the following command.  This command we use will redirect all traffic that is not over port 443 (in this example) to go out over the ‘YYY.YYY.YYY.YYY’ address that is about to go out over the XXX.XXX.XXX.XXX ip.

iptables -t nat -A POSTROUTING -p tcp ! --dport 443 -s XXX.XXX.XXX.XXX -j SNAT --to-source YYY.YYY.YYY.YYY

We didn’t see any examples of this clearly defined (after a quick google that is), on the web, so hopefully this will save you time from having to read through the iptables documentation.

 

TrackYourImpact.com Launched!

Recently we’ve launched a new site for a client called Purpose Beverages: http://trackyourimpact.com . We’ve received great feedback from users so far. The site uses a wide range of technologies. It is built on symfony and uses the Apostrophe CMS to manage the main parts of the site. It integrates with a SMS provider to allow you text into it to find out more about your purchase.

Tēvolution is a new brand of tea on the market that does good with each purchase. Every time someone buys it they done a specific amount(for example 25 cents) to a specific charity. In order to find out how large of a donation and what charity your bottle goes to you can actually text the code found on the bottle to the website, or you can login in on your phone browser or regular browser and enter the code. You will find out how much and to whom you just donated money to!

Right now Tēvolution is just coming to the market so keep your eyes peeled for it! It’s a great product that does good!

Getting an extra ‘Invalid’ or other error on your symfony form?

On a project I’m working on I came across the following problem: we had a email field that we needed to be unique in our system, but we also made sure that it matched a confirm email field. A snippet of our form looks like this:

When we submitted an email that was already in the system we got back two errors:

  • Sorry! A user with that email address already exists.
  • Invalid.

For a while I thought is there some extra validator somewhere that I left on? Where is this invalid coming from? It ended up being due to the way the validators work. If a validator throws an error it doesn’t return that validator’s value. So by the time it gets to the sfValidatorSchemaCompare post validator the value of `email` is null and `confirm_email` has the value you input, thus the seemingly extra ‘Invalid’ message.

This can be fixed easily with a sfValidatorCallback instead of the sfValidatorSchemaCompare. Here is the fix:

This way if the email is blank it doesn’t both making sure that the `email` matches the `confirm_email`. You don’t need to worry about a person just passing two blank emails as the earlier validator(the sfValidatorEmail requires it to be there and valid).

If you are getting an extra validation error, check your postValidators and how the values get to them.