Yii Framework Easy Test Fixture Creation

We’ve said it before, and we’ll say it again – we are huge fans of the Yii Framework.  This PHP framework is easy to understand, and even better, easy to create test cases.  One of the most time consuming portions of writing the test suite, however, was getting your test data into Yii’s ‘fixture’ files.  These fixture files correspond to data that would be in your database tables, but the files stay constant so you always have a known start state.  That way, you can test your application easily at any time, ensuring that your recent build hasn’t broken any legacy functions.

Due to the fixture files, we had resorted to running a custom script that took data out of our production database and exported it to a fixture file.  However, with a recent new installation of phpMyAdmin, we came across the PHP Array plugin.  Using this plugin, you can easily export your table data into PHP array format – the same format that is needed for your Yii fixture files.

We hope this saves someone some time and hassle down the road!

Read More

Google Chrome DNS Caching

For the most part, I enjoy Google Chrome and use it almost exclusively for web browsing.  However, I ran into a bit of a problem this weekend as Hollow Developers was switching our production servers from one host to another.  As soon as our DNS records were updated, I hopped over to OpenDNS, the DNS server that I use at home, and ensured their cache for the domain was using the updated server.  It was – so I was good to go – or so I thought.

Next, I loaded up the domain in Chrome, but it was loading the old server!  I opened up Opera, and it was loading up the correct server.  Odd, since DNS should be shared between all applications on my laptop.  And then it hit me, Chrome has some pretty extensive DNS settings and a corresponding DNS cache.  After a little searching, I found out that I could clear the DNS cache at chrome://net-internals/#dns.

Read More

SVN Commit Error

Ah, version management.  For the professional and novice alike, version management can really prevent a lot of headaches.  Accidentally break something in your most recent version?  It’s easy to go back and revert to the last working version.

As helpful as Subversion (and associated TortoiseSVN Windows app) is, it can sometimes throw some really strange errors.  The most recent one that we received was:

“Can’t open file ‘folder.svn\tmp\text-base\file.svn-base’: The system cannot find the file specified.”

Needless to say, we didn’t quite know what to do at first.  However, it turns out that there is a great Stack Overflow article explaining the solution.  We also came up with our own solution, since the root of the problem was a renamed file that differed only in case.  We just appended ‘2’ to the file name, committed, and renamed it again.  The second commit works, and prevents the error from occurring again.

Hope this helps someone else along their development way!

Read More

GoDaddy Instant DataCenter vs. Rackspace Cloud Servers

10/09/2012 Update

We have written in the past about Rackspace Cloud servers, and the fact that our site is actually built on these servers.  As traffic increases and decreases, we can quickly scale up and down our servers to accommodate spikes, and remove cost during slow periods.

Recently, GoDaddy introduced their answer to Rackspace’s cloud servers – GoDaddy Instant DataCenter.

We haven’t had much time with GoDaddy’s product, but wanted to provide some initial thoughts on the two products since there doesn’t seem to be much discussion on the products yet.

First, the areas where GoDaddy wins out over Rackspace:

  • Price – as usual, GoDaddy undercuts the competition by a significant margin.  Three 1GB servers with 100GB outbound transfer will run you $120/month (cheaper if you signup for a longer term).  Comparable servers on Rackspace would cost $150/month.
  • Ease of setup – we called GoDaddy support and had a running server within 2 hours.  Setup time was comparable on Rackspace.  However, GoDaddy provided a stock LAMP Ubuntu server, something that saves just a little time, but is helpful nonetheless for quick proof-of-concepts.
  • Easy firewall – GoDaddy provides a firewall in front of your entire network, so you can use their interface to open ports and establish load balancers.  Rackspace doesn’t let you off quite this easy and requires modifications on each server.
  • Simple load balancer – in the control panel, you tell GoDaddy which port and IP should be load balanced, and also provide target machines – all in a web interface.  Nothing’s easier, and this layer is free.  I would like more details about the load balancer, however.  I am assuming that it is a high availability load balancer with many nodes at the entrance of the network.  You know what they say about assuming, though.

