SUBSCRIBE VIA RSS


Subscribe to our feed

Symfony Experts

Symfony Experts
If you have an urgent question for a symfony-related issue, this is the place to ask.

Topics

Stack Overflow


The old fashioned way

RECENT TUNES

  Archive for June, 2007

June 22, 2007 – 2:18pm OS X Tip of the Day: Drag applications to the finder toolbar

If you want easy access to your commonly used applications, here is a tip that will save you some time. Drag an application icon up to your finder tool bar to create little shortcut icons in every window. You can click these icons to open the application, or better yet, drag files onto them to open those files with that application.

I use this feature with TextMate to open up new projects on the fly, and with Preview to get a quick look at documents that otherwise would open up in Photoshop of Fireworks.

finder toolbar shortcut

Posted by in  OS X   |  1 Comment »

June 18, 2007 – 12:15pm Linking between Apps within Symfony

There has been some recent discussion on the symfony mailing list about cross-linking between apps within the same project. I have managed to avoid having to use complex routing rules and instead have gotten away with adding absolute URLS to my app’s settings.yml file, and then using these addresses within my templates.

First, add appropriate URLs in the project’s config/app.yml file. As there are different settings used depending on the environment, you can put the full URL here and have it automatically use the right setting.

prod:
  url:
   frontend:  http://public.mysymfonyapp.com
    backend:   http://private.mysymfonyapp.com
dev:
  url:
   frontend:  http://myappdev/frontend.php
   backend:  http://myappdev/backend.php

Then, in your template, whenever you need to link to the other app, use these settings:

<?php echo link_to('Admin Site', sfConfig::get('app_url_backend')) ?>
or
<?php echo link_to('Public Site', sfConfig::get('app_url_frontend')) ?>
Posted by in  Web Development   |     |  4 Comments »

June 17, 2007 – 10:21pm Symfony Resources

Even after working with Symfony for over a year, we still have to refer back to various resources to help us along the way. This is a list of useful resources for a symfony developer, including links to the sometimes hard to find Creole API, Propel API, and Propel docs.

Posted by in  Web Development   |     |  Comments Off on Symfony Resources

June 13, 2007 – 2:15pm svn export and zip

Sometimes it’s necessary to make a copy of a project stored in an SVN repository. If you just copy the directory manually, you will also be copying those sneaky .svn files that exist in every directory in the project. Instead you should use the svn export command. This will make a new copy of all of the files in the respository than you can zip up and send off to whomever you please.

svn export file:///path/to/your/repository my_export

If you want to zip this baby up:

zip -r my_export.zip my_export

If you wanted to get really creative, and tag this export as a release, you could something like this:

