Bradezone
May 21st, 2009

CakePHP, beforeFilter, and the Error Error

We all know CakePHP is the bee’s knees for developing web applications, but what’s not so hot is Cake’s handling of error pages. Most developers discover soon enough that they can customize their error pages, most commonly the 404 “not found” page, by creating an appropriately named file, e.g. error404.ctp, within the views/errors folder. Easy peasy, right? Sure, but lurking in the bowels of Cake’s code is a significantly more obscure problem that manifests itself in various ways. Simply put, CakePHP fails to load components and does not run the beforeFilter() function of the AppController, deviating from its normal page-loading process. This can lead to utterly maddening behavior if you do anything important in beforeFilter(), which would be almost always.

An application I’m developing at work runs critical code in beforeFilter() that checks if a user is logged in and uses the results to set the website title and which links appear in the main menu. So you could say that’s fairly important. But on my error pages, Cake would conveniently display no title or main menu whatsoever. Because no debugging messages were displayed, I thought the issue might have been a minor case of a different layout file being used for error pages. But after a thorough combing of Cake’s library code, I discovered the ugly truth within the cake/libs/error.php file: the CakeErrorController class, which is used by the accompanying ErrorHandler class, never calls the beforeFilter() function. This contrasts with the Dispatcher class in cake/dispatcher.php that is responsible for most normal pages—this code eventually runs beforeFilter() within the controller’s _invoke() function, but before that it also calls the controller’s constructClasses() function, which turned out to be a critical part of my solution to this now unwieldy problem.

After attempting several ways of making the error pages run my beforeFilter() code, I found that simply adding $this->beforeFilter(); as the last line of the CakeErrorController constructor seemed to work. The problem with doing this, however, is that I had to change a core file within Cake. As my fellow developers know, this is not an option, so I had to make it work from within my own code. But luckily I was on the right track: the constructor inherits from the AppController constructor, which I was free to modify. So within my application’s app_controller.php file, I added a constructor and copied the code from CakeErrorController, making sure to add my call to beforeFilter() at the end. Amazingly it seemed to work, so I then proceeded to see which lines I could safely comment out, until I was left with just a few lines of code. The constructClasses() function in particular seems to be Cake’s succinct way of loading the components used by the application. After testing several normal pages and error pages alike, I feel fairly confident that I have solved my initial problem. Here’s the code I added to app_controller.php:

function __construct() {
    parent::__construct();
    if ($this->name == 'CakeError') {
        $this->constructClasses();
        $this->beforeFilter();
    }
}

Since I was forced to put the code in the main AppController class, some side effects may exist: beforeFilter() is potentially called twice on standard pages and perhaps earlier than normal. From what I can tell, this doesn’t affect the application’s performance or behavior. So hopefully this solution will help other CakePHP developers who want their error pages to behave as expected. But surely I am not alone in hoping that future versions of CakePHP will make this workaround unnecessary.

UPDATE: I tweaked the code to include an explicit check for CakeErrorController before running the extra lines of code in the constructor. I found a fail case that had to do with adding new users via the Auth component—new passwords were being hashed twice. So this new snippet should successfully eliminate the possibility of code running twice needlessly.

May 6th, 2009

Reasons

For lack of blogging:

But fear not, for there are a couple of drafts in the works, one entitled “Alice in Plaid,” the meaning of which you are free to guesstimate.

March 22nd, 2009

Balance

The following is an essay I wrote in October 2000. I felt quite strongly at the time that I had crossed an important bridge of thought in my own mind, and I have since thought about these writings many times over the last decade and how they still truly shape the way I approach life. In many ways this is the foundational essay for everything I have written on Bradezone, and I have decided to republish it today since I have been considering very recently the dichotomy of individuality and assimilation—a subject I hope to write about soon enough.

Above all else, I try to make decisions based on logic and common sense. Many people corner themselves into doing things solely because most others do them or solely because most others don’t do them. I see both of these as entirely simplistic, even though the former faction thinks the latter weird and freaky whilst the latter thinks the former mindless and shallow. Those who show up at the school prom because “everyone’s going” are just as flawed in judgment as the person who gets multiple piercings and tattoos simply to “stray from the norm.” This has led to a situation wherein I am the guy few understand most of the time, even though theoretically I should be the easiest to understand. People have sacrificed so much of their potential because of their concern for how others perceive them—the one type wants to be loved, the other type wants to be hated. Why not live based on your own sound judgment, without regard for the reactions of others?