Rackspace has quite a few things going for them, however:

  • API Control – Scripts can easily control your cloud server settings – everything from creating a new server instance to increasing the RAM on a server.  This allows you unparalleled flexibility, and is not, as of yet, available on the GoDaddy Instant DataCenter product.
  • Reputation – A huge plus for Rackspace here.  I don’t know anyone who can say “I’m really embarrassed that I buy products from Rackspace.”  However, the same cannot be said for GoDaddy.  From their icky advertising to their CEO’s elephant killing video, the company is a little sketchy.  Every SuperBowl, I hang my head in shame when their commercial comes on.
  • Documentation – Rackspace wins by a mile with best practices for setting up the servers and step-by-step instructions for performing almost any task that you will need to do.  It’s still early in GoDaddy’s product, but even for their older products, GoDaddy lacks solid documentation and a strong community.
  • Easy CDN Integration – Content delivery network is provided in the control panel to allow quick offloading of resources.
The verdict: mixed.  If you’re just trying things out, you might want to give GoDaddy a try since they seem to be the cheapest option for 1GB servers.  However, Rackspace allows you to start at 256MB, so their cheapest option is also a good starting point.  If you require a more complex setup, I would definitely go with Rackspace due to their flexibility and API integration.

Read More

One Week In Google+

Google+ Logo

So it’s been a week since I signed up for Google+.  (Profile link)  So far, so good.  But, it’s still early in the service’s evolution, and I have a few thoughts:

  • It’s a ghost town among non-techies.  As much as I love the tech community, many of my close friends and acquaintances are not in that community.  Once invites start to make it to the general public, it will be interesting how the community evolves.
  • Photo sharing doesn’t seem to be as intuitive as it could be.
  • In your news stream, posts that were recently commented on get moved back up to the top (at least that was the case a few days ago).  Adding an option that would allow you to sort based on post time or last comment time would be helpful.
  • No threaded conversations – insanely annoying for posts that generate a lot of traffic, as is the case with the most prolific Plus users right now.
  • I could see how the email generated by the service could get spammy very quickly with the default settings.

On the plus side:

  • It’s a ghost town among non-techies.  (Yes, a pro and a con.)  I get to start my social network over again.  Facebook filled up quickly with a lot of acquaintances and people that I only met once.
  • It’s easy to group people into circles.  As easy as it could have been with Facebook, they didn’t capitalize on this feature, and adding people to lists is more difficult than circles.
  • No ads – yet.  I’m glad that Google+ isn’t bombarding me with workout and protein powder ads – yet.  I know that this is the ultimate focus of Google, and that we’ll probably start seeing more relevant ads throughout the internet on AdSense, but advertisements on Facebook can be creepy.  I’m not sure how that will change as Google gets to learn more about me and my friends.
I’m excited to continue using Google+, and ultimately writing a ‘One Year in Google+’ post.

Read More

Yii Framework Separate Configurations for Different Environments

Yii doesn’t have a built-in way of changing configurations based on the environment that it is running in. However, there are a number of ways to accomplish this.

Method #1

There is a great extension available that allows you to use different configuration files based on the environment that is found in the Apache configuration file.  Yii-environment does require modification of these files, so the most basic hosting plan may not be able to accommodate the extension.  However, as is true with any programming task, there is more than one way to skin a cat.

Method #2

Another method for differentiating environments is to edit the index.php file. Based on a PHP server variable, a different configuration file can be used.

switch ($_SERVER['SERVER_NAME']) {
    case "development":
        $config=dirname(__FILE__).'/protected/config/development.php';
        break;
    default:
        $config=dirname(__FILE__).'/protected/config/production.php';
        break;
}

To make things easier, you can just include the variables that will differ in your development/production configuration files. A third file can be used to hold all shared variables. For instance, your shared configuration file can look like:

return array(
    'basePath' => dirname(__FILE__) . DIRECTORY_SEPARATOR . '..',
    'name' => 'Application Name',
    // autoloading model and component classes
    'import' => array(
        'application.models.*',
        'application.components.*',
    ),
    // application components
    'components' => array(
        'user' => array(
            // enable cookie-based authentication
            'allowAutoLogin' => false,
        ),
   ),
);

