Remember when Subversion was the new tool that all the cool kids were flocking to? Well, Subversion is now the old and busted, and it’s time to move to Git.
It’s time to upgrade your Subversion repo (if your still using it) to Git because of the benefits you will gain from moving to a more flexible tool.
I could go on, but those are the big ones for me. Note: I’m not against other DVCS systems like Mercurial, Bazaar, but I chose Git because of it’s popularity and ability to handle the Linux kernel.
Read MoreI needed to write a simple web app to automatically cache a password protected tumblr admin account, so I wrote simple symfony app to do it. It was pretty simple to do because I could leverage the sfWebBrowserPlugin which provides most of the heavy work for simulating a browser and logging into the site.
While this project is setup to cache tumblr, you can easily modify it to cache any website. It’s built in PHP on the symfony framework.
Configure it by changing the apps/frontend/config/app.yml file to add in the blog name, email, and password, with these config parameters: app_tumblr_blog_name, app_tumblr_email, app_tumblr_password
To cache a page, run it via command line:
./symfony tumblr:cache
Source is on github: Cache Tumblr Admin
Read MoreI find it curious that WordPress, one of the biggest and best blogging platforms currently around does not come default with a caching plugin. I think the WordPress developers should either include one of the excellent WordPress caching plugins, or build their own and then enable it by default. Users and blog hosts worldwide would have better page load performance and improved scalability.
This blog is build with WordPress, and in my first year of blogging, one of my posts received a lot of hits. Unfortunately, the default WordPress install I had setup wasn’t able to cope with the demand effectively. It was taking 2-5 seconds for visitors to load a page. That’s unreasonable for a simple blog and I’m sure I lost a lot of visitors because of it. So I looked into ways to make my blog load faster without paying extra for better hosting hardware. That’s when I found an excellent caching plugin called Hyper Cache.
With Hyper Cache, I made my blog page load from 2-5 seconds under heavy load, to down to less than a second, under load the same load. The HTML itself only takes about 230ms to download, down from 4000ms, allowing the other resources to start downloading in a paralleled fashion much earlier. How is this possible? Well a caching mechanism works like this: The first time a page is requested, it will render it as normal, but what’s different is that it will save the rendered page in a special cache file. Then, subsequent visitors simply get handed this same cache file immediately, without much PHP processing required. It’s like skipping to the front of the line.
So we can see a cache has a huge effect on performance, and made a big difference to my blog, but what other benefits are there?
In my opinion, well worth it. So WordPress team, please?
Read MoreThe best way to sanitize any input from your user is to use the HTML Purifier library. HTML Purifier will remove any XSS from your code, produce valid HTML, and generally make you sleep just a bit safer at night. It doesn’t completely sanitize user input, and you still need to be careful with it before using it anywhere (such as an SQL statement), but it will remove all XSS attacks against your website.
Here’s a simple example of how to use it:
$purifier = new HTMLPurifier(); $purifier->purify($user_string);Read More
The Yii Framework is very flexible and has a variety of way you can configure it. Here I will show you how you can customize parameters on a Command task.
The default Yii Migration command asks the user for a confirmation before running if there are any tables that have been changed, this is quite a sensible default, but I don’t want to be asked if the command should be run after a deployment. Of course it should be.
To see what options can be configured, open the Migrations file
vendors/framework/cli/commands/MigrateCommand.php
Any of the public class variables can be configured in your config/console.php file. Using the commandMap parameter, you can configure values for Yii Commands. Then specify the migrate task, and then the config values you want to change. In this case, I want to change interactive to false, so it won’t ask for a confirmation.
Sample config/console.php:
return array(
...
// database migration, don't ask for confirmation
'commandMap'=>array(
'migrate'=>array(
'class'=>'system.cli.commands.MigrateCommand',
'interactive'=>false,
),
),
);
Read More
Often times you want to be able to specify configuration parameters or settings that only apply to a single environment. These local configuration don’t need to, and shouldn’t be entered into version control, and should over ride default values. I needed a solution for a project I was working on so I wrote one for Yii.
The main configuration file protected/config/main.php returns an array of parameters. Edit this file to merge 2 arrays, 1 from main.php, and another from local.php.
Edit main.php to look like this:
<?php
return CMap::mergeArray(
array(
'basePath'=>dirname(__FILE__).DIRECTORY_SEPARATOR.'..',
'name'=>'Web app',
... other parameters ...
'params'=>array(
// this is used in contact page
'adminEmail'=>'[email protected]',
),
),
local_config()
);
// return an array of custom local configuration settings
function local_config()
{
if (file_exists(dirname(__FILE__).'/local.php'))
{
return require_once(dirname(__FILE__).'/local.php');
}
return array();
};
And then add any of your own configuration to local.php in the same config directory.
<?php
return array(
'components'=>array(
'db'=>array(
'connectionString' => 'mysql:host=localhost;dbname=db_name',
'username' => 'my_user',
'password' => 'secret',
'enableParamLogging'=>true,
),
'log'=>array(
'class'=>'CLogRouter',
'routes'=>array(
'file'=>array(
'class'=>'CFileLogRoute',
'levels'=>'trace, info, error, warning',
),
'profile'=>array(
'class'=>'CProfileLogRoute',
'report'=>'summary',
),
),
),
),
'params'=>array(
// this is used in contact page
'adminEmail'=>'[email protected]',
),
);
Here we’ve overridden the adminEmail parameter to [email protected], we’ve added in custom database username and password, and we’ve enabled logging.
Feel free to use this as a straightforward way to add custom config values to your Yii project. Just remember to make local.php an ignored file in Git or Subversion.
Read MoreMy last post explained the basics on how to add static pages in symfony, this post expands on that and shows you how to do it for a multilingual site.
We split the template finding code out for code maintainability, and we enhance it on where to look for the file. First it tries to find the template in the language and country eg: en_CA, then it tries to find the template in the matching language, and if that is not found, it falls back to the default language.
/**
* Load a static page.
* @param sfRequest $request A request object
*/
public function executePage(sfWebRequest $request)
{
$template = $this->findTemplate($request->getParameter('view'), $this->getUser()->getCulture());
$this->forward404Unless($template);
$this->setTemplate($template);
}
/**
* Check if a template page exists for a given culture.
* Be intelligent and check if language & country exist, try language, and then default to english.
* @param string $name Template filename to check
* @param string $culture Symfony culture string
*/
protected function findTemplate($name, $culture)
{
// for safety, strip out all non-alphanumeric characters
$name = preg_replace('/[^a-zA-Z0-9\s]/', '', $name);
$directory = $this->getContext()->getModuleDirectory() . DIRECTORY_SEPARATOR ."templates";
// try language and country: en_CA
if (is_readable($directory . DIRECTORY_SEPARATOR . $culture. DIRECTORY_SEPARATOR . $name ."Success.php"))
{
return $culture. DIRECTORY_SEPARATOR . $name;
}
// try langage only: en
elseif (is_readable($directory . DIRECTORY_SEPARATOR . substr($culture, 0, 2). DIRECTORY_SEPARATOR . $name ."Success.php"))
{
return substr($culture, 0, 2). DIRECTORY_SEPARATOR . $name;
}
// try default language
elseif (is_readable($directory . DIRECTORY_SEPARATOR . $name ."Success.php"))
{
return $name;
}
return false;
}
The template directory should have the default language file as usual, eg: templates/helpSuccess.php, and then there should be folders for each language and possibly language & country with the same filename, but localized. eg: templates/fr/helpSuccess.php
Read More