CakePHP and dompdf autoload error

I recently tried using dompdf in a CakePHP project to easily generate PDFs from HTML. I ran into a rather obtuse error while trying to render a page and generate a PDF in the same controller action.

Fatal error: require_once() [function.require]: Failed opening required 'vendors/dompdf/include/htmlhelper.cls.php' in vendors/dompdf/dompdf_config.inc.php on line 194

That makes it seem a lot like dompdf is trying to include one of its files and failing. What’s really happening is dompdf is specifying an __autoload function which PHP is attempting to use to load the HtmlHelper class used by CakePHP. dompdf blindly includes the file if it exists or not thinking only its files would be loaded this way. To get around this and load the files normally, simply edit the DOMPDF_autoload function to make sure the file exists before including.

function DOMPDF_autoload($class) {
    $filename = DOMPDF_INC_DIR . "/" . mb_strtolower($class) . ".cls.php";
    if(is_file($filename)) {
        require_once($filename);
    }
}

I found this snippet after much searching over at http://www.dashinteractive.net/dompdf/index.php?v=3278826, hopefully this post will save someone else a few minutes of googling.

Loading app models inside a plugin controller in CakePHP

I recently ran into a problem while writing a plugin in CakePHP. I wanted to do some authentication with one of the models in my app. I added this in the beforeFilter of my AppController. In there I was using $this->loadModel to load the model on the fly. This works fine inside the app. However, as soon as you move to a plugin things break down. It will try to load the model inside your plugin. Since that model doesn’t exist in the plugin, it will fail. You can specify a plugin in the loadModel call, like ‘Plugin.Model’, but you can’t specify no plugin. The way to get it to load correctly is the $uses variable. That will load the correct model when initializing the controller. Then you can use it as normal with $this->Model. This has the side effect of always loading the model on every controller. In my case that was perfectly fine since its used for auth on all actions. I can’t see any viable way to use loadModel to load a model outside of your plugin.

0 Size Mac Fonts

This no longer works in Snow Leopard

I was trying to do this again after upgrading to Snow Leopard and the OS no longer handles extended attributes in the same fashion. Attributes are now in a new style and the old style attributes you can only print out the hex. To get the value you have to do xattr -px com.apple.ResourceFork file_name | xxd -r -p > file_name.ttf. I tried this a few times and even though the file contents matches up exactly with the resource fork, the font does not appear to work. I also noticed that simply copying or moving the individual fonts on my Mac would cause them to stop working.

I just ran into a very weird issue today trying to transfer fonts from a Mac to a PC. I had several fonts on my mac that were working, installable, usable, and showed as having a size. When I tried sending them to a friend they would show up as 0k. I tried sending individual fonts, as a zip, via gmail, from a link, nothing worked. I decided to take a look at the files, opening them in a text editor showed nothing. Listing their file size in the terminal showed them as 0 bytes. The only place I could think of that data being stored was somewhere in the file attributes.

Back in OS 9 Mac fonts used to store their data in the resource fork. Normally this is used for storing metadata about a file. Someone at Apple decided that putting fonts in there was a good idea. Now in OS X the resource fork has been moved to the extended attribute com.apple.ResourceFork. Extended attributes are not used in file size calculations by terminal. If you want to see the extended attributes you can use xattr -l file_name. Running that on the font file showed a giant chunk of data in com.apple.ResourceFork that was definitely the font info. Mystery solved.

Converting the file is easy once you figure this out. You can simply dump the resource fork into a file with the extension .ttf and OS X will interpret it as a PC true type font. Use xattr -p com.apple.ResourceFork file_name > file_name.ttf to get the data. This will allow you to copy the file to a PC. I make absolutely no promises as to how well this works, but it worked for me. You can also try converting using transtype http://www.fontlab.com/font-converter/transtype/

MSSQL Bitwise Operations Using Two Varbinary Variables And COLUMNS_UPDATED()

While trying to write some triggers for MSSQL I stumbled upon this nice function called COLUMNS_UPDATED(). It returns a bitmask representing the columns that were modified during an update operation. It just so happened that this was exactly what I was looking for. I had a group of columns that I wanted the trigger to act upon, the rest I didn’t care about. So I went about creating a bitmask for my columns to & against COLUMNS_UPDATED(). Here is where I ran into two problems.

First, COLUMNS_UPDATED() returns a VARBINARY, so logically I also made mine a VARBINARY. Unfortunately, MSSQL does not support bitwise operations on two VARBINARY variables. One can be a VARBINARY, but the other must be an INT. This isn’t a problem if your table is 32 columns or less. Unfortunately that was not the case for the 74-column monster of a table I was working with. I searched around and it seemed like there really wasn’t a solution to this problem. So I wrote my own. It’s a stored procedure that will perform the bitwise operations, &, |, or ^ on two VARBINARY variables. It splits the VARBINARY variables into INT sized chunks and the performs the operations. I’m sure it could be more efficient, but it works.
binary_bitwise.sql

The second wonderful thing is the way that bits are organized. Withing each byte (8 bits) the least significant bit (rightmost) is the first column. So if you were interested in columns 1,3,4 you would get: 00001101. Then within your whole bitmask the most significant byte (leftmost) is the first 8 columns. So let’s say you were interested in columns 1,3,4,7,9,15,16 then you would get 01001101 11000001. Writing out the bits in order doesn’t make much sense to the human brain, notice columns 15 and 16 are in the middle. The easiest way I found is to write out 0s in byte sized groups then go through them backwards putting 1s in your columns.
Once you figure out your bitmask convert it to a hex number and you can use in the trigger. My monster table ended up with:

IF(dbo.binary_bitwise(COLUMNS_UPDATED(),0xFFF57851150404C02102,'&') != 0x0)

. Also remember to fill out all your bits. If you only have 12 columns, you still need 16 bits. Let’s say you are interested in column 2 and 11. 00000010 00000100 = 0x24.