I have an idea for an invention called the Discussion Light. It would be a light on a bracelet or necklace that people could wear to indicate whether they want to be talked to. Green means I want to be talked to. Red means do not talk to me right now. Yellow means I do not care one way or the other. Good idea, right? Then we could avoid all those stupid times where we say “hi” to someone just because we know them. I am a guy who does not need to be acknowledged every time I see a familiar face. Unless we have something to discuss, let’s not waste time with a meaningless conversation. This could also apply when you see someone you know in a store, restaurant, or doctor’s office. With the Discussion Light, awkwardness is avoided.

The above is an example of something that would be considered odd by many people, even though it is a fabulous concept. I am a person with immense confidence in myself, whilst fully recognizing what my limits are. Any reluctance to share ideas comes not from a lack of self-confidence, but from the knowledge that everyone has not adequately trained their minds to react without pretense and predictability. It’s like laughing at a sex joke. Are you laughing just because sex is being mentioned, and you do not want to be deemed a “prude” or “religious right” by not programming yourself to laugh regardless of the actual existence of humor? Or are you laughing because it genuinely is funny? Here we have the perception issue again.

We have been called a selfish society, but in a way we are only selfish in the wrong way. We all seem to be immensely unselfish when it comes to formatting our personality based on who we are around. This is precisely the occasion where we do not need to make such a sacrifice. Our society uses the catchphrase “be yourself,” but they seem not to have the slightest idea what it means. To most of them, it simply means “be rebellious, make people mad, be different for no reason other than to be different.” Until this simple-minded and incorrect thinking discontinues, our world is stuck in Lameness Mode.

I am someone who manages to get along great with others by actually “being myself.” No, I won’t laugh at 99% of your sex jokes. No, I won’t go to that party with you and enjoy a beer or two. No, I won’t rent a tux and go to a formal with you. These are things that have proliferated not because of any logical reason, but simply because society feels they need a few things to proliferate in order to be considered a society, regardless of how truly dumb said things are. It is all part of crafting our “culture.” Ah, now this is a loaded word, and one I tend to despise. Culture mostly applies to the predominant behaviors of a society, but the vast majority of these behaviors become predominant for the reasons I mentioned above—simply because society is always feeling this need for a common behavior rather than a preference for autonomous thought. It is here where I could dive headfirst into religion, and describe what kind of common behavior is the intended ideal for humanity as a whole, but I am all too sure I would receive resistance from someone who is too “open-minded” for me. Be aware that society’s current definition of open-minded actually teeters between closed-minded and half-minded. Thus I will leave this topic at present.

So are others important? Absolutely. I have an intense affection for humankind. I want to see them happy. But our current society is set up in such a way to guarantee that will not happen. The concept of rebellion as voiced in such loaded terms as “open-minded” and “be yourself” depends on the perpetual existence of a large faction of society to “rebel” against. Rather than seeking to throw off our simplistic concepts of “culture” and actually attempt to reach a true harmony in humanity’s existence, we are still too wrapped up in the wrong kind of selfishness. The kind based on a primitive sort of competition. The kind based on a few being better than the rest. The kind based on excess, without regard for the condition of others—be this in the form of actual contempt for those others, or the idea that someone else will take care of those others.

For reasons mentioned in my long-lost essay The Final Echelon, this world is not designed for perfection—death and harbored emotions are the key reasons. Our intellect and basic emotions must coexist. Far too often we use the terms “what I think” or “my opinion” or “what I want” without realizing that our intellect and emotions often conflict with each other. What seems to be what you want may simply be what one aspect of your self wants, but not the other. A million problems have been caused by this lack of recognition—in fact, any problem not based on pure accident. Having sex prematurely, taking your first drug, killing someone—all these are based on what your immediate emotions told you that you wanted. You failed to engage the intellect. In the opposite way, the intellect can override the emotions of love and compassion. You may not logically see the need of saying a nice word to this person or buying a gift for that person, but emotionally you know it is right. Without emotion, we may not have murder or rape. But we would also not have laughter, crying, joy, and contentment.

This leads to the obvious conclusion. The world is based on balance. A balance of selfishness and unselfishness. A balance of intellect and emotion. A balance of culture and individuality. The problem with our society is merely that different people place far too much emphasis on one or the other in each pair. I do not claim to have figured it all out myself, but by recognizing the problem and keeping my eye on the solution, I feel I am making adequate headway.

My main fault is communicating with others as though they possess the same mindset as I have. That is why I have previously used terms like “scum,” “pathetic,” and “poison-tipped thumbtacks” while addressing others, when I definitely should not have. If that person were another me, he or she would take no offense, recognizing that I said those words out of my perception of their relative insignificance. But this tendency must be tempered until all of us are on the same page. In the meantime, I would best be served by writing something like this very document, which attempts to relate my thoughts to any and all readers.

I still hold out hope for humanity. Maybe we will learn to exist together without war and disregard for each other’s feelings. But in the ever-important spirit of Balance, I must also realize that we could simply continue to fail.