Archive for July, 2009

An old Firefox trick with a Windows 7 twist.

I’ll come right out and say it.  I never would have thought I would have been excited about an OS release (again) but I am starting to like it. So many things I used to use third party programs for are now built into Windows 7 and they did a decent job too.While I could fill several posts about the tricks I’ve found (and I probably will in the near future) this particular post is about a trick I just figured out how to do.

The new task bar in Windows 7 functions very similar to OS X's Dock Bar

The new task bar in Windows 7 functions very similar to OS X's Dock Bar

A quick description of the windows 7 feature I’m talking about, In windows 7 you have the ability to ‘Pin’ applications to the task bar.  In all honesty, it feels very similar to the Mac OS X dock bar. The ‘Pinned Application’ becomes the task bar entry while the program is running and remains once the application has ended. It doesn’t do any nifty scaling of the application’s Icon, but it is none the less effective.

Windows 7 Task Bar Multiple Windows + 'peek'

Windows 7 Task Bar Multiple Windows + 'peek'

Also very important to my article is the changes to the Windows Grouping feature as it was called in Windows XP. They’re now called Combined Taskbar buttons. As you can see from the screenshot to the right, multiple windows appear as layered icons in the task bar, and when you hover your mouse over this group of icons you’ll be able to see the contents of those windows if you have Aero Peek enabled.

As you can tell from my screenshots that I use Firefox as my primary browser (and I use Pidgin and FooBar 2000 but that’s neither here nor there) and it’s a great browser for many reasons I don’t need to expand on here. If you’re not using it, you don’t know what you’re missing! get it here!

I tend to have several separate Firefox profiles depending on what I’m going to be doing at the time. I have my normal day-to-day browsing profile, my Web Developer profile (You don’t want to try and casually browse with some of the more advanced dev plugins installed, odd things happen) and a clean profile with no addons.  If you’re not familiar with Firefox profiles please read this article. The one missing tidbit of information from that article is if you add -no-remote to the command arguments, you can run multiple copies of Firefox, each using a different profile to store it’s data.

None of this is news. It’s been written, blogged, twittered, stumbled, shared, and posted about.  I’ve always launched my devel environment with the -no-remote argument and my normal one with out it. The problem I ran into was Windows 7 (and Windows XP) would group all Firefox windows together on the same taskbar button. I usually turned off window grouping to combat this problem in XP.  I’ve grown quite fond of Windows 7’s way of handling Combined Taskbar entries and I wanted to find a way to have one taskbar entry for each profile I was running. Thankfully I found out how!

Firefox Development Shortcut Information

Firefox Development Shortcut Information

Two Firefox instances with multiple windows appear as two "stacks" of task bar entries.

Two Firefox instances with multiple windows appear as two "stacks" of task bar entries. Warning: large image.

The Solution turned out to be as simple as creating a copy of the Firefox installation in my Program Files directory.  When creating the shortcut that launches the second profile as described in the article above, use the copy of Firefox as the target Application. I went as far as to rename the shortcut and add a custom icon to it. See my example on the right. After creating the shortcut, execute the shortcut. If you did it right, it will create a new taskbar entry with the name and icon you specified in the shortcut. You then have to right click on the taskbar entry and select “Pin this program to Taskbar”.

There are a few little side notes. You don’t have to keep the original shortcut around. The process of pinning to the task bar actually creates a copy of the shortcut used to launch the program into C:\Users\<user>\AppData\Roaming\Microsoft\Internet Explorer\Quick Launch\User Pinned\TaskBar and you can delete the one you created initially. I’d also recommend disabling Firefox’s Default Browser check. Make sure one of your installations is configured to be default, not the other or else Firefox will ask you each time. Finally, changing the icon of the shortcut does not change the icon of the Firefox window itself, as indicated by the red arrow on the image to the left.  It will only change the icon on the task bar as indicated by the green arrow.

, , , , , ,

1 Comment

Simple Logging Utility Class for Symfony

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";
    }
}

, , ,

No Comments

Symfony Template and Component Templates

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()
    {
 
    }
}

, , , , ,

No Comments

Symfony 1.1+ Form Template

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]');
    }
}

, , , , ,

1 Comment