In what seems like an eternity ago at my old agency job, I forked a plugin for redmine called redmine_git_hosting. See, I had a grand idea that maybe we could move to git, just so long as we could meet some basic requirements. Redmine git hosting, should you follow its family tree, is a child of redmine-gitosis. Gitosis was close, but Gitolite was closer. Essentially we needed to lock down source control due to third party access, and lets face it, perhaps some not so stellar users.
So I forked this repo and figured, what the hey, all I need to do is change how it manages the config and add in some basic UI, right? right? Well yes, thats more or less it. But the support for the project faltered in the company, I had no time for it and I moved on to greener freelance pastures not long after. No harm no foul?
As it turns out, I had started to scratch an itch many people felt. I had quite a few contacts asking if it worked, it was forked fairly well (5 or 6 times). I had abandoned it, but GitHub had allowed it to live on. Other forks quickly got it to working prototype, and as far as I understand, its now been pulled back in to some sort of potential officiality. All I really did was click a button and change some lines, but it was enough.
So I was a bad parent, I started a public project and then almost immediately walked away. But it didnt matter, just starting it was all that was needed. I think this is the sort of thing that emphasises how important GitHub is. I dont think this would ever happen at, say, Sourceforge.
Programmers often talk about how every little piece of code you put out there can follow you around for a long time, long past your own interest. People will ask for support years after you wrote something small and then walked away. GitHub doesn’t negate that, but it makes it easier when someone does or you need to. It lets project live beyond the grip of their parents.
I was messing around with using Data URi’s with CSS background images, when I ran into an odd error: Resource interpreted as Other but transferred with MIME type undefined. Here was my code (more or less):
I quite like Linkinus as an irc
client. Its a bit bulky and not hugely well optimised, but theres something
about it I enjoy. It does have some annoying habits however. One of those is
that it doesn’t utilise the Mac OS X Keychain for server passwords. Super
annoying when you’re like me and you forget what they are.
These passwords are retrievable however, they’re stored in
~/Library/Application Support/Linkinus 2/Networks.lnkData, and if you use a
Hex Editor and search for your network
name in ASCII mode, you’ll see the passwords in plaintext a few blocks later.
Not exactly a point in security for Linkinus, but I’m glad I have my passwords
back :) I’ll probably file this as a bug and hope they choose to start using
Just for your reference and mine, since its not obvious why this gets thrown
(given the error name and message)
Your form needs to be enctype="multipart/form-data" otherwise the $_FILES
array is empty and it all goes pear shaped. Kind of obvious, but thats a long
garden path to walk down to find you’ve forgotten something so fundamental :/
It’s super useful to hide files and folders from the finder. I find it’s a
good way to deal with badly behaved applications that put folders in your
Documents folder instead of in Library/Application Support like they should.
If you have SetFile from the developer tools, you can also symlink these bad
directories into their proper location and hide the symlink.
This method wont affect anything that needs to write to the folders since the
paths remain the same.
If you dont have developer tools installed, use this: (Note: this doesn’t work
chflags -R hidden chflags -R nohidden
If you do have developer tools installed, you can use SetFile
Paths in PHP, theres a way to do them properly. Lately I’ve seen this issue
poke it’s head up amazingly frequently and I dont think it gets as much
discussion as it should. I thought it was a solved problem, apparently not so.
Lets get started
Most PHP applications litter their code with include
'../../library/someclass.php.class'. This isn’t much good to anyone, because
its very easy to break, and no-one likes doing path janitor work when you
should be coding. Want to move a file? Now you have to change 20 other files?
bummer. So ok, maybe we could just create a constant, and use the full path?
Well thats a damn sight better. Now we have a concrete place to look for our
files. It’s good, but erm, what if we deploy on windows? Also, are we going to
define path on every script entrance point? Not very DRY if you ask me. Plus,
moving deployments is going to be a huge pain if the folder structure is
different, and let’s just face it, it will be. Clearly, while we’re closer
it’s not much of an improvement.
Luckily, PHP provides a few magic bullet functions that can help us out
So lets just say you have a single entrance point for your application, or at
the very least a shared header file. We can grab our deployment root pretty
quickly if we know where our header file is related the the code root. IE, in
Awesome, thats our document root. It’s OS independant and its pretty easy to
adapt if you change where set_paths.php lives. Now we can talk about some
other locations in our application, just because constants are handy:
This is all very well and good, but its not really much better than our
previous solution. We still have to specify a constant with our path to get
includes to work. Enter in the PHP include path. By adding the relevant
constants to our path, we wont need to reference them every time we include a
file. Order of paths in the include path is actually pretty important for
speed, so we make every effort to get them in order of usage.
<?php// There are some paths here by default, obviously. // We want to pull the current directory out of the stack so we can move it later.$paths['inc']=array_flip(explode(PATH_SEPARATOR,get_include_path()));unset($paths['inc']['.']);$paths['inc']=array_flip($paths['inc']);// The first item on the path the external libs that get used all the time, // then the application path, then the site path, and any php configured items.// The current directory should be last. Why is the current directory on the path?// Well if it wasn't, you couldn't have relative includes.$paths=array_merge(array(PATH_LIBRARY,PATH_APPLICATION,PATH_SITE),$paths['inc'],array("."));// PATH_SEPARATOR is a PHP defined constant, and its better to use a constant// than a 'magic' string.set_include_path(implode(PATH_SEPARATOR,$paths));
Now all the critical locations in our application are on the path, and you can
include to your hearts content, regardless of where you decide to store your
libraries, settings etc.
A step further
If you’re working with a fairly well designed OOP Application, we can go a bit
further. If you subscribe to one file, one class (You do don’t you?), then the
PEAR naming convention makes life very simple. It also makes a lot more sense
as a naming convention than .php.class or .inc or whatever other silly
pointless conventions exist.
The PEAR naming conventions dictate a 1:1 relation between the filesystem and the class. As an example, the class Foo_Bar_Baz would be found in the file “Foo/Bar/Baz.php” on your include_path.
Once you have a predictable mapping of files to classes, you can then
implement spl_autoload_register And you can replace
I was looking for a way to get better control over my buffers in vim. Theres a
fantastic blog post that explains how splits and windows
work. Since I dont use the number pad, I’ve bound a heap of shortcuts to it
for navigation around my vim instance.
The idea is the arrows on the numpad move around my buffers, and hitting 5
allows creation of a new split in that direction. So 58 gives me a split above
my current one. Double tapping the direction gives a window, so 588. Its very
intuitive, give it a try :)
Something that doesn’t seem to be covered very well, at least in my cursory
googling, is an easy way to manipulate ranges of data in sql. MySQL provides a
tool called Range Partitioning, which is great if your ranges are used regularly.
However, most of the time ranges are needed temporarily when pulling
After a bit of fiddling about, I think I’ve found a fairly acceptable way to
get around the issue, by creating a temporary table to specify your ranges
against your data set, and then performing your final result query against