Posts tagged with “”

CakePHP: Watch Out for the compact() Function

Okay, so maybe this caveat isn’t specific to CakePHP since the function is a native PHP function, but I just spent the past hour trying to figure out why variables that I clearly set in my controller weren’t available to my view. I’ll never get that hour back, but maybe I can keep someone else from losing it. As far as I’ve been able to tell, this particular behavior isn’t documented, but I haven’t done any kind of exhaustive search.

The compact() function exists as a shorthand function to create an array of variables. The PHP documentation does a nice job of detailing the function and providing a few simple examples, so I won’t belabor that point. Within CakePHP, it’s a handy shortcut for passing variables from a controller to a view. In my case, I have a vendor application form with a few variances that I need to manage. Without using compact(), a snippet from the action method of my VendorsController would look like this:

public function index() {
   …
   $vendor_type      = ‘Food’;
   $application_type = ‘Commercial’;
   $states           = $this->Vendor->Address->State->find ( 
      ‘list’, 
      array ( ‘order’ => ‘State.title’ ) 
   );

$this->set ( ‘vendor_type’, $vendor_type ); $this->set ( ‘application_type’, $application_type ); $this->set ( ‘states’, $states ); … }

That’s not an intolerably verbose example, but it’s easy to see how it could become so. Being the laconic kind of guy that I am, though, I decided to use the compact() function to cut down on the verbiage. Now my action code looks like this:

public function index() {
   …
   $vendor_type      = ‘Food’;
   $application_type = ‘Commercial’;
   $states           = $this->Vendor->Address->State->find ( 
      ‘list’, 
      array ( ‘order’ => ‘State.title’ ) 
   );

$this->set ( compact ( ‘vendor_type’, ‘application_type’, ‘states’ ) ); … }

That’s a little better, but there’s a caveat.

Using this example, I went to my view code and tried to access my $vendor_type variable only to get an undefined variable error. After working my way through various debugging techniques, I pulled out the big gun. In my view, I dumped the output of PHP’s get_defined_vars() function and found that my $vendor_type variable had been renamed to $vendorType. I don’t know if the change was made by CakePHP or by PHP itself, but I didn’t expect it (nor do I have any reason to believe that I should have expected it) and the difference is as fatal to an application as it is obvious.

PHP and the Negative Lookahead

I am, quite unabashedly, a sucker for a good regex question. I dig regular expressions. I love their power, their flexibility and their precision. Often I’ll use a regex even when I don’t have to because I can be absolutely precise about what I want even at the expense of a millisecond or two.

Being the sucker that I am, I was thoroughly hooked when @benrasmusen asked for regex help on Twitter yesterday.

He had a set of text that looked something like this:

<p>With more than 20 years’ experience recording, mixing, and mastering, I have an in-depth understanding of the mindsets involved in each step of a project. The focus of the mixer is the balances of the individual elements and how they relate to create a song. By contrast, the mastering engineer focuses on the song as a whole.</p>
<p>In mixing numerous songs for an album, the mixing engineer typically has a hard time creating consistency across all the songs. But the mastering engineer seeks to maintain energy levels and sonic flow among all the songs (except when not appropriate), creating a unified signature for the record. Those involved in recording a project often become emotionally attached to it, whereas the mastering engineer can provide an objective ear.</p>

He also had a set of terms that he wanted to find in that text so that he could replace each instance of the term with markup that injected a link around the text. For example, the word “mastering” might be replaced with:

<a href="#" title="A link to information about mastering">mastering</a>

The problem he was having was that the title attribute value applied to the injected link occasionally contained a word that matched a term that would be replaced in a future iteration. For example, in his case, the title of the link around “mastering” included the word “mix”. “Mix” was another term that had to be replaced with its own link and that happened after the replacement of “mastering”. Result: the instance of “mix” in the title attribute of one link was being replaced with another and he ended up with nested links – a new link nested right within the title attribute of another.

Oy.

Over the years, I think I’ve become a competent user of regex and perhaps even proficient. I am not, however, a guru. There are a number of concepts that elude me on a practical level, though I understand the theory well enough. One of these concepts is the lookahead and another is its sister concept, the lookbehind.