Then, each of the environment-specific variables can go into the development or production.php configuration files.

return CMap::mergeArray(
        require(dirname(__FILE__) . '/shared.php'),
        array(
            'components' => array(
                'db' => array(
                    'connectionString' => 'mysql:host=mysql;dbname=databaseName',
                    'emulatePrepare' => true,
                    'username' => 'user',
                    'password' => 'password',
                    'charset' => 'utf8',
                ),
            ),
     )
);

Read More

Yii Framework – reCAPTCHA with Active Form

CAPTCHA example
CAPTCHA example

CAPTCHAs on the Internet are as prevalent as they are annoying.  Unfortunately, these squiggly words are sometimes the best protection from automated attacks.  In our applications, we try to reduce use of CAPTCHAs, but when we do have to use them, we utilize the reCAPTCHA service from Google.  The nice thing about this service is that it is used to verify text from old publications, allowing for better scans of these publications and digitizing them for the common good.

Readers of our blog know that we love the Yii Framework, and luckily, an extension for this framework allows for very easy reCAPTCHA verification.  Here are the steps:

1. Download the reCAPTCHA extension for Yii.

2. Export the ZIP file contents into your protected/extensions folder.  After you do that, you will have a recaptcha folder in your extensions folder that contains the EReCaptcha.php and EReCaptchaValidator.php files.  There is also a subdirectory that contains the reCAPTCHA PHP library.

3. Visit Google’s reCAPTCHA site to receive your public and private key. At this point, you may want to get 2 keys – one for development purposes, and one for production purposes. We apply for a production key that can only be used on a specific domain, and a global key that can be used during development on any developer’s workstation. If this is the case, see our next post that will detail how to utilize different configuration files depending on the environment the script is currently running in.

4. Add your public and private key to your configuration file in the ‘params’ section:

'recaptcha' => array(
     'publicKey' => 'INSERT_YOUR_PUBLIC_KEY_HERE',
     'privateKey' => 'INSERT_YOUR_PRIVATE_KEY_HERE',
),

5. If you want to add the reCAPTCHA to an ActiveForm, add this to your view:

echo $form->labelEx($model, 'validation');
$this->widget('application.extensions.recaptcha.EReCaptcha',
   array('model'=>$account, 'attribute'=>'validation',
         'theme'=>'red', 'language'=>'en_US',
         'publicKey'=>Yii::app()->params['recaptcha']['publicKey']));
echo $form->error($model, 'validation');

6. In your model, add a line to your ‘rules’. ‘resetPasswordWithCaptcha’ will be used below as the scenario, so keep track of what you name it!

array(
    'validation',
    'application.extensions.recaptcha.EReCaptchaValidator',
    'privateKey'=> Yii::app()->params['recaptcha']['privateKey'],
    'on' => 'resetPasswordWithCaptcha'
),

7. In your controller, add a unique scenario to your model.  For example:

$model = new User;
$model->scenario = "resetPasswordWithCaptcha";

8. Now, validate and save if necessary.

if ($model->validate()) {
    // Put false in this save action so we don't validate again - or the CAPTCHA
    //  will be invalid!
    if ($model->save(false)) {
    }
}

We hope this helps someone use the reCAPTCHA extension with the Yii Framework! Not only are you protecting your site from automated attacks, you are also helping digitize the written word!

Read More

Gmail Smart Labels

Gmail introduced new smart labels earlier this week as a Labs feature. When you activate this lab, Google will attempt to assign the appropriate label to the message.  At this time, these labels are categorized as:

  • Bulk
  • Forums
  • Notifications
  • Personal
  • Promotions

This is a great first step, but think of how much further it could go!  It would be amazing for Gmail to learn what labels it should apply to different mail depending on who sent it, what the subject is, and other pertinent data.  For instance, our developers always label security updates as a ‘ToDo Item’, as well as a label that indicates what website it is pertinent to.  While our current filters work great for this type of thing, it would make everyone’s lives so much easier if this happened in the background.  So get on that, Google engineers.  A pint of Guinness is in it for you next time we’re at the Googleplex.

Read More