svn copy file:///path/to/repos/trunk file:///path/to/repos/tags/1.0release -m "tagging version 1.0 release"
svn export file:///path/to/repos/tags/1.0release 1.0release
# for a zip:
zip -r 1.0release.zip 1.0release/
# for a tgz
tar -czvf 1.0release.tgz 1.0release.zip/*

References:

  • http://svnbook.red-bean.com/en/1.1/re10.html
Posted by in  Web Development   |     |  4 Comments »

June 12, 2007 – 4:12pm Symfony exceptions, logging, and debugging

Since I always forget, here is a quick reference for throwing exceptions and adding log/debug messages throughout your symfony project.

Exceptions
This is how you can throw a new symfony exception.

throw new sfException('An error occurred. Please go back and try again.');

Logging

Within an action, this is how you can log a message:

<?php use_helper('Debug') ?>
<?php if ($problem): ?>
  <?php echo log_message('{mainActions} been there', 'err') ?>
<?php endif ?>

And elsewhere within the code (model, etc):

sfContext::getInstance()->getLogger()->info($message);
sfContext::getInstance()->getLogger()->err($message);

Debugging

// in an action
$this->debugMessage($message);
// in a template
<?php echo debug_message($message) ?>

Reference: Symfony Docs: Debugging

Posted by in  Web Development   |     |  4 Comments »

June 12, 2007 – 12:06pm Propel Queries using Custom SQL, Peer Classes, and Criterion Objects

Propel provides many ways to generate queries. Here are a few of the more common methods.

Perhaps the easiest way for newcomers to Propel are custom queries written using standard SQL.

$con = Propel::getConnection(DATABASE_NAME);
$sql = "SELECT books.* FROM books 
    WHERE NOT EXISTS (SELECT id FROM review WHERE book_id = book.id)";
$stmt = $con->createStatement();
$rs = $stmt->executeQuery($sql, ResultSet::FETCHMODE_NUM);
$books = BookPeer::populateObjects($rs);

Another method would be to use the peer class to gain some more flexibility in case down the line you decide to change your column names. For this we will use the PrepareStatement() method. This example also returns specific data from the query rather than entire propel objects.

public function getTotals($banner_id = NULL, $letter = NULL) {
	$con = Propel::getConnection();
 
	$sql = "SELECT SUM(".LetterBannerPeer::VIEWS.") AS view_total,
		SUM(".LetterBannerPeer::CLICKS.") AS click_total
		FROM ".LetterBannerPeer::TABLE_NAME."
		WHERE ".LetterBannerPeer::LETTER." = ?
		AND ".LetterBannerPeer::REGION_ID." = ?
		GROUP BY (".LetterBannerPeer::LETTER.")";
 
	$stmt = $con->PrepareStatement($sql);
	$stmt->setString(1, $letter);
	$stmt->setInt(2, REGION_ID);
 
	$rs = $stmt->executeQuery();
	while ($rs->next()) {
		$totals['views'] = $rs->getInt('view_total');
		$totals['clicks'] = $rs->getInt('click_total');
	}
	return $totals;
}

Notice how anytime you want to insert actual values into the query, you put in a ? (question mark) as a place holder which is then automatically escaped for the query by calling the $stmt->setString($position, $value) function.

For our third example we will use the Criterion Object. This function returns a propel object.

public static function getResponseTypes($message_type_id)
{
	$c = new Criteria();
	$c->addJoin(MessageTypePeer::ID, 
		MessageTypeResponsePeer::RESPONSE_TYPE_ID, Criteria::LEFT_JOIN);
	// think of a Criterion object as one 'XX=YY' within the WHERE clause
	$cton1 = $c->getNewCriterion(
		MessageTypeResponsePeer::MESSAGE_TYPE_ID, $message_type_id
	);
	$cton2 = $c->getNewCriterion(
		MessageTypePeer::NAME, 'general'
	);
	$cton1->addOr($cton2);  // combine them into one (XX=YY OR AA=BB) clause
	$c->add($cton1); 		// add to Criteria
 
	return MessageTypePeer::doSelect($c);
}

The Criteria object provides some other useful functions for generating queries. This is a great example of how to use addAsColumn(), addGroupByColumn(), and addDescendingOrderByColumn().

$c = new Criteria();
$c->addJoin(BookPeer::ID, FavoriteBookPeer::BOOK_ID, Criteria::LEFT_JOIN);
$c->addAsColumn('cnt', 'COUNT('.FavoriteBookPeer::BOOK_ID.')');
$c->addGroupByColumn(BookPeer::ID);
$c->addDescendingOrderByColumn('cnt');
$book = BookPeer::doSelect($c);

If you want to use a criteria object but only select certain columns, you can do something like this:

$c = new Criteria();
$c->clearSelectColumns()
$c->addSelectColumn(self::PAYABLE_TO);
$c->add(self::ID, $id);
 
$rs = self::doSelectRS($c);
$payable_to = false;
if ($rs->next()) {
  $payable_to = $rs->getInt(1);
}

If you want to do a subselect, you can use Criteria::CUSTOM.

$c = new Criteria();
$subSelect = "users.user_type_id IN (
    SELECT
          user_type.ID
    FROM
          user_type
    WHERE
         user_type.name = 'public'
    )";
$c->add(UserPeer::USER_TYPE_ID, $subSelect, Criteria::CUSTOM);
$publicUsers = UserPeer::doSelect($c);

You of course could rewrite that query using JOINS if you thought that was too messy.

This custom criterion type is also useful when you want to compare two fields from the same table.

$c = new Criteria();
$c->add(MyTablePeer::COL1, MyTablePeer::COL1.'>='.MyTablePeer::COL2, Criteria::CUSTOM);

Take a look at snippets 75 and 53 for more information.

June 11, 2007 – 5:26pm Safari 3 Beta out for OS X / Windows – Crashes Unexpectedly

With claims that it is up to 1.6 times faster than Firefox 2 I thought I would give the new Safari 3 beta a run-around. Turns out it gave me the run-around as first it required a restart after installation and then would unexpectedly quit every time I tried to open it. Our advice: wait until it becomes more stable–at least enough to open it–before you download it.

This was on a Powerbook G4 1.5 GHz running 10.4.9 and 2 GB of RAM

Posted by in  OS X   |  Comments Off on Safari 3 Beta out for OS X / Windows – Crashes Unexpectedly

June 10, 2007 – 11:53pm Turn off php magic_quotes_gpc within .htaccess or php.ini

A lot of shared hosts will have magic quotes turned on by default. This can create some extra overhead depending on your application. Symfony apps prefer to have this turned off. Here’s how you can do it using either an .htaccess or php.ini file in your web root directory.

#.htaccess
php_flag magic_quotes_gpc off
 
# php.ini
magic_quotes_gpc=off
</code>
Posted by in  Web Development   |     |  2 Comments »

June 10, 2007 – 3:59pm Rsync to the rescue: Copying files from server to server

We recently had to move a client’s web site to a new host. There is about 600 MB of images, video clips, and other files that we needed to transfer between hosts. Rather than FTP the files down from the old host and then re-copy them up to the new host, we used rsync to copy the files directly between the two hosts. To do this, you need shell access to both servers.

Login to the new host. Then at the shell prompt use the following command:

 rsync -avc -e ssh [user]@[oldhost]:[path] [new path]

The -avc flags are for archive mode (recursive), verbose, and checksum. -e is to specify the remote shell.

Posted by in  Web Development   |  2 Comments »