BASH: Recursively finding files

Posted by & filed under Linux.

I recently wanted to locate a specific file recursively within my directory tree. A simple way to do this is to:

In this example, we would be searching for a .htaccess file, but this could be changed to any file name, and even use wildcards like *.php.

MySQL: Create a Unique Composite Key

Posted by & filed under Uncategorized.

I had a scenario where I want to ensure that multiple values are unique in a table. Meaning I want to allow this:

But not this:

This is suprisingly easy to use when we implement unique composite keys. For an existing table:

ALTER TABLE TableName ADD UNIQUE KEY (KeyOne, KeyTwo, ...);

Now if a insert is attempted the following error is thrown:

Integrity constraint violation: 1062 Duplicate entry ‘Nathan Riley-4’ for key ‘name’

In yii, we trap this using a custom validator class in components/CompositeUniqueKeyValidator.php:

if (count($keyColumns) == 1) {
throw new CException('CUniqueValidator should be used instead');
$columnsLabels = $object->attributeLabels();

$criteria = new CDbCriteria();
$keyColumnsLabels = array();
foreach ($keyColumns as &$column) {
$column = trim($column);
$criteria->compare($column, $object->$column);
$keyColumnsLabels[] = $columnsLabels[$column];
$criteria->limit = 1;

if ($class::model()->count($criteria)) {
$message = Yii::t('yii', $this->errorMessage, array(
'{columns_labels}' => join(', ', $keyColumnsLabels)
if ($this->addErrorToAllColumns) {
foreach ($keyColumns as $column) {
$this->addError($object, $column, $message);
else {
$this->addError($object, $attribute, $message);



Then in our model’s rules():

public function rules()
return array(
array('name', 'CompositeUniqueKeyValidator', 'keyColumns' => 'name, tournamentId'),

Yii model relationships()

Posted by & filed under Programming.

It’s very common to see new Yii users confusing the relations HAS_ONE and BELONGS_TO, and getting it wrong means you won’t get proper values back. And though we’ll talk about HAS_MANY as well, we’re specifically omitting the MANY_MANY relation because it’s a whole different animal.…

Yii CGridView dropdown for page size

Posted by & filed under Programming.

I found myself in the need for a dropDownList to select the page size on a CGridView. I was amazed that only a few lines of code where required. So i thought i’d share.

On top of my controller action for the gridview (if you used CRUD, this is actionAdmin() ) i added:

// page size drop down changed
if (isset($_GET['pageSize'])) {
unset($_GET['pageSize']); // would interfere with pager and repetitive page size change

In the model (e.g. model/User.php) the data provider in search() is configured like:

return new CActiveDataProvider(get_class($this),array(
'pageSize'=> Yii::app()->user->getState('pageSize',Yii::app()->params['defaultPageSize']),

And finally the view (e.g. views/user/admin.php) :

user->getState('pageSize',Yii::app()->params['defaultPageSize']); ?>

// change 'user-grid' to the actual id of your grid!!
'onchange'=>"$.fn.yiiGridView.update('user-grid',{ data:{pageSize: $(this).val() }})",

Et voilà, we have a page size selector that keeps it’s value in user state.

Forgot to mention the configuration in the application parameters:

// Accessable with Yii::app()->params['paramName']
'params'=>array (


Understanding Yii’s RBAC

Posted by & filed under Programming.

Yii is a very powerful PHP framework, and among other PHP frameworks it is distinguished by its great object-oriented design, MVC support, speed, flexibility and many other virtues. Recently I had some experience with the PRADO framework and chose Yii to build my image processing web application demo. It took some time for my app to stay in my home server sandbox and now it’s matured enough to be revealed to public.……

Yii Fragment Caching

Posted by & filed under Uncategorized.

Fragment caching refers to caching a fragment of a page. For example, if a page displays a summary of yearly sale in a table, we can store this table in cache to eliminate the time needed to generate it for each request.

To use fragment caching, we call CController::beginCache() and CController::endCache() in a controller’s view script. The two methods mark the beginning and the end of the page content that should be cached, respectively. Like data caching, we need an ID to identify the fragment being cached.…

Using Yii’s CArrayDataProvider

Posted by & filed under PHP, Programming.

This snippet shows how to feed the CGridView widget data from the CArrayDataProvider rather from a database model.……

.htaccess Notes

Posted by & filed under Uncategorized.

Quick notes on configuring password auth via .htaccess:

  • Step 1: Create the directory area and set permissions to read the area
  • Step 2: Create a file called .htaccess in the directory you want to protect
    In that file: 

    AuthUserFile /your/directory/here/.htpasswd
    AuthGroupFile /dev/null
    AuthName "Secure Document"
    AuthType Basic
    require valid-user

  • Step 3: Create a file called .htpasswd in the directory as set in the AuthUserFile directive in the .htaccess file
    You create this file by typing in the information below, at the system prompt, in the directory area to be protected: 

    htpasswd -c .htpasswd username

A Practical git guide (git cheatsheet)

Posted by & filed under Uncategorized.

A practical git guide

Notes extracted from git screencast at

identify yourself to git: email and your name

git config --global "David Beckwith"

git config --global ""

To view all options:

git config --list


cat .git/config
Set up aliases

git config --global checkout

View your configuration

cat .gitconfig
To ignore whitespace (Ruby is whitespace insensitive)

git config --global apply.whitespace nowarn

Some nice aliases:

gb = git branch
gba = git branch -a
gc = git commit -v
gd = git diff | mate
gl = git pull
gp = git push
gst = git status

Start using git

git init
Ignoring files

Add a file in the root directory called .gitignore and add some files to it: (comments begin with hash)
*.log db/schema.rb db/schema.sql

Git automatically ignores empty directories. If you want to have a log/ directory, but want to ignore all the files in it, add the following lines to the root .gitignore: (lines beginning with ‘!’ are exceptions)


Then add an empty .gitignore in the empty directory:

touch log/.gitignore
Scheduling the addition of all files to the next commit

git add .
Checking the status of your repository

git status
Committing files

git commit -m "First import"
Seeing what files have been committed

git ls-files
Scheduling deletion of a file

git rm [file name]
Committing all changes in a repository

git commit -a

Scheduling the addition of an individual file to the next commit
git add [file name]

Viewing the difference as you commit

git commit -v
Commit and type the message on the command line

git commit -m "This is the message describing the commit"
Commit and automatically get any other changes

git commit -a
A “normal” commit command

git commit -a -v
Viewing a log of your commits

git log
Viewing a log of your commits with a graph to show the changes

git log --stat
Viewing a log with pagination

git log -v
Visualizing git changes

gitk --all
Creating a new tag and pushing it to the remote branch

git tag "v1.3"
git push --tags

Creating a new branch

git branch [name of your new branch]
Pushing the branch to a remote repository

git push origin [new-remote]
Pulling a new branch from a remote repository

git fetch origin [remote-branch]:[new-local-branch]
Viewing branches

git branch
Viewing a list of all existing branches

git branch -a
Switching to another branch

The state of your file system will change after executing this command.

git checkout [name of the branch you want to switch to]


git co [name of the branch you want to switch to]
Making sure changes on master appear in your branch

git rebase master
Merging a branch back into the master branch

First, switch back to the master branch:

git co master

Check to see what changes you’re about to merge together, compare the two branches:

git diff master xyz

If you’re in a branch that’s not the xyz branch and want to merge the xyz branch into it:

git merge xyz
Reverting changes to before said merge

git reset --hard ORIG_HEAD
Resolving conflicts

Remove the markings, add the file, then commit.
Creating a branch (and switching to the new branch) in one line

git checkout -b [name of new branch]
Creating a stash (like a clipboard) of changes to allow you to switch branches without committing

git stash save "Put a message here to remind you of what you're saving to the clipboard"
Switching from the current branch to another

git co [branch you want to switch to]

Do whatever
Then switch back to the stashed branch

git co [the stashed branch]
Viewing a list of stashes

git stash list
Loading back the stash

git stash apply

Now you can continue to work where you were previously.
Deleting a branch (that has been merged back at some point)

git branch -d [name of branch you want to delete]
Deleting an unmerged branch

git branch -D [name of branch you want to delete]
Deleting a stash

git stash clear
Setting up a repository for use on a remote server

Copy up your repository. e.g.:

scp -r my_project

Move your files on the remote server to /var/git/my_project
For security make the owner of this project git
On the repository server:

sudo chown -R git:git my_project

Then (for security) restrict the “deploy” user to doing git-related things in /etc/passwd with a git-shell.
Checking out a git repository from a remote to your local storage
git clone
Viewing extra info about a remote repository

cat .git/config

By virtue of having cloned the remote repository, your local repository becomes the slave and will track and synchronize with the remote master branch.
Updating a local branch from the remote server

git pull
Downloading a copy of an entire repository (e.g. laptop) without merging into your local branch

git fetch laptop
Merging two local branches (ie. your local xyz branch with your local master branch) USE MERGE

git merge laptop/xyz

This merged the (already copied laptop repository’s xyz branch) with the current branch you’re sitting in.
Viewing metadata about a remote repository

git remote show laptop
Pushing a committed local change from one local branch to another remote branch

git push laptop xyz
Creating a tracking branch (i.e. to link a local branch to a remote branch)

git branch --track local_branch remote_branch

You do not need to specify the local branch if you are already sitting in it.

git pull

Note: You can track(link) different local branches to different remote machines. For example, you can track your friend’s “upgrade” branch with your “bobs_upgrade” branch, and simultaneously you can track the origin’s “master” branch (of your main webserver) with your local “master” branch.

By convention, ‘origin’ is the local name given to the remote centralized server which is the way SVN is usually set up on a remote server.
Seeing which local branches are tracking a remote branch

git remote show origin
Working with a remote Subversion repository (but with git locally)

git-svn clone [http location of an svn repository]

Now you can work with the checked out directory as though it was a git repository. (cuz it is)
Pushing (committing) changes to a remote Subversion repository

git-svn dcommit
Updating a local git repository from a remote Subversion repository

git-svn rebase

NOTE: make sure you have your perl bindings to your local svn installation.
I screwed up, how do I reset my checkout?

git checkout -f