In this case, I knew enough to know that a lookahead (in this case, a negative lookahead) was needed, but not enough to know exactly how to do it. So I looked. And now I’m documenting for my own later reference. What he needed was this regex:

$regex = '/\b' . $term . '\b(?![^<]*>)/ig'

This finds all of the word-delimited instances of the replacement term that are not followed by zero or more instances any character other than a “<” and is, in turn, followed by a “>”. In other words, all of the instances of a replacement term that are not followed at some point, but before opening a new tag, by a “>”.

It’s not perfect, of course, but it’s workable, I think.

Extended Tech Tips for the Basic Computer User

This morning I read David Pogue’s excellent article offering tips for average computer users. I like to think of myself as a power user, but there’s some really good stuff in there and I learned a few things. Nonetheless, a couple of his tips either didn’t go far enough to suit me or I thought they could be extended slightly to add usability without increasing complexity. I haven’t included all of David’s tips here, but only those that I wanted to extend. Read his article for all of his tips. You won’t be sorry you did.

David’s tips that I chose to extend are in the primary list below. My extensions are italicized in a nested (read: indented) list.

  • You can double-click a word to highlight it in any document, e-mail or Web page.
    • If you’ve highlighted editable text (e.g. in an email, form field, etc.), you can just start typing. The highlighted text will be entirely replaced by what you’re typing. You don’t have to hit Delete or Backspace to explicitly clear the text before typing.
    • To copy the highlighted text, save a few clicks by using the Control+C keyboard shortcut rather than right-clicking and selecting the “Copy” menu item. To paste the text, use the Control+V shortcut.
  • When you get an e-mail message from eBay or your bank, claiming that you have an account problem or a question from a buyer, it’s probably a “phishing scam” intended to trick you into typing your password. Don’t click the link in the message. If in doubt, go into your browser and type “www.ebay.com” (or whatever) manually.
    • A helpful “trick” is to simply mouseover the link first (but don’t click it!). The destination will appear in the status bar of your browser (usually in the lower left corner). If the destination is anything other than what you’d expect then beware.
  • You can open the Start menu by tapping the key with the Windows logo on it.
    • You can open Windows Explorer by pressing Windows+E
  • You generally can’t send someone more than a couple of full-size digital photos as an e-mail attachment; those files are too big, and they’ll bounce back to you. (Instead, use iPhoto or Picasa–photo-organizing programs that can automatically scale down photos in the process of e-mailing them.)
    • Better yet, don’t send more than one or two photos by email at all. Upload them to Picasa, Flickr or some other online repository and send a link in the email message. Your recipients will thank you.

Source Control Strategies for Frameworks

I’m starting to get my hands dirty with CakePHP and as I’m getting started, I find myself pondering the use of source control. Not whether to use source control, mind you (because, well, duh), but how to use it optimally in the context of a framework or even a product that can be extended with custom code. Ideally, I’d like to version any and all code that I write or modify, but none of the framework code that is left unmodified. I’m not sure that I’ve ever spent much time on that question. As best I can remember, I’ve always just committed everything.

I’m wondering what strategies others employ with respect to source control when custom code is mixed with product or framework code. Are there any best practices?

(Dis)Organizing Bookmarks

This is another call for help. In all my years of computing, browsing and generally keeping up with the times (or trying to), I’ve never – seriously, never – found a way of organizing and accessing my browser bookmarks that doesn’t quickly devolve into utter madness. Madness, I tell you.

I’ve tried the entry-level folder structuring, centralized solutions like Delicious and Google Bookmarks and am beginning down the path of a synchronized solution in Mozilla Weave (true, not a purely organizational metaphor, but synchronization will facilitate maintained organization). I’m also vaguely aware of new bookmarking features in Mozilla 3, but must confess my total ignorance of the details and to how to use those features effectively.

So to those of you out there who actually like how your bookmarks are organized, what the hell are you doing right that I’m doing so freakishly wrong?

← Earlier Posts Page 1 of 2