Archive for category Programming
Simple Logging Utility Class for Symfony
Posted by PhazeonPhoenix in Symfony on July 10th, 2009
Here’s a little gem I’ve been using for quite some time. Sometimes during your development process you simply want to see the contents of a variable while it’s being used or want to know when a certain bit of code is firing. In my PHP programming infancy I would simply dump such data on screen with functions like echo and print_r. This was an ugly and brutish way of doing it.
Since one of the nice features Symfony sports is it’s logging features, I started dumping such data to the log. I quickly found out that depending on what part of the code I was working on, the syntax of my logging was different and became quite cumbersome in some cases.
In comes the following class, the Logging class, or L class for short. It simplifies logging and dumping a variable to the log. I also found it helpful when I was first learning Symfony to know what methods a class had. I’ve also included that function as well.
Here are some examples:
L::log('Something happened.'); $array = array('1', '2', 'Tom' => 'Jones', 'Richard' => 'Smith', 'Harrold' => 'Jackson'); L::dump($array, 'Example Array', 'info'); $config = new sfConfig(); L::methods($config);
Output:
Jul DD HH:MM:SS symfony [debug] *********************** * Something happened. * *********************** Jul DD HH:MM:SS symfony [info] ******************************* * Variable Dump Example Array * ******************************* array ( 0 => '1', 1 => '2', 'Tom' => 'Jones', 'Richard' => 'Smith', 'Harrold' => 'Jackson', ) Jul DD HH:MM:SS symfony [debug] ************************ * Methods for sfConfig * ************************ sfConfig::get sfConfig::has sfConfig::set sfConfig::add sfConfig::getAll sfConfig::clear
Here is the code. Simply drop it into a file in your project’s lib directory (I placed it into a util subdirectory) and clear your cache to start using it.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 | <?php /** * Pretty Simple Logger * * @package util * @author Phazeon Phoenix <phoenix@phazeon.com> * @copyright 2009 Phazeon.com * @version 1 */ class L { static public $allowedMessageLevels = array('notice', 'emerg', 'alert', 'crit', 'info', 'debug', 'err', 'warning'); /** * Log a message. * * @param mixed $message * @param string $level * @param boolean $pretty Does not add the star header if false. * @return void */ static public function log($message, $level = 'debug', $pretty = true) { if (sfConfig::get('sf_logging_enabled')) { if ( ! in_array($level, self::$allowedMessageLevels)) $level = 'debug'; if ($pretty) $output = self::prettyHeader($message); else $output = $message; sfContext::getInstance()->getLogger()->$level($output); } } /** * Dump a variable to the log. * * Known Limitation: Variables that are too large, such as many of the * Symfony core classes, will cause this function to fail. This is a * limitation of var_export(). If you need to dump such a variable, use * print_r(). It's ugly but it'll work no matter how large the variable is. * * @param mixed $var * @param mixed $message * @param string $level * @return void */ static public function dump($var, $message = null, $level = 'debug') { if (sfConfig::get('sf_logging_enabled')) { $output = self::prettyHeader("Variable Dump $message"); $output .= var_export($var, true); L::log($output, $level, false); } } /** * Output all publicly accessable methods of a class. * * @param mixed $class * @param mixed $message * @param string $level * @return void */ static public function methods($class, $message = null, $level = 'debug') { if (sfConfig::get('sf_logging_enabled')) { $class = get_class($class); $output = self::prettyHeader("Methods for $class $message"); $methods = get_class_methods($class); foreach($methods as $method) { $output .= "$class::$method\n"; } L::log($output, $level, false); } } /** * Build a string padded and surrounded by stars. * * @param mixed $text * @return string */ static public function prettyHeader($text) { $stars = ''; $text = "* " . trim($text) . " *"; $stars = str_repeat('*', strlen($text)); return "\n" . $stars . "\n" . $text . "\n" . $stars . "\n"; } } |
Symfony Template and Component Templates
Posted by PhazeonPhoenix in Symfony on July 6th, 2009
Today I’ve got a pair of small templates.
The first is a comment header for the Symfony template files. Due to the shear number of these template files you can create if you’re partial and component happy, sometimes just the filename isn’t enough to really describe what file your editing. My motto is you can never have too much documentation.
1 2 3 4 5 6 7 8 9 10 11 | <?php /** * Template Template * * @author Phazeon Phoenix <phoenix@phazeon.com> * @version 1 * @package Templates * @copyright 2009 Phazeon.com */ ?> <h2>My Template</h2> |
Next is a template for new components. This is the sort of thing that I always had trouble remembering. I had to track down the exact syntax for the component class declaration each time. Now in my IDE (phpDesigner) I can define user entered variables in my snippets/templates. It prompts me for the model name and the method name minus the “execute” prefix.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | <?php /** * Component Template * * @author Phazeon Phoenix <phoenix@phazeon.com> * @version 1 * @package Components * @copyright 2009 Phazeon.com */ class templateComponents extends sfComponents { public function executeSomething() { } } |
Symfony 1.1+ Form Template
Posted by PhazeonPhoenix in Symfony on July 4th, 2009
In my work with Symfony I’ve started collecting a library of code snippets that I use to speed up my creation of different objects in the Symfony tree. Since most of them are cut and splices of other people’s code (especially the Symfony documentation) I’m going to start posting some of the better ones on my blog.
The one that I’m going to share today involves the creation of a form class for the new form handling classes added in Symfony 1.1. I found myself constantly having to go back to the form and adding the sections that I needed but forgot the list time I was working it. I created this template and included all of the options I felt I’d need to declare to correctly implement a nice looking and behaving form.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | <?php /** * Template Form * * @author Phazeon Phoenix <phoenix@phazeon.com> * @version 1 * @copyright 2009 Phazeon.com * @package Forms */ class templateForm extends sfForm { public function configure() { $this->setWidgets(array( )); $this->setValidators(array( )); $this->setDefaults(array( )); $this->widgetSchema->setLabels(array( )); $this->widgetSchema->setFormFormatterName('list'); $this->widgetSchema->setNameFormat('template[%s]'); } } |
New Symfony Project Woes
Posted by PhazeonPhoenix in Symfony on June 16th, 2009
Generating a new Symfony framework project is as simple as a single command. But as with many things it rarely works the way you want out of the box. I’ve documented every step and every command that I end up running on a new project to ensure that it behaves the way it should and I ended up with a 30 point list! I have to initialize the project, modify several files to enable things such as the Doctrine ORM plugin, install several plugins such as the sfDoctrineGuard authentication plugin, SVN version control taking careful steps to avoid placing the cache, logs, and the base model classes under revision, and set up my development environment for the new project.
I need to work on a way to automate as much as I can of the process. The tricky thing is that certain commands need to be executed as root (inlcuding rebooting the web server) and that throws a monkey wrench in the gears of that idea. Certainly one could create a script and SUID root, but that is going to require extensive care to ensure that the process is handled gracefully if it fails for whatever reason. It’s a large undertaking to say the least. I guess I have to weigh the time spent each new project vs. coding such a script.
Data Weaving
Posted by PhazeonPhoenix in Programming on June 13th, 2009
Today I am working diligently on a new project. I was busily moving textual data from various applications I use in my development and into an excel spreadsheet for quick reference later. From three different files opened in two different (and both very large) applications and Excel 2007 all at the same time. If computers were ever revolt mine’s going to go straight for the jugular.
Then after I finished building the table in Excel I realized I had to create multiple (24 to be exact) template files for all the pages this new project required. I didn’t feel like typing the command out (I used touch on my Linux devel box) so I copied the text I needed for the base of the file name, tacked on the remainder of the file name and removed the carriage returns with a quick recorded macro in UltraEdit 32, and pasted it into my shell window. BAM!
OK for most of you that will probably be complete gibberish. And that’s OK. It just suddenly dawned on me what exactly I was doing to accomplish my goal. Such a contrived, inefficient but effective way of doing it. Also as suddenly, the phrase “Data Weaving” popped into mind.
Setting up Subversion and Trac on CentOS 5
Posted by PhazeonPhoenix in Programming on June 12th, 2009
I stumbled upon this article and I must say it’s a great guide for getting both of these applications up and running correctly. I now use a slightly modified process to create new projects on my dev server. This in conjunction with a quick and dirty WordPress blog installed on my dev server’s root for posting links to the various parts of my new project and it’s an impromptu development environment!
Also on a side note, I switched away from Gentoo to CentOS for my dev server. Not that I do not enjoy Gentoo (I’m a geek, give it a break) but I needed a turn-key enviroment for development. So far I’ve been satisfied with CentOS. Since it’s based on Red Hat Enterprise Linux it’s solid as a rock and help is easy to find.
actAs: Accountable Doctrine Behaviour
Posted by PhazeonPhoenix in Symfony on June 8th, 2009
It was fairly easy to create a Signable behaviour and it was done within a couple days. I soon realized though that the behavior of the SoftDelete behaviour wasn’t quite what I wanted. It only adds a “deleted” boolean field to the DB. I also wanted to know who deleted it and what time it was deleted. I decided to expand SoftDelete and make it use a timestamp instead of a boolean. That part worked too.
The problem I soon ran into was with when I combined SoftDelete and Signable with it’s new preDelete hook. Seems since SoftDelete stops the preDelete event it doesn’t let the Signable code execute properly. I decided that the correct answer to the problem was to create a whole new behaviour which would combine not only SoftDelete and Signable but also Timestampable. I called it Accountable since it’s primary function is to keep record of who touched an object.
I did a manual test and so far it’s worked as planned. I’m not yet sure of the SoftDelete filters… I made a change to preDqlDelete and preDqlSelect and I’m not quite sure if it still works. Time will tell I’m sure. Once I’m more certain this code is solid I’ll give more information on it.
Doctrine Behaviours
Posted by PhazeonPhoenix in Symfony on June 6th, 2009
I’m finding that I need to write a couple behaviors that for some reason are not in the default distribution. The features I’m needing in particular are “Signable” to add created_by, updated_by and deleted_by to each table, and “Commentable” to handle the comments that you’re going to be able to post on almost every single object.
Thankfully the best way for me to learn is to find an example. I’m going to modify the code for “Timestampable” for “Signable” and I think I’m going to look at csDoctrineActAsAttachablePlugin for how it behaves and build from it to make “Commentable”. I might even release it to the community.
Doctrine Behaviours are fairly new to me but I understand what’s going on for sure. Behaviours allow you to modularize your reusable database code. In my examples, I need to be able to keep track of who created, updated, and/or deleted an item. Instead of adding that bit of code to each model by hand, I can cut it out and make a Behaviour that I then attach to each model.
Database Schema and Doctrine Model planning
Posted by PhazeonPhoenix in Symfony on June 3rd, 2009
Today I did some major database planning for a major project I’m working on and it’s quite an interesting process. You have to take such a large concept as every bit of information your application might need to store and slicing that into smaller pieces to create the tables and models needed to access and process them.
I’m finding the best way to plan them out is to grab a piece of paper and something to write with and start scribbling. Maybe it is low tech but whatever works you know. I found myself creating what could have easily have been a flow chart spanning several pages. I started in one small area and quickly expanded to other less obvious and obscure tables I’d need. All while relaxing on my bed.
I started writing my schema file. This being my first real application of the Doctrine ORM it was a bit slow going. The syntax for the schema.yml is a bit new to me. It took me a couple tries to get the correct relationships to form exactly the way I wanted. But so far so good.
Adding Google Analytics to your Wordpress Blog
Posted by PhazeonPhoenix in Wordpress on June 1st, 2009

My friend Ryan over at GoldenComm Posted a nice article about adding Google Analytics to your Wordpress Blog. While his method works just fine, not everyone is comfortible editing the raw files in your Wordpress Theme.
There is a plugin that you can install located here that can do this for you. After installing the plugin you’ll see “Google Analytics” under ”Plugins” like in the image on the right. The plugin is pretty self explanitory, you simply paste your in the appropiate field and hit Update Settings. The important thing to remember if you are using any form of Wordpress Caching you will have to clear your Cache before the plugin can take effect.
