Adam Gotterer

Find the secrets to infinite income, and automate it!

Archive for the ‘Programming’ Category

Recursive PHP in_array function

I needed a recursive in_array function the other day and disliked all the samples I found on php.net. I wrote this one using the StandardPHPLibrary. It will recursively search through a multidimensional array and return true if the $needle is found in the $haystack.

 
function in_array_recursive($needle, $haystack) {
 
    $it = new RecursiveIteratorIterator(new RecursiveArrayIterator($haystack));
 
    foreach($it AS $element) {
        if($element == $needle) {
            return true;
        }
    }
 
    return false;
}
  • 1 Comment
  • Filed under: PHP
  • Weebly Puzzle

    This site attracts a decent amount of JavaScript folks so I thought this would be relevant and maybe even helpful. I read news.ycombinator.com everyday (or several times a day). If you are into the startup world, you should as well. It has by far the best startup news and a great community. The feedback and questions posted on there are generally informative and trolling is at a bare minimum. It’s what reddit used to be. Regardless, I came across a job posting at Weebly for a web developer position. The job description came with a little JavaScript puzzle. I had no intention of actually applying for the job, but when ever I find these puzzles I like to do them. I’m not going to post the results, because thats not cool. If you want to check your answer email me your best guess. But it entertained me for about 20 minutes. So if you’re bored or actually looking for a job check it out at http://www.weebly.com/jobs.html.

    Muxtape’s Is Growing Fast!

    Muxtape

    On Tuesday March 25th, Justin Ouellette one of the developers from Vimeo launched Muxtape as a side project. The idea isn’t totally original, but its executed far better then the competition. Muxtape is a site that lets you make virtual mix tapes. You upload up to 12 songs from your computer and share the custom link with anyone who wants to listen. The design is one of the cleanest and easiest to use sites I have ever seen.

    When Justin sent out an office wide link looking for feedback on Tuesday morning I googled “muxtape” and got back 33 results. I did the same thing the Wednesday and got back around 4,000 results. Thursday was around 9,000 and Friday around 22,000. I didn’t check over the weekend. I looked sometime early the next week and saw it was over 40,000. Tuesday April 1st, one week after the site launched google returned just over 100,000 results and as of today (April 4th) 121,000 result. That growth rate is pretty unbelievable and I would love to see at what point it stabilizes.

    I talked to Justin today about the growth on his site, I don’t want to throw numbers out without his permission but he said the site is growing at a nice rate every day. I assure you it’s a pretty impressive number for a site two weeks old. He must be paying a fortune in bandwidth on Amazon S3. I want to say that he didn’t have a clue how big this was going to get, but then I would be lying. I think he knew damn well how the site was going to do before he even launched. He gave Vimeo two weeks notice Monday, the day before he launched. Thats a pretty ballsy move to go from a stable income to the unknown. But thats what separates the people who build great companies and the people who are too afraid and work corporate the rest of their life. I don’t know Justin that well, but I have had some interesting conversations with him and he really knows his stuff. He didn’t give me much insight to future plans. But he said theres a monetization plan in the works and a bunch of new feature. I think he is going to do great and wish him the best of luck.

    Check out my Muxtape!

  • 0 Comments
  • Filed under: Programming
  • BustedTees Relaunch

    BustedTees

    This morning at 5am Kunal Shah, Nick Dunkman, Jmo and myself launched a new version of the BustedTees website! Visually the site hasn’t changed much. Amir Cohen, one the front end developer for CollegeHumor did an excellent job recoding the front end. We spent the better part of the last 4 months recoding everything from scratch. The original version was built on the open source Symfony PHP framework several years ago (before my time). The site served it’s purpose and helped take BustedTees to a new level, it wasn’t that it was poorly programmed, it just outgrew our requirements.

    BustedTees at 5am
    (Dev Team at 5:15am)

    I’m finding that a lot of the open source PHP frameworks that I have experimented with and seen throughout the community just don’t scale well. They serve a purpose and are great for average every day sites. But when dealing with a site the size of a BustedTees or CollegeHumor it really makes sense to roll your own framework, if you can. There are of course instances when writing a framework from scratch doesn’t always make sense. In the “unsure” startup setting it sometimes makes sense to get something out there quick and worry about scaling later. Scaling is a GREAT problem to have. If you are going to use open source code, not just frameworks, it’s important to really understand the underlying code. I can bet most coders don’t have a clue how the open source code they use actually works. Some of these applications are coded by excellent developers, you might learn something new by just reading their code.

    Working on BustedTees has been an incredible experience and I have learned so much. I have worked on some small ecommerce sites as a freelance developer, but nothing of this size. Theres so many things I would have never thought needed to be accounted for. In future posts I will try and elaborate a bit. Right now I’m running on a few hours of sleep I got from a nap, so I’m going to pass out…

    Using Prototype XUL

    The examples here are taken from Function page of the Prototype JS api documentation. They have been re-written to reflect the Prototype XUL changes. Hope they help!

    argumentNames

    var fn = function(foo, bar) {
       return foo + bar;
    };
     
    argumentNames(fn); //-> ['foo', 'bar']

    bind

    var fn = function(foo, bar) {
       return foo + bar;
    };
     
    argumentNames(fn); //-> ['foo', 'bar']

    bindAsEventListener

    var obj = { name: 'A nice demo' };
     
    function handler(e) {
      var tag = Event.element(e).tagName.toLowerCase();
      var data = $A(arguments);
      data.shift();
      alert(this.name + '\nClick on a ' + tag + '\nOther args: ' + data.join(', '));
    }
     
    Event.observe(document, 'click', bindAsEventListener(obj, handler, 1, 2, 3));

    curry

    String.prototype.splitOnSpaces = curry(String.prototype.split, " ");
    "foo bar baz thud".splitOnSpaces(); //-> ["foo", "bar", "baz", "thud"]

    defer

    function hideNewElement() {
      $('inserted').hide();
    };
     
    function insertThenHide(markup) {
      $('container').insert(markup);
     
      // Prototype XUL
      defer(hideNewElement);
    }
     
    insertThenHide("
    <p id="inserted">Lorem ipsum
     
    ");

    delay

    // before:
    window.setTimeout(function() {
    Element.addClassName('foo', 'bar'); }, 1000);
     
    // after:
    delay(Element.addClassName, 1, 'foo', 'bar');
     
    // clearing a timeout
    var id = delay(Element.hide, 5, 'foo');
    window.clearTimeout(id);

    delay

    // start off with a simple function that does an operation
    // on the target object:
    var fn = function(target, foo) {
      target.value = foo;
    };
     
    var object = {};
     
    // use the original function
    fn(object, 'bar');
    object.value //-> 'bar'
     
    // if we methodize it and copy over to the object, it becomes
    // a method of the object and takes 1 argument less:
     
    object.fnMethodized = methodize(fn);
     
    object.fnMethodized('boom!');
    object.value //-> 'boom!'

    wrap

    String.prototype.capitalize = wrap(String.prototype.capitalize, 
      function(proceed, eachWord) {
        if (eachWord && this.include(" ")) {
          // capitalize each word in the string
          return this.split(" ").invoke("capitalize").join(" ");
        } else {
          // proceed using the original function
          return proceed();
        }
      }); 
     
    "hello world".capitalize()     // "Hello world"
    "hello world".capitalize(true) // "Hello World"

    Prototype XUL Documentation

    For the most part the functionality of Prototype XUL works the same as normal prototype. The prototype documentation can be found here. The underlying changes are in the methods that extend Prototype.function. The functions that have been re-written are: argumentNames, bind, bindAsEventListener, curry, delay, defer, wrap and methodize. The core difference in use, is that these functions can not be extended from objects anymore and must be explicitly called.

    argumentNames

    argumentNames(someFunction) //-> Array

    bind

    bind(thisObj, someFunction) //-> Function

    bindAsEventListener

    bindAsEventListener(thisObj, someFunction) //-> Function

    curry

    curry(someFunction, [args...]) //-> Function

    defer

    curry(someFunction, [args...]) //-> Number

    delay

    delay(someFunction, seconds, [args...]) //-> Number

    methodize

    delay(someFunction, [args...]) //-> Function

    wrap

    delay(wrapperFunction, someFunction, [args...]) //-> Function

    Prototype XUL Update

    While writing out the Prototype XUL documention I came across a nasty little bug that took me a few hours to fix. I will wrap up the documentation tomorrow. If you downloaded the Prototype XUL 1.6.0.2 file anytime before today, please upgrade (the version number has not change).

    Drum roll please… After three attempts/failures, I present to you the newest version of the Prototype XUL library! The previous released version technically never worked. It was something I threw together for a Firefox project that only required the basic of functionality (Ajax.Request, utility functions, etc.). I was under the impression that converting the functions that failed due to the known XUL function bug would solve all the problems. Unfortunately this was not the case and under these assumptions more complex functionality ceased to work correctly. This version has gone through a finer examination, conversion and code update to (hopefully) be a fully functional representation of prototype. Hopefully Firefox 3 will have this bug corrected and I wont have to release many future updates. Please post any bug reports, questions or feedback in the comments section, this will help reduce duplication and make my life easier :). Enjoy!

    WARNING: I have not fully tested this library!

    Disclaimer: This modified version of the Prototye JavaScript framework is in no way affiliated, distributed or supported by Sam Stephenson or the Prototype library project. This library has been modified from its original intended version/use and I take no responsibility for any bugs, damages or problems this library may cause.

    Download Prototype XUL

    * Most up to date version as of 2/22/08
    * Documentation
    * Examples

    I wrote a class to deal with preference handling in the PriceAdvance Firefox extension. I found the Mozilla documentation to be difficult to understand. So, I decided to share the class. Theres a little bug in Firefox that took me two days and borderline suicide to figure out… Extensions can have a default preference file that you can query using the preference interface. These preference files are “magically” loaded from a very specific file folder/location - “defaults\preferences\xxxxx.js”. To set a preference you simply put “pref(”branch_title.variable_name”, value);” in the file. If you use the class I made these preferences can be accessed like this: “Preference.getPref(”variable_name”)”. Now the bug I found is with the way you configure your extension. If the extension is bundled and installed “properly” it will work without a hitch. For development purposes I have my extension using a pointer from the extension folder to another folder location where I do all the work. Apparently when its setup as a pointer it wont load the preference files. Whats really annoying is theres no way to verify if the magical files have been loaded or not. Because of this I have avoided preference defaults and use my own variables class.

    Preferences = {
    initialize: function() {
      this.prefs = Components.classes['@mozilla.org/preferences-service;1']
      .getService(Components.interfaces.nsIPrefService)
      .getBranch('extensions.branch_title.');
     
      this.prefs.QueryInterface(Components.interfaces.nsIPrefBranch2);
    },
     
    getPref: function(name) {
      var type = this.prefs.getPrefType(name);
     
      if (type == this.prefs.PREF_STRING)
        return this.prefs.getCharPref(name);
      else if (type == this.prefs.PREF_INT)
        return this.prefs.getIntPref(name);
      else if (type == this.prefs.PREF_BOOL)
       return this.prefs.getBoolPref(name);
    },
     
    setPref: function(name, value) {
      var type = this.prefs.getPrefType(name);
     
      if(type == 0) {
        if(typeof(value) == 'number')
          type = 64;
        else if(typeof(value) == 'string')
          type = 32;
        else if(typeof(value) == 'boolean')
          type = 128;
      }
     
      if (type == this.prefs.PREF_STRING)
        this.prefs.setCharPref(name, value);
      else if (type == this.prefs.PREF_INT)
        this.prefs.setIntPref(name, value);
      else if (type == this.prefs.PREF_BOOL)
        this.prefs.setBoolPref(name, value);
    }
    };
     
    // USAGE:
    Preferences.initialize();
    Preference.setPref('this_works', true);
    alert(Preference.getPref('this_works'));
    /******************/

    To view preference variables that have been set, type “about:config” into the address bar and filter for your branch.

    CollegeHumor is hiring!

    CollegeHumor Logo

     

    CollegeHumor is looking to fill two development positions…

    Flash / Action Script Developer

    PHP /MySQL Developer

     

    Connected Ventures is cool, but what could better then working with me?