Feeds

100689 items (1996 unread) in 22 feeds

CNN CNN
MSNBC MSNBC
PHP PHP
Deals Deals
Tech Tech
Web Development Web Development
CNN Money CNN Money
Frugal Blogs Frugal Blogs

PHP (74 unread)

 

Planet PHP

Nettuts+

Planet PHP

Nettuts+

Planet PHP

Nettuts+

Planet PHP

Nettuts+

Planet PHP

Nettuts+

Planet PHP

  • Permalink for 'Interview with Mage+ creator'

    Interview with Mage+ creator

    Posted: May 16th, 2012, 3:11am MDT by Mayflower Blog - PHP

    [You may have heard about the Magento fork Mage+.]

     

    Lee, just tell us: who are you and what are you doing?

    I'm a Magento technical architect, developer and contributor to Magento CE. I specialise in architecting and building large scale and complex installations of Magento - having built enterprise Magento platforms for Warner Music Group both in Europe & USA, and for Rebate Networks, who operate a collection of localised flash-sales websites throughout the world. I'm also the founder of the London Magento Users Group.

    I created a fork of Magento CE called Mage+, after the frustrations I'd experienced whilst working with Magento.


    Continue reading "Interview with Mage+ creator"
  • Permalink for 'Composer Dependency Woes'

    Composer Dependency Woes

    Posted: May 15th, 2012, 3:35pm MDT by blog.phpdeveloper.org » PHP

    I spent the better part of this afternoon trying to figure out why a Composer installation wasn’t working and finally figured out the problem…it wasn’t mine.

    First, a little context – I’m currently working on a testing presentation for some folks at work and I wanted to show them how to work with the Behat testing tool to create some handy functional/integration tests for our framework-based apps. I threw together a little framework (yes yes, I know) and got the PHPUnit tests set up and running in no time. When it came to the Behat tests, though, no matter what I did, I was still having a problem:

    PHP Fatal error:  Class 'Goutte\Client' not found in /www/htdocs/testing-examples/app/vendor/behat/mink/src/Behat/Mink/Driver/Goutte/Client.php on line 13
    

    No matter how I tried to configure the composer install, it always gave me this message. I tried everything I could think of and, finally, at the suggestion of Rafael Dohms, checked out the github repository for the Goutte client (a href= [github.com] As it turns out, in the past day or so, there’s been a large change where Fabien implemented composer support on the repo.

    Apparently this was what broke things – thankfully not something obvious I was missing.

    So, how did I solve it so I could see the lovely green of passing tests again? Well, if you’re familiar with composer, you know there’s a composer.lock file that’s created after you install. When you run the “composer install” and it fetches from “fabpot/goutte”:”*”, you get this latest version that has the issues. A quick modification of the composer.lock file takes care of that though:

    {
        "package": "fabpot/goutte",
        "version": "master-dev",
        "source-reference": "5ecceb7c28a428fb93f283982cc4f5edfd96630b"
    },
    

    See that “source-reference” setting? Well, that can either point to the branch or version you want to pull from or it can point to a specific commit. In my case, I just pulled the hash for the commit before all of the changes and dropped it in there. Then it’s just a matter of running a “composer install” to get the code from this commit instead. Don’t run an update though – that will wipe out your manual changes to the lock file and you’ll be back to square one.

    Hope this helps someone out there who might be dealing with a similar issue regarding brokenness on an external lib!

Nettuts+

  • Permalink for 'How to Super-Scale Magento in the Cloud'

    How to Super-Scale Magento in the Cloud

    Posted: May 15th, 2012, 11:31am MDT by Jed Galbraith

    This tutorial will help you prepare a Magento install for high traffic, better load times, and simpler ongoing site management. Ready?

    Requirements

    You can download the finished code for this tutorial, or launch the “magento-basic” Quickstart from your Pagoda Box account to test a working site.

    • A Pagoda Box Account (free)
    • A functional local Magento Install
    • Local Development Software (MAMP or WAMP)
    • Git Installed (Can use SFTP)
    • The Pagoda Terminal Client Installed

    Fair Warning: This tutorial may change your life. Pagoda Box is not traditional hosting. The teachings in this article will not only help scale Magento, but it also lays the groundwork for a progressive development-to-production workflow.

    Step 1: Set Up Git Locally (SFTP will work as an alternate)

    Note: If you already use Git, you can skip this section. If not, the guide Setting Up Git provides specific instructions for creating an SSH Key, as well as links for downloading and installing Git (also below).

    While it is possible to use just SFTP on Pagoda Box, the officially recommended (and most efficient) workflow integrates Git into your daily development. Git enables features like collaboration, uniform code distribution, deploys, deploy history and rolling back code. While most of these features are available to FTP users, using Git makes integration seamless.

    If you want to fully take advantage of Pagoda Box, download Git, and Learn the Basics. Depending on your operating system, set up may vary slightly. Regardless of your OS, the commands are identical once Git is installed.

    Using Git to manage collaboration and version control may involve a brief learning curve. However, there are generally only three commands we’ll use on an ongoing basis to commit changes locally, then deploy to Pagoda Box:

    • git add . – Adds local files to your repository
    • git commit -m "some message about what you've done" – Commits your changes
    • git push pagoda --all – Pushes changes to Pagoda Box Repository (auto-deployed by default)

    We’ll use these later.

    Step 2: Install the Pagoda Box Terminal Client
    
                                 *
                               /   \
                             /       \
                         +_/ / / | \ \ \_+
                             ||*|||*||
                             |+||*||+|
                             /       \
                         +_/ / / | \ \ \_+
                             ||*|||*||
                             |+||*||+|
         ____   _    ____  ___  ____    _    ____   _____  __
        |  _ \ / \  / ___|/ _ \|  _ \  / \  | __ ) / _ \ \/ /
        | |_) / _ \| |  _| | | | | | |/ _ \ |  _ \| | | \  /
        |  __/ ___ \ |_| | |_| | |_| / ___ \| |_) | |_| /  \
        |_| /_/   \_\____|\___/|____/_/   \_\____/ \___/_/\_\
    
           Welcome To Your Pagoda Box Terminal Client.
          -----------------------------------------------
              -----------------------------------------
                 ---------------------------------
                              Enjoy.

    Pagoda Box provides a Terminal Client that lets you clone, create, deploy, destroy, rename and rollback an application from the command line. Later in this tutorial, we’ll use the client to create a secure tunnel to the live Magento database with Sequel Pro (the process is similar for other database managment tools like HeidiSQL).

    The Pagoda Box Terminal Client is a rubygem, so installation is pretty simple. First off, Ruby needs to be installed. Installation is different for each operating system.

    • Mac – Ruby and RubyGems come pre-installed on Mac OSX. As long as you are running v10.5 or later, you should be good to go.
    • Windows – There are a couple of different ways to install Ruby in Windows. We recommend this auto-installer. If it doesn’t work for your set-up, a Google search will give you a pretty good list of installation walk-throughs.
    • Linux – Use your preferred package manager to download the Ruby package. For Ubuntu users, the gem is available through getdeb.net.
    Install and Verify Terminal Client

    Once Ruby is installed, simply run the following command to install the Pagoda RubyGem:

    On Mac or Linux:

    $ sudo gem install pagoda
    

    On Windows:

    $ gem install pagoda
    

    Then, to verify you have the Pagoda Gem installed properly, run:

    $ pagoda list
    

    If this is the first time you’ve used the Gem, it will ask for your Pagoda Box Username and Password. After you’ve entered those, expect to see a list of your Pagoda Box applications. If you haven’t created any applications, the list will be blank.

    If you get an error, it’s most likely invalid credentials. You can verify or change which credentials the gem uses by editing the file located on your local computer at ~/.pagodarc. Make sure to exactly match the credentials you use in your Pagoda Box account. (Note: this is a hidden file, so you’ll need to enable hidden files or open via the terminal. Also note that the file stores your credentials twice, so edit both if needed.)

    Step 3: Install Magento Locally

    Note: Skip this step if you already have a working local Magento install.

    If you don’t have it already, ensure you are using local webserver and database management software. There are several options available, depending on your operating system. A common option for Mac is MAMP, or WAMP for Windows. Both are free and easily set up.

    Once your local development environment is set up, go ahead and download Magento, then follow the official guide to install Magento locally.

    Feel free to use Magento’s auto install script to set up the application in your local environment. However, due to Pagoda Box’s distributed cloud architecture, the script will not install Magento directly in your production environment. The Pagoda Box workflow and architecture requires you to make code modifications locally, commit, then deploy to production. This workflow accommodates collaboration and development > staging > production best practices.

    Step 4: Configure PHP Using a Boxfile

    Note: On Pagoda Box, a YAML Boxfile can be included in the root of your code repository. While the Boxfile is optional, it does provide advanced features, like manipulating your hosted environment on each deploy. We’ll use the Boxfile extensively in this Tutorial to simplify tasks, and to make the respository reusable on Pagoda Box.

    Create a file named “Boxfile” in the root of your local Magento installation, then copy the following into your Boxfile (explanation below):

    web1:
      name: mag-app
      shared_writable_dirs:
        - media
        - var
      php_version: 5.3.8
      php_extensions:
        - pdo_mysql
        - mysql
        - simplexml
        - mcrypt
        - hash
        - gd
        - dom
        - iconv
        - curl
        - soap
    
    Create / Name the Web Cluster

    This Boxfile serves several purposes. First, it creates a web1 component, then names it mag-app.

    Shared Writable Directories

    Second, the Boxfile identifies media and var as shared writable directories. This allows users to upload images, video, and other media to a distributed Magento cloud site without instances writing themselves out of sync.

    When a directory is marked as writable, the contents are no longer deployed to Pagoda Box from your local repository. Any time local files need to be deployed to these directories, they must be manually copied via SSH or SFTP. You may also use SSH/SFTP to transfer files from Pagoda Box to your local machine as needed.

    PHP Version and Extensions

    The Boxfile also declares which PHP version and extensions will be included in your web instances as they deploy. This way, both the environment and the application are versioned together, so rolling back to a previous deploy includes the correct PHP version and extensions. The list of PHP extensions in this Boxfile was taken from Magento’s official system requirements.

    Tip: Once Git is installed in your local environment, use the .gitignore file to ignore the writable directories specified in your Boxfile. Identifying these directories inside the .gitignore file helps reduce the size of your repo, and your deploy time. In addition to the writable directories, you can also add the downloader directory to the .gitignore file, since it’s used locally, and not on Pagoda Box.

    Once you’ve installed Git and the Terminal Client, configured the Boxfile and finalized your local source code, you’re ready to launch on Pagoda Box.

    Step 5: Create a Free Pagoda Box Account

    If you don’t already have one, create a free Pagoda Box account. You will not need to enter a credit card to install Magento for testing.

    If you have not already done so, follow this guide to Add an SSH Key in your Pagoda Box Admin panel. The guide will provide specific instructions for setting up an SSH Key on either Mac or Windows.

    Step 6: Upload Magento to Pagoda Box

    Once you’ve created a Pagoda Box account and set up an SSH Key, go to the Home Page in your new account and click the “New Application” button to create a new application.

    Note: This tutorial names our sample application “magento”. The app name is also used for the Pagoda Box repository, the subdomain for the freshly deployed application (magento.pagodabox.com), and the username in SFTP mode. Replace “magento” with “your-app-name-here” where appropriate throughout the remainder of this tutorial.

    Upload to an Empty Repo (recommended for this tutorial)

    Next, choose from the 3 options to launch your Magento site. Since you already have a customized version of Magento locally, select ‘Empty Repo’ to deploy using SFTP or Git, name your application, and click “Launch Application”.

    You’ll be asked to select your preferred deployment method (Git or SFTP). Click on your preference, and follow the instrutions on-screen.

    Git Option

    You can copy and paste the on-screen instructions from the Pagoda Box dashboard to your terminal after using Terminal to change directory (cd) to the root of your project.

    The pasted commands do the following:

    • git init – Initialize your Magento project as a Git Repository
    • git add . – Add all files from the project to the repo
    • git commit -m 'your commit message' – Commit files with a message that allows you to quickly scan deploy history in the future, in case you need to revert or modify changes
    • git remote add pagoda git@git.pagodabox.com:magento.git – Add Pagoda Box as a remote (the specific git url for your application appears on both this screen, and in your app dashboard
    • git push pagoda --all – Push your local code to the Pagoda Box remote repository. As long as you’re on the “master” branch (which is the default), Pagoda Box will automatically deploy your code, and carry out the instructions we set in the Boxfile. Auto-deploy can be turned off in the Admin dashboard, or configured to deploy automatically from a Git branch other than Master.
    SFTP Option

    If you opted for SFTP, Pagoda Box will guide you through establishing credentials and a password. Connect via SFTP to Pagoda Box, and upload your Magento source code in the code directory.

    Step 7: Create a Database

    There are two ways to create a database on Pagoda Box. Each has benefits, explained below:

    Create a DB in the Boxfile

    The Boxfile will automatically create a database component on deploy, as long as that component (db1, db2, etc.) doesn’t already exist. Declaring the database in the Boxfile saves a bit of time now, and makes deploying multiple Magento sites from a standardized code base much simpler in the future. (Note: Only cloud DBs can be deployed from the Boxfile. If you need a larger, dedicated or redundant database, see the Dashboard option later in this Step.) Add the following to your Boxfile:

    db1:
      name: mag-db
      type: mysql
      

    Your updated Boxfile should look like this:

    web1:
      name: mag-app
      shared_writable_dirs:
        - media
        - var
      php_version: 5.3.8
      php_extensions:
        - pdo_mysql
        - mysql
        - simplexml
        - mcrypt
        - hash
        - gd
        - dom
        - iconv
        - curl
        - soap
    db1:
      name: mag-db
      type: mysql
      

    Then commit changes to the updated file and push changes to Pagoda Box:

    $ git commit -m "pagoda config"
    $ git push pagoda --all
    
    Alternate: Create a DB in the Dashboard

    You can also create a database from the Pagoda Box Dashboard. This is where you add a larger, dedicated or redundant database.

    First, click “Add Database” in the Dashboard.

    Pagoda Box will step through a series of screens to configure your database, depending on your choices. If you’ve chosen the Dedicated option, you will be asked to size your database as follows:

    Cloud databases usually deploy within minutes. If you chosen Dedicated, don’t get impatient. You may wait for up to 90 minutes for a big server to be provisioned to your specifications.

    Step 8: Configure DB Credentials for Production

    Your database automatically generates credentials when it’s created on Pagoda Box. We’ll use those credentials to configure Magento in production.

    However, since Magento will be used in both local environments and in production, we need to supply different database credentials for each. We’ll use Deploy Hooks in the Boxfile to simplify this process by executing scripts or commands during deploy.

    In the case of Magento, we’ll swap the local.xml file upon deploy. That way, without manually switching credentials, the app/etc/local.xml file will automatically have local database credentials in development, but production database credentials on Pagoda Box.

    Create a local.xml for Production

    First, create a directory named pagoda in root, then copy Magento’s app/etc/local.xml to the new directory.

    Next, edit local.xml to include Pagoda Box database credentials from your account dashboard. Note that Pagoda Box uses 3 levels of authentication, so that even if your credentials are compromised, other users cannot access your database.

    Swap local.xml Configs on Deploy

    Add the following into your Boxfile, under the web1 section to create the Deploy Hook.

    after_build:
      "mv pagoda/local.xml app/etc/local.xml"
    

    Your updated Boxfile should look like this:

    web1:
      name: mag-app
      shared_writable_dirs:
        - media
        - var
      php_version: 5.3.8
      php_extensions:
        - pdo_mysql
        - mysql
        - simplexml
        - mcrypt
        - hash
        - gd
        - dom
        - iconv
        - curl
        - soap
      after_build:
      - "mv pagoda/local.xml app/etc/local.xml"
    db1:
      name: mag-db
      type: mysql
      

    Then commit changes and push to Pagoda Box:

    $ git add .
    $ git commit -m "pagoda config"
    $ git push pagoda --all
    
    Step 9: Migrate the Database

    With the same tools you use to manage a local database, you can securely manage a live database on Pagoda Box. We’ll use Sequel Pro for this example, but the process is similar for tools like HeidiSQL.

    Export Your Local DB

    When the Magento install script ran locally, it created several tables in the local database. Those tables need to be migrated to production.

    First, export your local database using your database manager: File > Export.

    Now choose a location, and Save the export.

    Establish a Secure DB Connection

    Now establish a database tunnel. Using the Pagoda Box Terminal Client, specify the app whose database you are trying to access, and the ID of the database component (e.g. db1), as in this example:

    $ pagoda -a magento tunnel -c db1
    --OR--
    $ pagoda --app=magento tunnel --component=db1
    

    Once the tunnel is established, use Sequel Pro (or similar) to connect to the database using the Host and Port provided by the Pagoda Terminal Client…

    And the username and password in your Pagoda database credentials. These were automatically created with your database, and may be found in the Pagoda Box Dashboard under the database component (see example in Step 8).

    Import and Update the Production DB

    Next, import your database into production using Sequel Pro (or similar): File > Import. Now select the database export file, and Open.

    Finally, since we ran the install script locally, it’s necessary to adjust the base url directly in the database before browsing the site. While you are still connected to the Pagoda Box database in Sequel Pro, navigate/filter to the core_config_data table and edit the value for the following paths:

    web/unsecure/base_url
    web/secure/base_url
    

    The values for each should look something like this:

    Step 10: Configure Mail

    To protect your IPs from being flagged as spam, Pagoda Box uses the SMTP mail protocol to send email via third party mail provider SMTP credentials. In English, that means you need a company (like Gmail) that provides mail services.

    Regardless of which mail provider you choose, enter account credentials from that provider in your Pagoda Box dashboard. It should look something like this:

    Step 11: Cron Jobs (Optional)

    A few recurring tasks in Magento (e.g. sending newsletters, log cleaning, customer notifications, etc.) need to happen periodically. The cron.php file located in Magento’s root will trigger these tasks. We’ll set up a Cron Job in the Pagoda Box admin panel to run cron.php every 15 minutes. (Note: To configure Magento specific tasks, see their Official Guide.)

    Cron Jobs in the Boxfile

    Cron Jobs can be added or updated via the Boxfile, then deployed to Pagoda Box. To schedule a task at 15 minute intervals, add the following to your Boxfile under the web1: component (change the “magento” to point to your own app name / subdomain):

      cron:
        - "*/15 * * * *": "curl -s -o /dev/null [magento.pagodabox.com]     

    Your updated Boxfile should look like this:

    web1:
      name: mag-app
      shared_writable_dirs:
        - media
        - var
      php_version: 5.3.8
      php_extensions:
        - pdo_mysql
        - mysql
        - simplexml
        - mcrypt
        - hash
        - gd
        - dom
        - iconv
        - curl
        - soap
      after_build:
      - "mv pagoda/local.xml app/etc/local.xml"
    cron:
        - "*/15 * * * *": "curl -s -o /dev/null [magento.pagodabox.com] db1:
      name: mag-db
      type: mysql
      
    Alternate: Cron Jobs in the Dashboard

    In the Pagoda Box admin panel under the Cron tab, add the following (change the “magento” to point to your own app name):

    Command: curl -s -o /dev/null [magento.pagodabox.com]

    Schedule: */15 * * * *

    It should look like this:

    Part 2 – Optimization: Redis, Scaling & Benchmarking

    You’ve already gotten the heavy lifting out of the way. Your Magento application is scalable, and changes are easily deployed across all instances with $ git push pagoda --all.

    In the follow-up article, we’ll optimize Magento, add a Redis cache, SSL and Domain aliases, then scale the application for benchmarking and production. See you soon!


Planet PHP

  • Permalink for 'Some throttling for PECL/mysqlnd_ms 1.4'

    Some throttling for PECL/mysqlnd_ms 1.4

    Posted: May 15th, 2012, 7:11am MDT by Ulf Wendel
    Users of MySQL Replication sometimes throttle client requests to give slaves time to catch up to the master. PECL/mysqlnd_ms 1.4, the current development version, features some throttling through the quality-of-service filter and global transaction identifier (GTID). Both the plugins client-side GTID emulation and the MySQL 5.6 built-in GTID feature can ...
  • Permalink for 'Sami: Yet another PHP API documentation generator'

    Sami: Yet another PHP API documentation generator

    Posted: May 15th, 2012, 5:58am MDT by Fabien Potencier

    Today is my "let open source some of my private Github repositories" day, and more specifically, I'm releasing a bunch of code related to documentation.

    Earlier today, I've released the Sphinx extensions I'm using to generate the Symfony documentation.

    And now, I'm releasing my API documentation generator. Yes, I know that PHP already has a bunch of such generators, but I started to work on this project several years ago, when the only viable option was the old phpdocumentor.

    Nowadays, phpDocumentor version 2 is probably the best option out there as it has a good architecture, it works fine, it is extensible, and quite a few big PHP projects is already using it. And that's fine. I don't want to compete with it, I don't want to replace it, I'm just open sourcing some code used by Symfony, Twig, and Silex because I'm not comfortable with closed-source software. And to be totally honest and transparent, I have not released the code before because it was not "good enough".

    With this disclaimer out of the way, let's see what makes Sami "different" (compared to phpdocumentor)?

    • It uses a PHP file for configuration to give a very flexible way of tweaking the API generation;

    • It uses Twig for templating;

    • It uses a dependency injection container (Pimple) to let you override any internal class;

    • It only works with PHP 5.3 (but it can generate documentation for PHP 5.2 projects);

    • It uses the excellent PHP Parser project for PHP code parsing;

    • It is able to manage versions of your code to generate documentation for all of them in a single tree (without the overhead of re-parsing everything for each version of course).

    Curious about what Sami generates? Have a look at the Symfony API.

    Installation

    First, get Sami from Github (or integrate it as a dependency in your project Composer file -- you are using Composer, right?):

    https://github.com/fabpot/Sami
     

    You can also download an archive from Github.

    As Sami uses Composer to manage its dependencies, installing it is a matter of running composer:

    $ composer.phar install
    

    Check that everything worked as expected by executing the sami.php file without any arguments:

    $ php sami.php
    
    Configuration

    Before generating documentation, you must create a configuration file. Here is the simplest possible one:

    <?php
     
    return new Sami\Sami('/path/to/symfony/src');
     

    The configuration file must return an instance of Sami\Sami and the first argument of the constructor is the path to the code you want to generate documentation for.

    Actually, instead of a directory, you can use any valid PHP iterator (and for that matter any instance of the Symfony Finder class):

    <?php
     
    use Sami\Sami;
    use Symfony\Component\Finder\Finder;
     
    $iterator = Finder::create()
        ->files()
        ->name('*.php')
        ->exclude('Resources')
        ->exclude('Tests')
        ->in('/path/to/symfony/src')
    ;
     
    return new Sami($iterator

    Truncated by Planet PHP, read more at the original (another 8447 bytes)

  • Permalink for 'Interview with Derick Rethans'

    Interview with Derick Rethans

    Posted: May 14th, 2012, 11:00pm MDT by Cal Evans

    Blog: [derickrethans.nl]
    Twitter: @derickr

    Show Notes:

    Sponsored by:
    Engine Yard

  • Permalink for 'Quick and Dirty REST Security (or Hashes For All!)'

    Quick and Dirty REST Security (or Hashes For All!)

    Posted: May 14th, 2012, 3:44pm MDT by blog.phpdeveloper.org » PHP

    So in working up a new RESTful service I’ve been tinkering with, I wanted to provide some kind of “authentication” system for it. I started to look into OAuth, but got a bit overwhelmed by everything that was involved with it. Looking for something a bit more lightweight (and simpler to implement a bit more quickly) I came across this older article with a suggestion of a private key/hash combination. I figured that could do the job nicely for a first shot, so I set to implementing it.

    On the Server Side

    I’m using the FuelPHP framework for this one, but that’s really only giving me a structure to work in and pull the request information from. This would work in most major frameworks (and even outside of one if you you’re a “do it my way” kind of developer). First off, let’s start with the controller side:

    <?php
    class Controller_User extends Controller_Rest
    {
        protected function validateHash()
        {
            $request = file_get_contents('php://input');
            $requestHeaders = apache_request_headers();
    
            if (!isset($requestHeaders['X-Auth']) || !isset($requestHeaders['X-Auth-Hash'])) {
                $this->response('fail!',401);
            } else {
                // we have the headers - let's match!
                $user = Model_User::find()->where('public_key',$requestHeaders['X-Auth'])->get_one();
    
                if ($user !== null) {
                    $hash = hash_hmac('sha256',$request,$user->private_key);
                    return ($hash == $requestHeaders['X-Auth-Hash']) ? true : false;
                } else {
                    return false;
                }
            }
        }
    
        public function post_index()
        {
            // return the user details here....
        }
    
        public function router($resource, array $arguments)
        {
            if ($this->validateHash() == false) {
                $resource = 'error';
                $arguments = array('Not Authorized',401);
            }
    
            parent::router($resource,$arguments);
        }
    }
    ?>
    

    There’s a lot going on here, so let me walk you through each of the steps:

    1. First off, we’re making a RESTful service, so we’re going to extend the Controller_Rest that Fuel comes with. It has some handy special routing. Our POST request in the example below would try to hit the “post_index” method and have its hashes checked in the process.
    2. Next up is the “validateHash” method – this is where the hard work happens:
      • The request and headers are read into variables for easier use ($request and $requestHeaders).
      • It then checks to be sure that both of our required headers are set (X-Auth and X-Auth-Hash). There’s nothing magical about these header names, so they can be switched out depending on need and naming preference.
      • If they’re there, the next step is to find the user based on the public key that was sent. This value is okay to openly share because, without the private key to correctly hash the data, your requests will fail.
      • The hash_hmac function is then used (with the “sha256″ hash type) to regenerate the hash off of the contents of the request and the private key on the found user.
    3. If all goes well, the request continues on and the “post_index” method is used. If it fails, however, the check in the “route” method of the controller makes a switch. It changes the currently requested resource to “/error/index” instead of what the user wants. This seamlessly shows the user a “Not Authorized” error message (401) if the hash checking fails.
    A Client Example

    Now, to help make it a bit clearer, here’s an example little script showing a curl request using the hashes:

    <?php
    
    $privateKey = 'caa68fb2160b428bd1e7d78fcf0ce2d5';
    $publicKey  = '01fa456c4e2a2bc13e5c0c4977297fbb';
    
    $data = '{"username":"happyFunBall"}';
    $hash = hash_hmac('sha256',$data,$privateKey);
    
    $headers = array(
        'X-Auth: '.$publicKey,
        'X-Auth-Hash: '.$hash
    );
    
    $ch = curl_init('http://mysite.localhost:8080/user');
    
    curl_setopt($ch,CURLOPT_HEADER,true);
    curl_setopt($ch,CURLOPT [HTTPHEADER,] headers);
    curl_setopt($ch,CURLOPT_POSTFIELDS,$data);
    curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);
    
    $result = curl_exec($ch);
    curl_close($ch);
    
    print_r($result);
    echo "\n\n";
    ?>
    

    You can see that both the public and private keys are specified (but on the PHP side, not visible to the user) and are sent as the “X-Auth*” headers as a part of the request. In this case, we’re POSTing to the &

    Truncated by Planet PHP, read more at the original (another 733 bytes)

Nettuts+

  • Permalink for 'Lots Of New Premium Content!'

    Lots Of New Premium Content!

    Posted: May 14th, 2012, 1:57pm MDT by Jeffrey Way

    As Tuts+ Premium continues to sky-rocket, our ability to post better, more frequent, content has improved dramatically as well. This week, we have a variety of fun new things available to members!

    Course – How To Be A Terminal Pro

    In this fifteen-episode course, you’ll learn how to take advantage of that scary app you never touch: Terminal! We’ll begin with the obligatory “hello world” command, and work our way up to advanced usage.

    Course – JavaScript Testing With Jasmine

    Admit it: you say that you test your JavaScript, but, in reality, you…don’t. That’s okay; the idea of testing JavaScript is a relatively new thing. And unfortunately, there aren’t too many “hold your hand” resources for getting up and running. Well, that all changes with this course. We start from scratch, and slowly work our way up the testing chain.

    Along the way, we’ll take advantage of the fantastic Jasmine BDD (Behavior-Driven Development) framework to make our tests as readable as possible. Upon completion of the course, you’ll not only have a robust test suite at your fingertips, but your tests will also make for fantastic documentation!

    eBook - Client Centric Web Design

    Other than Internet Explorer, what is the most challenging part of your job? Did you answer clients? If so, this eBook, by Paul Boag, is for you. Discover how to keep your clients happy, maintain your own sanity and produce the most effective websites you have ever built, resulting in happier clients, better websites, and improved job satisfaction.

    eBook - Building Websites for Return on Investment

    Building Websites For Return on Investment

    ‘Building Websites for Return on Investment’ uncovers the secrets of sites that successfully generate real return on investment. This book will enable you to transform your website from an expense to a measurable source of income.

    Article – Are You Using CoffeeScript?

    For those who haven’t yet had the chance to dig into CoffeeScript, this article will get you up and running in no time!

    Coming Soon to Tuts+ Premium

    Nothing above pique your interest? That’s okay; we have plenty of amazing new content on the near horizon, including the following courses:

    • PHP Fundamentals
    • What’s New in PHP 5.4?
    • Cleaner Code With CoffeeScript
    • Backbone.js Fundamentals
    • The Sublime Text 2 Guide
    • Test-Driven Development in Ruby

    Already a member? What requests do you have? Haven’t signed up yet? Well now’s the perfect time!


Planet PHP

  • Permalink for 'PHP as a templating language'

    PHP as a templating language

    Posted: May 14th, 2012, 9:06am MDT by Sean Coates

    There’s been quite a bit of talk, recently, in PHP-land about templates and the ramifications of enforcing “pure” PHP scripts by preventing scripts from entering html mode. I’m not quite sure how I feel about this RFC, but it got me thinking about the whole idea of using PHP for templating in modern web apps.

    For many years, I was a supporter of using PHP as a templating language to render html. However, I really don’t buy into the idea of adding an additional abstraction layer on top of PHP, such as Smarty (and many others). In the past year or so, I’ve come to the realization that even PHP itself is no longer ideally suited to function as the templating engine of current web applications — at least not as the primary templating engine for such apps.

    The reason for this evolution is simple: modern web apps are no longer fully server-driven.

    PHP, as you know, is a server technology. Rendering html on the server side was fine for many years, but times have changed. Apps are becoming more and more API-driven, and JSON is quickly becoming the de facto standard for API envelopes.

    We can no longer assume that our data will be rendered in a browser, nor that it will be rendered exclusively in html. With Gimme Bar, we render html server-side (to reduce page load latency), in JavaScript (when adding or changing elements on an already-rendered page), in our API (upcoming in a future enhancement), in our iPhone app, and certainly in other places that I’m forgetting.

    Asset rendering in Gimme Bar can be complicated — especially for embed assets. We definitely don’t want to maintain the render logic in more than one place (at least not for the main app). We regularly need to render elements in both html and JavaScript.

    This is precisely why we don’t directly use PHP to render page elements anymore. We use Mustache (and Mustache-compatible Handlebars). This choice allows us to easily maintain one (partial) template for elements, and we can render those elements on the platform of our liking (which has been diversifying more and more lately, but is still primarily PHP and JavaScript).

    Rendering elements to html on the server side, even if transferred through a more dynamic method such as via XHR">[HttpRequest">XHR] , really limits what can be done on the display side (where “display side” can mean many things these days — not just browsers).

    We try hard to keep the layers our web applications separated through patterns such as Model/View/Controller, but for as long as we’ve been doing so, we’ve often put the view bits in the wrong place. This was appropriate for many years, but now it is time to leave the rendering duties up to the layer of your application that is actually performing the view. This is often your browser.

    For me, this has become the right way to do things: avoid rendering html exclusively on the server side, and use a techonology that can push data rendering to your user’s client.

  • Permalink for 'Speaking at OSCON 2012'

    Speaking at OSCON 2012

    Posted: May 14th, 2012, 1:22am MDT by Lorna Mitchell

    In July, I'm speaking at OSCON. Actually I have a few interesting speaking engagements coming up, and I haven't got around to adding upcoming dates to my blog yet but I'll be at phpDay in Verona next week with a talk on API Design and DPC in Amsterdam in June with a tutorial on Web Services and a talk on what OAuth is actually for.

    OSCON is special because I have always wanted to go and never imagined it would actually happen. Every year I read the list of sessions from the year before, and decide that I absolutely must submit to the call for papers, regardless of how small I think my chances of being accepted are! I've submitted a couple of times in the past, excluding last year because I was newly freelance (OSCON does not cover any speaker expenses at all, they just give you a conference pass. That's kind of hard going for those of us self-funding halfway across the world, and last year, I just couldn't do it. This year I still can't really justify it but I'm going anyway!)

    I have two talks, both of them brand new, and I'm excited about them both!

    PHP 5.4 Features You'll Actually Use

    When I told one of my local user groups (how excellent to have more than one local user group!) about this talk they said "that'll be a short talk" and I am a little worried they are right! Cool new array syntax, traits, and a web server ... am I missing anything important? To make this even easier and more fun, Rasmus has the slot immediately before mine and his abstract includes "a detailed review of new PHP 5.4 features". I feel like a spare part and I haven't even written the talk yet!

    Get Some Rest: Best RESTful API Practices

    This one will be lots of fun, because I firmly believe in writing services that make users, rather than textbooks, very happy. Which means that I do break the rules and I think there are times when that's acceptable. I suspect that there will be heckling, flaming, and foaming at the mouth involved but hey, I'm not there to be popular! Honestly, I love REST, I think it's possible to take it too far, and I'm only a little bit scared to say that in public :)

    OSCON Conversations

    OSCON does a cool thing where it opens the comments on a talk page immediately - which means that you can already go and ask questions, make requests, or leave comments on either my PHP 5.4 talk or the RESTful one and let me know what you do (and perhaps do NOT) want to hear. If you're going to OSCON or are just interested in the topics, I'm interested to hear your thoughts, either over here in the comments or over on the talks themselves!

    Lorna is an independent web development consultant, writer and trainer, open source project lead and community evangelist. This post was originally published at LornaJane

  • Permalink for 'Magento CE 1.7 forked on GitHub'

    Magento CE 1.7 forked on GitHub

    Posted: May 12th, 2012, 9:08am MDT by Mayflower Blog - PHP

    [This blog post is also available in German.]

     

    Yesterday, it was the news of the day: Magento CE 1.7 was forked on GitHub by some community people. After the spectacular departure of Yoav Kutner, then-CTO at Magento (TechCrunch reported), it was just a matter of time until Magento was forked. Indeed, as Vinai Kopp pointed out on twitter, there have been some forks of Magento already (project agent-ohm, a fork of Magento 1.3), but Mage+ seems to be another case.

    What are the reasons of the fork of Magento? And what's in it for the Magento community?


    Continue reading "Magento CE 1.7 forked on GitHub"
  • Permalink for 'Query parameter handling in Symfony2'

    Query parameter handling in Symfony2

    Posted: May 12th, 2012, 8:02am MDT by Lukas Smith

    So this topic has been going back and forth in my head a lot over the last months: how do we best handle query parameters in Symfony2? Obviously you can already access query parameters today already but it could be easier. Essentially what I want is a way for developers to easily configure what query parameters they expect and what values they expect. This is useful for several things like easier reading and validating of query parameters, self documenting API both for API docs for humans but also for machines. Now thanks to Alexander we have a solution that works. But there is the big question if this is really the right approach. For now ignore the fact that it only works with annotations for now, because that is fixable. But it does point to the question if this shouldn't be integrated into the routing configuration itself by adding query support for our implementation of uri-templates.

    While this at first seems like the right place for this sort of configuration, it raises the questions of its own since path parameters (i.e. /{foo}) should be handled differently than query parameters (i.e. /{?bar}). For one I don't think that a mismatch on a route requirement of a query parameter cause the route to not match. However then it can quickly become confusing for the end user or it would require adding more and more syntax to handle all the different cases.

    Feedback much appreciated!

    Update: I have just merged the change to FOSRestBundle.

Nettuts+

  • Permalink for 'How to Convert a Widget into a Joomla Module'

    How to Convert a Widget into a Joomla Module

    Posted: May 11th, 2012, 7:00am MDT by KazKarizmatic

    This tutorial will cover the process of creating a basic Joomla module from an existing widget. We’re going to take a widget from Mixcloud, learn how to convert it into a Joomla module and, finally, distribute the extension to JED (Joomla Extension Directory).

    If you’ve never created a Joomla module before, this article is the best place to start!

    Step 1: Setting up Our Files Basic Files

    For every module created for Joomla, there are two files that absolutely need to be present. One file is a configuration XML file that will hold the module details and parameters and a PHP file that will control our module. For the purpose of this tutorial, we will create a folder called mod_mixcloud_widget and, within it, using your favorite code editor, create mod_mixcloud_widget.php and mod_mixcloud_widget.xml. Before we move on to the next step, create a single HTML file named index.html.The index.html file that was created will be used to hide the contents of the module folder when viewing via a browser.

    Template Files

    Now that you’ve added the core files, it’s time to add the template files. We do this by creating a folder called tmpl. Within that folder, we create default.php and index.html. The file default.php will be the module template that will take generated information and output them into clean HTML format on the page.

    Language Files

    Lastly, while inside our root module folder, we create a new folder called language. This folder will have two files: en-GB.mod_mixcloud_widget.ini and en-GB.mod_mixcloud_widget.sys.ini which will be used to make our module internationable with the option of having different languages.

    Final File Structure

    After following each step, you should have the following file structure

    • language/en-GB.mod_mixcloud_widget.ini
    • language/en-GB.mod_mixcloud_widget.sys.ini
    • tmpl/default.php
    • tmpl/index.html
    • index.html
    • mod_mixcloud_widget.php
    • mod_mixcloud_widget.xml
    Step 2: Setting Up Our XML File

    Each Joomla Extension installed has an XML file, which is referred to as a manifest or Install file. This file contains metadata details, such as author, version, description etc. It is also used as a configuration file for module prameters. For the purpose of this tutorial, we will be creating a manifest file for a Joomla 2.5 module. Add the following snippet to your XML file.

    <?xml version="1.0" encoding="utf-8"?>
    <extension 	type="module"	version="2.5"	client="site"	method="upgrade">
    	<name>MOD_MIXCLOUD_WIDGET</name>
    	<author>B4ucode</author>
    	<creationDate>May 2012</creationDate>
    	<copyright>Copyright (C) 2011 - 2012. All rights reserved.</copyright>
    	<license>GNU General Public License version 2 or later;</license>
    	<authorEmail>info@b4ucode.com</authorEmail>
    	<authorUrl>www.b4ucode.com</authorUrl>
    	<version>1.0.0</version>
    	<description>MOD_MIXCLOUD_WIDGET_XML_DESCRIPTION</description>
    

    The primary tag extension has a few attributes:

    • type: Tells Joomla what type of extension is being installed, in this case module.
    • version: Instructs the installer what version of Joomla we are creating the module for.
    • method: There are two options: new and upgrade. We will be using upgrade, in case of any future updates to the module, it will simply upgrade what is currently there.
    • client: Instructs whether the module is a front-end or back-end module.

    The other set of tags are metadata tags which hold information about the module which will be used during installation and the administration of the module.

    Module Files

    As mentioned before, the manifest file holds information about the files used in the module. During installation, Joomla checks the manifest file for all the files that should be added to the system. If any of the files are missing, then Joomla will give an error explaining the files that are missing. Any files found in the module, that aren’t listed in the XML file are not added to the system with the others. Add the following snippet to your manifest file.

    	<files>
    		<filename module="mod_mixcloud_widget">mod_mixcloud_widget.php</filename>
    		<folder>tmpl</folder>
    		<filename>index.html</filename>
    		<filename>mod_mixcloud_widget.xml</filename>
    	</files>
    

    Instead of writing a line for each file in a folder, we simply use the folder element. This element will instruct the installer to install all the files in this folder.

    Language Files

    This element holds the language files that are to be installed with the module. For the purpose of this tutorial, only one language will be used. When there are more languages, you can simply change the prefix of the files and the tag attribute to the exact language based on the Joomla framework.

    	<languages>
    		<language tag="en-GB">language/en-GB.mod_mixcloud_widget.ini</language>
    		<language tag="en-GB">language/en-GB.mod_mixcloud_widget.sys.ini</language>
    	</languages>
    
    Adding Parameters

    Some extensions don’t work right out of the box, but need certain settings added: these settings are called, parameters, and are defined in the manifest file.

    The first element is config which holds other elements that will be displayed in HTML format. The element called field is the meat of our parameters where you can define what type of form data you wish to display. This element at its basic level is made up of some core attributes:

    • type: Type of form field like text, textarea, checkboxes, radio and calendar.
    • name: The name element of the form field to displayed.
    • default: Default value of the field.
    • label: Text displayed at the beginning of our form field.
    • description: Description that will be shown in a tooltip when hovering on our form field
    • There are different attributes as they vary per form field type like size, filter, exclude, directory and more.

      	<config>
      		<fields name="params">
      			<fieldset name="basic">
      				<field type="text" name="feed" default="" label="MOD_MIXCLOUD_WIDGET_FEED_TITLE" description="MOD_MIXCLOUD_WIDGET_FEED_DESC" />
      				<field name="color" type="color" default="" label="MOD_MIXCLOUD_WIDGET_COLOR_TITLE" description="MOD_MIXCLOUD_WIDGET_COLOR_DESC" />
      				<field name="width" type="text" default="300" size="40" label="MOD_MIXCLOUD_WIDGET_WIDTH_TITLE" description="MOD_MIXCLOUD_WIDGET_WIDTH_DESCRIPTION" />
      				<field name="height" type="text" default="300" size="40" label="MOD_MIXCLOUD_WIDGET_HEIGHT_TITLE" description="MOD_MIXCLOUD_WIDGET_HEIGHT_DESCRIPTION" />
      			</fieldset>
      			<fieldset
      				name="advanced">
      				<field
      					name="layout"
      					type="modulelayout"
      					label="JFIELD_ALT_LAYOUT_LABEL"
      					description="JFIELD_ALT_module_LAYOUT_DESC" />
      				<field
      					name="moduleclass_sfx"
      					type="text"
      					label="COM_moduleS_FIELD_moduleCLASS_SFX_LABEL"
      					description="COM_moduleS_FIELD_moduleCLASS_SFX_DESC" />
      				<field
      					name="owncache"
      					type="list"
      					default="1"
      					label="COM_moduleS_FIELD_CACHING_LABEL"
      					description="COM_moduleS_FIELD_CACHING_DESC">
      					<option value="1">JGLOBAL_USE_GLOBAL</option>
      					<option	value="0">COM_moduleS_FIELD_VALUE_NOCACHING</option>
      				</field>
      			</fieldset>
      		</fields>
      	</config>
      </extension>
      

      You may notice that we have written labels and description in some uppercase characters like MOD_MIXCLOUD_WIDGET_FEED_TITLE. These are strings that we will make translatable when creating our language files.

      Finished XML File

      If you’ve followed thus far, you should have a completed XML File like following

      <?xml version="1.0" encoding="utf-8"?>
      <extension 	type="module"	version="2.5"	client="site"	method="upgrade">
      	<name>MOD_MIXCLOUD_WIDGET</name>
      	<author>B4ucode</author>
      	<creationDate>May 2012</creationDate>
      	<copyright>Copyright (C) 2011 - 2012 Open Source Matters. All rights reserved.</copyright>
      	<license>GNU General Public License version 2 or later;</license>
      	<authorEmail>info@b4ucode.com</authorEmail>
      	<authorUrl>www.b4ucode.com</authorUrl>
      	<version>1.0.0</version>
      	<description>MOD_MIXCLOUD_WIDGET_XML_DESCRIPTION</description>
      	<files>
      		<filename module="mod_mixcloud_widget">mod_mixcloud_widget.php</filename>
      		<folder>tmpl</folder>
      		<filename>index.html</filename>
      		<filename>mod_mixcloud_widget.xml</filename>
      	</files>
      	<languages>
      		<language tag="en-GB">language/en-GB.mod_mixcloud_widget.ini</language>
      		<language tag="en-GB">language/en-GB.mod_mixcloud_widget.sys.ini</language>
      	</languages>
      	<config>
      		<fields name="params">
      			<fieldset name="basic">
      				<field type="text" name="feed" default="" label="MOD_MIXCLOUD_WIDGET_FEED_TITLE" description="MOD_MIXCLOUD_WIDGET_FEED_DESC" />
      				<field name="color" type="color" default="" label="MOD_MIXCLOUD_WIDGET_COLOR_TITLE" description="MOD_MIXCLOUD_WIDGET_COLOR_DESC" />
      				<field name="width" type="text" default="300" size="40" label="MOD_MIXCLOUD_WIDGET_WIDTH_TITLE" description="MOD_MIXCLOUD_WIDGET_WIDTH_DESCRIPTION" />
      				<field name="height" type="text" default="300" size="40" label="MOD_MIXCLOUD_WIDGET_HEIGHT_TITLE" description="MOD_MIXCLOUD_WIDGET_HEIGHT_DESCRIPTION" />
      			</fieldset>
      			<fieldset
      				name="advanced">
      				<field
      					name="layout"
      					type="modulelayout"
      					label="JFIELD_ALT_LAYOUT_LABEL"
      					description="JFIELD_ALT_module_LAYOUT_DESC" />
      				<field
      					name="moduleclass_sfx"
      					type="text"
      					label="COM_moduleS_FIELD_moduleCLASS_SFX_LABEL"
      					description="COM_moduleS_FIELD_moduleCLASS_SFX_DESC" />
      				<field
      					name="owncache"
      					type="list"
      					default="1"
      					label="COM_moduleS_FIELD_CACHING_LABEL"
      					description="COM_moduleS_FIELD_CACHING_DESC">
      					<option value="1">JGLOBAL_USE_GLOBAL</option>
      					<option	value="0">COM_moduleS_FIELD_VALUE_NOCACHING</option>
      				</field>
      			</fieldset>
      		</fields>
      	</config>
      </extension>
      
      Step 3: Creating mod_mixcloud_widget.php

      The first thing you want to with your module is to add your copyright notice. If you intend to submit your module to JED [Joomla Extension Directory], you should add some GPL license information.

      This is one of the checks done before approving a module into the directory. Directly below this, I use the statement defined('_JEXEC') or die; which is used in most PHP files to protect against hackers. This is also another requirement for approval on JED.

      <?php
      /**
       * @package		B4ucode
       * @subpackage	mod_mixcloud_widget
       * @copyright	Copyright (C) 2011 - 2012 B4ucode, Inc. All rights reserved.
       * @license		GNU General Public License version 2 or later;
       */
      // no direct access
      defined('_JEXEC') or die;
      

      Next, we define our paramaters as variables. Developers sometimes define their paramaters as variables in order to have cleaner template files. In order to call a paramaters we use the $params->get() function and get the param name defined in our manifest file. Finally, we call the module Helper function, getLayoutPath, which will render our module template. The first argument of the function takes the module name that we are trying to call, then the second argument looks for the template we intend to render for that module. In this case, we get the parameter layout and in the second argument we set the default layout to be default. This layout is the exact name of the file that we have in our tmpl folder.

      $width = $params->get('width',300);
      $height = $params->get('height',300);
      $feed = $params->get('feed');
      $color = $params->get('color');
      $moduleclass_sfx = htmlspecialchars($params->get('moduleclass_sfx'));
      require JmoduleHelper::getLayoutPath('mod_mixcloud_widget', $params->get('layout', 'default'));
      ?>
      
      Finished File
      	<?php
      /**
       * @package		B4ucode
       * @subpackage	mod_mixcloud_widget
       * @copyright	Copyright (C) 2011 - 2012 B4ucode, Inc. All rights reserved.
       * @license		GNU General Public License version 2 or later;
       */
      // no direct access
      defined('_JEXEC') or die;
          $width = $params->get('width',300);
          $height = $params->get('height',300);
          $feed = $params->get('feed');
          $color = $params->get('color');
          $moduleclass_sfx = htmlspecialchars($params->get('moduleclass_sfx'));
          require JmoduleHelper::getLayoutPath('mod_mixcloud_widget', $params->get('layout', 'default'));
      ?>
      
      Step 4: Creating default.php

      At this point, we have created our manifest file with paramaters, took those same parameters and turned them into variables. In this step, we are going to use those variables in our template file. The template file will render all of our HTML for the module. Edit default.php from your tmpl folder and add the following snippets:

      Copyright Notice and Restricted Access Script
      <?php
        /**
       * @package		B4ucode
       * @subpackage	mod_mixcloud_widget
       * @copyright	Copyright (C) 2011 - 2012 B4ucode, Inc. All rights reserved.
       * @license		GNU General Public License version 2 or later;
       */
       // no direct access
      defined( '_JEXEC' ) or die( 'Restricted access' );
      

      It is recommended that you add the Copyright Notice and Restricted Access line to your PHP files.

      Adding our HTML

      For this tutorial, we will need the embed code from Mixcloud. Here is an example on getting the code . Our module’s purpose is to make the code reusable without having to get the embed each time we want to create or modify a Mixcloud Widget on our site. The default embed code comes with some extra information about the widget content which we don’t need. So for this tutorial, I have stripped it down to just the embed script. Paste this embed code to your default.php file.

      <div><object width="480" height="480"><param name="movie" value=" [www.mixcloud.com] name="allowFullScreen" value="true"></param><param name="wmode" value="opaque"></param><param name="allowscriptaccess" value="always"></param><embed src=" [www.mixcloud.com] type="application/x-shockwave-flash" wmode="opaque" allowscriptaccess="always" allowfullscreen="true" width="480" height="480"></embed></object></div>
      
      Making the Script Configurable

      If we wanted to embed one widget permanently, we could just zip up the module right now. However we don’t, so we are going to replace some of the attributes with our module params . We’re going to change the width, height, color and feed. Paste the following snippet over your embed script.

      	<div><object width="<?php echo $width; ?>" height="<?php echo $height; ?>">
      <param name="movie" value=" [www.mixcloud.com] echo $feed; ?>&amp;embed_uuid=&amp;stylecolor=<?php echo $color; ?>&amp;embed_type=widget_standard"></param><param name="allowFullScreen" value="true"></param><param name="wmode" value="opaque"></param><param name="allowscriptaccess" value="always"></param><embed src=" [www.mixcloud.com] echo $feed; ?>&amp;embed_uuid=&amp;stylecolor=<?php echo $color; ?>&amp;embed_type=widget_standard" type="application/x-shockwave-flash" wmode="opaque" allowscriptaccess="always" allowfullscreen="true" width="<?php echo $width; ?>" height="<?php echo $height; ?>"></embed></object>
      </div>
      

      Take note of how we are just calling the variables from our controller file.

      Step 5: Creating Language Files

      In step one, you might have noticed that we created a folder, called language, with two files. Then, in step two, we added some translatable text. In this section, we are going to translate that text to English. Insert the following snippet to the ini files, en-GB.mod_mixcloud_widget.sys.ini and en-GB.mod_mixcloud_widget.ini.

      ; B4ucode
      ; Copyright (C) 2011 - 2012 B4ucode. All rights reserved.
      ; License GNU General Public License version 2 or later;
      ; Note : All ini files need to be saved as UTF-8 - No BOM
      
      MOD_MIXCLOUD_WIDGET="Mixcloud Widget"
      MOD_MIXCLOUD_WIDGET_XML_DESCRIPTION="This module displays the Mixcloud Widget using feed and other paramaters"
      MOD_MIXCLOUD_WIDGET_ITEMS_LAYOUT_DEFAULT="Default"
      MOD_MIXCLOUD_WIDGET_FEED_TITLE="Feed Url"
      MOD_MIXCLOUD_WIDGET_FEED_DESC="Add the link to single/cloudcast"
      MOD_MIXCLOUD_WIDGET_COLOR_TITLE="Color"
      MOD_MIXCLOUD_WIDGET_COLOR_DESC="Add Style color"
      MOD_MIXCLOUD_WIDGET_WIDTH_TITLE="Width"
      MOD_MIXCLOUD_WIDGET_WIDTH_DESCRIPTION="Width of Widget"
      MOD_MIXCLOUD_WIDGET_HEIGHT_TITLE="Height"
      MOD_MIXCLOUD_WIDGET_HEIGHT_DESCRIPTION="Height of Widget"
      

      If you look closely, you will notice that the text I used for the parameters now have an English translation. You can add other files and create translations in other languages!

      Step 6: Packaging the Module

      After following all the steps thoroughly, your module is now installable, but we’d like to make a checklist of things to do before installation and distribution.

      Add index.html to Folders

      It is recommended that you add a index.html file to each folder. This file, as mentioned previously, stops users from viewing the contents of a module folder directly in a browser. Add the following snippet to your files:

      	<html><body bgcolor="#FFFFFF"></body></html>
      
      Comparing our File Structure to the Manifest File

      At this stage, it is recommended that you look at the files and folder defined in your manifest file, and make sure they exist in your module folder. Any file that does not exist can stop the installer from installing files, or, it may throw an error.

      Packaging

      After our little checklist, we can package the module into a zip file, and install it.

      By navigating to the modules manager, and selecting the module, you can modify the paramaters with your desired width, height, color and song feed.

      Enable the module and check to see if it operates the way that it should.

      Step 7: Submitting to JED Locating the Category

      After registering to JED, one of the main things to note is that you cannot add an extension to multiple sections. So, choosing the appropriate section is very important. Find a suitable section by browsing the site then looking at the top left cornder you will see Submit Extension

      Filling Out the Details

      Once you’ve chosen to submit an extension, there will be a form to fill in all the details about your submission. Review the screenshots below to see the different fields to be filled out, and read the instructions carefully.

      Success Image

      Once all the appropriate fields and files have been submitted, you will see a message like the screenshot above; it will explain how many submissions are in the queue to be checked prior to yours.

      Conclusion

      Now that you’ve learned how to create a Joomla module from a widget, go forth and code. With the basics of this tutorial, the same idea can be applied to Facebook plugins, Twitter widgets, Social bookmarkers, Youtube video embeds, and so much more. Happy Coding!


Planet PHP

  • Permalink for 'Nelmio is coming to a conference near you'

    Nelmio is coming to a conference near you

    Posted: May 11th, 2012, 4:19am MDT by Nelmio

    Here is a quick update on conferences we will attend and speak at in the next couple months. If you are attending any, feel free to come and say hi!

    Next week our entire team will be at jsDay and phpDay in Verona, Italy. If you haven’t got tickets yet, hurry up because it is about to be sold out.

    Pierre will talk about Backbone.js, Igor has two talks about realtime apps with websockets and the Silex microframework and I myself will be talking about managing your dependencies with Composer.

    In June there are two notable events. The first is SwissJeese. A local JavaScript-oriented conference co-organized by Pierre that will be in Bern. It is free and on a Saturday so there is really no excuse not to come if you have an interest in JavaScript. Register for free on eventbrite!

    The second a week later is Symfony Live in Paris which we are always looking forward to.

    If you get a chance to go to both phpDay and Symfony Live, you can follow Igor’s second talk about Silex, which will be more advanced given the audience is already more familiar with the Symfony Components. If you miss Verona you can catch up on my Composer talk in Paris as well. William will hold an introduction to the Propel2 ORM and even you have no interest in PHP I will present the Redis key-value store so you can come anyway ;)

    We sure hope to see some old friends and make new ones there, so if you were hesitant to come, just register before it’s too late!

Nettuts+

  • Permalink for 'Aspect-Oriented Programming in PHP'

    Aspect-Oriented Programming in PHP

    Posted: May 10th, 2012, 8:01am MDT by Chris Peters

    There’s a new player in town, and he brought new toys: The PHP World welcomes FLOW3, an enterprise application framework written and backed by the community of the TYPO3 CMS. FLOW3 can be used as standalone full-stack framework for your applications. It’s interesting, because it introduces some concepts of software development that haven’t been adapted to PHP before.

    Among these new concepts is “Aspect Oriented Programming”. We will have a look on the theory of the pattern, and will set up a basic FLOW3 Application and weave in our own aspect!

    Why Should I Care?

    If a new framework hits stable, an excellent question to rise might be: What can it do that the tools that I love can’t?

    PHP already has an armada of excellent frameworks and most of them claim to be written with separation of concerns in mind. So does FLOW3.

    In terms of software development this means, that the classes that are implementing the logic of your application should only care about one thing. For example, a mailer class should send mails. It should not retrieve potential receivers from a database.

    All modern frameworks (including FLOW3) push a lot of patterns into the software stack that do a great job at separating the concerns of your business logic; among them the famous MVC that is separating your logic into different layers.

    However, an application is not only built on business logic alone. As it grows, you may want to implement additional services, features, plugins or plugins of plugins. You surely don’t want this stuff in your business logic! But what are your options?

    Let’s say you want to implement a logging service that writes some stuff to a text file every time a specific set is deleted from the database. Naturally, the logging service is not part of your database layer. But in order to make it work, you have to place some code right there, like this:

    /**
     * Delete a user
     * @param UserModel $user
     * @return void
     */
    public function deleteUser(UserModel $user) {
    $this->loggingService->log('removing user ' . $user->getName());
    $this->users->remove($user);
    }
    

    Horrible, isn’t it? Let’s face it: The logging service adds dirt to your code. You have to touch the original code in order to implement it and you add an additional dependency, in this case an instance of the LoggingService.

    Hence, you’re adding complexity. And you likely will have to add it all over your app (depending on what else you want to log).

    You may come up with an pattern like an event dispatcher or a hook system like it’s implemented in Drupal and WordPress and then have your logger listen for events:

    /**
     * Delete a user
     * @param UserModel $user
     * @return void
     */
    public function deleteUser(UserModel $user) {
    $this->eventDispatcher->dispatch(self::USER_DELETED);
    $this->users->remove($user);
    }
    

    This is better, but it’s still not cool. You’re code is still dependency aware: it has some code with the sole purpose of informing other parties that something happens.

    This has some bad side-effects: What if you want to log something, but there’s not an event dispatched at that time? What if you haven’t written that code because you are writing a plugin? You’d have to change the original code – not once, but every time an update is available.

    Let’s call the logging service an aspect and see how FLOW3 takes care of the problem.

    Aspect Weaving

    Our logging service is only interested in one thing regarding the existing code: It wants to intercept it in some classes at various points (e .g. when something is deleted). With the implementation discussed above, the existing code controls the points of execution.

    Wouldn’t it be nice if the service could define a set of rules at which point it would want to inject itself into the class?

    This is a software development concept named Inversion of control. It decouples classes from another, because there’s no need to change existing code when you’re changing the service. The service takes care of this itself.

    Let’s say we simply want to execute logging on every method in every class that starts with delete, like deleteUser(), deleteEntry() or whatever. A convenient way would be to write a rule into the logging service and let the framework take care of the correct execution of the code. This is remarkably easy in FLOW3:

    /**
     * An aspect that is executed on all methods that start with "delete".
     *
     * @FLOW3\Before("method(.*->delete.*())")
     */
     public function logginMethod() {
    // Do some logging here.
     }
    

    FLOW3 performs some really advanced PHP techniques under the hood.

    The rule is named pointcut in AOP and there are some easy-to-learn ways to define them. The one above tells FLOW3 to inject the logging code in every class before every method that starts with delete.

    It does so by using the method keyword and by adding wildcards (*) for the class and for parts of the method name. If you’re adding this code in an Aspect Class (as we do later), you’re good to go. You will be able to access properties of the class that you are targeting as well. The targeted class itself remains untouched. It may not yet be written – if it’s added to your app in the future, the rule will then match and the code will be injected.

    Maybe you have read the above paragraph twice and are asking yourself: Is this magic? What’s the damn trick? – I sure did, when I was first introduced to AOP!

    Well, AOP has been around for some time in the Java world. FLOW3 is heavily inspired by the AOP implementation of Spring, a Java Framework. The word was on the street, that the pattern can’t be transferred to interpreted languages, because it requires compilation.

    The trick is, that the framework – or some tools like JAspect – intercepts the compilation process (from Java code to bytecode, that can be executed by the Java runtime) and do an analysis of the defined aspects. Whenever a set of rules (aka the pointcut) matches a method, it is weaved directly into the compiled code. Hence, the framework takes care of merging the code parts together:

    FLOW3 did adapt that concept to the world of PHP by introducing an advanced cache. While most frameworks offer caching to increase performance, FLOW3 additionally uses the cache to weave aspects into the original classes.

    If you are running your app, FLOW3 delivers the cached classes instead the ones you’ve written. Hence, your original code remains untouched.

    This sounds complex – and it is: FLOW3 performs some really advanced PHP techniques under the hood, that are well worth to be explored! But: To you as an application developer, it’s not complicated at all. You don’t have to care, if you don’t want to: FLOW3 monitors your files for changes and if you make some, FLOW3 auto-commits them to the cache upon your next request. If an aspect matches to a method, it’s automatically weaved in – no further configuration needed.

    It’s a complex pattern conveniently at your service!

    A Few Words About the Cache

    Every cool feature comes with a downside – so does FLOW3. At the moment, we just scratched the surface of what FLOW3′s caching-mechanism is capable of, but I want to give you an idea.

    Take a look at the following code:

    /**
     * @FLOW3\Inject
     * @var \YourApp\MailerServiceInterface
     */
     protected $mailer;
    /**
     * Sends a mail.
     *
     * @param \YourApp\Model\User $user
     * @param string $message
     */
     protected function sendMail(\YourApp\Model\User $user, $message) {
         // Sends a mail.
     }
    

    The consequence is that PHP is to some degree no longer an interpreted language.

    This may look like some code that is just well documented. But it’s much more.

    The first property annotation (FLOW3\Inject) tells FLOW3 to look for some class in your app that implements the MailerServiceInterface and injects it here (and maybe configure it before). This pattern is known as Dependency Injection.

    The second class defines some type definitions in its comment’s annotations – and FLOW3 uses them. If you’re giving the method some data that can be used to build a User object of your model (for example an array with pure strings from a HTML form), FLOW3 auto-transforms the data safely to a User object and applies some security and validation rules to the second parameter (in this case a string).

    This is (among some other tricks) done by weaving in some code into the cache.

    The consequence is that PHP is to some degree no longer an interpreted language. The process of caching is somewhat similar to compiling and it has the same downsides: You can’t just save & refresh your browser, you have to wait for the cache to be warmed up during development. If you are committing code to your production environment, you have to flush the cache in order to see the changes.

    On top of that, FLOW3 adds some kind of type-validation at runtime: You can’t pass an integer as second argument in the example above – it’ll throw an error. I really like this, because I have a background in strictly typed languages like Java and ActionScript. It also adds a lot of security to your application. But if you’re a PHP purist, this may be something that you don’t want.

    Setting Up Flow3

    Alright, enough with theory. Let’s get our hands dirty.

    Setting up FLOW3 is pretty straightforward, if you already have a PHP-capable server like XAMP or MAMP installed. Just grab a copy of the framework from FLOW3′s download site (or clone from git) and unpack it into your htdocs directory.

    You should already be done now on Windows machines. Unix-based systems like MAC or Linux need to grant the required rights for building the cache. FLOW3 ships with a powerful command line tool, that packs this task into a one-liner:

    # On linux:
    ./flow3 core:setfilepermissions chris www-data www-data
    # On Mac:
    ./flow3 core:setfilepermissions chris _www _www
    

    Please replace chris with your username! This should be enough. However, I’ve installed FLOW3 on
    various machines and have run into some problems. The most common ones are:

    • If you’re on MAC and FLOW3 complains “index.php not found “, open the .htaccess in the webdir and add a # before the line Rewrite Base /“–
    • If you’re on Windows and the command line tool does not work, open Settings.yaml.example in FLOW3′s configuration directory, uncomment and adjust the phpBinaryPathAndFilename variable to the correct path (e.g. C:\xampp\php\php.exe) and save the file as Settings.yaml

    • On some machines, if FLOW3 is very slow, you have to increase the memory limit of PHP in the php.ini

    If you run into problems, that are not listed here, please post them in the comments!

    Now fire up your favorite browser and navigate to [localhost] FLOW3 should welcome you with an introduction screen:

    The first run may take a while, as FLOW3 has to index your code and build all caches.

    This is the Welcome Package. Every application in FLOW3 (and FLOW3 itself) is a package and packages can share code with each other. For example, once the new TYPO3 Version is finished, you can add it as a package and your application will then have an enterprise-ready CMS on top!

    Let’s start our own package. It’s an easy task, because FLOW3′s command line tool will handle most of the work! Type in the following command:

    # On linux / MAC
    ./flow3 kickstart:package Nettuts.AspectDemo
    # On Windows
    flow3 kickstart:package Nettuts.AspectDemo
    

    This will create a ready-to-go package named Nettuts.AspectDemo in FLOW3′s Packages/Application folder. If you review the file structure, you will find many folders that do follow a specific convention.

    The important ones are:

    • Classes: The home of your PHP Code, a first Controller is already created in the Classes/Controller Folder: the StandardController!
    • Resources/Private: The home of all templates that are fired into Fluid, FLOW3′s powerful Templating Engine. It hosts some other stuff like localization files as well.
    • Resources/Public: This has not been created yet, but every file in the Resources/Public folder will be directly accessible from the web. This is a good place for images, CSS, Javascript etc.

    Building a full-featured app is beyond the scope of this tutorial, so we’ll go with the defaults. Please open the following URL: http://localhost/flow3/Web/index.php/Nettuts.AspectDemo

    This is not much, but it’s a start. We want to write something to a logfile, every time this site is called. We do this by weaving in an aspect into the StandardController!

    Writing a First Aspect

    Take a look at the StandardController in theClasses/Controller Folder in your Nettuts.AspectDemo Package.

    It implements a method, named indexAction(). FLOW3 has automatically configured our app in a way, that this method inside the StandardController gets called when we enter the URL above.

    For the moment, we see that this method assigns some strings to the view:

    /**
     * Index action
     *
     * @return void
     */
    public function indexAction() {
    $this->view->assign('foos', array(
    'bar', 'baz'
    ));
    }
    

    If you open the file index.html of this view in Resources/Private/Templates/Standard inside our package, you’ll see how these strings are processed by the templating engine.

    However, our goal is to intercept the code execution before this method gets called.

    At first, create an empty file named Access.log in FLOW3′s Log folder at flow3/Data/Logs. You may save this file wherever you want, but this is a nice place for log files.

    Next, create a folder named Service in your Nettuts.AspectDemo/Classes Folder and inside of it, create another folder, and name it Logging. Then create a PHP file named LoggingAspect.php inside of it. It should have the following content:

    <?php
    namespace Nettuts\AspectDemo\Service\Logging;
    use TYPO3\FLOW3\Annotations as FLOW3;
    /**
     * @FLOW3\Aspect
     */
    class LoggingAspect {
       /**
        * Log a message if this site is called.
        *
        * @param \TYPO3\FLOW3\AOP\JoinPointInterface $joinPoint
        * @FLOW3\Before("method(Nettuts\AspectDemo\Controller\StandardController->indexAction())")
        * @return void
        */
       public function logSiteAccess(\TYPO3\FLOW3\AOP\JoinPointInterface $joinPoint) {
               $filePath = '/home/chris/www/flow3/Data/Logs/Access.log';
         $message = 'The site has been accessed at ' . time() . '.' . PHP_EOL;
         file_put_contents($filePath, $message, FILE_APPEND);
       }
    }
    ?>
    

    This is a very basic class, and if you’d like to have an advanced logger, you may want to separate the logging from the intercepting aspect.

    What’s going on here? At first, we define a namespace, which is your package name and the path to the actual class (without the class folder itself). Next, we import FLOW3′s annotation namespace. Thus, we can use FLOW3′s powerful annotation parser to configure our class.

    That’s exactly what we do in the class comments. We define the class as aspect with the following annotation:

    /**
     * @FLOW3\Aspect
     */
    

    From now on, FLOW3 is aware that this class may define rules for the interception of the code flow and watches our codebase for matches.

    This is the rule:

    @FLOW3\Before("method(Nettuts\AspectDemo\Controller\StandardController->indexAction())")
    

    We could use regular expressions or some other techniques to match multiple methods or classes, but we know exactly where we want to go: Before the indexAction() Method in the StandardController – and that’s exactly what we’re telling FLOW3.

    Note the $jointInterface Parameter of the logSiteAccess() Method, that is provided to us by FLOW3. We don’t use it here, but it contains some useful data about the actual context. For example, if the intercepted method would have arguments, that we may want to use, we could access them like this:

    $argument = $joinPoint->getMethodArgument('argumentName');
    

    The code in our logSiteAccess() method, itself, is fairly simple. Just adjust the path to the Access.log to your environment and you’re good to go!

    Now, again, open http://localhost/flow3/Web/index.php/Nettuts.AspectDemo – nothing should have changed. But when you open the Access.log file, you should see the following entry:

    The site has been accessed at 1335715244.
    

    If you can read this, the aspect has been weaved into the cache. Let’s have a look at the magic!

    FLOW3 stores the cache at flow3/Data/Temporary/Development/Cache/Code/FLOW3_Object_Classes.

    You will find a class named Nettuts_AspectDemo_Controller_StandardController_Original.php. This is the original class from our codebase.

    But there is another class: Nettuts_AspectDemo_Controller_StandardController.php. This class extends our original class and it is build up purely by generated code. Among the many lines you’ll find something like this:

    $this->FLOW3_Aop_Proxy_targetMethodsAndGroupedAdvices = array(
       'indexAction' => array(
          'TYPO3\FLOW3\Aop\Advice\BeforeAdvice' => array(
             new \TYPO3\FLOW3\Aop\Advice\BeforeAdvice(
             'Nettuts\AspectDemo\Service\Logging\LoggingAspect', 'logSiteAccess'
             $objectManager, NULL),
             ),
          ),
    );
    

    This is were FLOW3 initiates the aspect and it’s weaved in directly into your class. The aspect gets executed right where we want it – without touching the original controller.

    The code snippet initiates an instance of the BeforeAdvice class, with our aspect, the respective method and the $objectManager as arguments. The object manager contains the needed information to build the jointInterface, that is passed to the aspect.

    If you’re interested in the details, have a look at the AOP Folder in the FLOW3 package!

    Conclusion

    The aspect oriented approach has many advantages waiting to be discovered.

    The aspect oriented approach has many advantages waiting to be discovered. For example, FLOW3 uses AOP to intercept its own bootstrap to build up a firewall if you choose to use FLOW3′s security framework. Apart from that, we haven’t yet discussed the specific terminology that is commonly used in AOP.

    However, FLOW3 ships with some other unique concepts like Domain-Driven-Design. It has a powerful Doctrine integration and a smart Templating Engine. We have only seen the tip of the iceberg!

    What’s your opinion? Are you eager to learn more about the philosophy behind FLOW3? What’s your impression of AOP? Are you excited to have a robust port for the PHP world or do you think it’s too much overhead for an interpreted language?


Planet PHP

  • Permalink for 'Talk - Don't Be Stupid, Grasp Solid - NYPHP'

    Talk - Don't Be Stupid, Grasp Solid - NYPHP

    Posted: May 10th, 2012, 8:00am MDT by Anthony Ferrara
    Time for some more shameless self-promotion...  I'll be doing a talk at the New York PHP group on Tuesday May 22, 2012. I'll be discussing some Object Oriented design principles and how to apply them to your projects. We'll specifically discuss the STUPID and SOLID principles. Here's the full abstract:
    When it comes to Object Oriented Programming, there is no shortage of guidelines and principles for how to properly design an OO system. There is also no shortage of acronyms to describe these principles: DRY, SRP, LSP, LoD, ISP, OCP, etc. However, there are two acronyms that really shine through to describe how to, and how not to do OOP well. The two acronyms are SOLID and STUPID (respectively). We'll discuss some of the underlying principles of Object Oriented Programming, and how we can learn from the principles identified by each of these two acronyms. Additionally, we'll explore some additional anti-patterns of Object Oriented Design and how they can be avoided. Finally, we'll talk about how all of this applies to our every day development tasks, and the real-world benefit these design principles provide...

    If you plan on attending, be sure to RSVP first! If not, the talk will be streamed via ustream.
  • Permalink for 'State of PHPCR'

    State of PHPCR

    Posted: May 10th, 2012, 4:45am MDT by Lukas Smith

    It feels like every minute a PHP developer somewhere on this planet starts implementing something aching to a CMS from scratch. Some do it because their project is "so big" it that it "obviously needs" a custom solution. Some do it because their project is "so small" it "obviously needs" just a few days of hacking .. to build a custom solution. Let me briefly focus on the later group. Working in a company with less than 10 people building websites for customers a project needs a bit of a CMS to manage those 10 "semi static" pages seems to be the poster child example of this group. The devs whip up a DB table, slap an ORM in front, maybe even use some generator for the admin UI. Done. Later the clients also wants versioning and luckily many ORMs provide some solution for that. Easy. Permissions? Most frameworks provide some ACL system. Child pages? ORM has some tree algorithm supported. Fulltext search? Integrate ElasticSearch. Custom page types? Uhm well by now you have enough sunken costs that you will make that happen somehow too. Some morning you wake up and you have created the next Drupal or Typo3. If you did, then it would be hard to claim that you did it wrong because both are very successful projects. What PHPCR aims to be is to provide you with a short cut for this path. Or in other words there should be a PHPCR implementation that is so easy to use, with so many helpful higher level components in your favorite framework, that it becomes the natural choice for your next CMS needing project.

    Every time anyone talks about PHPCR, they will mention Jackrabbit sooner or later as it is the basis for the currently most mature PHPCR implementation. Here, I just did it too. Jackrabbit requires Java. More importantly it is not trivial and most of you have never heard about it, let alone used it. I think for many high scale use cases its great that PHPCR has been integrated with Jackrabbit, but it needs to be relegated to a side note you mention when someone starts talking about scaling to millions of documents and many GBs of data. Once there is a PHPCR implementation that works with pure PHP, using any RDBMS (including SQLite which is bundled with PHP) it will become easier to just use that instead of whipping up your own tables. No more convincing the sys-admin guy about adding a new daemon to the setup. Instead being able to tell the client what other features they could get in the next code sprint.

    So today, we are not there yet. We have an implementation of PHPCR that works on top of Doctrine DBAL to in theory support any RDBMS. Well in reality it already does though the search API only works with MySQL and PostgreSQL. It also doesn't support versioning and ACLs. Oh and if you drop more than 50 documents into it, search performance will start to hurt quickly. Bummer. But there is good news too. The core infrastructure is laid out thanks to Benjamin. Progress on it, while not rocket fast, is continuous thanks to Liip intern Adrien .. as a matter of fact if you go to our demo page it would run all but the admin interface on top of it just fine (yes this includes the cool inline editing!).

    I believe that a decently experienced database developer would need a man month to fix up the searching to perform decently unto lets say 1k documents as well as implement simple versioning on top of SQLite. Another 2 man months should enable implementing permissions and support for even more documents, ACLs and a few other goodies. Is this something that a 10 developer company can commit to when offering that simple CMS solution to one of their customers? Obviously not. This takes a few developers who are willing to invest into the future. Until they come along unfortunately PHPCR will continue to not be a viable option for many small CMS projects.

    Update: In this post I failed to mention that there is also already a pretty solid implementation of PHPCR written in C by the Midgard team. However just as a Java solution can't be our pitch, I believe that a custom extension cannot either.

  • Permalink for 'Getting PEAR Working On Windows 7'

    Getting PEAR Working On Windows 7

    Posted: May 10th, 2012, 2:30am MDT by Stuart Herbert

    So that I don’t forget how to do this next time around. Worked for me, your mileage may vary.

    First step is to get a working install of PHP.

    1. Download PHP 5.4.latest ZIP file from the PHP Windows website
    2. Unpack the ZIP file into c:\php. You should end up with c:\php\php.exe
    3. Copy c:\php\php.ini-development to be c:\php\php.ini
    4. Edit c:\php\php.ini to suit (e.g. set date.timezone)
    5. Make sure you add c:\php to your system PATH (via Computer’s Advanced Properties -> Environment Variables)
    6. Reboot (this is Windows, after all :)

    At this point, you should be able to open up a Command Prompt, and type ‘php -v’, and see the response ‘PHP v5.4.latest …’ appear as expected.

    Now for PEAR itself.

    1. Open [pear.php.net] in a browser, save this file into c:\php
    2. In a Command Prompt, cd to c:\php and then run “php c:\php\go-pear.phar”
    3. At the prompt, select ‘system’. A text menu of paths will appear
    4. Fix the default path for pear.ini (option 11) to be c:\php\pear.ini
    5. Fix the default folder to look inside for php.exe to be c:\php
    6. Make sure the binaries folder (option 4) is c:\php
    7. Check all of the other options, make sure they are prefixed with c:\php
    8. Press ENTER, and you should see PEAR downloading various PEAR packages onto your system
    9. Double-click the PEAR_ENV.reg file in c:\php
    10. Reboot again to make sure PEAR_ENV registry entries have taken effect

    At this point, PEAR is installed and should be available to use in your own projects, or with something like Phix.

    Personal Notes

    Some reminders to myself for the next time I have to do this.

    • Documentation for PHP for Windows and PEAR for Windows both seem to be out of step with current downloads. There’s currently no Windows installer for PHP available, and the PHP .ZIP file doesn’t contain the ‘go-pear.bat’ file.
    • You have to pay close attention to the default folders offered when running ‘go-pear.phar’. They appear to use the current working directory as the prefix even when installing system-wide, except for the location of pear.ini and php.exe – neither of these defaults are sane, and must be manually changed during the install :(
    • After install, pear command doesn’t seem to be 100% compatible with its behaviour on Linux and OS X. -D switch didn’t work, there may be other problems too that I haven’t yet found.
    • Both reboots are required – I’m not taking the piss there – for all running Windows apps to pick up the changes.

Nettuts+

  • Permalink for 'Which Tuts+ Site Should We Launch Next?'

    Which Tuts+ Site Should We Launch Next?

    Posted: May 9th, 2012, 7:18am MDT by David Appleyard

    We’re planning our next few Tuts+ sites, and would love your opinion and advice on which topics you think we should cover next! We’d be really grateful if you could take a minute to answer our quick poll and share your thoughts…

    Have Your Say
    Nettuts+ Readers: Which Tuts+ Site Should We Launch Next?

    We’ve been considering lots of different ideas for our next Tuts+ sites over the past few weeks, and wanted to also ask the opinion of our awesome community!

    A selection of different concepts are included in the poll to the right, along with the option for you to submit your own ideas as well.

    The important thing to note is that these are just ideas. Some of these are close to making our final cut, and others aren’t… We’d love to hear what you think, to help guide our decision.

    Thanks for taking the time to offer your suggestion — I can’t wait to see what you have to say!

    Win a 6-Month Tuts+ Premium Membership

    Our poll will be running for the next couple of weeks, and we’ll be choosing one respondent at random to receive a six-month Tuts+ Premium membership!

    To be entered into the giveaway, just leave a comment on this post to go into a bit more detail about your site suggestion. We’ll choose one comment at random to win the Tuts+ Premium membership when the poll ends.

    Best of luck!


Planet PHP

  • Permalink for 'License migration tool'

    License migration tool

    Posted: May 9th, 2012, 6:49am MDT by Lukas Smith

    So Benjamin just went and wrote a license migration tool, which he will hopefully soonish have time to release as OSS itself. So far things are going well. The tool basically reads out the list of authors and then can list up their commits. Here is for example my list of commits. As some users didn't use the same config for all their commits, we might have authors in our system that in the real world map to the same people. Via an admin tool we can manually update the emails. The system can generate a hash for each author and send out notification emails where the author can then approve or disapprove of the change .. or simply reply that we got the wrong email. Works great as can be seen in the projects overview except that some users have not configured an email address properly when they setup git. However the bigger issue are old contributors back in the svn days. While many of these commits technically do not need to be approved since the code is actually no longer found inside Doctrine, it would be still great to get their approval. So if you find yourself or someone you know in the list authors who has not yet approved, please let us know!

  • Permalink for 'Doctrine looking for feedback from its old contributors'

    Doctrine looking for feedback from its old contributors

    Posted: May 9th, 2012, 6:49am MDT by Lukas Smith

    So Benjamin just went and wrote a license migration tool, which he will hopefully soonish have time to release as OSS itself. So far things are going well. The tool basically reads out the list of authors and then can list up their commits. Here is for example my list of commits. As some users didn't use the same config for all their commits, we might have authors in our system that in the real world map to the same people. Via an admin tool we can manually update the emails. The system can generate a hash for each author and send out notification emails where the author can then approve or disapprove of the change .. or simply reply that we got the wrong email. Works great as can be seen in the projects overview except that some users have not configured an email address properly when they setup git. However the bigger issue are old contributors back in the svn days. While many of these commits technically do not need to be approved since the code is actually no longer found inside Doctrine, it would be still great to get their approval. So if you find yourself or someone you know in the list of authors who have not yet approved, please let us know!

Nettuts+

  • Permalink for 'Prototypes in JavaScript'

    Prototypes in JavaScript

    Posted: May 9th, 2012, 5:00am MDT by Leigh Kaszick

    When you define a function within JavaScript, it comes with a few pre-defined properties; one of these is the illusive prototype. In this article, I’ll detail what it is, and why you should use it in your projects.

    What is Prototype?

    The prototype property is initially an empty object, and can have members added to it – as you would any other object.

    var myObject = function(name){
        this.name = name;
        return this;
    };
    
    console.log(typeof myObject.prototype); // object
    
    myObject.prototype.getName = function(){
        return this.name;
    };
    

    In the snippet above, we’ve created a function, but if we call myObject(), it will simply return the window object, because it was defined within the global scope. this will therefore return the global object, as it has not yet been instantiated (more on this later).

    console.log(myObject() === window); // true
    The Secret Link

    Every object within JavaScript has a “secret” property.

    Before we continue, I’d like to discuss the “secret” link that makes prototype work the way it does.

    Every object within JavaScript has a “secret” property added to it when it is defined or instantiated, named __proto__; this is how the prototype chain is accessed. However, it is not a good idea to access __proto__ within your application, as it is not available in all browsers.

    The __proto__ property shouldn’t be confused with an object’s prototype, as they are two separate properties; that said, they do go hand in hand. It’s important to make this distinction, as it can be quite confusing at first! What does this mean exactly? Let me explain. When we created the myObject function, we were defining an object of type Function.

    console.log(typeof myObject); // function

    For those unaware, Function is a predefined object in JavaScript, and, as a result, has its own properties (e.g. length and arguments) and methods (e.g. call and apply). And yes, it, too, has its own prototype object, as well as the secret __proto__ link. This means that, somewhere within the JavaScript engine, there is a bit of code that could be similar to the following:

    Function.prototype = {
        arguments: null,
        length: 0,
        call: function(){
            // secret code
        },
        apply: function(){
            // secret code
        }
        ...
    }
    

    In truth, it probably wouldn’t be quite so simplistic; this is merely to illustrate how the prototype chain works.

    So we have defined myObject as a function and given it one argument, name; but we never set any properties, such as length or methods, such as call. So why does the following work?

    console.log(myObject.length); // 1 (being the amount of available arguments)

    This is because, when we defined myObject, it created a __proto__ property and set its value to Function.prototype (illustrated in the code above). So, when we access myObject.length, it looks for a property of myObject called length and doesn’t find one; it then travels up the chain, via the __proto__ link, finds the property and returns it.

    You might be wondering why length is set to 1 and not 0 – or any other number for that fact. This is because myObject is in fact an instance of Function.

    console.log(myObject instanceof Function); // true
    console.log(myObject === Function); // false

    When an instance of an object is created, the __proto__ property is updated to point to the constructor’s prototype, which, in this case, is Function.

    console.log(myObject.__proto__ === Function.prototype) // true

    Additionally, when you create a new Function object, the native code inside the Function constructor will count the number of arguments and update this.length accordingly, which, in this case, is 1.

    If, however, we create a new instance of myObject using the new keyword, __proto__ will point to myObject.prototype as myObject is the constructor of our new instance.

    var myInstance = new myObject(“foo”);
    console.log(myInstance.__proto__ === myObject.prototype); // true

    In addition to having access to the native methods within the Function.prototype, such as call and apply, we now have access to myObject’s method, getName.

    console.log(myInstance.getName()); // foo
    
    var mySecondInstance = new myObject(“bar”);
    
    console.log(mySecondInstance.getName()); // bar
    console.log(myInstance.getName()); // foo
    

    As you can imagine, this is quite handy, as it can be used to blueprint an object, and create as many instances as needed – which leads me onto the next topic!

    Why is Using Prototype Better?

    Say, for instance, that we are developing a canvas game and need several (possibly hundreds of) objects on the screen at once. Each object requires its own properties, such as x and y coordinates, width,height, and many others.

    We might do it as follows:

    var GameObject1 = {
        x: Math.floor((Math.random() * myCanvasWidth) + 1),
        y: Math.floor((Math.random() * myCanvasHeight) + 1),
        width: 10,
        height: 10,
        draw: function(){
            myCanvasContext.fillRect(this.x, this.y, this.width, this.height);
        }
       ...
    };
    
    var GameObject2 = {
        x: Math.floor((Math.random() * myCanvasWidth) + 1),
        y: Math.floor((Math.random() * myCanvasHeight) + 1),
        width: 10,
        height: 10,
        draw: function(){
            myCanvasContext.fillRect(this.x, this.y, this.width, this.height);
        }
        ...
    };
    

    … do this 98 more times …

    What this will do is create all these objects within memory – all with separate definitions for methods, such as draw and whatever other methods may be required. This is certainly not ideal, as the game will bloat the browsers allocated JavaScript memory, and make it run very slowly… or even stop responding.

    While this probably wouldn’t happen with only 100 objects, it still can serve to be quite a performance hit, as it will need to look up one hundred different objects, rather than just the single prototype object.

    How to Use Prototype

    To make the application run faster (and follow best practices), we can (re)define the prototype property of the GameObject; every instance of GameObject will then reference the methods within GameObject.prototype as if they were their own methods.

    // define the GameObject constructor function
    var GameObject = function(width, height) {
        this.x = Math.floor((Math.random() * myCanvasWidth) + 1);
        this.y = Math.floor((Math.random() * myCanvasHeight) + 1);
        this.width = width;
        this.height = height;
        return this;
    };
    
    // (re)define the GameObject prototype object
    GameObject.prototype = {
        x: 0,
        y: 0,
        width: 5,
        width: 5,
        draw: function() {
            myCanvasContext.fillRect(this.x, this.y, this.width, this.height);
        }
    };
    

    We can then instantiate the GameObject 100 times.

    var x = 100,
    arrayOfGameObjects = [];
    
    do {
        arrayOfGameObjects.push(new GameObject(10, 10));
    } while(x--);
    

    Now we have an array of 100 GameObjects, which all share the same prototype and definition of the draw method, which drastically saves memory within the application.

    When we call the draw method, it will reference the exact same function.

    var GameLoop = function() {
        for(gameObject in arrayOfGameObjects) {
            gameObject.draw();
        }
    };
    
    Prototype is a Live Object

    An object’s prototype is a live object, so to speak. This simply means that, if, after we create all our GameObject instances, we decide that, instead of drawing a rectangle, we want to draw a circle, we can update our GameObject.prototype.draw method accordingly.

    GameObject.prototype.draw = function() {
        myCanvasContext.arc(this.x, this.y, this.width, 0, Math.PI*2, true);
    }
    

    And now, all the previous instances of GameObject and any future instances will draw a circle.

    Updating Native Objects Prototypes

    Yes, this is possible. You may be familiar with JavaScript libraries, such as Prototype, which take advantage of this method.

    Let’s use a simple example:

    String.prototype.trim = function() {
        return this.replace(/^\s+|\s+$/g, ‘’);
    };
    

    We can now access this as a method of any string:

    “ foo bar   “.trim(); // “foo bar”

    There is a minor downside to this, however. For example, you may use this in your application; but a year or two down the road, a browser may implement an updated version of JavaScript that includes a native trim method within the String‘s prototype. This means that your definition of trim will override the native version! Yikes! To overcome this, we can add a simple check before defining the function.

    if(!String.prototype.trim) {
        String.prototype.trim = function() {
            return this.replace(/^\s+|\s+$/g, ‘’);
        };
    }
    

    Now, if it exists, it will use the native version of the trim method.

    As a rule of thumb, it’s generally considered a best practice to avoid extending native objects. But, as with anything, rules can be broken, if needed.

    Conclusion

    Hopefully, this article has shed some light on the backbone of JavaScript that is prototype. You should now be on your way to creating more efficient applications.

    If you have any questions regarding prototype, let me know in the comments, and I’ll do my best to answer them.


Planet PHP

  • Permalink for 'Using DaDaBIK to create a PHP CRUD Database Front-End without coding'

    Using DaDaBIK to create a PHP CRUD Database Front-End without coding

    Posted: May 9th, 2012, 4:50am MDT by PHP Classes
    Using DaDaBIK to create a PHP CRUD Database Front-End without coding By eugenio tacchini DaDaBIK is an Open Source PHP project which allows you to create Web front-end and simple database applications without coding. The new stable version 4.4 of DaDaBIK was released recently.

    Read this article to learn more about DaDaBIK and how you can use it to productively create your PHP applications.
  • Permalink for 'Using an Existing Vagrant Setup for PHP Development'

    Using an Existing Vagrant Setup for PHP Development

    Posted: May 9th, 2012, 12:09am MDT by Lorna Mitchell

    I've been hearing great things about puppet, chef, vagrant, and friends for a while now, but since I work on my own I tend to either develop straight onto my ubuntu machine or grab an appropriate existing VM and use that. So I read about this brave new world of virtualisation but (as with most tools) they can be hard to introduce on your own, and I didn't.

    Then I went to WhiskyWeb, which had a hackathon. I'm unclear on exactly what happened because my attention was elsewhere but it seems like @JayTaph showed off puppet and vagrant to @deizel*, who immediately built a vagrant setup for joind.in, which is an open source project that I'm currently leading. With the shiny new technology all packaged for me, I decided it was time to take a look!

    Starting the VM

    The goal is that a user can simply grab the code base and type a single command:

    vagrant up

    When you do this the first time, then a "base box" is downloaded and puppet installs the various packages that will be used to run your platform. Once you have the base box, you can use it again with a different configuration; very handy for anyone working with similar-but-not-quite-identical projects. The setup process goes beyond the platform and also sets up the application with appropriate configuration files, databases created and so on. This is fabulous because if you break something, change platforms, or otherwise get into a tangle of any kind - you can just recreate your platform!

    If you've run the virtual machine before, this command just starts the VM again so that you can use it.

    Puasing Between Sessions

    You probably don't want to leave the VM running all the time (I have a shiny new machine with enough RAM that I can if I want to, which is nice!), and just like any other virtual machine you can shut it off and restart it at the same point later on, using:

    vagrant suspend

    What I like about this is that it's so simple :)

    Throw it All Away

    If for any reason, either you broke something, or you have new puppet config perhaps, you want to throw away your VM and start again, that's easy to do:

    vagrant destroy

    We keep the base box, but throw away the actual VM instance when we do the above. This means that you get an entirely clean installation when you run vagrant up the next time, with everything reset to the way that it was. All the settings are very configurable so if you do end up making any changes on the VM, you can also make them in the configuration so that the next time you create the VM anew, those changes will be included.

    Network Topology

    Something I really liked about this setup, in comparison to the way that I usually do virtual machines, is that the VM shares files with the host machine. Joind.in is hosted on github, so I grab a copy of the repo, type vagrant up, and then just edit the files in the current directory as I normally would. I'm a vim user, so editing files on virtual machines has never really bothered me, but if you use a desktop IDE then this feature will make a big difference to the way that you work with it - and even for vim users, this eliminates the need for copying of .vimrc files and swearing at distros that install one leg of vi and call it good!

    The vagrant box also knows how to connect to itself, so to get shell access you simply need to ask for it:

    vagrant ssh

    I think especially if you have a bunch of machines running, or potentially running, because all your development uses these platforms, this approach becomes increasingly valuable as you don't have to keep tabs on hostnames or IP addresses. When you are in the directory for this project, the command gives you access to this VM ... simple!

    Shiny New Tools

    It's always easiest to learn something new by looking over someone's shoulder (which is why I teach a tools course) and while I'm sure I'll be diving into configuring the virtual machines in detail over time, just having this setup to try has been a great way to get start

    Truncated by Planet PHP, read more at the original (another 917 bytes)

  • Permalink for 'PHP talking to Magnolia CMS'

    PHP talking to Magnolia CMS

    Posted: May 8th, 2012, 3:11pm MDT by Liip

    Since we started working on Jackalope, we always claimed it would also provide an integration point with other enterprise systems. Last week, we set out to proof this idea. Grégory Joseph of the Java based Magnolia CMS came to help us on the Magnolia side of things. Magnolia is using the JCR reference implementation Jackrabbit for storing its content. After an interesting exchange on their design decisions and our ideas, we started to hack.

    Trying to import an XML export from Magnolia in the JCR standard format showed that the Jackalope importer is not yet perfect. In the end Greg was faster in building a Magnolia module that exposes the Jackrabbit Davex binding that Jackalope uses to communicate with the server.

    After that, things really started flowing. We managed to not only read data, but also write using the frontend editing feature of the CMF. Additionally, we managed to configure PHPCR-ODM to determine document classes based on the MetaData child every Magnolia page node has. And all of that using several parallel connections to the repositories, so that the normal pages and navigation can still be loaded from our standalone jackrabbit backend (you could just as well use another PHPCR implementation like jackalope-doctrine).

    All in all a very successful hackday. We integrated the demos into the cmf-sandbox (branch magnolia_integration). See the MagnoliaController in src/Sandbox/MagnoliaBundle/Controller.

    Screencapture showing the edit functionality

    Installing the Sandbox with Magnolia

    If you want to try things out for yourself, you need to:

    • Download Magnolia Community Edition
    • unpack it into a folder
    • Download the Magnolia Jackrabbit-Davex Module and drop all .jar files from this archive into apache-tomcat-6.0.32/webapps/magnoliaAuthor/WEB-INF/lib/
    • edit apache-tomcat-6.0.32/conf/server.xml to change the port from the default 8080 to 8888, so it looks something like <connector port="8888" protocol="HTTP/1.1">...
    • remove open file limitations. in bash, this will be ulimit -n 5000
    • launch magnolia with something like this: apache-tomcat-6.0.32/bin/magnolia_control.sh start tail -f apache-tomcat-6.0.32/logs/catalina.out
    • visit localhost:8888 and follow the Magnolia installation (login with superuser/superuser)

    If you followed the above steps, you should be able to access Magnolia data with Jackalope-Jackrabbit at [localhost:8888] (Note that there is no web browser access, as the servlet does not issue a basic auth challenge but just expect the credentials to be set from the beginning).

    Now try the urls /magnolia_edit, /magnolia/about/subsection-articles/article and /magnolia_odm and read the code to see what we do.

  • Permalink for 'PHP 5.4.3 and 5.3.13 fix several security issues'

    PHP 5.4.3 and 5.3.13 fix several security issues

    Posted: May 8th, 2012, 1:36pm MDT by Dr. Christopher Kunz - PHP

    The PHP team has announced PHP 5.4.3 and 5.3.13, fixing two separate security issues.



    • CVE-2012-2311 and CVE-2012-1823 are both fixed now. These are the CVE numbers for the PHP-CGI bug that has been announced by Eindbazen last week, and extensively covered by myself in various posts.

    • In addition, CVE-2012-2329 has been fixed, another issue in PHP-CGI. This was a heap overflow triggered by specially crafted HTTP headers and a script executing apache_request_headers().

    I have tested my own exploit against the new version (5.4 only, I have no 5.3 setup) and there does not seem to be a possibility to exploit the vectors opened in CVE-2012-2311 and CVE-2012-1823. These issues seem to be fixed now. I have no exploit code for CVE-2012-2329, so I cannot make a statement if it is fixed yet. Update: I have tested Georg Wicherski’s PoC exploit against 5.4.3 and it seems that CVE-2012-2329 is now also fixed.

    Read the announcement here: PHP 5.4.3/5.3.13 release announcement


    The download page for PHP 5.4.3 is here, the download for 5.3.13 is over here.

  • Permalink for '10 years of Xdebug and Xdebug 2.2.0 released'

    10 years of Xdebug and Xdebug 2.2.0 released

    Posted: May 8th, 2012, 7:00am MDT by Derick Rethans
    10 years of Xdebug and Xdebug 2.2.0 released London, UK Tuesday, May 8th 2012, 14:00 BST cake.jpg

    Today it has been ten years since the first release of Xdebug: version 0.7.0. I would like to celebrate this tenth anniversary with a new release: Xdebug 2.2.0. Xdebug 2.2 adds support for PHP 5.4 and provides some new features:

    Colours on the command line

    First of all there is now var_dump() overloading and colours on the command line. I've already written about that before, but here are the screenshots again:

    Linux/Mac:

    cli-color-linux.png

    Windows:

    cli-color-windows.png

    You can find an article about this here.

    Better support for closures in stack and function traces

    Closures are functions that don't have a function name associated with them. Therefore, Xdebug creates a pseudo function in its stack traces. The stack trace for this example:

    <?php function test1()
    {
            $f = function($a, $b) {
                    $Q = strlen($a * $b);
                    trigger_error('foo');
            };
    
            $f(5, 25);
    }
    
    test1();
    ??>

    Looks like:

    Notice: foo in /tmp/closure-stack-trace.php on line 21
    
    Call Stack:
            0.0009     268464   1. {main}() /tmp/closure-stack-trace.php:0
            0.0026     269288   2. test1() /tmp/closure-stack-trace.php:27
            0.0032     270024   3. {closure:/tmp/closure-stack-trace.php:19-22}($a = 5, $b = 25) /tmp/closure-stack-trace.php:24
            0.0038     270496   4. trigger_error('foo') /tmp/closure-stack-trace.php:21
    
    

    In the 3rd line in the call stack you see {closure:/tmp/closure-stack-trace.php:19-22}($a = 5, $b = 25) where /tmp/closure-stack-trace.php:19-22 contains the filename and line numbers on which the closure is defined at.

    The size of arrays is now shown with the overloaded variable output

    After this change, each array in the html version of the overloaded var_dump() function now looks like:

    array (size=5)
    
    

    Before the change, this was only:

    array
    
    

    Added the method call type to xdebug_get_function_stack

    This changes adds another array element to xdebug_get_function_stack() to show whether it was a static or dynamic function call. For example, for:

    new Error_Entry(false, $errno);
    
    

    It now adds the ["type"]=> string(7) "dynamic" element to each stack element:

    array(6) {
      ["function"]=>
      string(11) "__construct"
      ["type"]=>
      string(7) "dynamic"
      ["class"]=>
      string(11) "Error_Entry"
      ["file"]=>
      string(%d) "%sbug00241.php"
      ["line"]=>
      int(11)
    
    
    

    Extra information to error printouts to tell that the error suppression operator has been ignored due to xdebug.scream

    When you have the xdebug.scream option activated, Xdebug will now tell you when it had any effect on the error reporting with a big "SCREAM: Error suppression ignored for" warning prepended to the actual error message.

    champagne.jpg

    Changelog

    You can find the full changelog for Xdebug 2.2.0 at the Xdebug website where you can also download the latest version. If you are using Windows, and don't know which binary to download, please refer to the wizard.

    Support

    If you find Xdebug valuable for your PHP development, perhaps you want to support its development by acquiring a "support" contract. See the buying "support" page if you feel generous.

    Truncated by Planet PHP, read more at the original (another 761 bytes)

  • Permalink for 'Boston PHP community, I need your help!'

    Boston PHP community, I need your help!

    Posted: May 8th, 2012, 6:06am MDT by Stefan Koopmanschap
    This morning, I had a nice e-mail in my mailbox telling me I got accepted into the NorthEast PHP conference with no less than 3(!) topics! Awesome, and I would love to be part of the conference, however... the conference is organized by the community, and the way they work, there is no travel reimbursement.
  • Permalink for 'Using Composer to manage dependencies in Heroku PHP apps'

    Using Composer to manage dependencies in Heroku PHP apps

    Posted: May 8th, 2012, 4:18am MDT by Henri Bergius

    Heroku is a very nice Platform-as-a-Service provider that allows you to focus on writing applications instead of managing servers. If your application code is already managed in Git, in most cases you only need to create a Heroku app setup, and then git push to deploy it on Heroku. Scaling your app is easy and there are many useful add-ons available in their "app store".

    While Heroku got its start from hosting Ruby on Rails applications, it nowadays supports many different environments in the Cedar stack. Node.js is what many use, but they also do support PHP.

    Dependency management is easy for Node.js applications as Heroku recognizes your package.json files and automatically installs the libraries needed via NPM.

    Until now PHP developers haven't had this convenience, but as Composer is emerging as the default PHP package manager, I've now added support for it. Before the pull request gets accepted, Composer dependency handling can already be used by specifying my custom PHP buildpack when creating Heroku apps.

    I've written a simple example app to show how this works.

    First you need to create the folder for your app and make it a Git repository:

    $ mkdir myapp
    $ cd myapp
    $ git init
    

    Then create the Heroku app using a custom buildpack (when the pull request is accepted you can skip the buildpack definition):

    $ heroku create -s cedar --buildpack [https:] my-cool-app
    

    Then it is time to write your composer.json file. In this case we'll only depend on the urlize library:

    {
        "require": {
            "php": ">=5.2.0",
            "midgard/midgardmvc-helper-urlize": "*"
        }
    }
    

    For Heroku to recognize the app as a PHP one, you also need to have an index.php. In this case with the following code:

    <?php
    // URLizer service
    require 'vendor/midgard/midgardmvc-helper-urlize/interface.php';
    if (isset($_GET['urlize'])) {
        $data = array();
        $data['from'] = $_GET['urlize'];
        $data['to'] = midgardmvc_helper_urlize::string($_GET['urlize']);
        header('Content-type: application/json; charset=utf-8');
        die(json_encode($data));
    }
    header('Content-Type: text/html; charset=utf-8');
    ?>
    <h1>Urlizer service</h1>
    <form method="GET">
        <label>
            String to URLize
            <input name="urlize" type="text" />
        </label>
        <input type="submit" value="URLize" />
    </form>
    

    Now add and commit these files, and then deploy to Heroku:

    $ git push heroku master
    

    You should see that Heroku notices the Composer dependencies and installs them:

    -----> Heroku receiving push
    -----> Fetching custom buildpack... done
    -----> PHP app detected
    -----> Bundling Apache version 2.2.22
    -----> Bundling PHP version 5.3.10
    -----> Installing Composer dependencies
    Installing dependencies
      - Package phptal/phptal (dev-master)
        Cloning e146361f25b8672d364695b757eddf1c169e05d2
    
      - Package midgard/midgardmvc-core (dev-master)
        Cloning 2b00d38cb2fea42c8f9791c5ecc7270dc81182e8
    
      - Package midgard/midgardmvc-helper-urlize (dev-master)
        Cloning 92d0c8c638c389b7be1887ca67cd334f51932912
    
    midgard/midgardmvc-core suggests installing ext-midgard2 (>=10.05.5)
    Writing lock file
    Generating autoload files
    -----> Discovering process types
           Procfile declares types -> (none)
           Default types for PHP   -> web
    -----> Compiled slug size is 13.2MB
    -----> Launching... done, v13
    

    And that is it! You can see an example of this app at [urlizer-service.herokuapp.com] .

  • Permalink for 'Wsunit - the first release'

    Wsunit - the first release

    Posted: May 8th, 2012, 3:48am MDT by Liip

    It's always the same issue... you write unit tests for a web-service, giving you a feeling of confidence about the correctness of your code. Then the service provider changes the response without notifying you. Suddenly your implementation doesn't work anymore, but even your continuous integration server says it's "all green".

    So what happened?

    Surely the fixture files you used are outdated, and since they won't get updated automatically your tests don't stand a chance to detect the change.

    Wsunit to the rescue

    Implemented as a PHPUnit test listener, once configured wsunit will request a new response every time you run your test suite. It saves the response to your test's fixture file to verify the correct behavior of your implementation. Therefore you probably want to run this test suite as a separate job on your continuous integration server so you don't disturb the developers when doing their job.
    Furthermore, wsunit keeps every 'old' responses (aka fixture files) enabling you to find the differences between the current response and an old response.

    How does it work?

    After configuring the test listener in the PHPUnit configuration file, the central point of interest is the wsunit configuration file. Here you define which test (identified by it's name) will send a request to which location together with what query parameters.
    If you now run the test suite the test listener detects that there is a request to be sent and fetches the requested data from the defined location. After a conversion to XML the response will be stored in a fixture file named after the executed test.
    The test now just uses the fixture file to verify the correct implementation of your code.
    Since the header and response body are converted into a XML structure it is fairly easy to check it's content by using PHPUnit's 'assertXml*' assertion methods.

    Further reading

    A complete description how to install and set up wsunit is written down in Bastian's blog.

  • Permalink for 'Interview with Keith Casey'

    Interview with Keith Casey

    Posted: May 7th, 2012, 11:00pm MDT by Cal Evans

    Blog:  [caseysoftware.com]
    Twitter: @caseysoftware

    Show Notes:

    Sponsored by:
    Engine Yard

  • Permalink for 'PHP 5.4.3 and PHP 5.3.13 Released!'

    PHP 5.4.3 and PHP 5.3.13 Released!

    Posted: May 7th, 2012, 4:00pm MDT by PHP: Hypertext Preprocessor
    The PHP development team would like to announce the immediate availability of PHP 5.4.3 and PHP 5.3.13. All users are encouraged to upgrade to PHP 5.4.3 or PHP 5.3.13The releases complete a fix for a vulnerability in CGI-based setups (CVE-2012-2311). Note: mod_php and php-fpm are not vulnerable to this attack.PHP 5.4.3 fixes a buffer overflow vulnerability in the apache_request_headers() (CVE-2012-2329). The PHP 5.3 series is not vulnerable to this issue.For source downloads of PHP 5.4.3 and PHP 5.3.13 please visit our downloads page, Windows binaries can be found on windows.php.net/download/. The list of changes are recorded in the ChangeLog.
  • Permalink for 'Expose services via an ssh tunnel'

    Expose services via an ssh tunnel

    Posted: May 7th, 2012, 3:02pm MDT by till

    Ever since I remember, I have this inability to learn the most basic things, until I actually write down a couple notes or instructions somewhere. This is one of these notes blog posts — so in case it's too basic, just skip over it. Or bear with me.

    ssh tunnels — useful and powerful. They can help me with all kinds of trickery — e.g. usually for remoting through a tight firewall setup to access remote resources. So point taken there are a lot of GUIs for this, but if you spend a couple minutes with the ssh man page, you will realize how amazingly simple they are.

    My example for an ssh tunnel put to good use is our production gearman setup: The gearmands runs isolated on EC2. On the upside: pretty secure, but the downside is that the service is unavailable when you need to a little live data for some local tests. When we added an interface to get more visibility into the processes we push through gearman, of course we couldn't access it.

    A tunnel to the rescue!

    Consider this:

    till@macbook$ screen -S gearman-ssh-tunnel
    till@macbook$ ssh -L 2222:127.0.0.1:4730 production-gearmand
    Linux Ubuntu SMP AMD64
    
    Last login: Sat May  5 16:22:47 2012 from YYY.YYY.YYY.YYY
    till@production-gearmand:~$
    

    ("ctrl + a + d", to detach from screen.)

    So what does that do?

    First off, we are starting a session in screen: it's called "gearman-ssh-tunnel". You could use tmux as well, but screen works just as nice.

    The consecutive command maps port 2222 on my (local) macbook to a service running on the server production-gearmand (this is via .ssh/config) but only listens on 127.0.0.1:4730.

    Your .ssh/config could look like this:

    Host production-gearmand
    HostName ec2-XXX-XXX-XXX-XXX.compute-1.amazonaws.com
    User till
    IdentityFile ~/.ssh/gearman.pem
    

    If I wanted to connect to this server in a PHP-script on my macbook, I would use the following configuration:

    <?php
    $client = new GearmanClient;
    $client->addServer('127.0.0.1', 2222);
    var_dump($client->echo('ehlo'));
    ?>
    

    Run it from the terminal:

    till@macbook$ php gearman-ping.php
    bool(true)
    

    Success!

    Need to stop the tunnel?

    The following command lets you resume your session with screen:

    till@macbook$ screen -r gearman-ssh-tunnel
    ...
    

    Type exit twice, or hit "ctrl + d" to log off the server and "ctrl + d" again to kill the screen. Done.

    Fin

    Bonus points if you use this from your VM in vagrant. But otherwise, that's all for today.

  • Permalink for 'Natural Load Testing'

    Natural Load Testing

    Posted: May 7th, 2012, 8:57am MDT by Sean Coates

    My friend Paul Reinheimer has put together an excellent product/service that is probably of use to many of you.

    The product is called Natural Load Testing, and it harnesses some of the machinery that powers the also-excellent wonderproxy and its extremely useful VPN service.

    The gist is that once you've been granted an account (they're in private beta right now, but tell them I sent you, and if you're not a horrible person such as a spammer, scammer, or promoter of online timesuck virtual farming, you'll probably get in—just kidding about that farming clause… sort of), you can record real, practical test suites within the simple confines of your browser, and then you can use those recorded actions to generate huge amounts of test traffic to your application.

    In principle, this idea sounds like nothing new—you might already be familiar with Apache Bench, Siege, http_load, or other similar tools—but NLT is fundamentally different from these in several ways.

    First, as I already mentioned, NLT allows you to easily record user actions for later playback. This is cool but on its own is not much more than merely convenient. What isn't immediately obvious is that in addition to the requests you're making (HTTP verbs and URLs), NLT is recording other extremely important information about your actions, too: I find HTTP headers and timing particularly interesting.

    Next, NLT allows you to use the test recordings in a variable manner. That is, you can replace things like usernames and email addresses (and many other bits of variable content) with system-generated semi-random replacements. This allows you to test things like a full signup process, or semi-anonymous comment posting, all under load.

    NLT also keeps track of secondary content that your browser loads when you're recording the test cases. Things like CSS, JavaScript, images, and XHR/Ajax requests are easy to overlook when using less-intelligent tools. NLT records these requests and (optionally) inserts them into test suites along side primary requests.

    Tools like Siege and the others I've mentioned are useful when you want to know how many concurrent requests your infrastructure can sustain. This is valuable data, but it is often not really practical. Handling a Slashdotting (or whatever the modern day equivalent of such things is called) is only part of the problem. Wouldn't you really prefer to know how many users can concurrently sign up for your app, or how many page-1-to-page-2 transitions you can handle, without bringing your servers to their knees (or alternatively: before scaling up and provisioning new machines in your cluster)?

    Here's a practical example. Since before the first edition of the conference, the Brooklyn Beta site had been running on my personal (read: toy) server. Before launching this year's edition of the site, which included the announcement for Summer Camp, I got a bit nervous about the load. I wasn't so much worried about the rest of my server suffering at the traffic of Brooklyn Beta, but more about the Brooklyn Beta site becoming unavailable due to overloading. This seemed like a good opportunity to give NLT a whirl.

    I recorded a really simple test case by firing up NLT's proxy recorder, and visiting each page, in the order and timeframe I expected real users to browse from page to page. Then we unleashed the NLT worker hounds on the pre-release version of the site (same hardware, just not on the main URL), and discovered that it wasn't doing very well under load. I then set up Varnish and put it into the request chain (we were testing mostly dynamically-generayed static content after all—why not cache it?). The results were clear and definitive: Varnish made a huge difference, and NLT showed us exactly how. (We've since moved the Brooklyn Beta site to EC2, along with most of the rest of our infrastructure.)

    This chart shows several response times over 20 seconds with only 100 concurrent requests without Varnish, and most response times less than 20 milliseconds with 500 concurrent requests. Conclusion: we got over a thousand times better performance with five times as

    Truncated by Planet PHP, read more at the original (another 606 bytes)

  • Permalink for 'Will it ever Matter if PHP Sucks? - Lately in PHP podcast episode 23'

    Will it ever Matter if PHP Sucks? - Lately in PHP podcast episode 23

    Posted: May 7th, 2012, 5:54am MDT by PHP Classes
    Will it ever Matter if PHP Sucks? - Lately in PHP podcast episode 23 By Manuel Lemos Once in a while we see fans of other languages writing long articles on why PHP sucks and you should not use it. But will that ever matter?

    That is one of the main topics discussed by Manuel Lemos and Ernani Joppert in the episode 23 of the Lately in PHP podcast, for the first time also recorded in video using Google Hangouts On Air.

    They also covered other polemic ideas for future PHP versions like the pure PHP script proposal, making function names case-sensitive and the option to skip optional function parameters.

    Another interesting topic discussed in this podcast is about the proposals for HTTP 2.0 protocol.

    Listen to the podcast, watch the video recording or read the transcript to learn about these and other interesting PHP related topics.

Nettuts+

  • Permalink for '14 Reason Why Nobody Used Your jQuery Plugin'

    14 Reason Why Nobody Used Your jQuery Plugin

    Posted: May 7th, 2012, 4:45am MDT by Jonathan Cutrell

    With so many folks developing jQuery plugins, it’s not uncommon to come across one that just plain – for lack of better words – sucks. There’s no examples or documentation, the plugin doesn’t follow best practices, etc. But you’re one of the lucky ones: this article will detail the pitfalls that you must avoid.

    jQuery is no stranger to those of you frequent Nettuts+. Jeffrey Way’s awesome 30 Days to Learn jQuery (and various other tutorials here and elsewhere) have led us all down the path to Sizzle-powered awesomesauce. In all the hype (and a lot of leaps in JavaScript adoption by developers and browser vendors), plenty of plugins have come onto the scene. This is partially why jQuery has become the most popular JavaScript library available! The only problem is that many of them aren’t too great.

    In this article, we’ll focus less on the JavaScript specifically, and more on best practices for plugin delivery.

    1 – You Aren’t Making a jQuery Plugin

    There are some patterns that are, more or less, universally accepted as “The Right Way” to create jQuery plugins. If you aren’t following these conventions, your plugin may… suck! Consider one of the most common patterns:

    (function($, window, undefined){
    $.fn.myPlugin = function(opts) {
    	var defaults = {
    		// setting your default values for options
    	}
    
      // extend the options from defaults with user's options
      var options = $.extend(defaults, opts || {});
    
    	return this.each(function(){ // jQuery chainability
    	  // do plugin stuff
    	});
    })(jQuery, window);
    

    First, we are creating a self-invoking anonymous function to shield ourselves from using global variables. We pass in $, window, and undefined. The arguments the self invoking function is called with are jQuery and window; nothing is passed in for undefined, so that if we decide to use the undefined keyword within the plugin, “undefined” actually will be undefined.

    This shields from other scripts potentially assigning a malicious value to undefined, such as true!

    $ is passed as jQuery; we do it this way to ensure that, outside of the anonymous function, $ can still refer to something else entirely, such as Prototype.

    Passing the variable for the globally accessible window object allows for more compressed code through the minification processes (which you should be doing, as well).

    Next, we are using the jQuery plugin pattern, $.fn.PluginName. This is a way of registering your plugin to be used with the $(selector).method() format. It simply extends jQuery’s prototype with your new method. If you want to instead create a plugin that defines a function on the jQuery object, add it directly, like so:

    $.PluginName = function(options){
    	// extend options, do plugin stuff
    }
    

    This type of plugin won’t be chainable, as functions that are defined as properties of the jQuery object typically don’t return the jQuery object. For instance, consider the following code:

    $.splitInHalf = function(stringToSplit){
    	var length = stringToSplit.length;
    	var stringArray = stringToSplit.split(stringToSplit[Math.floor(length/2)]);
    	return stringArray;
    }
    

    Here, we are returning an array of strings. It makes sense to simply return this as an array, as this is likely what users will want to use (and they can easily wrap it in the jQuery object if they wish). In contrast, consider the following contrived example:

    $.getOddEls = function(jQcollection){ //
    	return jQcollection.filter(function(index){
    		var i = index+1;
    		return (index % 2 != 0);
    	});
    }
    

    In this case, the user is probably expecting the jQuery object to return from $.getOddEls; so, we return the filter method, which returns the jQuery collection defined by the function that is passed. A good rule of thumb is to wrap returned elements in the jQuery function, especially if they can be chained; if you are returning arrays, strings, numbers, functions, or other data types, leave them unwrapped.

    2 - You Aren’t Documenting Your Code (Correctly)

    Arguably, the most important thing you can do when publishing your code is add the necessary documentation. The gap between what you explain to developers and what the code actually does or can do is the time that users don’t want to waste figuring out the ins and outs of your code.

    Documentation is a practice that doesn’t have any hard-fast rules; however, it is generally accepted that the more (well organized) documentation you have, the better.

    This process should be both an internal practice (within/interspersed throughout your code) as well as an external practice (explaining every public method, option, and multiple use cases thoroughly in a wiki or readme).

    3 – You Aren’t Providing Enough Flexibility or Customizability

    The most popular plugins offer full access to variables (what most plugins refer to as “options” objects) that a user may want to control. They also may offer many different configurations of the plugin so that it is reusable in many different contexts. For instance, let’s consider a simple slider plugin. Options that the user might wish to control include the speed, type, and delay of the animation.

    It’s good practice to also give the user access to classnames/ID names which are added to the DOM elements inserted or manipulated by the plugin. But beyond this, they may also want to have access to a callback function every time the slide transitions, or perhaps when the slide transitions back to the beginning (one full “cycle”).

    It’s your job to think of all possible uses and needs for the plugin.

    Let’s consider another example: a plugin that makes a call to an API should provide access to the API’s returned object. Take the following example of a simple plugin concep:.

    $.fn.getFlickr = function(opts) {
    	return this.each(function(){ // jQuery chainability
    		var defaults = { // setting your default options
    			cb : function(data){},
    			flickrUrl : // some default value for an API call
    		}
    	    // extend the options from defaults with user's options
    	    var options = $.extend(defaults, opts || {});
    
    	    // call the async function and then call the callback
    	    // passing in the api object that was returned
    	    $.ajax(flickrUrl, function(dataReturned){
    			options.cb.call(this, dataReturned);
    		});
    	});
    }
    

    This allows us to do something along the lines of:

    	$(selector).getFlickr(function(fdata){ // flickr data is in the fdata object });
    

    Another way of publicizing this is to offer “hooks” as options. As of jQuery 1.7.1 and up, we can use .on(eventName, function(){}) after our plugin call to separate the behaviors into their own functions. For instance, with the plugin above, we could change the code to look like this:

    $.fn.getFlickr = function(opts) {
    	return this.each(function(i,el){
    		var $this = el;
    		var defaults = { // setting your default options
    			flickrUrl : " [someurl.com"] // some default value for an API call
    		}
    	    var options = $.extend(defaults, opts || {});
    
    	    // call the async function and then call the callback
    	    // passing in the api object that was returned
    	    $.ajax(flickrUrl, function(dataReturned){
    	    	// do some stuff
    			$this.trigger("callback", dataReturned);
    		}).error(function(){
    				$this.trigger("error", dataReturned);
    			});
    	});
    }
    

    This allows us to call the getFlickr plugin and chain other behavior handlers.

    $(selector).getFlickr(opts).on("callback", function(data){ // do stuff }).on("error", function(){ // handle an error });
    

    You can see that offering this kind of flexibility is absolutely important; the more complex actions your plugins have, the more complex the control that should be available.

    4 – You’re Requiring Too Much Configuration

    Ok, so tip number three suggested that the more complex actions your plugins have, the more complex control that should be available. A big mistake, however, is making too many options required for plugin functionality. For instance, it is ideal for UI based plugins to have a no-arguments default behavior.

    $(selector).myPlugin();
    

    Certainly, sometimes this isn’t realistic (as users may be fetching a specific feed, for instance). In this case, you should do some of the heavy lifting for them. Have multiple ways of passing options to the plugin. For instance, let’s say we have a simple Tweet fetcher plugin. There should be a default behavior of that Tweet fetcher with a single required option (the username you want to fetch from).

    $(selector).fetchTweets("jcutrell");
    

    The default may, for instance, grab a single tweet, wrap it in a paragraph tag, and fill the selector element with that html. This is the kind of behavior that most developers expect and appreciate. The granular options should be just that: options.

    5 – You’re Mixing External CSS Rules and Inline CSS Rules

    It’s inevitable, depending upon the type of plugin, of course, that you will have to include a CSS file if it is highly based on UI manipulations. This is an acceptable solution to the problem, generally speaking; most plugins come bundled with images and CSS. But don’t forget tip number two – documentation should also include how to use/reference the stylesheet(s) and images. Developers won’t want to waste time looking through your source code to figure these things out.

    Things should just…work.

    With that said, it is definitely a best practice to use either injected styles (that are highly accessible via plugin options) or class/ID based styling. These IDs and classes should also be accessible, via options as previously mentioned. Inline styles override external CSS rules, however; the mixing of the two is discouraged, as it may take a developer a long time to figure out why their CSS rules aren’t being respected by elements created by your plugin. Use your best judgment in these cases.

    As a rule of thumb, inline CSS is bad – unless it’s so minimal to the point that it doesn’t warrant its own external stylesheet.

    6 – You Don’t Offer Examples

    The proof is in the pudding: if you can’t provide a practical example of what your plugin does with accompanying code, people will quickly be turned off to using your plugin. Simple as that. Don’t be lazy.

    A good template for examples:

    • A “hello world” example – usually the plugin call with the minimum configuration/options passed, and it’s accompanying html/css
    • A few more involved examples – usually with examples of full functionality of multiple options
    • An integration example – if someone might use another plugin with your plugin, here is where you can show how to do that. (This gets you bonus points in the open-source development world, too. Kudos.)
    7 – Your Code Doesn’t Match Their jQuery Version

    jQuery, like any good code library, grows with every release. Most methods are kept even after support is deprecated. However, new methods are added on; a perfect example of this is the .on() method, which is jQuery’s new all-in-one solution for event delegation. If you write a plugin that uses .on(), people using jQuery 1.6 or earlier will be out of luck. Now I’m not suggesting that you code for the lowest common denominator, but, in your documentation, be sure to explain which version of jQuery your plugin supports. If you introduce a plugin with support for jQuery 1.7, you should strongly consider maintaining support for 1.7 even once 1.8 comes out. You should also consider taking advantage of new/better/faster features in jQuery as they come out.

    Encourage developers to upgrade, but don’t break your plugin too often! One option is to offer a “legacy” deprecated, non-supported versions of your plugin.

    8 - Where’s the Changelog?

    It’s time to bite the bullet if you haven’t learned how to use version control yet.

    Along with keeping your jQuery version support/compatibility a part of your documentation, you should also be working in version control. Version control (specifically, via GitHub) is largely the home of social coding. If you are developing a plugin for jQuery that you want to eventually publish in the official repository, it must be stored in a GitHub repository anyway; it’s time to bite the bullet if you haven’t learned how to use version control. There are countless benefits to version control, all of which are beyond the scope of this article. But one of the core benefits is that it allows people to view the changes, improvements, and compatibility fixes you make, and when you make them. This also opens the floor for contribution and customization/extension of the plugins you write.

    Additional Resources 9 – Nobody Needs Your Plugin

    The world doesn’t need another slider plugin.

    Ok, we’ve ignored it long enough here: some “plugins” are useless or too shallow to warrant being called a plugin. The world doesn’t need another slider plugin! It should be noted, however, that internal teams may develop their own plugins for their own uses, which is perfectly fine. However, if you’re hoping to push your plugin into the social coding sphere, find a reason to write more code. As the saying goes, there’s no reason to reinvent the wheel. Instead, take someone else’s wheel, and build a racecar. Of course, sometimes there are new and better ways of doing the same things that have already been done. For instance, you very well might write a new slider plugin if you are using faster or new technology.

    10 – You Aren’t Providing a Minified Version

    This one is fairly simple: offer a minified version of your code. This makes it smaller and faster. It also ensures that your Javascript is error free when compiled. When you minify your code, don’t forget to offer the uncompressed version as well, so that your peers can review the underlying code. Free and cheap tools exist for front-end developers of all levels of experience.

    Refer to tip number thirteen for an automated solution.

    11 – Your Code is Too Clever

    When you write a plugin, it is meant to be used by others, right? For this reason, the most effective source code is highly readable. If you’re writing countless clever one-liner lambda style functions, or your variable names aren’t semantic, it will be difficult to debug errors when they inevitably occur. Instead of writing short variable names to save space, follow the advice in tip number nine (minify!). This is another part of good documentation; decent developers should be able to review your code and understand what it does without having to expend too much energy.

    If you find yourself calling variables “a” or “x“, you’re doing it wrong.

    Additionally, if you find yourself consulting documentation to remember what your own strange looking code is doing, you also likely need to be less concise and more explanatory. Restrict the number of lines in each function to as few as possible; if they stretch for thirty or more lines, there might be a code smell.

    11.You Don’t Need jQuery

    As much as we all love using jQuery, it is important to understand that it is a library, and that comes with a small cost. In general, you don’t need to worry too much about things like jQuery selector performance. Don’t be obnoxious, and you’ll be just fine. jQuery is highly optimized. That said, if the sole reason why you need jQuery (or a plugin) is to perform a few queries on the DOM, you might consider removing the abstraction entirely, and, instead, sticking with vanilla JavaScript, or Zepto.

    Note: if you decide to stick with vanilla JavaScript, ensure that you’re using methods that are cross-browser. You might potentially need a small polyfill for the newer APIs.

    13 – You’re Not Automating the Process

    Use Grunt. Period.

    Grunt is a “task-based command line build tool for JavaScript projects”, which was covered in detail recently here on Nettuts+. It allows you to do things like this:

    grunt init:jquery
    

    This line (executed in the command line) will prompt you with a set of questions, such as the title, description, version, git repository, licenses, etcetera. These pieces of information help to automate the process of setting up your documentation, licensing, etc.

    Grunt does far more than just make some customized boilerplate code for you; it also offers built in tools, like the code linter JSHint, and it can automate QUnit tests for you as long as you have PhantomJS installed (which Grunt takes care of). This way, you can streamline your workflow, as tests run instantly in the terminal on save.

    14 – You’re Not Testing

    Oh, by the way – you do test your code, right? If not, how can you ensure/declare that your code works as expected? Manual testing has its place, but, if you find yourself refreshing the browser countless times every hour, you’re doing it wrong. Consider using tools, such as QUnit, Jasmine, or even Mocha.

    Testing is particularly useful when merging in pull requests on GitHub. You can require that all requests provide tests to ensure that the new/modified code does not break your existing plugin.

    If the concept of testing jQuery plugins is brand new to you, consider watching our Premium-exclusive screencast, Techniques For Test-Driving jQuery Plugins. Additionally, we’re launching a new “JavaScript Testing With Jasmine” course later this week on the site!

    Some Helpful Resources

    We wouldn’t be doing you any favors by just telling you what you’re doing wrong. Here are some links that will help get you back on the right path!

    Closing Thoughts

    If you are writing a jQuery plugin, it is vital that you stray away from the pitfalls listed above. Did I miss any key signs of a poorly executed plugin?


Planet PHP

Nettuts+

  • Permalink for 'Best of Tuts+ in April 2012'

    Best of Tuts+ in April 2012

    Posted: May 6th, 2012, 6:20pm MDT by David Appleyard

    Each month, we bring together a selection of the best tutorials and articles from across the whole Tuts+ network. Whether you’d like to read the top posts from your favourite site, or would like to start learning something completely new, this is the best place to start!

    We’ve Been in Kuala Lumpur!

    This month we’ve been attending an Envato company meet-up in Malaysia. We’ve had a fun time working together as a team, made lots of exciting plans for the future of Tuts+, and also had the chance to meet up with lots of our readers! Thanks to everyone who took the time to attend our community meet-up and, if you’re interested, you can find out a bit more about our trip here (and see a few photos!)

    Psdtuts+ — Photoshop Tutorials
    • Use Photoshop CS6 to Create a Micro Machines Inspired Scene Use Photoshop CS6 to Create a Micro Machines Inspired Scene

      Photoshop CS6 is packed with new features and effects that you can use in your work. In this tutorial we will utilize Photoshop’s new 3D capabilities as well as its new content aware features to create a Micro Machines inspired composition. Let’s get started!

      Visit Article

    • Create a Snowy Landscape From Desert Photography in Photoshop – Tuts+ Premium Tutorial Create a Snowy Landscape From Desert Photography in Photoshop – Tuts+ Premium Tutorial

      Photoshop is a great tool because it allows us to be creative and produce imagery that would be impossible to create otherwise. In this Tuts+ Premium tutorial, author Tony Aubé will create a snowy landscape from desert photography and photos of sand. This tutorial is available exclusively to Tuts+ Premium Members. If you are looking to take your photo manipulation skills to the next level then Log in or Join Now to get started!

      Visit Article

    • Create a Light Bulb Inspired Text Effect in Photoshop Create a Light Bulb Inspired Text Effect in Photoshop

      Layer styles are a powerful and time saving feature that can help you apply amazing effects to your designs. In this tutorial we will use layer styles to create a light bulb inspired text effect in Photoshop. Let’s get started!

      Visit Article

    • Nettuts+ — Web Development Tutorials
    • The Build Tool for JavaScript Meet Grunt: The Build Tool for JavaScript

      If you’re working on a large project, you’ll no doubt have a build script or a bunch of task scripts to help with some of the repetitive parts of the process. You might use Ant or Rake, depending on the language the project is written in.

      Visit Article

    • Borders CSS Refreshers: Borders

      Sure, we’re all familiar with borders. Is there anything new that could possibly be introduced? Well, I bet there’s quite a few things in this article that you never knew about!

      Visit Article

    • Lightning Fast Folder and File Creation in Sublime Text 2 Lightning Fast Folder and File Creation in Sublime Text 2

      I’m frequently asked about how I’m able to create new directory structures and files so quickly in Sublime Text 2. Well the answer is that this functionality is not offered natively; instead, I use a helpful plugin. I’ll demonstrate it in this video.

      Visit Article

    • Vectortuts+ — Illustrator Tutorials
    • The Line of Action, Make Your Character Poses More Dynamic! Quick Tip: The Line of Action, Make Your Character Poses More Dynamic!

      The line of action is a key ingredient to making your character’s poses look more dynamic. In this guide, we will explore what the line of action is and how it can be used to make your character poses come alive.

      Visit Article

    • 200+ Free Vector Grunge Graphics for Designers and Illustrators Free Vector Grunge Graphics for Designers and Illustrators

      If you’re looking for free vector grunge graphics, such as distressed backgrounds, worn textures, dirty paint splatter, and more, then you’ve found a compilation worth downloading. We’ve collected an assortment of vector grunge illustrations, free vector grunge textures, and wickedly worn graphics available for free download. Jump in and grab these free grunge vectors now and start making grunge vector art for your next project.

      Visit Article

    • Creating a Retro Flyer Design Vintage Vector Design Workflow: Creating a Retro Flyer Design

      This tutorial will cover the process of creating a vintage inspired retro flyer design. There are four main areas of concentration to achieve this look and feel: color, type, character and texture. We’ll review a complete vintage vector design workflow to create this retro flyer design. Let’s get started.

      Visit Article

    • Webdesigntuts+ — Web Design Tutorials
    • Speed Up Your Workflow With Photoshop Actions Quick Tip: Speed Up Your Workflow With Photoshop Actions

      Avoiding repetitive tasks is always going to speed up your workflow. In today’s Quick Tip we’ll do just that, by utilizing Photoshop’s actions panel and combining it with hotkeys. Watch this quick screencast and I guarantee you’ll save tons of time next time you’re designing!

      Visit Article

    • Finishing Off Building a Responsive Layout With Skeleton: Finishing Off

      During previous screencasts in this series we’ve covered a lot of ground, building our responsive (or adaptive) layout with the Skeleton boilerplate. It’s now time to finish all the final details; arguably the most time-consuming part of any website build!

      Visit Article

    • Improvements for Web and UI Designers Adobe Photoshop CS6: Improvements for Web and UI Designers

      Photoshop CS6 has been hailed as a huge improvement for web and UI designers. Im going to share with you some of the features that Photoshop CS6 Beta has to offer and demonstrate how they can help you in your web or UI design workflow.

      Visit Article

    • Phototuts+ — Photography Tutorials
    • A How-To Guide to Getting Started in Real Estate Photography A How-To Guide to Getting Started in Real Estate Photography

      Real estate is one of the world’s most competitive industries. Dominated by ambitious agents looking for the next big sale, selling real estate is all about setting yourself apart from the competition. What better way to catch a buyer’s eye than the perfect photo of the perfect home? In today’s article, we’re taking a look at the exciting world of real estate photography.

      Visit Article

    • The 18% Gray Card A Simple Solution to White Balance and Exposure: The 18% Gray Card

      An 18% gray card is a handy accessory that every serious photographer should keep in their bag. It doesn’t cost much and it barely takes up any space. If you encounter a situation where you have mixed lights, this unassuming piece of plastic helps you determine the white balance. It can also be used to determine the correct exposure.

      Visit Article

    • An Expert Guide to Matting and Framing a Photo An Expert Guide to Matting and Framing a Photo

      The final printed image is the culmination of my journey in creating a piece of artwork that represents my view of the world around me. As photographers in the digital age we spend far too much time staring at our photographs on our computer screens and very little time holding them in our hands. I still take great pride in every print I produce. There are a myriad of options for printing your work today, from canvas wraps to Metal prints, however for me there is something timeless and classic about a finely Matted and Framed print.

      Visit Article

    • Cgtuts+ — Computer Graphics Tutorials
    • Rigging A Voodoo Doll Character In Maya Using Setup Machine & Face Machine Rigging A Voodoo Doll Character In Maya Using Setup Machine & Face Machine

      In this tutorial you’ll learn how to create a complete character rig for a voodoo doll character in Maya using the Setup Machine and Face Machine plugins from Anzovin studios. You’ll learn how these plugins can save you valuable time during rigging by allowing you to utilize pre-built body and face rigs which can then be customized to fit you and your character’s specific needs.

      Visit Article

    • Creating A Stylish 3D Countdown Animation In Cinema 4D Creating A Stylish 3D Countdown Animation In Cinema 4D

      In this tutorial we’re going to create a smooth, stylish countdown animation. You can use words, letters, logos or whatever you want to make this type of animation. As you can see it’s easy to set up and looks very stylish and attractive.

      Visit Article

    • Create a 3D Micro Robotic Insect in ZBrush Create a 3D Micro Robotic Insect in ZBrush

      This week, Cgtuts+ has teamed up with our sister site Psdtuts+ to bring you this amazing two part, in-depth tutorial from Nacho Riesco. In this tutorial we are going to sculpt a Micro Bionic Insect with chemical war purposes using simple hard-surface modelling techniques with the Clipping Brush, Masking and much more. Head over to Psdtuts+ for the conclusion of this project where we’ll composite our render passes from Zbrush, and create the final image in Photoshop!

      Visit Article

    • Aetuts+ — After Effects Tutorials
    • Make Your Own Durable Light Dimmers For Less Than $30 Make Your Own Durable Light Dimmers For Less Than $30

      In today’s tutorial we’re going to take you step by step through everything you need to know to build your own rugged light dimmers. We use these exact dimmers on all our studio and on location shoots. Besides being extremely durable, these little devices provide a wider range of lighting options and are surprisingly valuable when you have to light a scene in a tight location.

      Visit Article

    • Is Working On Stills Easier in After Effects or Photoshop? Is Working On Stills Easier in After Effects or Photoshop?

      We always tend to go to Photoshop for working with still images, but today I’d like to bring up a few thoughts about why working in After Effects might be a better solution for your next project.

      Visit Article

    • Show A Motion Path With The StroMotion Effect Show A Motion Path With The StroMotion Effect

      In this tutorial we will track freeze frames into a hand-held scene utilizing The Foundry’s CameraTracker to achieve an effect that is often referred to as “StroMotion”. We’ll be talking about different methods of how to remove the subject from the background and how to line everything up. Enjoy! )

      Visit Article

    • Audiotuts+ — Audio & Production Tutorials
    • 30+ Sites That Serve Up Great Loops and Samples Sites That Serve Up Great Loops and Samples

      Loops can form the foundation of a track, and are useful for quickly putting some ideas together when sketching out an arrangement. Samples provide us with sounds and colors to create our music with. But where can you download great loops and samples? Here are 30+ great places to start.

      Every music producer worth his salt is in the process of building up a useful collection of useable sounds.

      Visit Article

    • Morphing in Pro Tools Morphing in Pro Tools

      We’ve all seen how you can morph one face into another in the graphical world. In this screencast Rishabh Rajan shows us how to achieve the same thing with audio using Pro Tools.

      Visit Article

    • Mastering, The Final Chapter (Part 1) D Mixing Part 7: Mastering, The Final Chapter (Part 1)

      Although this is a series on mixing, it feels incomplete not to get into at least a brief discussion on master bus options and to discuss what exactly goes on when you print all your hard work to a single and final stereo file. Due to the depth of this topic, I am splitting it into two parts.

      Visit Article

    • Activetuts+ — Flash, Flex & ActionScript Tutorials
    • What Is Dart, and Why Should You Care? What Is Dart, and Why Should You Care?

      In this tutorial, I’ll introduce you to Google’s new web programming language, Dart, and explain why you should like it and what you need to know about it. Learn about this new language and form some opinions about it – will it really replace JavaScript?

      Visit Article

    • Accessing the Same Saved Data With Separate Flash and JavaScript Apps Accessing the Same Saved Data With Separate Flash and JavaScript Apps

      In this tutorial I will show you how to access the same saved data in separate Flash and JavaScript apps, by storing it in HTML5 LocalStorage and using ExternalInterface to reach it with AS3. We will create the same app in both JavaScript and Flash to demonstrate that it is platform agnostic.

      Visit Article

    • Introduction An ImpactJS Overview: Introduction

      Impact is an incredibly powerful HTML5 game framework which takes advantage of modern browser’s canvas element and can also run on mobile or be compile into a native iOS app. In this video I will go over the framework, how to set up a project, some background into how to create classes in it and finally go over the core classes that make up the framework. This is a high level overview which will give you a general sense for how things work.

      Visit Article

    • Wptuts+ — WordPress Tutorials
    • Mini Guide to Contact Form 7 Mini Guide to Contact Form 7

      Usually a website needs a contact form to communicate with the site owner. One of our favorites is Contact Form 7. Let’s see what it can do!

      Visit Article

    • Custom Post Type Helper Class Custom Post Type Helper Class

      For a lot of WordPress projects these days we use custom post types. The WordPress development team created some handy methods to integrate them into your projects. But when you use custom post types, taxonomies and meta boxes frequently, it’s quite probable that you’re going to repeat yourself. That’s why we are going to use the power of these WordPress functions to build a more powerful class, which we can use to quickly register post types, taxonomies and meta boxes.

      Visit Article

    • Using WordPress as an Intranet Using WordPress as an Intranet

      When we talk about WordPress we usually associate it with either being a blogging platform or just another content management system, but what about as an Intranet? This tutorial will show you how you can turn your basic installation of WordPress into a robust Intranet for your business.

      Visit Article

    • Mobiletuts+ — Mobile Development Tutorials
    • Create an Awesome Carousel, Version 2.0 Create an Awesome Carousel, Version 2.0

      Engage your users with stunning carousels! We’ll look at how easy and clean it can be to implement scrollable, interactive carousels in your iOS applications. With high configurability, you can have 3D, flat, rotating, and endless scrolling arrays for data, images, and buttons.

      Visit Article

    • Create an Alphabet Soup Game Corona SDK: Create an Alphabet Soup Game

      In this tutorial series, you will learn how to create a minimalistic Alphabet Soup game. The goal of this game is to allow the player to pick words out from a jumbled set of letters. Read on!

      Visit Article

    • Interacting with Web Services iOS Quick Tip: Interacting with Web Services

      At some point in your iOS development career, you will have the need to interact with a web service from within your app. You may need to access remote data, parse a social network feed, or even download some assets into your application. This quick tip will teach you to do so without using third party libraries!

      Visit Article


Planet PHP

  • Permalink for 'OSInet library converted to PSR0 / PSR1'

    OSInet library converted to PSR0 / PSR1

    Posted: May 6th, 2012, 4:21am MDT by Riff Blog - PHP-GTK

    Over the last few days, I finally decided to revisit the old OSInet PHP library, to dust it off somehow, and convert the class-based parts to PSR0 and the whole to what seems to be liable to become PSR1 at some point.

    This library contains a zoo of function helping with PHP-GTK development, and three packages with their demo application:

    Class Grapher Build a graph of inheritance and interface implementations on a directory (and subdirectories) of PHP code This package uses the Drupal Grammar Paser to parse code, and includes a Drush 5 plugin for easy use within a Drupal site, but can also be used to parse non-Drupal code, as long as the Grammar Parser - which does not depend on Drupal either - is installed in the include path. It is a more complete version of the Drupal-only Class Grapher sandbox on drupal.org. In the current version, graphs are generated using GraphViz. An extension to a client-side visualization tool like the Infovis toolkit should come someday. Suggestions for other client-side libraries welcome (please comment!). Open Document Calc reader This package provides a few classes and methods to extract the content of OpenDocument (LibreOffice, OpenOffice.org, ...) spreadsheets. Finite State Machine This package is used to build applications designed around a finite state machine, and is mostly intended for use in PHP-GTK applications, to provide asynchronous processing. The demo application uses the PHP FTP extension to expose its asynchronous notifications in a PHP-GTK UI

    read more

  • Permalink for 'PHP 5.3.12 and 5.4.2 releases about CGI flaw (CVE-2012-1823)'

    PHP 5.3.12 and 5.4.2 releases about CGI flaw (CVE-2012-1823)

    Posted: May 5th, 2012, 4:00pm MDT by PHP: Hypertext Preprocessor
    PHP 5.3.12/5.4.2 do not fix all variations of the CGI issues described in CVE-2012-1823. It has also come to our attention that some sites use an insecure cgiwrapper script to run PHP. These scripts will use $* instead of "$@" to pass parameters to php-cgi which causes a number of issues. Again, people using mod_php or php-fpm are not affected. One way to address these CGI issues is to reject the request if the query string contains a '-' and no '='. It can be done using Apache's mod_rewrite like this: RewriteCond %{QUERY_STRING} ^[^=]*$ RewriteCond %{QUERY_STRING} %2d|\- [NC] RewriteRule .? - [F,L] Note that this will block otherwise safe requests like ?top-40 so if you have query parameters that look like that, adjust your regex accordingly.Another set of releases are planned for Tuesday, May, 8th. These releases will fix the CGI flaw and another CGI-related issue in apache_request_header (5.4 only).We apologize for the inconvenience created with these releases and the (lack of) communication around them.
  • Permalink for 'PHP 5.3.12 and 5.4.2 and the CGI flaw (CVE-2012-1823)'

    PHP 5.3.12 and 5.4.2 and the CGI flaw (CVE-2012-1823)

    Posted: May 5th, 2012, 4:00pm MDT by PHP: Hypertext Preprocessor
    PHP 5.3.12/5.4.2 do not fix all variations of the CGI issues described in CVE-2012-1823. It has also come to our attention that some sites use an insecure cgiwrapper script to run PHP. These scripts will use $* instead of "$@" to pass parameters to php-cgi which causes a number of issues. Again, people using mod_php or php-fpm are not affected. One way to address these CGI issues is to reject the request if the query string contains a '-' and no '='. It can be done using Apache's mod_rewrite like this: RewriteCond %{QUERY_STRING} ^[^=]*$ RewriteCond %{QUERY_STRING} %2d|\- [NC] RewriteRule .? - [F,L] Note that this will block otherwise safe requests like ?top-40 so if you have query parameters that look like that, adjust your regex accordingly.Another set of releases are planned for Tuesday, May, 8th. These releases will fix the CGI flaw and another CGI-related issue in apache_request_header (5.4 only).We apologize for the inconvenience created with these releases and the (lack of) communication around them.

Nettuts+

  • Permalink for 'Reshaping Our Perception of Success'

    Reshaping Our Perception of Success

    Posted: May 4th, 2012, 8:02pm MDT by Jeffrey Way

    Over the course of these last two weeks, I had the pleasure of attending an Envato meetup/conference in Malaysia. As you might expect, Envato is composed of ridiculously smart and talented folks…folks so smart that it quickly becomes intimidating!

    But I’m not here to talk about the conference specifically; instead, I’d prefer to ramble a bit on one of my largest takeaways from the event.

    The Old-Fashioned “Path” The Path

    One day during the conference, I had a chat with Envato’s current (temporary) lead development manager, Pete, about the traditional concept of advancement in a company. In many ways, we’re designed/brainwashed from an early age to follow a very specific path:

    • Begin at the bottom.
    • Slowly work your way up to your target position (meaning the job in which you are most content and fullfilled).
    • Finally, despite your instincts advising you otherwise, you disregard your current contentment, and instead continue once again up the stairs… to management.

    That’s a good thing, right? Well, in our industry, specifically, maybe not.

    Management can be a bit of a scary word. It indicates Excel, not code. It indicates… management, not development.

    Our life-long training tells us that this is what’s supposed to happen.

    But, nonetheless, it’s still a higher level (hopefully higher paying) job. Our life-long training tells us that this is what’s supposed to happen, if we desire to be successful. You’ve worked hard; now you get to manage others (and maybe drink scotch). This is the path.

    For creatives, though, does this sort of role make us happy?

    • Is this what kept us up late at night learning how to code?
    • Are we selling our souls (to be dramatic) for slightly more money?
    • Are we addicted to some silly notion of control or power or respect?

    Sure, we may have a bit more input into the direction of the business, but does it make us happier? For the last year or so, I’ve struggled with this very thing. I adore my current job: I’m able to help shape the future of education in the creative fields (more on that later this year), and spend all of my spare/free time learning how to be a more efficient developer. What could be better than that?

    Still, though, that lingering feeling always rested in the back of my mind: I’m only “advancing” in the world if my job title/rank increases sporadically. I had (and have) no desire to change my current involvement/role in the company (Envato), but, nevertheless, felt that I should reach for these more traditional managerial roles.

    This old-fashioned notion of advancement is a silly metric for success.

    The Lesson

    Pete taught me that this old-fashioned notion of advancement is a silly metric for success. Instead, we have to reshape our perception of what both success and fulfillment are. Remember when I noted that Pete was the development manager at Envato? Well, technically, at his own choosing, he’s the temporary manager, while we search for a new development manager. Despite the fact that he’s certainly qualified for the job, he doesn’t want it – which I find incredibly admirable. Instead, his skills/desires rest firmly in things like software architecture. In his own words, that is where he is able to contribute most effectively to the company. So, a bit oddly, perhaps, he is currently in the position of finding and hiring his future manager.

    Closing Thoughts

    It’s interesting how the older I get, the more and more I come back to this one word: “contentment.” It’s not about job titles, or vanity, or even money (to some extent); it’s simply about contentment. Do what you love, and forget those old-fashioned job titles and notions of success. Or…

    Figure out where you’re most effective in your company, and do…that. Period.


Planet PHP

  • Permalink for 'New HTTP status codes'

    New HTTP status codes

    Posted: May 4th, 2012, 2:44pm MDT by Evert Pot

    RFC 6585 has been published quite recently. This document describes 4 new HTTP status codes.

    So in case you were wondering, yes.. HTTP is still evolving :), and these new statuses may be quite useful for developing your REST, or otherwise [HTTP-based] service. This post describes why they are important, and when you should use them.

    428 Precondition Required

    A precondition is something a client can send along with a HTTP request. This condition needs to be met in order for the request to complete.

    A good example is the If-None-Match header, which is often used along with GET requests. If the If-None-Match is specified, the client can request to only receive the response if the ETag changed.

    Another example of a precondition, is the similar 'If-Match' header. An If-Match header is usually sent along with PUT requests to indicate to only update the resource if it hasn't changed. This is useful if multiple clients are using a [HTTP-based] service, and they want to make sure they are not overwriting each others contents.

    Using the 428 Precondition Required status, the server can now indicate that the client *must* send along one of those headers to perform the request. This is effectively a way for the server to force clients to prevent this 'lost update' problem.

    429 Too Many Requests

    This status code is useful in cases where you want to limit the amount of requests a client may want to do on your API (also known as rate limiting).

    In the past different status codes have been used, such as '509 Bandwidth Limit Exceeded'. Twitter uses 420 for some stuff (which is an unused status code). Thus it was important enough to give it it's own code.

    So if you limit the number of requests clients may do on your server, 429 Too Many Requests is the way to go. Include a 'Retry-After' response header to indicate to a client when they are allowed to make requests again.

    431 Request Header Fields Too Large

    I was surprised to see that this was a common enough usecase to warrant it's own status code, but here it is!

    In a case where a client is sending a HTTP request header that's too big, the server can respond with 431 Request Header Fields Too Large to indicate exactly that.

    I have no idea why they skipped over 430 though. I tried to search around, but couldn't quite find the reasoning. My best guess is that a lot of people may have mistyped '403 Forbidden' as '430 Forbidden', and they wanted to avoid complications. If you know, let me know!

    511 Network Authentication Required

    This status code is very interesting to me. You will not have to deal with this if you're writing a server, but it can be important if you're writing a (desktop) HTTP client.

    If you move around with your laptop or smartphone a lot, you may have noticed that a lot of public wifi services now require you to accept their license agreement, or just log in before the web works.

    This is generally done by intercepting the HTTP traffic and presenting a redirect and login when the user tries to access the web. Quite nasty, but that's the way it is.

    Using these 'intercepting' clients can have some nasty side effects. There are two great examples mentioned in the RFC to illustrate this.

    • If you hit a website before logging in, the network device intercepts the first request. These devices also tend to have a 'favicon.ico' stored. After logging in, you'll notice that the favicon is now cached for the website you tried to visit, and it may follow you around for quite some time.
    • If a client uses HTTP requests to find documents, the 'network' may respond with a login page, instead of the json or other document you expected. Your client may (in error) assume it's a 'normal' response and use that instead. This can put clients in a broken or irrecoverable state. I've noticed this in real life a few times working on a CalDAV system as well.

    So to fix this 511 Network Authentication Required is introduced.

    So if you write an application that runs on an desktop or phone and use [HTTP,] you should ideally check for this HTTP response code. In a way, it simply means that a network is not yet available and you should pretty much ignore anything coming back until it is. You could even provide the user with the returned login page, like iOS and OS X 10.7 do.

  • Permalink for 'Introduction to wsunit'

    Introduction to wsunit

    Posted: May 4th, 2012, 1:31am MDT by Bastian
    Testing interactions with data providers via Http (e.g. webservices) is an essential thing to ensure the service has not changed it's dataformat or even worse is not reachable at all. In both cases you want to be the first to now and probably be able to fix this before your customer finds out. So you write integration tests and run then as a different job in youe continuous integration environment. So far so good. But then you are as lazy as I am and hate doing work more than once. This is where WSUnit gets handy.
  • Permalink for 'readfile() not considered harmful'

    readfile() not considered harmful

    Posted: May 3rd, 2012, 8:12pm MDT by Larry Garfield

    If you're like me, you've probably read a dozen or two articles about PHP performance in your career. Many of them are quite good, but some are simply flat out wrong, or misinformed.

    One of the old truisms that has been repeated for as long as I can recall is "don't use readfile() if you have big files, because it reads the whole file into memory and your server will explode." The usual advice is to manually stream a file, like so:

    <?php
    $fp = fopen('bigfile.tar', 'rb');
    while (!feof($fp)) {
    print fread($fp, 1024);
    }
    fclose($fp);
    ?>

    There's just one problem with that age-old truism: It's not true.

    read more

  • Permalink for 'Attack against PHP-CGI - DoS, Code disclosure and more...'

    Attack against PHP-CGI - DoS, Code disclosure and more...

    Posted: May 3rd, 2012, 9:41am MDT by Dr. Christopher Kunz - PHP

    There is a new PHP bug that just became public today (leaked accidentially, it seems...). A flaw in the PHP CGI’s input sanitation process allows attackers to set command-line options via the query string.This behavior seems to be an oversight / misplaced design decision from 2004 and is only exploitable in specific web servers. Apache is one of them...


    This opens interesting opportunities. I have blogged about those here: New Exploit @ php-security.net


    By the way, Suhosin partially mitigates one of the easier remote code execution vectors that are opened through this attack. Suhosin can be circumvented completely and trivially.

  • Permalink for 'Making the Web Faster with HTTP 2 Protocol'

    Making the Web Faster with HTTP 2 Protocol

    Posted: May 3rd, 2012, 7:24am MDT by PHP Classes
    Making">[HTTP-2-Protocol.html">Making] the Web Faster with HTTP 2 Protocol By Manuel Lemos The HTTP protocol version 2.0 is in the process of being defined. There was a call for proposals and several researchers submitted specifications and ideas that can make the Web faster and better in several other aspects.

    Read this article to learn about the details of these proposals and what Web developers can expect to prepare to take advantage of the planned improvements of the HTTP 2.0 protocol.
  • Permalink for 'Tips on Writing an API for a Smartphone App'

    Tips on Writing an API for a Smartphone App

    Posted: May 3rd, 2012, 7:22am MDT by Lorna Mitchell

    Yesterday, I saw this tweet:

    bunoire14 bunoire14 (Olly Warren) @lornajane @nabeels tips on starting to write an API to interact with Smartphone App?? :-s

    On 2-5-2012 12:48:53 from Twitter for Mac in reply to Lorna Mitchell

    I have lots of advice for Olly (whom I know personally) but there's no way it will fit into a tweet! So here it is, in rather longer form :)

    Be Consistent

    Whatever data format you pick, whatever app you are building, whichever approach you choose, be consistent. Your whole API should call things by the same name, use the same validation rules for everything, and accept parameters in the same order. Every time. Look out in particular for things like singular/plural names, mixing case and parameters which are sometimes optional.

    Fail Really Really Excellently

    Things will go wrong. This is the way the world works in general, and on the web in particular. Requests sometimes don't arrive, or the responses don't. Disks fill up, databases fall offline, all kinds of weird stuff does happen. All that matters is how you deal with it.

    Make all your errors arrive in the same format as the successful response would have. This means that the client can parse it and understand what is there. If you feed html into something that wasn't expecting it, something unexpected will happen (actually PHP's json_decode() will cause PHP to segfault if you try hard enough).

    Give meaningful error messages. This allows users to help themselves, continue to use your API, hopefully learn to love it - and all without having to bother you in the process. This is the holy grail of API creation!

    Keep It Tidy

    A Small API is easy to maintain and support, so try to keep your APIs as minimal as possible. Only write functionality that is really needed. Make things flexible so that clients can ask for more or fewer records than the default (especially if the data sets can get large!), and get the result set sorted sensibly - it's very expensive to do those kinds of operations on any kind of large data set on a small device.

    Keeping this small is also keeping things simple, and the KISS principle is good advice for all areas of software design.

    The Actual Advice

    For a non-novice programmer, an API is a project that is absolutely approachable. For sending data to a smart phone, I'd recommend the following:

    • JSON format - it's lightweight, easy to parse, and also relatively easy to debug if you need to
    • RPC style - REST is much cooler, but it's hard to get started with if you haven't used it before, and bad REST just gets everyone upset. You already know how to declare and call a function - so make your API along those lines. Look at wikipedia's JSON-RPC page for some ideas
    • Make sure you understand HTTP headers and status codes, and use them! Use Accept and Content-Type for sorting out data formats, status codes to say if things went well or not.
    • I feel like there should be more advice here ... please add a comment if you know what else I should be telling Olly!
    Tools to Help You

    You'll be doing a lot of debugging, print_r($_SERVER) is a good place to start with understanding what requests came in. Use wireshark to make sure that you are sending and receivi

    Truncated by Planet PHP, read more at the original (another 624 bytes)

  • Permalink for 'Tips on Writing an API for a Smartphone App'

    Tips on Writing an API for a Smartphone App

    Posted: May 3rd, 2012, 7:22am MDT by Lorna Mitchell

    Yesterday, I saw this tweet:

    bunoire14 bunoire14 (Olly Warren) @lornajane @nabeels tips on starting to write an API to interact with Smartphone App?? :-s

    On 2-5-2012 12:48:53 from Twitter for Mac in reply to Lorna Mitchell

    I have lots of advice for Olly (whom I know personally) but there's no way it will fit into a tweet! So here it is, in rather longer form :)

    Be Consistent

    Whatever data format you pick, whatever app you are building, whichever approach you choose, be consistent. Your whole API should call things by the same name, use the same validation rules for everything, and accept parameters in the same order. Every time. Look out in particular for things like singular/plural names, mixing case and parameters which are sometimes optional.

    Fail Really Really Excellently

    Things will go wrong. This is the way the world works in general, and on the web in particular. Requests sometimes don't arrive, or the responses don't. Disks fill up, databases fall offline, all kinds of weird stuff does happen. All that matters is how you deal with it.

    Make all your errors arrive in the same format as the successful response would have. This means that the client can parse it and understand what is there. If you feed html into something that wasn't expecting it, something unexpected will happen (actually PHP's json_decode() will cause PHP to segfault if you try hard enough).

    Give meaningful error messages. This allows users to help themselves, continue to use your API, hopefully learn to love it - and all without having to bother you in the process. This is the holy grail of API creation!

    Keep It Tidy

    A Small API is easy to maintain and support, so try to keep your APIs as minimal as possible. Only write functionality that is really needed. Make things flexible so that clients can ask for more or fewer records than the default (especially if the data sets can get large!), and get the result set sorted sensibly - it's very expensive to do those kinds of operations on any kind of large data set on a small device.

    Keeping this small is also keeping things simple, and the KISS principle is good advice for all areas of software design.

    The Actual Advice

    For a non-novice programmer, an API is a project that is absolutely approachable. For sending data to a smart phone, I'd recommend the following:

    • JSON format - it's lightweight, easy to parse, and also relatively easy to debug if you need to
    • RPC style - REST is much cooler, but it's hard to get started with if you haven't used it before, and bad REST just gets everyone upset. You already know how to declare and call a function - so make your API along those lines. Look at wikipedia's JSON-RPC page for some ideas
    • Make sure you understand HTTP headers and status codes, and use them! Use Accept and Content-Type for sorting out data formats, status codes to say if things went well or not.
    • I feel like there should be more advice here ... please add a comment if you know what else I should be telling Olly!
    Tools to Help You

    You'll be doing a lot of debugging, print_r($_SERVER) is a good place to start with understanding what requests came in. Use wireshark to make sure that you are sending and receivi

    Truncated by Planet PHP, read more at the original (another 531 bytes)

  • Permalink for 'PHP 5.3.12 and PHP 5.4.2 Released!'

    PHP 5.3.12 and PHP 5.4.2 Released!

    Posted: May 2nd, 2012, 4:00pm MDT by PHP: Hypertext Preprocessor
    There is a vulnerability in certain CGI-based setups (Apache+mod_php and nginx+php-fpm are not affected) that has gone unnoticed for at least 8 years. Section 7 of the CGI spec states: Some systems support a method for supplying a [sic] array of strings to the CGI script. This is only used in the case of an `indexed' query. This is identified by a "GET" or "HEAD" HTTP request with a URL search string not containing any unencoded "=" characters. So, requests that do not have a "=" in the query string are treated differently from those who do in some CGI implementations. For PHP this means that a request containing ?-s may dump the PHP source code for the page, but a request that has ?-s&=1 is fine.A large number of sites run PHP as either an Apache module through mod_php or using php-fpm under nginx. Neither of these setups are vulnerable to this. Straight shebang-style CGI also does not appear to be vulnerable.If you are using Apache mod_cgi to run PHP you may be vulnerable. To see if you are, just add ?-s to the end of any of your URLs. If you see your source code, you are vulnerable. If your site renders normally, you are not.To fix this, update to PHP 5.3.12 or PHP 5.4.2. We recognize that since CGI is a rather outdated way to run PHP, it may not be feasible to upgrade these sites to a modern version of PHP. An alternative is to configure your web server to not let these types of requests with query strings starting with a "-" and not containing a "=" through. Adding a rule like this should not break any sites. For Apache using mod_rewrite it would look like this: RewriteCond %{QUERY_STRING} ^(%2d|-)[^=]+$ [NC] RewriteRule ^(.*) $1? [L] If you are writing your own rule, be sure to take the urlencoded ?%2ds version into account.Making a bad week worse, we had a bug in our bug system that toggled the private flag of a bug report to public on a comment to the bug report causing this issue to go public before we had time to test solutions to the level we would like. Please report any issues via bugs.php.net.For source downloads of PHP 5.3.12 and PHP 5.4.2 please visit our downloads page, Windows binaries can be found on windows.php.net/download/. A ChangeLog exists.
  • Permalink for 'Now serving: SPDY '

    Now serving: SPDY

    Posted: May 2nd, 2012, 8:01am MDT by Dr. Christopher Kunz - PHP

    This website (as long as you access it via HTTPS) is now serving pages with SPDY, Google’s still-experimental web acceleration protocol. Since SPDY mandates usage of SSL, I am using a CACert certificate to serve up pages. If you want to know why I didn’t buy a CA-signed certificate, please see this talk for a couple thoughts: SSL and the future of web authentication (PDF)


    The reason this posting lands in the PHP category is that I want to have a playground testing PHP applications with mod_spdy. Currently (and probably also in the future), this machine uses mod_php instead of php_(f)cgi(d) - this is not recommended for interoperation with mod_spdy. To test the real-life impact of the possible thread safety issues, I am using my private pages as a sandbox.


     So, please test away. There is a couple of PHP applications here that might or might not work:



    If you have any comments, especially if you can share success stories about mod_spdy and PHP, or just want to see how SPDY performs, please comment away!


    Update: You can check if you’re using SPDY already by looking into the following little page, iframed for your convenience: SPDY check



    <br /> </p>


    "Now serving: SPDY " vollständig lesen

Nettuts+

  • Permalink for 'Why Wine and Macbooks Don’t Mix…and How to Handle the Aftermath'

    Why Wine and Macbooks Don’t Mix…and How to Handle the Aftermath

    Posted: May 1st, 2012, 4:18pm MDT by Jeffrey Way

    Ready for a revelation? A concept that you’ve never considered before? Well here it is: never ever, ever pour a glass of wine into your Macbook keyboard. Or, more practically put, be extremely careful when there’s a drink of any kind near your laptop. If a spill occurs, and you don’t act quickly enough, you’ll find yourself staring at a massive bill for a new logic board, hard-drive, battery, and anything in between.

    Accidents do happen — so plan on it. What’s more important is that you learn exactly what to do when these spills inevitably occur.

    July, 2010 Step 1. Don’t Freeze. Unplug! Macbook Wine Spill

    Ahhhh! The wife (meaning, you) accidentally spilled wine all over your keyboard. From personal experience, I can assure you that, for some odd reason, your first instinct with a massive computer spill is to freeze for five seconds or so, in shock. Don’t do this! Luckily Apple laptops are pretty helpful about automatically shutting down to prevent as many issues as possible before they happen. The more recent laptops even have liquid detection…though I’m certain that Apple is more interested in voiding your warranty than protecting you. For those uninformed, most laptop warranties do not cover spills.

    Nonetheless, don’t waste a single second. Quickly unplug the computer, and shut it down.

    The walls and carpet may have liquid on them as well, but ignore that. The computer is far more important right now.

    Step 2. Flip that Sucka Turn the laptop over to let the liquid drain

    The next step, which should occur within seconds of beginning Step 1, is to flip the laptop upside down, into an L-shape. Gravity will then force as much liquid to drain out of the keyboard as possible. Make sure that you lay it on a towel so that it can soak up the liquid.

    Let gravity do its job. Immediately flip the laptop into an L-shape.

    Step 3. Open the Back Unscrew the laptop to reveal the insides

    Using a tiny screw driver, unscrew the back-side of your laptop. This will, of course, vary, depending upon which model you’re using. I’m sure you can figure it out.

    Particularly on Macs, not all of the screws are the same size. Make a note of which screw goes where.

    Step 4. Remove the Battery and Hard Drive Remove the Macbook Pro battery

    Before progressing, ensure your livelihood and touch some metal objects nearby to remove any potential static electricity from your body.

    Needless to say, batteries and liquids — especially sugary, acidic liquids — don’t play nice together. Wherever yours is located on your laptop, remove it as quickly as possible. Next, get the hard drive out as well. We don’t want to risk any liquid seeping in, and corrupting your file system!

    And now that you know how easy it is to remove a hard drive, don’t ever again pay a person to upgrade your hard drive. It only takes a moment to do yourself. ;)

    Step 5. Dry the Insides Clean the insides of the computer after a drink spill

    With a paper towel of some sort, begin cleaning the insides of your computer. Depending upon how much liquid was spilled, this may either be a quick or lengthy process. For yours truly, it took around ten minutes to clean everything.

    Some people prefer to use a hair dryer to clean the insides. This one is up to you; however, I’d encourage you to not do so. Play it safe and use a towel. We don’t want to risk frying the insides.

    Step 6. Rubbing Alcohol and Cotton Clean the insides with a cotton swab

    Next, we need to continue removing as much sugar and acid as possible from the logic board. Otherwise, over time, it can begin to corrode the wiring. Yeah, this isn’t good!

    Using rubbing alcohol and a cotton swab, begin dabbing any stained areas — but be gentle. If you have access to the backside of your keyboard, clean that area as well. Unfortunately, on the newer Macbook Pro models, it’s extremely difficult to access this section. With past models, it was quite easy to remove the keyboard entirely, for cleaning purposes. Unfortunately, that’s no longer the case.

    Rubbing alcohol will help dissolve any remaining acid or sugar on the logic board.

    Step 7. Leave it Alone Leave the computer off for 3-5 days after a spill

    Anxiety is a dangerous thing. Resist the urge to determine whether or not you’ve destroyed your laptop, and keep it off for a minimum of 72-120 hours (3-5 days). This will allow any remaining liquid to dry/evaporate first. Make sure that, while its drying, you keep the battery outside of the computer. This is mostly a precaution.

    Keep the computer off for 3-5 days — no questions asked. Do not turn it on during this window.

    Step 8. Cross Your Fingers Cross your fingers

    After 72-120 hours, reconnect the battery, screw everything back in, cross your fingers, say a prayer, and turn on the computer. Particularly if you’re using a newer Macbook Pro (2010+ models), you’ve done everything you can do. With hope, and more often than not, it’ll chime, and start-up like a charm. However, if the battery is dead, or the hard drive is corrupted, you’re next best option is to take it in for official repair. Of course, this will somewhat depend upon how skilled you are, when working under the hood.

    About the Author

    Jeffrey Way — me…yes, I’m speaking in third person — once committed a Cardinal Sin, and caused a massive wine spill into his Macbook Pro. Had he not followed these exact steps, he’d be forking over another life savings for a new Mac. Luckily, that was not the case.

    Thanks for reading. Should the same ever happen to you, I hope this guide will help a bit!


Planet PHP

Nettuts+

  • Permalink for 'Recently in Web Development (April ’12 Edition)'

    Recently in Web Development (April ’12 Edition)

    Posted: April 30th, 2012, 2:04pm MDT by Siddharth

    Web development is an industry that’s in a state of constant flux with technologies and jargon changing and mutating in an endless cycle. Not to mention the sheer deluge of information one has to process everyday.

    In this series, published monthly, we’ll seek to rectify this by bringing you all the important news, announcements, releases and interesting discussions within the web development industry in a concise package. Join me after the jump!

    News and Releases

    All of the important news in a single place: releases, announcements, companies bickering, security issues and all related hoopla.

    Nettuts image The Infamous Semi-Colon Debate

    Ahh, JavaScript. I think it has caused more conflict than thatHelen. This time around there’s been a flurry of activity around a single, missing comma. I don’t want to take you away from the drama so check out the Github discussion below, after grabbing some popcorn.

    Personally, if you’re not CoffeeScript-ing, just add that darn semi-colon and call it a day.

    Click here for internet drama

    Nettuts image Django Moves to Github, Finally

    Most Pythonistas know Django. For those of you who don’t, Django is a high level Python framework that helps you out with web development. While Django has had a repo on Github for a long time now, it was in a state of desolation. You’d often see that the repo only held versions that were a lot behind the curve.

    Well, no more of that. Django has finally moved to Github and the repo seems to be active. If you’re interested, Subversion was what was used to manage Django earlier, since 2005.

    Github repo

    Nettuts image Meteor, a New Way to Build Apps

    Tired of the current frameworks and technologies, a group of devs has created a full stack, JavaScript only framework.

    Meteor is a set of new technologies for building top-quality web apps in a fraction of the time, whether you’re an expert developer or just getting started. I’m sure people are already tired of reading about JavaScript and the sheer number of frameworks sprouting out each day but this is really worth a look.

    Read more

    Nettuts image SPDY Gains More Traction With Firefox Beta

    SPDY, developed by Google, is a networking protocol aimed at improving web page load times as well as web security.

    As with anything web related, it takes eons to get anything standardized and browsers have already started implementing experimental versions of the technology. The latest Firefox beta adds support for the protocol, switching it on by default. It’s not the only browser to do — Chrome already includes support for SPDY while Opera does the same with its preview of version 12.

    Release Notes

    Nettuts image Microsoft Announces the Metro jQuery Mobile Theme

    Microsoft, in order to increase awareness of its spectacularly clean Metro interface, has open sourced a Metro themed design for jQuery mobile. The theme includes a large number of Metro themed widgets and interactions and seems to work really well.

    Read more

    Nettuts image Firefox is Now At Version 12

    Another month, another Firefox update. To be fair, the updates are now rather substantial this time around though.

    This version introduces a ton of developer tools and improvements along with a far more streamlined update process. The list of developer related updates, the ones we really care about, makes for a rather interesting read so make sure to hit the link below.

    Read more

    Nettuts image CoffeeScript, Now With JavaScript’s Strict Mode, Updates to Version 1.3

    Developers either love or hate CoffeeScript. I personally love it which is why you’re seeing this here. The latest version enforces the strict more at compile time helping you weed out those annoying, niggling issues.

    Version 1.3 also brings you improvements to the REPL as well as a bunch of tweaks and improvements.

    Change log

    Nettuts image Rails Updates in Light of Recent Security Issues

    With the havoc caused by the mass assignment issue last month, the Rails team has reconsidered their stance on this issue and has pushed out version 3.2.3 which changes the value of config.active_record.whitelist_attributes . There are also various, assorted fixes and improvements bundled into this version.

    Release Notes

    New Kids on the Block

    As web developers, the sheer amount of resources we can tap into increases exponentially with time. Here is just a quick look at some recently created resources that deserve your attention — everything from new books to scripts and frameworks.

    Smooth.js

    Smooth.js takes an array of numbers or vectors and returns a parametric function that continuously interpolates that array. Smooth.js supports several interpolation methods, and flexible options for boundary behavior.

    Github Repo

    Scroll Path

    jQuery Scroll Path is a plugin that lets you define your own custom scroll path. What this means exactly is best understood by checking out the demo. The plugin uses canvas flavored syntax for drawing paths, using the methods moveTo, lineTo and arc. To help with getting the path right, a canvas overlay with the path can be enabled when initializing the plugin.

    Github Repo

    keymaster.js

    Keymaster is a simple (100 LoC or so) micro-library for defining and dispatching keyboard shortcuts. It has no dependencies.

    Github Repo

    Ham

    PHP Microframework for use with whatever you like. Basically just a fast router with nice syntax, and a cache singleton. Will add more things as I go, like perhaps an extension system, autoloader and some other stuff to make developing in PHP less irritating than it currently is.

    Github Repo

    mailcheck.js

    The jQuery plugin that suggests a right domain when your users misspell it in an email address.

    Github Repo

    Hammer.js

    Hammer.js is a javascript library that can be used to control gestures on touch devices.

    Github Repo

    Monorail.js

    Monorail.js will never force you, and uses only what you need. Monorail.js will never force you to install anything not needed for your project. The goal is to use what you need. Anything other than creating a project will always be optional.

    Github Repo

    Rainbow

    Rainbow is a code syntax highlighting library written in Javascript. It was designed to be lightweight (1.4kb), easy to use, and extendable.

    Github Repo

    Timeline

    There are lots of timeline tools on the web but they are almost all either hard on the eyes or hard to use. Create timelines that are at the same time beautiful and intuitive for users. Timeline is great for pulling in media from different sources. Just throw in a link from Twitter, YouTube, Flickr, Vimeo, Google Maps or SoundCloud and Timeline will format it to fit perfectly. More media types will be supported in the future.

    Github Repo

    FakeS3

    FakeS3 is a lightweight server that responds to the same calls Amazon S3 responds to.
    It is extremely useful for testing of S3 in a sandbox environment without actually making calls to Amazon, which not only require network, but also cost you precious dollars.

    Github Repo

    retina.js

    retina.js makes it easy to serve high-resolution images to devices with retina displays. When your users load a page, retina.js checks each image on the page to see if there is a high-resolution version of that image on your server. If a high-resolution variant exists, the script will swap in that image in-place.

    Github Repo

    Rucksack

    Rucksack is a jquery plugin to arrange elements that can fit in the given width. It relies on the knapsack algorithm.

    Github Repo

    jQuery PopBox

    jQuery PopBox is a simple balloon UI element inspired by 37Signals Highrise CRM.

    Github Repo

    html2canvas

    This script allows you to take “screenshots” of webpages or parts of it, directly on the users browser. The screenshot is based on the DOM and as such may not be 100% accurate to the real representation as it does not make an actual screenshot, but builds the screenshot based on the information available on the page.

    Github Repo

    Best of the Internet

    Often, you’re not really looking for a tutorial as much as you’re looking for a rant, an opinion or the musings of a tired developer or just something cool with absolutely zero real world use. This sections contains links to precisely those — interesting and cool stuff from the developer community.

    Nettuts image PHP: a fractal of bad design

    A detailed look at why most people, when given a gun with two bullets and asked to shoot Hitler or PHP, want to shoot PHP twice. As much of a PHP lover I am, I can’t help but agree with a lot of this article.

    Read more

    Nettuts image PHP Sucks! But I Like It!

    A really well written counter point to the earlier article, backed by a lot of reasoned thinking.

    Read more

    Nettuts image The infernal semicolon

    Brendan Eich chimes in with his stance on the entire JavaScript semi-colon issue.

    Read more

    Nettuts image How to be a successful programmer without a CS degree

    A wonderfully detailed answer on StackOverflow that outlines how to be a kickass programmer without an expensive CS degree.

    Read more

    Nettuts image Zero downtime deploys for Rails apps

    A very informative presentation that outlines how you should go on about running and upgrading your Rails apps.

    Read more

    Nettuts image On being “Senior”

    A nice little read about the software industry and the rat race around titles.

    Read more

    Wrapping Up

    Well, that’s about all the major changes that happened in our industry lately.

    Do you want us to cover more standard news? A focus on upcoming scripts maybe? Or just more interesting posts and discussions from the community? Let us know in the comments and thank you so much for reading!


Planet PHP

  • Permalink for 'Common, Cryptic PHP Errors'

    Common, Cryptic PHP Errors

    Posted: April 30th, 2012, 11:00am MDT by Court Ewing
    Common, Cryptic PHP Errors

    If you've been programming for awhile, then you've probably experienced your fair share of cryptic error messages. It's understandable that building in detailed error messages that are clear to even novice developers is not always a high priority for programming languages when there are so many other features to create and issues to address. The PHP language has decent error messages, but it is by no means an exception to this rule.

    The following three error messages are as cryptic as they are common, but fortunately they are all easy to fix.

    Fatal error: Parse error: syntax error, unexpected T_PAAMAYIM_NEKUDOTAYIM in /path/to/index.php on line 48

    Paamayim Nekudotayim is hebrew for "twice colon", and it is the term adopted by Andi Gutmans and Zeev Suraski when they wrote the Zend engine for PHP 3. The more technical term for this is the Scope Resolution Operator, and it is used for accessing static properties and methods on classes. When you see this error, you are probably trying to access a static method or property on a non existent class name.

    If you've never experienced this error before, chances are it wouldn't take you too long to hunt down the problem. Writer daleV from Greek Gumbo created this excellent write up detailing this particular bug last year.

    Fatal error: Can't use function return value in write context in /path/to/index.php on line 48

    This error is a little more insidious than T_PAAMAYIM_NEKUDOTAYIM since, without experiencing it before, you may not realize what the problem is with a given line of code even if you were staring straight at it. This issue crops up when you try to pass the returned value from a function directly into either the isset() or empty() functions. This is easily resolved by storing the returned value in a variable first, but it does seem a little inconsistent, especially for new developers that have no concept of a construct versus a built-in function.

    At the time of this writing, there is actually an RFC that is in the voting phase for inclusion into the PHP core that addresses this issue for the empty() function. During the course of discussion about the RFC, it was decided that it was a bad idea to change this behavior for isset() as it is semantically confusing.

    Fatal error: Exception thrown without a stack frame in Unknown on line 0

    This is about as bad as error messages could possibly get as it requires you to have detailed knowledge about the technical implementation of the language for it to make any sense whatsoever. Also, no matter where this error occurs in your application, the error message still says that it happened in file "Unknown" and on line "0".

    This error is triggered when any exception is thrown but not caught from within a class destructor (i.e. __destruct()).

    When this happens, you do not really have many options other than hunting down the destructors in all of your objects to see which one may fail. May I suggest: grep --color -rn "n __destruct" to help hunt down the issue in a linux terminal.

    You can save yourself a whole lot of frustration in the future if you keep these three error messages in the back of your mind.

Nettuts+

  • Permalink for 'The Essentials of Zepto.js'

    The Essentials of Zepto.js

    Posted: April 28th, 2012, 2:13am MDT by Siddharth

    Modern JavaScript libraries are quite the behemoths — just take a look at jQuery. When you’re creating a mobile app, or even just targeting modern browsers, a library that’s much more svelte and nimble becomes a tastier proposition.

    Today, we’re going to look at one such library, named Zepto.

    The Issue With Mixing Desktop Libraries and Mobile Devices

    One thing that has snuck past most radars has been the rise of mobile devices.

    See, the internet, and the technology that powers it, has grown in leaps and bounds over the past years. We moved from static sites to web applications to dynamic web applications and then to real time, hyper responsive, thingamabob apps of today. One thing that has snuck past most radars has been the rise of mobile devices.

    Think about it: a lot of us use smart phones and use it for browsing on a constant basis. Even at home, a non-trivial portion of my circle has adopted a tablet device for casual surfing and email. While this influx of devices is good from an exposure point of view, it isn’t without its caveats.

    Instead of thinking of these devices as display constrained like consumers do, we, as developers, need to think of them in terms of resources and bandwidth. Not all them sport a hyper quad gajillion Ghz CPU or come with oodles of memory. And let’s not even get started with the bandwidth. A big portion of the browsing population is still stuck on these infernal excuses for a mobile internet connection.

    I think you see where I’m going with this. Big, monolithic libraries like jQuery or Prototype definitely have their place but for this mobile era, I think there’s a place for something that’s a lot more nimble. And a lot of developers seem to agree with me.

    All the Code to Make a Library Work Across Browsers Adds Up

    Another big issue that I failed to mention is that contemporary libraries do a lot of cross browser stuff. In fact, a big draw of jQuery, initially, was how it abstracted away a lot of the cross browser quirkiness that front end developers had to work around. Even now, jQuery does a lot of heavy lifting under the hood to make sure nothing breaks in different browsers.

    But if you’re a developer looking to cater to only contemporary devices, do you really need all this, dare I say, cruft? The short answer is no. By cutting out unnecessary code, you both:

    • eke out more performance since there’s fewer lines of code for the browser to parse and
    • make your file smaller in size, which helps with the bandwidth constrained mobile devices.

    Think that this issue is overblown? Here’s a random blob of code from jQuery’s source:

    isPlainObject: function( obj ) {
    		// Must be an Object.
    		// Because of IE, we also have to check the presence of the constructor property.
    		// Make sure that DOM nodes and window objects don't pass through, as well
    		if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
    			return false;
    		}
    ....
    

    Or something a little more esoteric:

    // Perform a simple check to determine if the browser is capable of
    // converting a NodeList to an array using builtin methods.
    // Also verifies that the returned array holds DOM nodes
    // (which is not the case in the Blackberry browser)
    try {
    	Array.prototype.slice.call( document.documentElement.childNodes, 0 )[0].nodeType;
    
    // Provide a fallback method if it does not work
    } catch( e ) {
    	// The intended fallback
    }
    ....
    

    This may look fairly trivial but keep in mind this tends to adds up. If you’re only going to target modern browsers, either on desktops or mobiles, then there is no real need for all these additional checks and hacks. By cutting down your intended browsers, you win on both bandwidth and performance!

    So What’s Zepto’s Deal?

    I hear you guys saying “Enough buildup! Tell us about the darn library already!”. So let’s get to it.

    Zepto, as the title spoiled it for you, is a mobile JavaScript framework that rectifies both of the issues mentioned above. It has a very small code base and is feather weight at around 8kb.

    It manages to be so svelte by mostly cutting out the cross browser stuff. When it was created, the main focus was to support Webkit only. The mobile version of Webkit to be exact. Now, it’s been expanded to work with desktop browsers too — but only modern ones. No more klutzing around to make things work this IE6!

    Zepto’s API is jQuery compatible. If you use jQuery, you already know how to use Zepto.

    Another area where Zepto manages to be small is how it manages to avoid feature bloat. The core library doesn’t seem to include any extraneous functionality. Even the AJAX and animation functionality are available as separate modules, should the need arise. For users that primarily use libraries for DOM traversal and manipulation, this is an utter god send.

    And, oh, did I mention Zepto’s main party piece? Zepto’s API is jQuery compatible. If you use jQuery, you already know how to use Zepto.

    Are Zepto and jQuery Interchangeable?

    Yes and no. Depends is a more apt answer.

    Yes because Zepto’s core API mimics jQuery to a large extent. In order to make it easy to use and dramatically reduce the learning curve, Zepto emulates jQuery’s API. Most of the oft used methods, like DOM manipulation, are named pretty much the same and have the same parameters in the same order. The method signatures are the same, for the engineers out there.

    Let’s look at a small example:

    $('#element').html("Hey! Are you on the GW2 beta?");
    

    Looks familiar? It should. This is the exact same code you’d use with jQuery to change the HTML of an element. As I mentioned, this isn’t limited to just this method. Most DOM operations are built the same way along with your utilities, like AJAX.

    On the flip side, the API isn’t a 100% match. Zepto forgoes some methods present in jQuery that’s liable to break your code. And just as importantly, since Zepto is a subset of jQuery, you’ll probably miss out on specific functionalities that are built in — Deferred is a fine example. You simply can’t swap out jQuery with Zepto and expect everything to work.

    And for me, the biggest hurdle are the methods that have been copied from jQuery but have a different signature and feature set. It becomes a little frustrating when you think you’re using a method right but you aren’t. The clone method’s ability to copy event handlers is a good example. Without looking at the source, I really wouldn’t have found this out.

    Exploring the Core API

    If you’ve worked with jQuery before, everything below should be a snooze fest.

    Enough chit chat, let’s dive into some code now. As with a lot of modern libraries, DOM traversal and manipulation is a core feature that everyone wants to perfect. Since the API and overall functionality is very similar to jQuery, I think you can safely assume everything is top notch.

    Let’s take a look at some common DOM related functionality.

    Modifying the HTML contents of a container

    This is the bread and butter of DOM operations: reading or changing the HTML contents of an element. With Zepto, it’s as simple as calling the html method on the container, and passing in the new HTML, if needed.

    For example, this obtains the HTML of an element and stores it in a variable.

    var containerText = $('#element').html();
    

    Or if you want to change it to something else:

    $('#element').html("Hola there!");
    

    Pretty simple, right?

    Prepend/Append an Element to a Container

    As with jQuery, Zepto makes use of the append and prepend methods. And the invokation remains the same as well.

    $('#element').append("<p>This is the appended element.</p>");
    
    // or
    
    $('#element').prepend("<p>This is the appended element.</p>");
    
    Events

    Events are the backbone of any modern application and Zepto provides you with a bunch of easy to use methods to get your job done. The bulk of the work is done through the on method.

    $('#element').on('click', function(e){
       // Your code here
    });
    

    Easy to read and easy to parse. If you’re feeling old school and feel like using bind, delegate or live methods, don’t. Just like with jQuery, they’re deprecated here.

    AJAX

    Any modern low level library needs to provide an easy to use wrapper around AJAX and Zepto doesn’t let you down here. Here is an example of a super simple AJAX request.

    
    $.ajax({
      type: 'POST',
      url: '/project',
      data: { name: 'Super Volcano Lair' },
      dataType: 'json',
      success: function(data){
        // Do some nice stuff here
      },
      error: function(xhr, type){
        alert('Y U NO WORK?')
      }
    });
    

    Things might look a little complicated but what we’re doing can be boiled down to:

    • Creating the AJAX object and passing it options.
    • In the options, specifiy that we’d like to do a POST request. The default is GET, I imagine.
    • Specify the URL to POST to.
    • Specify the data that needs to be sent to the server. As you can see, I’m laughing maniacally and trying to create my own super villain lair.
    • Specify methods that will be triggered when the request succeeds or fails. This way, we can update the UI whatever happens.

    As with jQuery, there are separate method for a GET or POST request or ones to merely load up some web content.

    Animations

    What will the world come to without a few animations? Zepto exposes the almighty animate method that should handle most of your animating needs.

    $('#element').animate({
      opacity: 0.50, top: '30px', color: '#656565'
    }, 0.5)
    

    We’re basically selecting the element to be animated, invoking the animate method and specify the properties to be animated as well as the time it should take to finish animating. Zepto does the rest.

    Or if you just need to show and hide an element, the toggle should work just fine.

    I think you get the point here — Zepto’s DOM, animation and events API emulates that of jQuery to a large extent. And as we all know, jQuery is darn good with those things. If you’ve worked with jQuery before, you shouldn’t face too much trouble here.

    A Look at the Touch Events and Other Niceties

    Zepto does provide you with a few touch specific events that you can leverage in your apps. These include:

    • swipe — Handles your typical swipe motion. There are also separate events for different directions, like swipeLeft.
    • tap — Triggered in response to a generic tap action.
    • doubleTap — Obviously, this handles double taps.
    • longTap — It’s triggered when an element is tapped on for more than 750ms. There doesn’t seem to be a straightforward to change this delay though.

    Here’s a quick example, delightfully swiped from Zepto’s documentation.

    <ul id=items>
      <li>List item 1 <span class=delete>DELETE</span></li>
      <li>List item 2 <span class=delete>DELETE</span></li>
    </ul>
    
    <script>
    // show delete buttons on swipe
    $('#items li').swipe(function(){
      $('.delete').hide()
      $('.delete', this).show()
    })
    
    // delete row on tapping delete button
    $('.delete').tap(function(){
      $(this).parent('li').remove()
    })
    </script>
    

    When a list item is swept, every other list element’s delete button is hidden and only the current’s is displayed. Tapping a delete button removes that button’s parent li item to be removed from the DOM.

    This should be fairly similar to how you generally handle events, except you’ve binding your handlers to different events, that’s all.

    Wrapping Up

    Considering what and whom I develop for, this is perfect for me; but as it always is, your mileage may vary.

    Well, that’s about almost all there is to Zepto. At it’s core, it was meant to be a lean, cruft free version of jQuery that could be used on mobile devices. Over time, it has morphed into a lean library that does away with supporting archaic browsers.

    Considering what and whom I develop for, this is perfect for me; but as it always is, your mileage may vary. You may be locked into using jQuery plugins that require non-trivial modifications to make it work under Zepto or just have more faith in jQuery.

    Either way, you really need to give Zepto a try to see how it fits in with your workflow before writing it off. I did and I love it!

    Well, that’s all from me today. Let me know what you think in the comments below and thank you so much for reading!


Planet PHP

  • Permalink for 'The hidden cost of Clouds.. getting off Netsuite'

    The hidden cost of Clouds.. getting off Netsuite

    Posted: April 27th, 2012, 4:00pm MDT by Alan Knowles
    Article originally from rooJSolutions blog
    One of the more interesting projects I have ongoing is a migration and deployment of an ERP system. For a bit of background, our customer was persuaded about 3-4 years ago that moving their accounting and Stock management into Netsuite would be a good idea.
    For those who have not heard of Netsuite, it's a Cloud based ERP system, that from my understanding runs on an oracle backend and is totally web based. All the users log into the website, enter the various stock activity ( Purchase Orders, Item Receipt, Bills, Sales orders, Invoices, Item Fulfilments and Various Credit Memos), along with the standard accounting features like Journal entries. etc.... The system keeps track of your stock and should give you a value of stock on hand, along with doing your audit-able reports.
    Well, I'm guessing anyone who has worked with ERP systems, probably knows that the devil is in the details for this. The company I have been working with have been using this for over 2 years now, and are beginning to see the ugly side of cloud based system (which is why we are trying to migrate off of it.), Let's have a look through the issues.
  • Permalink for 'Migrating off Netsuite - The hidden cost of Clouds.. '

    Migrating off Netsuite - The hidden cost of Clouds..

    Posted: April 27th, 2012, 4:00pm MDT by Alan Knowles
    Article originally from rooJSolutions blog
    One of the more interesting projects I have ongoing is a migration and deployment of an ERP system. For a bit of background, our customer was persuaded about 3-4 years ago that moving their accounting and Stock management into Netsuite would be a good idea.
    For those who have not heard of Netsuite, it's a Cloud based ERP system, that from my understanding runs on an oracle backend and is totally web based. All the users log into the website, enter the various stock activity ( Purchase Orders, Item Receipt, Bills, Sales orders, Invoices, Item Fulfilments and Various Credit Memos), along with the standard accounting features like Journal entries. etc.... The system keeps track of your stock and should give you a value of stock on hand, along with doing your audit-able reports.
    Well, I'm guessing anyone who has worked with ERP systems, probably knows that the devil is in the details for this. The company I have been working with have been using this for over 2 years now, and are beginning to see the ugly side of cloud based system (which is why we are trying to migrate off of it.), Let's have a look through the issues.
  • Permalink for 'PECL/mysqlnd_ms 1.4 = charset pitfalls solved'

    PECL/mysqlnd_ms 1.4 = charset pitfalls solved

    Posted: April 27th, 2012, 9:41am MDT by Ulf Wendel
    Tweaking is the motto - what an easy release PECL/mysqlnd_ms 1.4 will be! The first tweak for the next stable version of the mysqlnd replication and load balancing plugin solves pitfalls around charsets. String escaping now works on lazy connection handles (default) prior to establishing a connection ...
  • Permalink for 'Not all licenses are created equal'

    Not all licenses are created equal

    Posted: April 27th, 2012, 3:49am MDT by Lukas Smith

    IANAL. As you are all are hopefully aware there are huge differences the exact "freedoms" allowed by the various open source licenses. I find that many younger developers have a natural affinity to the GPL, because they seem to feel its important to prevent someone from just taking their code, building upon it and not releasing their changes under an open source license when they distribute. Maybe with enough experience you start to realize that it happens close to never that a proprietary fork of an open source project ends up outpacing the original project. So why bother regulating this? It just makes legitimate business uses harder and in the grand scheme of things, I don't worry about this. People who prefer to go proprietary are likely not in the state of mind yet where I would want to work with them anyway.

    So these days I prefer BSD, Apache and MIT licenses. My first open source project PEAR MDB was licensed as BSD. The Symfony2 eco-system is mostly licensed under the MIT. With basically Johannes Schmitt being the odd one out using the Apache license. We moved PHPCR to the Apache license in the early stages of the development push thinking this makes sense given that JCR is also licensed under the Apache license. We also moved Jackalope to Aapche thinking we might one day contribute it to the Apache foundation. There is one trouble here in that I recently learned with Apache 2.0, the FSF considers it incompatible with (L)GPLv2. Note that (L)GPLv3 is considered compatible.

    Popular projects like Drupal being GPLv2+ and Doctrine LGPLv2 there is a problem. As Drupal is considering adopting PHPCR/Jackalope they would have to move to GPLv3+, which is easy for them to do since they made sure to include the "or later" when they went with GPLv2. Now for Doctrine the situation isn't so easy since its LGPLv2 without the "or later" option. Meaning we couldn't just drop the LGPLv2. That being said to me the LGPL is very fuzzy in combination with an interpreted language like PHP, but it would be good to avoid such a grey area. As a result all the current core developers have agreed to try and switch Doctrine to the MIT license. Due to its longer history moving the Doctrine ORM and more importantly the DBAL over is going to be quite hard, however the rest of the project is sufficiently young that its feasible to attempt this. Note that the DBAL actually started its life in Doctrine as part of the 1.x branch which in turn was a fork of my MDB project which was BSD licensed. Still since then a lot of code went in and out.

    Now the big question is how on earth can we work through such a license change? In short its going to be really really hard. At least in the days of git and github we will not be faced with quite as many patches that were committed by someone else than the creator as back in the day many changes came in via patch files submitted to issue tickets or mailing lists. But there is still the risk of code lifts from other projects that might also be using a non MIT compatible license. So it seems like we really need a tool to help manage determining all the contributors and if they have approved the license change. Then also helping in reviewing individual commits if they are worthy of a copyright (typo fixes and obvious bug fixes do not). Maybe even do some analysis to show is which code portions remain without consent for the license change so that we can choose to rewrite them. Unfortunately I am not aware of any such tool. The only high profile project I remember having done such a change is VideoLan, but at least in their blog posts it seemed like they simply got the permission of their few dozen core developers. Anyway I will follow up this blog post with another one outlining some ideas I have for how such a tool could work.

    Now to finish up this blog post I want to touch upon the topic of a CLA. When I first mentioned this issue on twitter, people were quick to point out that a CLA would make such a license change easier. Avid readers of my blog should know that I have spoken out against CLAs quite a lot in the past. The two main reasons is that it adds an annoying legal hurdle for contributors and that all CLAs I have seen include patent clauses which I reject. But it is true that a CLA would enable the entity to which the CLA would be signed to could easily do a license change (which could also be an irritating fact for some). Now there is a different kind of agreement called a Fiduciary Licensing Agreement which is used by the KDE. Essentially it gives the KDE guys the right to change the license, but also to defend the rights of the original creators in court. The difference to the CLA is that a FLA is also useful even if you do not force everyone to sign it. As a result the practice is to simply get people to sign it eventually after several contributions and not like a CLA before eve

    Truncated by Planet PHP, read more at the original (another 663 bytes)

Nettuts+

  • Permalink for 'Closures: Front to Back'

    Closures: Front to Back

    Posted: April 26th, 2012, 8:05pm MDT by Brian Scaturro

    Closures are often viewed as an arcane art in the land of JavaScript. Once mastered, they allow you to write some truly amazing JavaScript. This article will get you up to speed on the magic of JavaScript closures.

    What Is A Closure?

    One of the key truths of JavaScript is that everything is an object. This, of course, includes functions.

    A closure is nothing more than a function object with a related scope in which the function’s variables are resolved.

    Closures get their name because of the way they close over their contents. Consider the following bit of JavaScript:

    topping = "anchovi";
    function pizzaParty(numSlices) {
    	var topping = "pepperoni",
    
    	innerFunction = function() {
    		var topping = "ham";
    		console.log(" .....But put " + topping + " on " + numSlices + " slices");
    	};
    
    	console.log("This pizza is all about the " + topping);
    
    	innerFunction();
    }
    pizzaParty(3);
    

    If you open up your favorite console and run that bad boy, you will be greeted with a delicious message to the effect of “This pizza is all about the pepperoni ….. But put ham on 3 slices.” This example illustrates some key concepts of JavaScript that are crucial to getting a hold on closures.

    A Closure is a Function Object

    How many function objects are in the above code? Well… we have our pizzaParty function, and nested in that function is innerFunction. Math hasn’t always been my strong suit, but 1 + 1 = 2 in my book. Each function object has its own set of variables, which are resolved in each function’s scope.

    A Closure Has its Own Scope

    Closures can’t be fully understood without a firm grounding in scope. JavaScript’s scope mechanism is what allows each function to have its own topping variable, and without it we might have too much pepperoni, too little ham, or *gasp* … some anchovies at our pizza party. Let’s use a quick illustration to better illustrate this idea.

    Functions are executed using the scope that was in effect when the function was defined. It has nothing to do with the scope in effect when the function is called.

    Variable Accessibility Works Outside-In

    The green arrows show that accessibility works from the outside in. Variables defined in the scope outside of a function are accessibile from within it.

    If we were to omit the topping variable from inside the pizzaParty function, then we would get a message like “This pizza is all about the anchovi”, but since pizzaParty has a topping variable within its own scope; those salty suckers will never get near our pizza party.

    Likewise, the numSlices parameter can be accessed from within innerFunction because it is defined in the scope above – in this case the scope of pizzaParty.

    Variable Accessibility Does Not Work Inside-Out

    The red arrows show that variables in scope for a function are never accessible outside of that function. This is the case only when a variable meets one of the following conditions:

    1. The var keyword is being used.
    2. The variable is a parameter to the function or an outer function.
    3. The variable is a nested function.

    Omitting the var keyword when setting a variable will cause JavaScript to set the closest named variable in outer functions all the way up to the global scope. So, using our example, the ham topping in innerFunction cannot be accessed from pizzaParty, and the pepperoni topping in pizzaParty cannot be accessed out in the global scope where the anchovi dwells.

    JavaScript Uses Lexical Scoping

    Lexical scope means functions are executed using the variable scope in effect when the function was defined. It has nothing to do with the scope in effect when the function is called. This fact is crucial to unlocking the power of closures.

    Now that we understand what a closure is, and what scope means for closures, let’s dive into some classic use cases.

    Using Closures For Privacy

    Closures are the way to conceal your code from the public eye. With closures, you can easily have private members that are shielded from the outside world:

    (function(exports){
    
    	function myPrivateMultiplyFunction(num,num2) {
    		return num * num2;
    	}
    
    	//equivalent to window.multiply = function(num1,num2) { ...
    	exports.multiply = function(num1,num2) {
    		console.log(myPrivateMultiplyFunction(num1,num2));
    	}
    
    })(window);
    

    With closures, you can easily have private members that are shielded from the outside world.

    Let’s break it down. Our top level function object is an anonymous function:

    (function(exports){
    
    })(window);
    

    We invoke this anonymous function right away. We pass it the global context (window in this case) so we can “export” one public function, but hide everything else. Because the function myPrivateMultiplyFunction is a nested function, it exists only within the scope of our closure; so we can use it anywhere inside this scope, and only in this scope.

    JavaScript will hold a reference to our private function for use inside the multiply function, but myPrivateMultiplyFunction cannot be accessed outside of the closure. Let’s try this out:

    multiply(2,6) // => 12
    myPrivateMultiplyFunction(2,6) // => ReferenceError: myPrivateMultiplyFunction is not defined
    

    The closure has allowed us to define a function for private use, while still allowing us to control what the rest of the world sees. What else can closures do?

    Using Closures For Meta-Programming

    Closures are quite handy when it comes to generating code. Tired of remembering all those pesky key codes for keyboard events? A common technique is to use a key map:

    var KeyMap = {
    	"Enter":13,
    	"Shift":16,
    	"Tab":9,
    	"LeftArrow":37
    };
    

    Then, in our keyboard event, we want to check if a certain key was pressed:

    var txtInput = document.getElementById('myTextInput');
    txtInput.onkeypress = function(e) {
    	var code = e.keyCode || e.which //usual fare for getting the pressed key
    	if (code === KeyMap.Enter) {
    	    console.log(txtInput.value);
    	}
    }
    
    Capturing A Moment In Time

    The above example isn’t the worst, but we can use meta-programming and closures to make an even better solution. Using our existing KeyMap object, we can generate some useful functions:

    for (var key in KeyMap) {
    
    	//access object with array accessor to set "dyanamic" function name
    	KeyMap["is" + key] = (function(compare) {
    		return function(ev) {
    			var code = ev.keyCode || ev.which;
    			return code === compare;
    		}
    	})(KeyMap[key]);
    
    }
    

    Closures are so powerful because they can capture the local variable and parameter bindings of the function in which they are defined.

    This loop generates an is function for every key in KeyMap, and our txtInput.onkeypress function becomes a bit more readable:

    var txtInput = document.getElementById('myTextInput');
    txtInput.onkeypress = function(e) {
    	if(KeyMap.isEnter(e)) {
    		console.log(txtInput.value);
    	}
    }
    

    The magic starts here:

    KeyMap["is" + key] = (function(compare){
    
    })(KeyMap[key]); //invoke immediately and pass the current value at KeyMap[key]
    

    As we loop over the keys in KeyMap, we pass the value referenced by that key to the anonymous outer function and invoke it immediately. This binds that value to the compare parameter of this function.

    The closure we are interested in is the one we are returning from inside the anonymous function:

    return function(ev) {
    	var code = ev.keyCode || ev.which;
    	return code === compare;
    }
    

    Remember, functions are executed with the scope that was in place when they were defined. The compare parameter is bound to the KeyMap value that was in place during a loop iteration, and so our nested closure is able to capture it. We take a snapshot in time of the scope that was in a effect at that moment.

    The functions we created allow us to skip setting up the code variable everytime we want to check the key code, and we now have convenient, readable functions to use.

    Using Closures To Extend The Language

    At this point, it should be relatively easy to see that closures are vital to writing top notch JavaScript. Let’s apply what we know about closures to augmenting one of JavaScript’s native types (gasp!). With our focus on function objects, let’s augment the native Function type:

    Function.prototype.cached = function() {
    	var self = this, //"this" refers to the original function
    		cache = {}; //our local, lexically scoped cache storage
    	return function(args) {
    		if(args in cache) return cache[args];
    		return cache[args] = self(args);
    	};
    };
    

    This little gem allows any and every function to create a cached version of itself. You can see the function returns a function itself, so this enhancement can be applied and used like so:

    Math.sin = Math.sin.cached();
    Math.sin(1) // => 0.8414709848078965
    Math.sin(1) // => 0.8414709848078965 this time pulled from cache
    

    Notice the closure skills that come into play. We have a local cache variable that is kept private and shielded from the outside world. This will prevent any tampering that might invalidate our cache.

    The closure being returned has access to the outer function’s bindings, and that means we are able to return a function with full access to the cache inside, as well as the original function! This small function can do wonders for performance. This particular extension is set up to handle one argument, but I would love to see your stab at a multiple argument cache function.

    Closures in the Wild

    As an added bonus, let’s take a look at a couple uses of closures in the wild.

    jQuery

    Sometimes, the famous jQuery $ factory is not available (think WordPress), and we want to use it in the way we typically do. Rather than reach for jQuery.noConflict, we can use a closure to allow functions inside to have access to our $ parameter binding.

    (function($){
    	$(document).ready(function(){
    		//business as usual....
    	});
    })(jQuery);
    
    Backbone.js

    On large Backbone.js projects, it might be favorable to have your application models private, and then expose one public API on your main application view. Using a closure, you can easily acheive this privacy.

    (function(exports){
    
    var Product = Backbone.Model.extend({
        urlRoot: '/products',
    });
    
    var ProductList = Backbone.Collection.extend({
        url: '/products',
        model: Product
    });
    
    var Products = new ProductList;
    
    var ShoppingCartView = Backbone.View.extend({
    
        addProduct: function (product, opts) {
            return CartItems.create(product, opts);
        },
    
        removeProduct: function (product, opts) {
            Products.remove(product, opts);
        },
    
        getProduct: function (productId) {
            return Products.get(productId);
        },
    
        getProducts: function () {
            return Products.models;
        }
    });
    
    //export the main application view only
    exports.ShoppingCart = new ShoppingCartView;
    
    })(window);
    
    Conclusion

    A quick recap of what we learned:

    • A closure is nothing more than a function object with a scope.
    • Closures get their name by the way they “close” over their contents.
    • Closures cash in big time on JavaScript’s lexical scope.
    • Closures are the way to achieve privacy in JavaScript.
    • Closures are able to capture the local variable and parameter bindings of an outer function.
    • JavaScript can be powerfully extended with some closure magic.
    • Closures can be used with many of your favorite libraries to make them even cooler!

    Thanks so much for reading! Feel free to ask any questions. Now let’s enjoy the pizza party!


Planet PHP

  • Permalink for 'PHP 5.3.11 And PHP 5.4.1 Released!'

    PHP 5.3.11 And PHP 5.4.1 Released!

    Posted: April 25th, 2012, 4:00pm MDT by PHP: Hypertext Preprocessor
    The PHP development team announces the immediate availability of PHP 5.3.11 and PHP 5.4.1. These releases focuses on improving the stability of the current PHP branches with over 60 bug fixes, some of which are security related.Security Enhancements for both PHP 5.3.11 and PHP 5.4.1:Fixed bug #54374 (Insufficient validating of upload name leading to corrupted $_FILES indices). (CVE-2012-1172).Add open_basedir checks to readline_write_history and readline_read_history.Security Enhancement affecting PHP 5.3.11 only:Fixed bug #61043 (Regression in magic_quotes_gpc fix for CVE-2012-0831).Key enhancements in these releases include:Added debug info handler to DOM objects.Fixed bug #61172 (Add Apache 2.4 support).For a full list of changes in PHP 5.3.11 and PHP 5.4.1, see the ChangeLog. For source downloads please visit our downloads page, Windows binaries can be found on windows.php.net/download/.All users of PHP are strongly encouraged to upgrade to PHP 5.3.11 or PHP 5.4.1.

Nettuts+

  • Permalink for 'Meeting Grunt, the Build Tool for JavaScript'

    Meeting Grunt, the Build Tool for JavaScript

    Posted: April 25th, 2012, 1:05pm MDT by Andrew Burgess

    If you’re working on a large project, you’ll no doubt have a build script or a bunch of task scripts to help with some of the repetitive parts of the process. You might use Ant or Rake, depending on the language the project is written in.

    But what do you use if the project is primarily JavaScript? That’s the problem Ben Alman set out to solve when he created Grunt.

    What is Grunt, Anyway?

    What exactly is Grunt? Well, the README on Github says

    Grunt is a task-based command line build tool for JavaScript projects.

    Here’s the idea: when working on a JavaScript project, there are a bunch of things you’ll want to do regularly. Like what, you ask? Well, like concatenating given files, running JSHint on your code, running tests, or minifying your scripts. If you’re pasting your JavaScript into JSHint online, you probably realize that there’s a better way to do it; even if you’re using cat to concatenate files or a command line minifier, it would be nice to have a single, unified set of commands for all those extra tasks, that worked for every single JavaScript project, right?

    That’s what Grunt aims to be. It has a bunch of built-in tasks that will get you pretty far, with the ability to build your own plugins and scripts that extend the basic functionality.

    For more Grunt intro goodness, see Ben’s post on his personal blog and the Bocoup blog.

    How Do I Install Grunt?

    Grunt is built on Node.js, and it’s available as a package via the Node package manager (npm). You’ll want to install it globally, so use this command:

    npm install -g grunt

    You’ll notice it installs quite a few dependencies; there are other npm packages that Grunt uses. Once that’s done, you’re all set to go!

    How Do I Use Grunt?

    As you know, Grunt is a command line tool; therefore, I’ll assume you have a terminal window open for the rest of this tutorial.

    Let’s start by creating a sample project directory; we’re not actually going to be building a project here, but we’ll be seeing how Grunt works in this directory. Once you’re within that directory, run the grunt command (according to the documentation, if you’re on Windows, you might have to run grunt.cmd). You’ll probably see something like this:

    <FATAL> Unable to find 'grunt.js' config file. Do you need any --help? </FATAL>

    Before you can really leverage Grunt to its fullest potential, you’re going to need a grunt.js file in the project directory. Thankfully, Grunt can auto-generate a grunt.js file—and some other project skeleton material—with the init task, which can run without a grunt.js file in place. But grunt init still isn’t enough to get your project started, as you’ll see if you run it. You need to choose a type of project to generate. Running grunt init will give you a list of project types to choose from:

    • jquery: A jQuery plugin
    • node: A Node module
    • commonjs: A CommonJS module
    • gruntplugin: A Grunt plugin
    • gruntfile: A Gruntfile (grunt.js)

    If your project doesn’t really match any of the first four project types, you can use the final one: gruntfile: it just creates a basic grunt.js that you can fill in. So, let’s give this a try, with the jQuery plugin template. Run grunt init:jquery in your terminal.

    You’ll notice a lot of initial output. If you take the time to read the template notes, you’ll see that we’re going to have to fill in a few values, like project name and project title. In fact, after that note, you’ll see something like this:

    Please answer the following:
    [?] Project name (jquery.demo) 

    Whenever you initialize a project, Grunt will ask you a series of questions, so it can fill in a few options. That value in the parentheses? That’s the default suggestion, based on the project type and the name of the project directory. If you want to change it, write your own project name at the end of the line and hit ‘enter’; otherwise, just hit ‘enter’ to use the default name.

    Keep going and fill in the rest of the fields. For a jQuery plugin project, here’s what else you’ll need to give it:

    • Project title
    • Description
    • Version
    • Project git repository
    • Project homepage
    • Project issues tracker
    • Licenses
    • Author name
    • Author email
    • Author url
    • Required jQuery version

    A lot of these have default values; if you want to use the default value, just hit enter for that line; to leave the field blank, you can just type “none.” Once you’ve gone through all the options, you’ll see that Grunt is creating some basic project files. Like what? Like this:

    LICENSE-GPL
    LICENSE-MIT
    README.md
    grunt.js
    libs
    |-- jquery
    |    |-- jquery.js
    |-- qunit
         |-- qunit.css
         |-- qunit.js
    package.json
    src
    |-- jquery.demo.js
    test
    |-- jquery.demo.html
    |-- jquery.demo_test.js

    As you can see, this gives us a good start: not only do we have our plugin file (src/jquery.demo.js), we also have Qunit tests (test/jquery.demo_test.js). And these aren’t empty files, either. They’ve got some initial content, with a so-super-basic jQuery plugin and unit tests. Go ahead and check out the contents of these files, you’ll see what I mean.

    Grunt does more than set up the project for you.

    Of course, Grunt does more than set up the project for you. Notably, our project now has grunt.js: a project-specific configuration file; because of the options it sets, we’re now able to use Grunt’s other built-in tasks. Soon we’ll crack it open and make some adjustments, but for now let’s run some tasks.

    If you run grunt with no options now, we’ll run the default task, if one has been set. In the case of a jQuery plugin project, that’s equivalent to running these four commands:

    • grunt lint: checks your JavaScript against JSHint
    • grunt qunit: runs your Qunit tests
    • grunt concat: concatenates your project files together and puts the new file in a dist folder
    • grunt min: minifies the file concat put out.

    I should note something about the Qunit tests here: Qunit tests are meant to run in the browser by default; just open tests/jquery.demo.html (or your equivalent) in the browser. However, the grunt qunit test wants to run them on the terminal, which means you need to have PhantomJS installed. It’s not difficult: just head over to phantomjs.org and download and install the latest version. If Grunt can find that in your path, it will be able to run the Qunit tests from the terminal.

    So, running grunt should give you output to similar to this:

    Grunt Output

    As you can see, each of our four tasks have run. If any of them were to fail, the rest of the tasks would be cancelled (unless you call Grunt with the --force flag).

    How Do I Customize My Tasks?

    Already, we’ve gotten a lot of great functionality out of Grunt, using it just as it comes. However, let’s crack open that grunt.js file and do some configuring.

    Inside grunt.js, you’ll see that all configuring is done by passing an object literal to grunt.initConfig(). Let’s look at a few of the properties of our config object.

    pkg

    This property points to the package.json file that Grunt created in our project directory. Having a package.json file is part of the CommonJS Packages spec; it’s a single place where most of the metadata about the project (name, version, homepage, repository link … many of the values you set when initializing the project) can be stored. However, this pkg property does more than point to the package file: notice the syntax: '<json:package.json>'. That’s one of Grunt’s built-in directives: it actually loads the JSON file, so Grunt (or you) can access all the properties in the package.json file from the pkg property.

    meta

    The meta property is an object with only a single property: a banner. This banner is the comment that goes at the top of concatenated or minified project files. As you can see, it’s a string with some template tags (<%= %>); in most cases, the tags surround a call to a property on the pkg property, such as pkg.title. However, you can also execute functions from inside those tags: the use of grunt.template.today() and _.pluck() shows us that.

    concat / min / qunit / lint / watch

    I’ve grouped the next five properties together because they’re very similar. They all set options for specific tasks, the tasks they’re named after. When configuring these tasks, it’s important to note that Grunt distinguished between two types of tasks: regular tasks, and multitasks. Basically, the difference is that regular tasks have only a single set of configuration options, whereas multitasks can have multiple sets of instructions (called targets). Of the five tasks I listed in the header of this section, the only one that isn’t a multitask is watch.

    Notice that in our config object, the qunit and lint properties are both objects with the files property. files is a single target for this task. In both cases, they’re an array of files to be used when executing this task. Let’s say I want to be able to lint only the files in src sub-directory. I could add another target so that the lint property would look like this:

    lint: {
    	files: ['grunt.js', 'src/**/*.js', 'test/**/*.js'],
    	src: ['src/**/*.js']
    },

    Now, to lint only the files in src, I run grunt lint:src: I pass the target name after a colon. If I run only grunt lint, both targets will be run.

    In the case of the concat and min tasks, the targets are more complicated: they are objects with source (src) and destination (dest) properties. Of course, this tells Grunt where to get the files and where to put them when it is done processing them, respectively. If you add other files to your project, you’ll want to add them in the right place to make sure they are concatenated and minified correctly. So, if I added a src/utils.js file that my jQuery plugin depended on, I’d change concat.dist.src to this:

    src: ['<banner:meta.banner>', 'src/utils.js', '<file_strip_banner:src/<%= pkg.name %>.js>'], 

    Looking at some of these tasks more closely, you’ll notice a few other directives: the most important is probably the directive. This allows you to access the properties of other tasks for reuse. You’ll notice that the configuration for the watch task uses , so that it operates on the same list of files that we gave to the lint task. You can learn more about the other directives in the Grunt docs.

    Speaking of the watch task, what exactly does it do? Very simple: it runs the tasks in the tasks property when a file in that list of files is changed. By default, the lint and qunit tasks are run.

    jshint

    This property simply configures what “bad parts” JSHint looks for in your JavaScript. The complete list of options can be found on the JSHint website’s options pages.

    At the very bottom of our grunt.js file, you’ll see this line:

    grunt.registerTask('default', 'lint qunit concat min');

    This is what creates our default task; you know, the one that runs when we run just grunt. It’s actually creating an alias task, and you can create as many alias tasks as you want:

    grunt.registerTask('src', 'lint:src qunit:src concat:src min:src');

    Assuming you created src targets for each of those tasks, you can now call grunt src and do exactly what you want.

    How Do I Use Third-Party Tasks?

    While the tasks that come with Grunt will get your pretty far, you can probably think of other things that you’d love to be able to automate. Not to worry: Grunt comes with an API that allows anyone to create Grunt tasks and plugins. While we won’t be creating any Grunt tasks in this tutorial, if you’re interested in doing so, you should start with the Grunt plugin template (run grunt init:gruntplugin), and then read through the API docs. Once you’ve written your task, you can load it into a project by adding this line inside your project’s grunt.js file:

    grunt.loadTasks(PATH_TO_TASKS_FOLDER);

    Note that the parameter isn’t the path to the task file itself, it’s the path to the folder the task file is in.

    However, other Grunt plugins are starting to appear, and some are available on NPM. After you install them via npm install, you’ll load them into your project with this line:

    grunt.loadNpmTasks(PLUGIN_NAME);

    Of course, you’ll want to check the plugin documentation to see what you should add to your configuration object.

    What Grunt plugins are available? Well, since Grunt is so new (less than an month old as I write this), there aren’t too many yet. I’ve found two:

    If you’ve found others, I’d love to hear about them; post ‘em in the comments!

    Conclusion

    While Grunt is a very new project, it’s hardly incomplete; as we’ve seen, it comes with pretty much everything you’ll need to use it on a large project, and can be extended as much as you want.

    I’m hoping Grunt will become a community standard, and that we’ll see lots of tasks, plugins, and init templates popping up in the near future. How do you feel about it?


Planet PHP

  • Permalink for 'Want a DPC12 Ticket? Just ask!'

    Want a DPC12 Ticket? Just ask!

    Posted: April 25th, 2012, 2:09am MDT by TechPortal

    Good news! We've managed to acquire a conference ticket for the Dutch PHP Conference in Amsterdam, on June 8th and 9th, to give away to our readers. We know that since you're reading techPortal, you are interested in technology in general and probably PHP in particular. The Dutch PHP Conference is one of the leading european conferences for PHP content and we hope you can join us there!

    This year, we're running a sister conference alongside DPC - the very first Dutch Mobile Conference is being held! Your DPC ticket also gives you access to the mobile conference tracks, so whether you're into web, mobile, or a little bit of both - you're absolutely in the right place :)

       

    We have some excellent speakers lined up for both conferences; check out the mobile conference schedule and the PHP conference schedule to see what kinds of sessions are available.

    How to Win the Ticket

    We're keeping it nice and simple! To win, simply leave us a comment on this post (including your email address so we can get in touch with you if you win!) telling us why you should win the ticket, and we'll randomly draw a winner when we close the competition on May 9th. Want to join us in Amsterdam? Then what are you waiting for?

    (sadly we haven't got enough tickets to give away to everyone, so if you don't win then you can still buy tickets and we'll see you there!)

    Digg This  Reddit This  Stumble Now!  Buzz This  Vote on DZone  Share on Facebook  Bookmark this on Delicious  "/>

    Truncated by Planet PHP, read more at the original (another 2045 bytes)

Nettuts+

  • Permalink for 'Are You Our Next Awesome Writer?'

    Are You Our Next Awesome Writer?

    Posted: April 24th, 2012, 12:07pm MDT by Siddharth

    We’re in need of a kick-ass, talented author to help out on Nettuts+ on a regular basis, a Bieber fan preferably.

    We’re not sticklers but we’d optimally like to see weekly and bi-weekly submissions from you. Do you have what it takes? This is a paid gig, so read on!

    What You Need
    • A Ninja grasp of the subject matter: Nettuts+ is one of the biggest, most trusted web development blogs out there and this is built on quality content. You, as our author, will need to possess rock solid comprehension of what you’d like to write about.
    • Writing chops: You must be comfortable with the English language. We can proof your content but we can’t rewrite everything for you. If you struggle when deciding whether to write fewer or less, this might not be the gig for you.
    • Ability to stick to a schedule: We expect you to keep the schedule we’ve agreed upon. Be professional.
    What You’ll Get
    • $150 per tutorial for the first month.
    • $200 per from the second month onwards, with a pay review after a year.
    • Option to submit to our premium program which pays significantly more.

    So, assuming you submit an article a week, and one Premium tut/screencast per month, you can expect to make between $1100 – $1400 each month.

    Excellent! Where Do I Sign Up?

    We’ll need the following information from you:

    • Name.
    • A few sentences about yourselves.
    • A single link to an article that you’ve written, helped with or like. This is compulsory.
    • Two ideas for tutorials you’d like to write for us.
    • Emails with an optional tutorial as attachment will get more attention from us since this means you’re serious about the gig.
    • Preferential treatment (and higher pay) given to those who can record professional quality screencasts.

    Please email this information to net[at]tutsplus.com.

    We get a ton of single line emails. Don’t be that person. Emails without the requisite information will be discarded.

    If you can’t manage a weekly/bi-weekly schedule, get in touch either way. I’m sure we can work something out!

    Get cracking, ladies and gents! Looking forward to hearing from all of you.


Planet PHP

  • Permalink for 'Getting to grips with an existing XML structure'

    Getting to grips with an existing XML structure

    Posted: April 24th, 2012, 7:17am MDT by Danne Lundqvist

    Very often I find myself writing input filters for large XML files using PHP. Common enough task; and PHP offer a great variety of tools to do this effectively depending on the situation. Unfortunately, almost as common is the lack of documentation for the aforementioned XML files.

    Manually trying to document the XML structure is not a fun job. And I have looked around for a simple tool but I didn’t really find a  tool that gave me the quick and dirty overview I wanted. A year or so ago I finally wrote a small PHP class to analyze large XML files.

    It is simple, but quickly creates a good overview of the XML structure as well as the kind of data and attributes of the elements in the XML file. Even for a very large XML file it does a good job of showing just the relevant structure of the XML.

    It is best described using an example.

    Example XML

    <?xml version="1.0" encoding="UTF-8" ?>
     <company xmlns:dvoidcomp="http://dotvoid.se/schema/company" name="MegaCorp" employeeOfTheMonth="E0003">
      <department name="Advanced Technologies" location="NY" number="123">
        <employee name="Al Smith" SN="E0004" manager="true">
          <title>Tech manager</title>
        </employee>
        <employee name="John Jones" SN="E0001">
          <title>Worker</title>
        </employee>
        <employee name="Jane Doe" SN="E0003">
          <title>Worker</title>
        </employee>
      </department>
      <department name="Resarch & Development" location="JS" number="789">
        <employee name="Anders Andersson" SN="E0005">
          <title>Lead technologist</title>
        </employee>
        <employee name="Joe Schmoe" SN="E0008" manager="true"/>
        <employee name="Sven Svensson" SN="E0006">
          <title>Worker</title>
        </employee>
      </department>
    </company>
    

    Example output in html

    The output shows the overall structure of all possible elements and all possible attributes of the different elements. All attributes have example values so that you can see what kind of data you can expect. In this example I have also asked for all possible values of the title element to be included. This is good if you know there are XML elements with a limited set of values.

    XML Structure

    Usage of the PHP class

    The class is simple to use. And really the only thing you can do is give the path to an XML file and call parse() with an optional array of XML element names that you want all values for in the html output.

    s<?php
    	use Void\File\XmlStructure;
    	require __DIR__ . '/XmlStructure.php';
    
    	$xmlStruct = new XmlStructure();
    	$xmlStruct->parse(
    		__DIR__ . '/XmlStructure.xml',
    		array('title')
    	);
    
    ?>
    <html>
    	<head>
    		<style type="text/css">
    		 <?php echo $xmlStruct->css();?>
    		</style>
    	</head>
    	<body>
    	<?echo $xmlStruct->html();?>
    	</body>
    </html>

    Download: xmlgrips.tar.gz

    Eventually I might, and might not, put it on Bitbucket or Github. The PHP class is not well documented, but small enough. Bare in mind I wrote it quickly and I only use it as a simple means of boiling down a large XML file to the bare essentials. Hopefully you will find it useful or maybe give you ideas on how to improve it.

    Truncated by Planet PHP, read more at the original (another 2383 bytes)

  • Permalink for 'Symfony 2 Poster - Der perfekte Einstieg'

    Symfony 2 Poster - Der perfekte Einstieg

    Posted: April 23rd, 2012, 3:29am MDT by Mayflower Blog - PHP
    Symfony 2 Poster

    Das Symfony 2 Framework hat sich als OpenSource PHP-Framework etabliert. Die Anhänger und Community wächst stetig und auch Mayflower hat intern Mitarbeiter für den Umgang mit Symfony geschult. Damit Ihnen der Einstieg in Symfony 2 leichter fällt, haben wir in Zusammenarbeit mit der Liip AG ein Poster entworfen.

    Man erhält einen guten Überblick über Controller, View, Model, Formulare & Validierung, Bundles & Service Container, Event System, Testing und Ressourcen. Der perfekte Einstieg um mit dem Symfony Framework sofort loszulegen.

    Nach Deutschland und Österreich verschicken wir das DIN A0 Poster komplett kostenlos.
    Also nicht zögern. Ran an die Tastatur und jetzt bestellen!

Nettuts+

  • Permalink for 'Create an Animated 3D Bar Chart/Graph'

    Create an Animated 3D Bar Chart/Graph

    Posted: April 22nd, 2012, 9:53pm MDT by Kendra Schaefer and Ken Breeden

    The Truematter team was recently tasked with creating a fun, sexy web app that presents numerical data in an engaging way. After putting our heads together, we came up with a bar chart that responds interactively to user input without, heaven forbid, reloading any pages. We’re very pleased to be able to share that with the coding community. There are some CSS tricks involved, a dose of jQuery, and some graphic magic, but when we’re done with this tutorial, we’ll have a beautifully interactive chart that you can customize to your heart’s content.

    Prepping the Graphics

    The graphic elements and the way those elements are chopped up and compiled is what really gives this chart some wow-factor.  There are only three graphic elements needed for this project, but, since we’re essentially creating an illusion using CSS and images, those graphics need to be crafted with precision.

    The chart itself is composed of three separate PNGs stacked on top of each other using CSS, two of which are stationary (the front and back “glassy” chart casing pieces), and one of which is animated using jQuery (the green bar piece in the middle).

    These are the graphical elements that make up the final presentation. Graphic Element 1: Back of the Chart This is the back panel graphic used in the 3D animated graph.

    The background piece is comprised of the bottom of the chart (which we only see when the bar is empty at 0%), the back left and back right panels. On this bottommost layer, we include all of the faces of the graph casing that need to become “covered” when the graph is full or partially full. This is the layer that really gives the 3D illusion some depth.

    Graphic Element 2: The Bar Graph The is the middle layer and bar graph of the 3D animated jQuery tutorial

    The animated center portion of this graph is simple to create. We suggest using very basic 3D extrude functions in Illustrator, or you can also just draw a three-panel shape in Photoshop and call it a day.  Color your graph very brightly, oversaturating it as much as possible. Why? Because in the final chart, it will be shown beneath a semi-transparent casing, so the color will be muted by the layer that covers it.

    It’s super important that the top and bottom edges of this piece remain transparent, so be sure to save it as a PNG.

    Also just as important: make this piece exactly the same height as the graph casing pieces. In our pictures here, the middle layer looks shorter than the casing – when you create your central piece, make the central bar exactly as tall as the casing. If you make it too short, your graph will never be able to fill up to 100% properly. If you make it too tall, the graph can shoot out of the casing container when it’s animated.

    Graphic Element 3: The Top Casing The top casing to complete the 3D animated graph/chart using jQuery and CSS

    Here’s where we get to the real visual trickery, which happens along the bottom edge of this third and final piece. While the top left and right edges retain transparency, the bottom left and right edges should be filled in solid with the same color as the background the graph will be sitting on.

    For example, if your website background is black, the bottom two edges of this piece need to be filled in with solid black. In our example above, the site background is white, so we’ve filled in the bottom edges with white. This solid-color area effectively hides any overspill from the middle bar-chart piece (graphic element 2). Without this piece and its opaque bottom edge, we lose the 3D effect entirely. Here’s the graph without it:

    Image illustrating no correctly producing graphics for the 3D animated graph/chart using jQuery and CSS The HTML

    Okay! We’ve got all of our graphic pieces complete and we’re ready to jump right into the code. The HTML itself is pretty straightforward. You’re looking at a few basic form select fields and a few divs for the bar graph.

    First, let’s look at the complete code, then we’ll take it piece by piece (no pun intended!). Note that the bar graph div elements are included within the form tag.

    <noscript><h3>You must enable JavaScript to view this demo!</h3></noscript>
    
    <form id="form1" action="#" onsubmit="return false;">
    <!-- container for the form elements -->
    <div id="formcontainer">
    How much money do you want to contribute to savings each month?
    <select id="savings" onchange="calculate();">
    	<option selected="selected" value="0">- select an amount -</option>
    	<option value="100">100 dollars</option>
    	<option value="200">200 dollars</option>
    	<option value="300">300 dollars</option>
    	<option value="400">400 dollars</option>
    	<option value="500">500 dollars</option>
    	<option value="1000">1000 dollars</option>
    	<option value="2000">2000 dollars</option>
    	<option value="3000">3000 dollars</option>
    	<option value="4000">4000 dollars</option>
    	<option value="5000">5000 dollars</option>
    </select>
    
    What is your monthly income?
    <select id="income" onchange="calculate();">
    	<option selected="selected" value="0">- select an amount -</option>
    	<option value="1000">1000 dollars</option>
    	<option value="2000">2000 dollars</option>
    	<option value="3000">3000 dollars</option>
    	<option value="4000">4000 dollars</option>
    	<option value="5000">5000 dollars</option>
    </select>
    </div>
    
    <div id="grapharea">
    <h4>Percentage of Monthly Salary Saved</h4>
    <div id="p25">25%</div>
    <div id="p50">50%</div>
    <div id="p75">75%</div>
    <div id="p100">100%</div>
    <div id="graphcontainer">
    	<img id="graphbackground" src=" [d2o0t5hpnwv4c1.cloudfront.net] alt="" width="262" height="430" />
    	<img id="graphbar" src=" [d2o0t5hpnwv4c1.cloudfront.net] alt="" width="262" height="430" />
    	<img id="graphforeground" src=" [d2o0t5hpnwv4c1.cloudfront.net] alt="" width="262" height="430" />
    </div>
    </div>
    </form>
    
    The Breakdown

    Since this chart depends on javascript, we first check to make sure it’s enabled in the browser:

    		<noscript><h3>You must enable JavaScript to view this demo!</h3></noscript>
    		

    Now we begin the form. For the purposes of this demo, we’ve used two simple dropdowns, but you could just as easily modify this code to use text fields, radio buttons, or any other type of input. The select onchange attribute is given the function “calculate();”, which we’ll cover in the jQuery section below.

    		<div id="formcontainer">
    			How much money do you want to contribute to savings each month?
    			<select id="savings" onchange="calculate();">
    				<option selected="selected" value="0">- select an amount -</option>
    				<option value="100">100 dollars</option>
    				<option value="200">200 dollars</option>
    				<option value="300">300 dollars</option>
    				<option value="400">400 dollars</option>
    				<option value="500">500 dollars</option>
    				<option value="1000">1000 dollars</option>
    				<option value="2000">2000 dollars</option>
    				<option value="3000">3000 dollars</option>
    				<option value="4000">4000 dollars</option>
    				<option value="5000">5000 dollars</option>
    			</select>
    
    			What is your monthly income?
    			<select id="income" onchange="calculate();">
    				<option selected="selected" value="0">- select an amount -</option>
    				<option value="1000">1000 dollars</option>
    				<option value="2000">2000 dollars</option>
    				<option value="3000">3000 dollars</option>
    				<option value="4000">4000 dollars</option>
    				<option value="5000">5000 dollars</option>
    			</select>
    
    		</div>
    		

    And finally, included within the form tag, the graphic elements:

    		<div id="grapharea">
    			<h4>Percentage of Monthly Salary Saved</h4>
    			<div id="p25">25%</div>
    			<div id="p50">50%</div>
    			<div id="p75">75%</div>
    			<div id="p100">100%</div>
    			<div id="graphcontainer">
    				<img id="graphbackground" src=" [d2o0t5hpnwv4c1.cloudfront.net] alt="" width="262" height="430" />
    				<img id="graphbar" src=" [d2o0t5hpnwv4c1.cloudfront.net] alt="" width="262" height="430" />
    				<img id="graphforeground" src=" [d2o0t5hpnwv4c1.cloudfront.net] alt="" width="262" height="430" />
    			</div>
    		</div>
    		
    The CSS
    		#formcontainer { float: left; }
    		#grapharea { position: relative; float: left; margin-left: 4em; }
    		#graphcontainer {
    			position: relative;
    			width: 262px;
    			height: 430px;
    			overflow: hidden;
    		}
    		#graphbackground, #graphforeground { position: absolute; }
    		#graphbar { position: absolute; top: 430px; }
    
    		.graphlabel { position: absolute; left: 270px; }
    		#p25 { top: 365px; }
    		#p50 { top: 278px; }
    		#p75 { top: 191px; }
    		#p100 { top: 105px; }
    		

    Probably the most crucial thing that should catch your eye here is the #graphbar div. Notice that our #graphbar div starts out at 430px – the total height of the bar chart. This height declaration is the number that is manipulated via jQuery to make the graph animate. If you have created your own graphic elements which are taller or shorter than 430px, you’ll need to adjust that number to match your own graphics.

    Likewise, you’ll also need to adjust the px of #p25, #p50, #p75, and #p100. These top declarations set the position of the 25%, 50%, 75% and 100% markers on the right side of the graph.

    Also, take a close look at the #graphcontainer styles:

    		#graphcontainer {
    			position: relative;
    			width: 262px;
    			height: 430px;
    			overflow: hidden;
    		}
    		

    Putting a position:relative;declaration on this outer wrapper lets us use absolute positioning on the three divs within #graphcontainer, so we can stack them on top of each other using CSS offsets. Setting a height and a width are also vital here – the height and width of this div should perfectly match the height and width of graphic elements 1 and 3. And overflow: hidden; hides the animated graphic, element 2, when it extends outside the bounds of the wrapping div.

    The Code

    Ah, now for the jQuery! It ties all pieces together and adds in the animation. A quick review of the full jQuery:

    		<script>
    		 function calculate() {
    			var ZEROPOS = 355;
    			var salary = $("#income").val();
    			var savings = $("#savings").val();
    			var percent = savings / salary; 	
    
    			if (parseInt(savings) >  0 &amp;&amp; parseInt(salary) > 0)
    			{
    				if (parseInt(savings) > parseInt(salary))
    					alert("You cannot save more than you earn - please change your selections accordingly.");
    				else
    				{
    					val = (percent == 0) ? ZEROPOS : ZEROPOS - (percent * ZEROPOS);
    					$("#graphbar").animate({ top: val + "px" }, 1500);
    				}
    			}
    		}
    		</script>
    		
    The Final Breakdown

    First, create a constant to use in the calculations. ZEROPOS is the pixel value of where the central graphic element (graphic 2, the movable piece) should be positioned to represent 0%.

    var ZEROPOS = 355;

    Next, find the values selected by the user using the select boxes – salary and savings. Then calculate the percentage value – percent.

    		var salary = $("#income").val();
    		var savings = $("#savings").val();
    		var percent = savings / salary;
    		

    The next step is a validation check to make sure the user has actually selected values from both select boxes. If they have, we continue with the script. Otherwise, we do nothing.

    if (parseInt(savings) >  0 &amp;&amp; parseInt(salary) > 0)

    If the user has entered the appropriate values, we then make sure that they have selected a salary that is higher than the amount they want to contribute to savings. If they have, we continue with the script. Otherwise we prompt the user to change their selections.

    		if (parseInt(savings) > parseInt(salary))
    		alert("You cannot save more than you earn - please change your selections accordingly.");
    		

    Now we are finally to the meat of the script – calculating the position to which we will move the graph bar and then firing off the jQuery animate functionality to make it happen.

    		val = (percent == 0) ? ZEROPOS : ZEROPOS - (percent * ZEROPOS);
    		$("#graphbar").animate({ top: val + "px" }, 1500);
    		

    So, in calculating the value for the graph bar position – val –  first determine if the percentage is zero. If so, set value equal to the ZEROPOS constant. Otherwise, calculate the new bar position by subtracting the percentage value multiplied by the zero position value from the zero position value. This formula is used because we are animating the bar from the zero position at the bottom of the chart up towards the top.

    Once the pixel value is calculated, we know where we’re heading, so simply call the animate method in jQuery on the graphbar object passing in the new CSS value for the top position with an animation rate of 1500 (the speed of the animation in milliseconds). Then jQuery does the magic for us and moves the bar within the chart accordingly. Violà!

    Hope you enjoyed this tutorial!


  • Permalink for 'Lightning Fast Folder and File Creation in Sublime Text 2'

    Lightning Fast Folder and File Creation in Sublime Text 2

    Posted: April 19th, 2012, 12:48pm MDT by Jeffrey Way

    I’m frequently asked about how I’m able to create new directory structures and files so quickly in Sublime Text 2. Well the answer is that this functionality is not offered natively; instead, I use a helpful plugin. I’ll demonstrate it in this video.

    Choose 720p for the clearest video. Closing Thoughts

    It’s worth mentioning that, toward the end of the video, I assign a custom key-binding: n-n. Please note that this binding assumes that you’re working in Vintage (Vim) mode. To trigger it, you’d exit to command mode – by pressing Esc – and then type n-n.

    If you’re not a Vintage user, you can stick with the default key-binding that comes with the plugin.

    Show Links


  • Permalink for 'Top 10 Pitfalls When Switching to Vim'

    Top 10 Pitfalls When Switching to Vim

    Posted: April 18th, 2012, 9:16pm MDT by Jeffrey Way

    Admit it: every time you see a person using Vim, you consider the possibility that they know something you don’t. Why else would they be using an editor that, in your mind, is dated, open-source junk? Think what you wish, but there’s a reason why top developers swear by Vim.

    February 2011

    Until you’ve spent at least a month working every day with the editor, you’ll undoubtedly hate it! This is specifically why the majority of newcomers will play around with Vim for a day, become disgusted, and never touch it again. What’s unfortunate is that, if these developers could get beyond the pitfalls, they’d be introduced to incredible speed and flexibility.

    1. There’s Too Many Modes

    It’s true: Vim is not your standard code editor (it’s better). Transitioning from, say, TextMate to Vim is going to be an entirely different process than switching from TextMate to Espresso. Always keep that in mind when you find yourself tearing our your hair because Vim seemingly refuses to enter text when you type.

    Though there are multiple modes in Vim, we’ll focus on the three most important. But before we continue, note that each key serves a different function, dependent upon which mode you’re currently in. Even more confusing — at first — a capital letter triggers a different action than a lowercase.

    In command mode, pressing the lowercase “i” will trigger “Insert Mode.” However, an uppercase “I” will move the cursor to the beginning of the line. This might sound confusing, but it provides you will incredible power!

    • Command: By default, Vim should rest in command mode. Think of this mode as the “getting around” mode. While, in a traditional editor, you might be accustomed to using the mouse or the arrow keys to traverse your document, Vim’s command mode makes the process quicker and “mouse-less.”
    • Insert: Pressing the lowercase “i” in command mode will switch you into “Insert Mode.” Newcomers to Vim will find this mode to be familiar. As a result, though, they often remain in this mode far longer than they should (I know I did). As a rule of thumb, insert mode should purely be used for the sole purpose of inserting text. When finished, immediately return to command mode.
    • Visual: Think of visual mode as “selection” mode. Need to select the next five lines and delete them? With a normal code editor, you could use the mouse to visually select five lines, and then press the backspace key. With Vim, on the other hand, you’d press capital V to switch to Visual mode, and then type 5j to select five lines down. Finally, you’d press d, for delete.

    I know this sounds incredibly confusing at first. You might think to yourself, “All that work just to delete five lines?” The truth is, though, this method is significantly faster.

    2. Ancient Editor

    Why would you turn your nose up at over three decades of development?

    You might hear your friends say, “Isn’t Vim an ancient code editor?” Well, you could say that; it’s been around for over thirty years. Though honestly, why would you turn your nose up at over three decades of development? That’s longer than I’ve been alive! Better yet, even to this day, Vim is under active development. The most recent release, 7.3, was made available in August, 2010.

    Secondly, it’s important to keep in mind that Vim is not Vi. If your only experience is with the latter, take some time to download the latest release and toy around with the new features. You’ll be pleasantly surprised!

    3. I Love TextMate Snippets

    If Vim can’t natively do it, you can bet that there’s a plugin available somewhere!

    You’ll quickly find that, if Vim can’t perform a particular task, then it’s likely that a plugin has developed to provide that functionality. For instance, consider TextMate’s excellent snippets feature. While Vim doesn’t support this natively, you can download the snipMate plugin, which should make the experience virtually identical to what you’re used to.

    Learn More About Switching to Vim From TextMate 4. I Can’t Use the Arrow Keys

    The less movement, the better.

    Firstly, this isn’t true. It might have been the case with Vi, but you’re free to use how Vim in the way that feels most comfortable to you. So use the arrow keys to your heart’s content — though keep in mind that there’s a reason why most Vim users don’t.

    The h,j,k,l keys mapping to left, down, up, and right, respectively, serve two purposes:

    • No Choice: Back in the day, machines didn’t have those helpful arrow keys. As such, they had little choice but to choose the best alternative.
    • Less Movement: If your hands generally rest along the second row of the keyboard, it makes little sense to repeatedly move your hand to the lower-right portion of the keyboard every time you want to move the cursor. The less movement, the better. With this arrangement, you can traverse your documents without moving an inch.

    When all is said and done, you are the person using the editor. If, at first, you feel more comfortable using the arrow keys, then by all means do!

    5. I’m a Designer, Dude

    That’s okay! Vim is not for everybody. As a person who at least attempts to do design work from time to time, I can fully attest that Vim may not be the best fit for designers.

    Developers are not designers; it’s only natural that this fact will be reflected in their choice of editors.

    If you find that the bulk of your days are spent working with HTML and CSS, then maybe Vim is not for you. Now, that’s not to say that you shouldn’t give it a shot; but it’s certainly understandable, should you decide to stick with a more designer-friendly editor, such as Coda.

    6. Vim Offers Nothing My Current Editor Doesn’t Already Do

    Plain and simple, that’s rubbish. Certainly, every editor does have its strong points, but you’ll find that Vim is incredibly powerful, and, more importantly, flexible. There are hundreds upon hundreds of plugins available (for free) that will provide support for virtually any kind of functionality that you require.

    Many newcomers often cite the built-in “Change Inner” command as a huge selling point. It certainly was for me! Let’s say that you have the following piece of code:

    var joe = 'plumber';
    

    Assuming that the cursor is at the beginning of that line, and you wish to change the value “plumber” to “black,” traditionally, you might use the arrow keys or the mouse to select and change the text. With Vim, the process is hugely simplified. Simply type: ci'. This stands for “Change Inner Quotes,” or, find the next set of single quotes, and change the value inside.

    Kick-Ass Plugins
    • snipMate: Allows you to, for instance, type + tab, and have a full div element expanded. It’s tremendously helpful.
    • Surround: Wrap portions of text with parens, tags, braces, etc.
    • NerdTree: Explore your filesystem and to open files and directories. It presents the filesystem to you in the form of a tree which you manipulate with the keyboard and/or mouse. It also allows you to perform simple filesystem operations.
    • TComment: Easily and quickly comment certain lines of your code.
    • Sparkup: Similar to ZenCoding, but provide more support for applying values to elements as well, such as: ul > li { My list item text. }.
    7. My Vimrc File is Blank

    This was an initial gripe that I had with Vim, as well. When first launching, say, MacVim, you’re thrown into the wolf-pack! No code highlighting, no formatting, no smart indenting… no nothing! Particularly if you’re using a custom Vim editor, there should at least be a base vimrc file to get you started. It can be an intimidating experience trying to figure out how to apply your custom preferences.

    For those unfamiliar with a vimrc file, it’s essentially a file that allows you to specify your editor preferences.

    Use this as a starter (click the Expand button below):

    " .vimrc File
    " Maintained by: Jeffrey Way
    " jeffrey@jeffrey-way.com
    " [net.tutsplus.com] "
    
    "Forget compatibility with Vi. Who cares.
    set nocompatible
    
    "Enable filetypes
    filetype on
    filetype plugin on
    filetype indent on
    syntax on
    
    "Write the old file out when switching between files.
    set autowrite
    
    "Display current cursor position in lower right corner.
    set ruler
    
    "Want a different map leader than \
    "set mapleader = ",";
    
    "Ever notice a slight lag after typing the leader key + command? This lowers
    "the timeout.
    set timeoutlen=500
    
    "Switch between buffers without saving
    set hidden
    
    "Set the color scheme. Change this to your preference.
    "Here's 100 to choose from: [www.vim.org] colorscheme twilight
    
    "Set font type and size. Depends on the resolution. Larger screens, prefer h20
    set guifont=Menlo:h14
    
    "Tab stuff
    set tabstop=3
    set shiftwidth=3
    set softtabstop=3
    set expandtab
    
    "Show command in bottom right portion of the screen
    set showcmd
    
    "Show lines numbers
    set number
    
    "Prefer relative line numbering?
    "set relativenumber"
    
    "Indent stuff
    set smartindent
    set autoindent
    
    "Always show the status line
    set laststatus=2
    
    "Prefer a slightly higher line height
    set linespace=3
    
    "Better line wrapping
    set wrap
    set textwidth=79
    set formatoptions=qrn1
    
    "Set incremental searching"
    set incsearch
    
    "Highlight searching
    set hlsearch
    
    " case insensitive search
    set ignorecase
    set smartcase
    
    "Hide MacVim toolbar by default
    set go-=T
    
    "Hard-wrap paragraphs of text
    nnoremap <leader>q gqip
    
    "Enable code folding
    set foldenable
    
    "Hide mouse when typing
    set mousehide
    
    "Shortcut to fold tags with leader (usually \) + ft
    nnoremap <leader>ft Vatzf
    
    " Create dictionary for custom expansions
    set dictionary+=/Users/jeff_way/.vim/dict.txt
    
    "Opens a vertical split and switches over (\v)
    nnoremap <leader>v <C-w>v<C-w>l
    
    "Split windows below the current window.
    set splitbelow              
    
    " session settings
    set sessionoptions=resize,winpos,winsize,buffers,tabpages,folds,curdir,help
    
    "Set up an HTML5 template for all new .html files
    "autocmd BufNewFile * silent! 0r $VIMHOME/templates/%:e.tpl
    
    "Load the current buffer in Firefox - Mac specific.
    abbrev ff :! open -a firefox.app %:p<cr>
    
    "Map a change directory to the desktop - Mac specific
    nmap <leader>d :cd ~/Desktop<cr>:e.<cr>
    
    "Shortcut for editing  vimrc file in a new tab
    nmap <leader>ev :tabedit $MYVIMRC<cr>
    
    "Change zen coding plugin expansion key to shift + e
    let g:user_zen_expandabbr_key = '<C-e>'
    
    "Faster shortcut for commenting. Requires T-Comment plugin
    map <leader>c <c-_><c-_>
    
    "Saves time; maps the spacebar to colon
    nmap <space> :
    
    "Automatically change current directory to that of the file in the buffer
    autocmd BufEnter * cd %:p:h
    
    "Map code completion to , + tab
    imap <leader><tab> <C-x><C-o>
    
    " More useful command-line completion
    set wildmenu
    
    "Auto-completion menu
    set wildmode=list:longest
    
    "http://vim.wikia.com/wiki/Make_Vim_completion_popup_menu_work_just_like_in_an_IDE
    set completeopt=longest,menuone
    inoremap <expr> <CR> pumvisible() ? "\<C-y>" : "\<C-g>u\<CR>"
    inoremap <expr> <C-n> pumvisible() ? '<C-n>' :
      \ '<C-n><C-r>=pumvisible() ? "\<lt>Down>" : ""<CR>'
    inoremap <expr> <M-,> pumvisible() ? '<C-n>' :
      \ '<C-x><C-o><C-n><C-p><C-r>=pumvisible() ? "\<lt>Down>" : ""<CR>'
    
    "Map escape key to jj -- much faster
    imap jj <esc>
    
    "Delete all buffers (via Derek Wyatt)
    nmap <silent> ,da :exec "1," . bufnr('$') . "bd"<cr>
    
    "Bubble single lines (kicks butt)
    "http://vimcasts.org/episodes/bubbling-text/
    nmap <C-Up> ddkP
    nmap <C-Down> ddp
    
    "Bubble multiple lines
    vmap <C-Up> xkP`[V`]
    vmap <C-Down> xp`[V`]
    
    " Source the vimrc file after saving it. This way, you don't have to reload Vim to see the changes.
    if has("autocmd")
     augroup myvimrchooks
      au!
      autocmd bufwritepost .vimrc source ~/.vimrc
     augroup END
    endif
    
    " easier window navigation
    nmap <C-h> <C-w>h
    nmap <C-j> <C-w>j
    nmap <C-k> <C-w>k
    nmap <C-l> <C-w>l
    
    "------------------------"
    "NERDTREE PLUGIN SETTINGS
    "------------------------"
    "Shortcut for NERDTreeToggle
    nmap <leader>nt :NERDTreeToggle <CR>
    
    "Show hidden files in NerdTree
    let NERDTreeShowHidden=1
    
    "autopen NERDTree and focus cursor in new document
    autocmd VimEnter * NERDTree
    autocmd VimEnter * wincmd p
    
    "Helpeful abbreviations
    iab lorem Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
    iab llorem Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. 
    
    "Spelling corrects. Just for example. Add yours below.
    iab teh the
    iab Teh The
    
    " Get to home dir easier
    " <leader>hm is easier to type than :cd ~
    nmap <leader>hm :cd ~/ <CR>
    
    " Alphabetically sort CSS properties in file with :SortCSS
    :command! SortCSS :g#\({\n\)\@<=#.,/}/sort
    
    " Shortcut to opening a virtual split to right of current pane
    " Makes more sense than opening to the left
    nmap <leader>bv :bel vsp
    
    " Saves file when Vim window loses focus
    au FocusLost * :wa
    
    " Backups
    set backupdir=~/.vim/tmp/backup// " backups
    set directory=~/.vim/tmp/swap// " swap files
    set backup " enable backup
    
    " No more stretching for navigating files
    "noremap h ;
    "noremap j h
    "noremap k gj
    "noremap l gk
    "noremap ; l
    
    set showmatch " show matching brackets
    
    " print empty <a> tag
    map! ;h <a href=""></a><ESC>5hi
    
    8. I Don’t Want to Use the Terminal

    Me neither — at least not more than I have too — there are a variety of dedicated Vim editors which provide a more Windows/Mac GUI-like experience.

    These editors will provide support for the sorts of keystrokes that are ingrained into your body, such as “Command + F” to search, or “Command + W” to close the current window.

    9. Too Difficult to Learn Without a Teacher Venturing into Vim

    Well I suppose that depends on if you’re more of a visual learner. However, if that’s the case — promo alert — you might consider checking out our “Venturing into Vim” 4-week course. What’s unique about this series is that I recorded each episode in real-time, as I was learning Vim for the first time. The advantage to this is that you’ll get a far more practical overview of Vim. What confused me at first will undoubtedly confuse you as well!

    You can purchase it on the Tuts+ marketplace for $19.

    Remember how, in school, sometimes, the student sitting next to you was able to explain and help you understand some difficult concept more than the teacher? The reason is because, once you’re mastered a craft, it’s difficult to recall what personally gave you the most trouble. From September to October, I embarked on a four-week challenge, which I call “Venturing into Vim.” After hearing countless extremely talented developers praise this seemingly decade-old code editor, I decided that it was worth a month of my time to figure out why so many people consider Vim to be the best editor on the planet.

    10. I Can’t Edit Files on My Server

    Of course you can, though, admittedly, it’s not quite as user-friendly as, say, Coda’s remote server feature. Speaking of Panic, if you’re a Transmit user, you might consider installing the Transmit FTP plugin.

    “This script allows you to upload the current file via Transmit directly from Vim. For it to work, you need to be working on a file that’s tied to a Transmit connection, and this connection must have “DockSend” enabled.”

    With this plugin, when editing a file that has a Transmit connection (open file via Transmit), you only need to press Control + U to push those updates back to your remote server. It’s a cinch!

    Truthfully, though, you should try to adopt a better build/deployment process. This way, rather than using FTP, you can simply git push.

    Sure – there are a handful of reasons not to use Vim. It has a steep learning curve, and requires a complete rethinking of how a code editor should function. That said, there are hundreds of reason why you should use Vim. The only question is: why aren’t you?


Planet PHP

  • Permalink for 'Introducing phorkie: git based pastebin'

    Introducing phorkie: git based pastebin

    Posted: April 18th, 2012, 2:22pm MDT by Christian Weiske

    At work, we've been looking for a pastebin application with a special feature set:

    • Self-hosted, so we can paste code and data without having to care about sensitive customer data becoming public accidentially
    • written in PHP, since we're a PHP shop
    • editability so other people can do fixes for us
    • title support for pastes so we can find it later
    • navigation among pastes so we don't have to remember the number later
    • search because navigation doesn't help with 1k+ pastes

    We did not find anything suitable after researching for some days. Since I needed a new spare time project, I began working on phorkie.

    After working on it for a month, I've just released the first version 0.1.0 and you're welcome to try it.

    phorkie

    phorkie is a self-hosted pastebin software written in PHP. Pastes are editable, may have multiple files and are stored in git repositories.

    It turned out to be a clone of github's gist tool, but with less features - for now.

    Features
    • Every paste is a git repository
      • Repositories can be cloned
      • Clone url can be displayed
    • Multiple files in one paste
    • Pastes can be edited
      • Add and delete files
      • Replace file with upload
      • History in sidebar
      • Easy access to old revisions
    • Syntax highlighting with GeSHi
    • rST rendering with rst2html (python docutils).
    • image upload and display
    • external tool support (xmllint, php syntax check)
    Missing tools

    For the history/log display, I wanted to display the timestamps in a human readable manner, e.g. "5 minutes ago" instead of 2012-04-18 22:36.

    Looking for existing libraries, I found plenty for Python and Javascript, but not a single one for PHP. After asking on stackoverflow without getting a usable answer, I wrote my own and proposed it to PEAR: Date_HumanDiff.

    Screenshots

    new paste paste list history tools

    Also see the wiki.

    Code

    The code is in a git repository on sourceforge but also mirrored on github for your convenience.

    <script type="text/javascript" src="http://cweiske.de/tagebuch/js/shadowbox/shadowbox.js"> <script type="text/javascript"> Shadowbox.init({ continuous: true, displayCounter: false, displayNav: true, handleOversize: "resize" });
  • Permalink for 'Maintenance'

    Maintenance

    Posted: April 18th, 2012, 10:02am MDT by TechPortal

    We are down for maintenance, our apologies for the inconvenience.

    Digg This  Reddit This  Stumble Now!  Buzz This  Vote on DZone  Share on Facebook  Bookmark this on Delicious  Kick It on DotNetKicks.com  Shout it  Share on LinkedIn  Bookmark this on Technorati  ">[http%3A%2F%2Ftechportal.ibuildings.com%2F2012%2F04%2F18%2F3725-revision-3%2F">] Post on Twitter  Google Buzz (aka. Google Reader)  
  • Permalink for 'Maintenance'

    Maintenance

    Posted: April 18th, 2012, 10:02am MDT by TechPortal

    We are down for maintenance, our apologies for the inconvenience.

    Digg This  Reddit This  Stumble Now!  Buzz This  Vote on DZone  Share on Facebook  Bookmark this on Delicious  Kick It on DotNetKicks.com  Shout it  Share on LinkedIn  Bookmark this on Technorati  ">[http%3A%2F%2Ftechportal.ibuildings.com%2Fmaintenance%2F">] Post on Twitter  Google Buzz (aka. Google Reader)  
  • Permalink for 'Maintenance'

    Maintenance

    Posted: April 18th, 2012, 10:02am MDT by TechPortal

    We are down for maintenance, our apologies for the inconvenience.

    Digg This  Reddit This  Stumble Now!  Buzz This  Vote on DZone  Share on Facebook  Bookmark this on Delicious  Kick It on DotNetKicks.com  Shout it  Share on LinkedIn  Bookmark this on Technorati  ">[http%3A%2F%2Ftechportal.ibuildings.com%2F2012%2F04%2F18%2F3725-revision-2%2F">] Post on Twitter  Google Buzz (aka. Google Reader)  
  • Permalink for 'Maintenance'

    Maintenance

    Posted: April 18th, 2012, 10:01am MDT by TechPortal
    Maintenance
  • Permalink for 'Auto Draft'

    Auto Draft

    Posted: April 18th, 2012, 9:49am MDT by TechPortal
    Auto Draft
  • Permalink for 'Auto Draft'

    Auto Draft

    Posted: April 18th, 2012, 9:49am MDT by TechPortal
    Auto Draft
  • Permalink for 'Generating graphs from MySQL table data'

    Generating graphs from MySQL table data

    Posted: April 18th, 2012, 6:57am MDT by Eran Galperin

    Graphs and charts are a useful visual way to view historical data - they make it easier to detect trends and get a big-picture view of data. All we need is timestamped data - table rows that are stamped with a specific date/time format, that can be used to group rows into time periods.

    Time stamped data

    In order to aggregate table data by time periods / ranges, we need a date/time column in the table we want to analyze. Appropriate types for such a column include TIMESTAMP, DATETIME and DATE, but we can also use string / numeric types for grouping data together if they contain some sort of date/time information - though those will be much less flexible than native date/time types.

    I usually opt to go with the TIMESTAMP format, for a couple of reasons -

    • TIMESTAMP data is stored internally as UTC timezone - this makes such data portable between servers without needing to adjust for timezones.
    • TIMESTAMP type have auto-initialization and updating features - using the CURRENT_TIMESTAMP and ON UPDATE CURRENT_TIMESTAMP values. As of MySQL ver. 5.6.5 you can use those properties with DATETIME as well, but since most servers and linux distributions use lower (considered more stable) versions, it's usually not an option.

    The TIMESTAMP format is limited by its date range (1970-01-01 to 2038-01-19), so you might need to use DATETIME if you're using dates far in the future or past.

    Grouping time-stamped rows into time periods

    Assuming we have time-stamped data in our table, we can now start aggregating it into specific time periods. The most commonly used time periods for grouping are:

    • Day
    • Week
    • Month
    • Year

    Lets take an example table schema and see how we group the data for each period.

    users
    - (int) `id`
    - (varchar) `name`
    - (smallint) `role`
    - (timestamp) `created`

    A very simple users table. Our time-stamped column is obviously `created`, and we'll be using it to group our data.

    Daily data

    Our first task is to extract daily new users data from the table. We'll do this by extracting the date portion of the timestamp using the DATE() function.

    SELECT
        DATE(`users`.`created`) AS `date`,
        COUNT(`users`.`id`) AS `count`
    FROM `users`
    WHERE `users`.`created` BETWEEN '2012-01-01 00:00:00' AND '2012-01-31 23:59:59'
    GROUP BY `date`
    ORDER BY `date`

    This returns data that looks like the following:

    date count
    2012-01-01 12
    2012-01-02 12
    2012-01-03 36
    2012-01-04 34
    2012-01-05 36
    2012-01-06 29
    ... ...

    Note that I limited the query to a time range of 1 month (January 1st to January 31st). I used this particular format for a couple of reasons:

    • It allows MySQL to use an index for filtering the result. Had I used the DATE() function in the WHERE clause ( DATE(`users`.`created`) BETWEEN ... ), an index could n

    Truncated by Planet PHP, read more at the original (another 10919 bytes)

  • Permalink for 'Book Review: “The Grumpy Programmer’s Guide To Building Testable Applications”'

    Book Review: “The Grumpy Programmer’s Guide To Building Testable Applications”

    Posted: April 18th, 2012, 5:00am MDT by Brandon Savage
    When most developers think about books on testing, they think about books that highlight things like “test driven development” or “how to build a test for X.” There are lots and lots of testing books out there that supposedly teach us how to write tests and reach milestones like “100% test coverage.” But at the [...]
  • Permalink for 'We Don't Know Deployment: A 4-Step Remedy'

    We Don't Know Deployment: A 4-Step Remedy

    Posted: April 18th, 2012, 1:51am MDT by Lorna Mitchell

    Someone emailed me recently, having read my book and wanting some advice. Here's a snippet of his email:


    So here's my problem.
    We dont know deployment. We work from same copy on one test server through ftp and then upload live on FTP.

    We have some small projects and some big collaborative projects.

    We host all these projects on our local shared computer which we call test server.
    All guys take code from it and return it there. We show our work to clients on that machine and then upload that work to live ftp.

    Do you think this is a good scenario or do we make this machine a dev server and introduce a staging server for some projects as well?

    I wrote him a reply with some suggestions (and my consulting rate) attached, and we had a little email exchange about some improvements that could fit in with the existing setup, both of the hardware and of the team skills. Then I started to think ... he probably isn't the only person who is wondering if there's a better way. So here's my advice, now with pictures!

    Starting Point

    This is basically the place we begin from:

    The code lives on this staging server, when you need to make a change, you copy it onto your own machine, make the change, and put it back on the staging server. From here, it can be checked over before it is put onto the live machine over FTP.

    The first thing to say is: this does work, as long as you follow the process exactly. But I was asked if I thought there was a better way, and I think there is. When I work with a setup like this, there is always a moment where I have no idea if I just copied over something, or forgot to copy over something, or ... you get the picture.

    Step 1: Source Control

    Use source control. That's the best advice I can give anyone. Use a hosted solution, install your own, pick Subversion or Git or Mercurial, I really don't care. But use source control.

    Here's the diagram with the source control in place, using SVN as an example (but it makes little difference what kind of source control you pick)

    Hardly anything has moved, but we've added a piece to the middle of the puzzle. At this point, there's a central repository where things are always kept, and always backed up. We have a history of changes, and can see who changed what. The developers can collaborate on larger changesets, and those changes can be committed to the repository even before they are ready to be placed onto the staging server, so you are much less likely to lose code when a hard drive dies.

    To get the code from the repository to the staging and live servers, we can export a clean copy of code each time and upload that using FTP (or go one step further, SFTP). If you really must check out from source control repositories onto public servers, then make absolutely sure you are not serving the metadata that the source control product uses - since this is only step 1, that would be OK (but keep reading).

    Step 2: Branches

    Now we've gone to all the trouble of implementing a source control solution, we may as well make the most of the features that are now available to us. This means it is time to learn to branch. A branch is just another copy of the code, but isolated from the first one. Using branches means you can:

    • always have an exact copy of the current live code available
    • work on more than one feature (or bug fix) at once

    You would use the same setup as above, but branching means you are able to do a great many more things without any fear of who changed what or whether you can commit without hurting things.

    I could write another thousand words about branching, but I won't (well, unless you ask very nicely, and even then it will be written another time). Instead, look around for some resources for whichever platform you chose: the Red Bean Book is a great place to start.

    Step 3: Automated Deployment

    This is the jewel in the crown, especially if you run multiple sites. If you only run one site, no matter how complicated it is, you will eventually learn to get the deployment mostly right, most of the time. With multiple site

    Truncated by Planet PHP, read more at the original (another 3778 bytes)

  • Permalink for 'We Don't Know Deployment: A 4-Step Remedy'

    We Don't Know Deployment: A 4-Step Remedy

    Posted: April 18th, 2012, 1:51am MDT by Lorna Mitchell

    Someone emailed me recently, having read my book and wanting some advice. Here's a snippet of his email:


    So here's my problem.
    We dont know deployment. We work from same copy on one test server through ftp and then upload live on FTP.

    We have some small projects and some big collaborative projects.

    We host all these projects on our local shared computer which we call test server.
    All guys take code from it and return it there. We show our work to clients on that machine and then upload that work to live ftp.

    Do you think this is a good scenario or do we make this machine a dev server and introduce a staging server for some projects as well?

    I wrote him a reply with some suggestions (and my consulting rate) attached, and we had a little email exchange about some improvements that could fit in with the existing setup, both of the hardware and of the team skills. Then I started to think ... he probably isn't the only person who is wondering if there's a better way. So here's my advice, now with pictures!

    Starting Point

    This is basically the place we begin from:

    The code lives on this staging server, when you need to make a change, you copy it onto your own machine, make the change, and put it back on the staging server. From here, it can be checked over before it is put onto the live machine over FTP.

    The first thing to say is: this does work, as long as you follow the process exactly. But I was asked if I thought there was a better way, and I think there is. When I work with a setup like this, there is always a moment where I have no idea if I just copied over something, or forgot to copy over something, or ... you get the picture.

    Step 1: Source Control

    Use source control. That's the best advice I can give anyone. Use a hosted solution, install your own, pick Subversion or Git or Mercurial, I really don't care. But use source control.

    Here's the diagram with the source control in place, using SVN as an example (but it makes little difference what kind of source control you pick)

    Hardly anything has moved, but we've added a piece to the middle of the puzzle. At this point, there's a central repository where things are always kept, and always backed up. We have a history of changes, and can see who changed what. The developers can collaborate on larger changesets, and those changes can be committed to the repository even before they are ready to be placed onto the staging server, so you are much less likely to lose code when a hard drive dies.

    To get the code from the repository to the staging and live servers, we can export a clean copy of code each time and upload that using FTP (or go one step further, SFTP). If you really must check out from source control repositories onto public servers, then make absolutely sure you are not serving the metadata that the source control product uses - since this is only step 1, that would be OK (but keep reading).

    Step 2: Branches

    Now we've gone to all the trouble of implementing a source control solution, we may as well make the most of the features that are now available to us. This means it is time to learn to branch. A branch is just another copy of the code, but isolated from the first one. Using branches means you can:

    • always have an exact copy of the current live code available
    • work on more than one feature (or bug fix) at once

    You would use the same setup as above, but branching means you are able to do a great many more things without any fear of who changed what or whether you can commit without hurting things.

    I could write another thousand words about branching, but I won't (well, unless you ask very nicely, and even then it will be written another time). Instead, look around for some resources for whichever platform you chose: the Red Bean Book is a great place to start.

    Step 3: Automated Deployment

    This is the jewel in the crown, especially if you run multiple sites. If you only run one site, no matter how complicated it is, you will eventually learn to get the deployment mostly right, most of the time. With multiple site

    Truncated by Planet PHP, read more at the original (another 3685 bytes)

Nettuts+

  • Permalink for 'Creattica Redesign: Introducing UI Elements'

    Creattica Redesign: Introducing UI Elements

    Posted: April 17th, 2012, 10:50am MDT by Collis Ta'eed

    It’s a month of new beginnings over at our design and inspiration gallery Creattica. April has seen the site undergo a complete redesign with a whole new streamlined grid-style layout for its over 50 different categories. On top of that, Creattica now has better navigation, a new UI Elements section and a growing Freebies area of now over 700 items. All this and over 14,000 featured works from some 100,000 members. It’s quite the site!

    But that’s not all, let’s first take a look at some of Creattica’s top UI work – and then stay tuned for some exciting news at the conclusion!

    1. Hi 2. User Login 3. Simple Breadcrumb 4. WIP – Calendar App 5. Minimal Login User Interface 6. Switch 7. the One Club Video Player 8. the Creative Finder 9. Pagination 10. Pricing Tables The Future of Creattica

    When we started Creattica (originally Faveup) back in 2007, we wanted it to be one on the top inspiration galleries on the web. And as the site has grown and changed over the years, we find ourselves with what has become one of the biggest, broadest and most in-depth galleries of design out there. So I guess we can say – mission accomplished!

    Over these past few months, Envato has really started working on focusing on our core products of Marketplaces and Tuts+ sites. So while we love Creattica, we find ourselves in the regrettable position of having to put the site up for sale soon. We really want it to go to an awesome home, so if anyone would like to express interest in the sale or get more details, please contact us here.

    I’m certain we’ll find some new owners who can keep Creattica growing and evolving on into the future. And in the meantime I hope you enjoy the new design and all the gorgeous work as much as I do!


Planet PHP

  • Permalink for 'Properly Salting Passwords, The Case Against Pepper'

    Properly Salting Passwords, The Case Against Pepper

    Posted: April 17th, 2012, 9:00am MDT by Anthony Ferrara
    The other day I announced the release of my new password hashing library, PasswordLib. As I've come to expect, Reddit was full of interesting commentary on the topic. Some was good, some was bad and some surprised me. What surprised me was the insistence on a global salt (otherwise known as a "pepper"). So, I started thinking about it some more, and I figured I'd write a post on why I don't use peppers in my hashing algorithms (and why you may want to rethink it too).Read more »
  • Permalink for 'Book Review: “Code Simplicity”'

    Book Review: “Code Simplicity”

    Posted: April 17th, 2012, 7:40am MDT by blog.phpdeveloper.org » PHP

    Last night I finished my latest read from O’Reiily, Code Simplicity – The Science of Software Development. I spotted the book the other day when O’Reilly was running a special on a few books and the ebook was cheap so I figured it couldn’t hurt to give it a try. After all, the “science” part in the title made it sound like there might be some hidden truths that could be applied anywhere in development. Unfortunately, most of the book just ended up being more of a rambling journey though things that most software developers that have any years of experience (even the bad ones) would already know.

    The author spent a good bit of the book dedicated to definitions and explanations about various practices and ideas in development, as if he thought that maybe the audience reading the book wasn’t savvy on the topic. The first few chapters also included several sections about the book itself – why it was relevant and mentions of a “science” that never seemed to fully resolve. Granted, trying to make a “science” (more a set of laws than just best practices) out of something so varied as software development is a pretty difficult task, but I felt like the author tried a little too hard to make his case for the book and less time actually defining something that could have been interesting.

    All this being said, if you don’t worry too much about him trying to propose a “science” to it all, there were some good best practices reminders in here for developers of any language:

    • Don’t rewrite, rework – a reminder that, despite it seeming easier to chuck the whole system and start over with the knowledge you now have, you’d do better in the long run to change things from the inside out, a piece at a time (hint: unit tests make a world of difference here)
    • Know the problem before writing the solution – listen and understand the problem before you start with even one piece of code. If you don’t fully understand the problem, you’ll end up with half-assed software that only does part of what was needed.
    • Think specific, not general – if you immediately jump to the “well, if I use a plugin architecture for this part…” chances are you’ve already added too much complexity. Think small first – make it work, then make it better (I’m a big fan of iterative development)
    • Use more experienced developers as a sounding board – chances are, if someone’s been in the development biz longer than you, they’ve come across your situation before. Sometimes you have to seek out that person on a specific topic, but don’t just forge ahead blindly. At the very least, try to find blog posts or articles that you can use as a guide.
    • Don’t forget that time is important too – most developers (me included) easily forget that time is a factor in their development. No, I’m not talking about the actual time to write the code or the looming deadline to finish it by. I’m talking more about the time you’ll need to do research, try things out or even consult with fellow developers. Time put into something to gain knowledge is an investment too…don’t forget to remember the value of it.

    There were other points made throughout the book, some more relevant than others, but I wish the author had spent less time focusing on definitions and more on expanding the sections with some more practical advice. This (relatively short) book probably could have been summed up in a small series of blog posts and been just fine.

    Book: Code Simplicity – The Science of Software Development
    Publisher: O’Reilly
    Author: Max Kanat-Alexander
    Pages: 92

Nettuts+

  • Permalink for 'Advanced CodeIgniter Profiling With XHProf'

    Advanced CodeIgniter Profiling With XHProf

    Posted: April 17th, 2012, 7:16am MDT by James Constable

    There are a number of ways to profile and monitor the performance of PHP code in a development environment, but once it’s been let loose on a production server its extremely difficult to know what’s going on when your app is getting accessed by your users.

    In March 2009, Facebook released XHProf, a function level profiler that allows you to identify bottlenecks in your application. And it runs on a production server with little overhead.

    XHProf will provide you with a hierarchical profile of the functions your application calls, allowing you to follow the chain of events that lead up to resource intensive code running. You’ll be able to see exactly how much wall time (the actual time elapsed), CPU time and memory your application uses.

    This tutorial will help you get XHProf installed on your server, and integrated with your CodeIgniter application via hooks so that you can start profiling your application, in a production environment, straight away. Everything you see here was written for Ubuntu 10.04 – the latest LTS release at the time of writing.

    Installation

    Installation of XHProf can be done via PECL – that said, I’ve never been able to get the PECL version installed on Ubuntu easily so its easier to install from source. Start off by downloading the latest revision from the XHProf GitHub account.

      	wget [https:] -O xhprof.tar.gz
    

    Extract the tarball and switch into the extracted folder – this will change depending on the latest revision available from GitHub.

    	tar -xvf xhprof.tar.gz
    	cd facebook-xhprof-bc8ef04/extension
    

    Then install as normal.

    	phpize
    	./configure
    	make
    	sudo make install
    

    Finally, we need to tell PHP to load the extension. Create a config file for it – I do this for cleanliness but you can always drop it at the end of your main php.ini.

    	sudo nano /etc/php5/conf.d/xhprof.ini
    

    And paste in the following:

    	extension=xhprof.so
    	xhprof.output_dir="/var/tmp/xhprof"
    

    This tells XHProf to use the directory at /var/tmp/xhprof to save its run data.

    You can check whether XHProf is installed correctly by entering php -m at the command line and checking that the module is available. Remember to restart Apache so that it gets picked up in your PHP web applications as well.

    If you want to render the callgraph images you’ll also need the graphviz package. This can be obtained from apt.

    	sudo apt-get install graphviz
    
    Integration With CodeIgniter

    XHProf can be used on an ad-hoc basis to evaluate small pieces of code, but it’s at its most useful when you let it profile the full page. First of all, you’ll need to move the XHProf code into your web applications root so that it has access to the appropriate classes.

    	sudo mv ~/facebook-xhprof-bc8ef04  /var/www/xhprof
    

    CodeIgniter has an excellent mechanism for injecting custom code into the execution of a page called ‘Hooks’. This is what we’ll use to integrate XHProf with your application. Enable hooks in your application/config/config.php file.

    	$config['enable_hooks'] = true;
    

    Then specify your hooks in application/config/hooks.php

    	$hook['pre_controller'] = array(
    	  'class'  => 'XHProf',
    	  'function' => 'XHProf_Start',
    	  'filename' => 'xhprof.php',
    	  'filepath' => 'hooks',
    	  'params' => array()
    	);
    
    	$hook['post_controller'] = array(
    		'class'  => 'XHProf',
    		'function' => 'XHProf_End',
    		'filename' => 'xhprof.php',
    		'filepath' => 'hooks',
    		'params' => array()
    	);
    

    Then create the hook that will load XHProf into your application at application/hooks/xhprof.php. This class will provide the necessary minimum to get XHProf collecting data from your application.

    	class XHProf {
    
    		private $XHProfPath = 'xhprof/';
    		private $applicationName = 'my_application';
    		private $sampleSize = 1;
    		private static $enabled = false;
    
    		public function XHProf_Start() {
    			if (mt_rand(1, $this->sampleSize) == 1) {
    				include_once $this->XHProfPath . 'xhprof_lib/utils/xhprof_lib.php';
    				include_once $this->XHProfPath . 'xhprof_lib/utils/xhprof_runs.php';
    				xhprof_enable(XHPROF_FLAGS_NO_BUILTINS);
    
    				self::$enabled = true;
    			}
    		}
    
    		public function XHProf_End() {
    			if (self::$enabled) {
    				$XHProfData = xhprof_disable();
    
    				$XHProfRuns = new XHProfRuns_Default();
    				$XHProfRuns->save_run($XHProfData, $this->applicationName);
    			}
    		}
    
    	}
    

    There’s a few thing to point out in this code sample.

    • The $XHProfPath variable should point to the directory you installed XHProf in. In our example, we put it in the root of the web application, but you might be storing it somewhere central and symlinking it to multiple applications.
    • The $applicationName variable lets you specify the name of the application using XHProf. This could be especially important in an environment where you’re running multiple applications on the same server.
    • The $sampleSize variable lets you specify a factor for how often XHProf profiles a run. In a production environment where you’re receiving thousands of hits, it’s probably not worth storing every single run. You can increase this variable to get a random sample of runs. Changing it to 10, for example, will give you a report from one in every 10 visits to your application.

    The xhprof_enable() function can accept any combination of 3 constants.

    • XHPROF_FLAGS_NO_BUILTINS – skip all internal php functions. Adding this means you’ll only see time spent in functions that you have written (or are part of CodeIgniter)
    • XHPROF_FLAGS_CPU – add additional CPU profiling information
    • XHPROF_FLAGS_MEMORY – add additional memory profiling information

    Combine them using +. eg. xhprof_enable(XHPROF_FLAGS_NO_BUILTINS + XHPROF_FLAGS_MEMORY);

    After running through your application a couple of times, point your browser at the XHProf application directory http://localhost/xhprof/xhprof_html/index.php – adjusting for the address of your development server – and you’ll see a list of your last application runs with the newest at the top. Select one of the runs to see it’s profiling information.

    Evaluating the Results

    Storing all this profiling information is all very well and good but knowing how to evaluate it is the key to optimising your application.

    The ‘Overall Summary’ is a good place to start – it’ll show you:

    • Total inclusive wall time – how long (in microseconds) it took for you page to be generated
    • Total memory use – the total memory used by this run of your application
    • Total peak memory use – the maximum amount of memory that was used by your application
    • Number of function calls – the number of functions that were called by your application
    Run summary

    These number should give you an overall base to start from and provide headline numbers to compare against when you start optimisation.

    Below the summary is the detailed run report The bottlenecks in your application should be fairly obvious – they’re the function calls at the top of the report.

    Wall report

    The most resource intensive things you’re likely to come across will be those that make calls to external services or your database. By default, the results are sorted by ‘inclusive wall time’. This shows the functions that took the longest to run by the cumulative total of them and the functions they call. Ordering by ‘exclusive wall time’ allows you to see the specific functions that are using the most amount of resource.

    Clicking a function allows you to drill down into more detail about that function and the functions it called. From there, it’ll be easier to see exactly what your long running function was doing and spot any issues.

    When debugging your CodeIgniter application, one of the best places to start is the controller being called for your page – Welcome::index in the example. From there you can easily see the breakdown of where the controller spent most of it’s time.

    Controller summary Callgraph

    XHProf can generate a call graph view that provides a visual clue to the main path of your application. The main bottlenecks are highlighted in red to show where most your resources are being spent.

    Callgraph Comparing Runs

    XHProf provides a mechanism for comparing multiple runs – this will allow you to make a number of optimisations and then see how they’ve affected your application.

    http://localhost/xhprof/xhprof_html/index.php?run1=run_id_1>&run2=run_id_2&source=applicationName

    Note: run_id_1 and run_id_2 should be the ids from some of your previous runs and applicationName should be the name you specified when setting up the hook earlier.

    This will provide the same information you see in a regular report but provide percentage statistics on any changes since the first run, allowing you to easily see if your optimisations are moving your performance in the right direction.

    Aggregating Runs

    Sometimes a single run might not be enough to evaluate exactly what’s going on. Pages my work slightly differently depending on the query string or user input or there might be differences in caching mechanisms.

    Aggregating a number of runs allows you to combine a number of runs and receive an average of the resources consumed.

    http://localhost/xhprof/xhprof_html/index.php?run=run_id,run_id,run_id&source=applicationName

    Note: run_id should be the ids from some of your previous runs and applicationName should be the name you specified when setting up the hook earlier.

    Summary

    You should now have XHProf up and running in your CodeIgniter application and be able to see exactly where your code is spending most of it’s time. Optimisation can be a difficult task. Sometimes it’s not as simple as reimplementing a function, or adding a layer of caching. Thinking about why you’re doing something and what the exact effect that is having on your application is just as important.

    So let me know if you have any questions in the comments below. Thank you so much for reading!


Planet PHP

  • Permalink for 'Sismo Challenge: Results'

    Sismo Challenge: Results

    Posted: April 17th, 2012, 4:01am MDT by TechPortal

    We recently wrapped up the first Ibuildings Challenge of 2012; a contest to create a Sismo notifier. At the moment Sismo ships with Growl, DBus, Google Talk and XMPP notifiers. They all extend the Sismo\Notifier to provide feedback to developers in a particular way. The task was to create a new notifier that was useful, creative or inspiring. This post announces the winners and makes some observations based on the submissions we received.

    Contest Key Rules: A Recap
    • You should follow the Symfony code standards as described here.
    • Your script will be run on PHP 5.3.5 installation. Should you need any PHP extension you must provide a patch to the php.ini with the changes made to add the extensions you've used.
    • In the spirit of Sismo itself, we'd prefer self-contained solutions. Use Symfony or PHP extensions if you need to, and other frameworks if you must!
    • The name of the PHP class doesn't matter, but it must extend Sismo\Notifier and implement the notify() method.
    • You can look at existing Sismo notifiers to see implementation examples, but you cannot implement the same notifier in a different way, e. g. you cannot implement a Growl notifier which is already in master. You can find more instructions on how to extend the notifier on Sismo documentation. It can be found in sismo.sensiolabs.org or github.com/fabpot/Sismo under “Adding a notifier”.


    Competition Entries

    We created 3 categories; creative, inspiring and useful notifiers. None of the submissions selected a category, so we chose the category we thought best described the submission. We received a total of 23 subscriptions, but only 14 of those actually submitted their code or a link to an existing repository.

    Winners

    The competition was designed to inspire developers to contribute to open source projects. We specifically chose a tool that requires existing unit tests for you to use it – a continuous testing tool - to encourage contestants to write tests. Above all, I hope you have enjoyed taking part in this contest. Now, let's look at the winners

    Useful

    Considering Sismo is meant to run locally we chose a Wallpaper Notifier as the most useful. It shows the build result as a small bar added to the desktop wallpaper. This is a very customisable solution; you have control over colours, the size of the final wallpaper considering the screen resolution, and a bunch of other options. The added documentation was also very good.

    Category Winner Useful: Wallpaper Notifier by Javier Eguiluz

    Inspiring

    I have noticed that it has become common in some IRC channels to have a bot notifying the chat participants of the commits as they happen. One of the most popular of these bots is Eggdrop. So we picked an Eggdrop Notifier for the inspiring category. This would be particularly inspiring in open source projects that are just starting to build a community. The participants could see what the selected developers were working on locally.

    Category Winner Inspiring: Eggdrop Notifier by Andrew Graham

    Creative

    We had a few submissions of notifiers that would speak the test results, but this one made me laugh. I guessed immediately what it was because of its name, but still it was very funny when it ran with a failed build: "Houston, we have a problem here!", it said. Nice, funny, creative and original.

    Category Winner Creative: Houston Notifier by Andreas Hucks

    Prizes

    Amongst all the winners, we raffled three prizes: 2 tickets to the PHPNW Conference and an Apple iPad. The prizes go as follows:

    PHPNW tickets: Andrew Graham and Andreas Hucks
    iPad: Javier Eguiluz

    Congratulations to all the winners!

    Conclusions

    For us as organisers, this has been another fun challenge and we look forward to the next (watch this space!). We offer our warm congratulations to all our participants for such a high standard of submissions, and especially to our winners who fought off some stiff competition to emerge victorious. Thanks to all of you and we hope you had as much fun as we did!

    "/>

    Truncated by Planet PHP, read more at the original (another 4400 bytes)

  • Permalink for 'Sismo Challenge: Results'

    Sismo Challenge: Results

    Posted: April 17th, 2012, 2:26am MDT by TechPortal

    We recently wrapped up the first Ibuildings Challenge of 2012; a contest to create a Sismo notifier. At the moment Sismo ships with Growl, DBus, Google Talk and XMPP notifiers. They all extend the Sismo\Notifier to provide feedback to developers in a particular way. The task was to create a new notifier that was useful, creative or inspiring. This post announces the winners and makes some observations based on the submissions we received.

    Contest Key Rules: A Recap
    • You should follow the Symfony code standards as described here.
    • Your script will be run on PHP 5.3.5 installation. Should you need any PHP extension you must provide a patch to the php.ini with the changes made to add the extensions you've used.
    • In the spirit of Sismo itself, we'd prefer self-contained solutions. Use Symfony or PHP extensions if you need to, and other frameworks if you must!
    • The name of the PHP class doesn't matter, but it must extend Sismo\Notifier and implement the notify() method.
    • You can look at existing Sismo notifiers to see implementation examples, but you cannot implement the same notifier in a different way, e. g. you cannot implement a Growl notifier which is already in master. You can find more instructions on how to extend the notifier on Sismo documentation. It can be found in sismo.sensiolabs.org or github.com/fabpot/Sismo under “Adding a notifier”.


    Competition Entries

    We created 3 categories; creative, inspiring and useful notifiers. None of the submissions selected a category, so we chose the category we thought best described the submission. We received a total of 23 subscriptions, but only 14 of those actually submitted their code or a link to an existing repository.

    Winners

    The competition was designed to inspire developers to contribute to open source projects. We specifically chose a tool that requires existing unit tests for you to use it – a continuous testing tool - to encourage contestants to write tests. Above all, I hope you have enjoyed taking part in this contest. Now, let's look at the winners

    Useful

    Considering Sismo is meant to run locally we chose a Wallpaper Notifier as the most useful. It shows the build result as a small bar added to the desktop wallpaper. This is a very customisable solution; you have control over colours, the size of the final wallpaper considering the screen resolution, and a bunch of other options. The added documentation was also very good.

    Category Winner Useful: Wallpaper Notifier by Javier Eguiluz

    Inspiring

    I have noticed that it has become common in some IRC channels to have a bot notifying the chat participants of the commits as they happen. One of the most popular of these bots is Eggdrop. So we picked an Eggdrop Notifier for the inspiring category. This would be particularly inspiring in open source projects that are just starting to build a community. The participants could see what the selected developers were working on locally.

    Category Winner Inspiring: Eggdrop Notifier by Andrew Graham

    Creative

    We had a few submissions of notifiers that would speak the test results, but this one made me laugh. I guessed immediately what it was because of its name, but still it was very funny when it ran with a failed build: "Houston, we have a problem here!", it said. Nice, funny, creative and original.

    Category Winner Creative: Houston Notifier by Andreas Hucks

    Prizes

    Amongst all the winners, we raffled three prizes: 2 tickets to the PHPNW Conference and an Apple iPad. The prizes go as follows:

    PHPNW tickets: Andrew Graham and Andreas Hucks
    iPad: Javier Eguiluz

    Congratulations to all the winners!

    Conclusions

    For us as organisers, this has been another fun challenge and we look forward to the next (watch this space!). We offer our warm congratulations to all our participants for such a high standard of submissions, and especially to our winners who fought off some stiff competition to emerge victorious. Thanks to all of you and we hope you had as much fun as we did!

    "/>

    Truncated by Planet PHP, read more at the original (another 4530 bytes)

  • Permalink for 'Sismo Challenge: Results'

    Sismo Challenge: Results

    Posted: April 17th, 2012, 2:26am MDT by TechPortal

    We recently wrapped up the first Ibuildings Challenge of 2012; a contest to create a Sismo notifier. At the moment Sismo ships with Growl, DBus, Google Talk and XMPP notifiers. They all extend the Sismo\Notifier to provide feedback to developers in a particular way. The task was to create a new notifier that was useful, creative or inspiring. This post announces the winners and makes some observations based on the submissions we received.

    Contest Key Rules: A Recap
    • You should follow the Symfony code standards as described here.
    • Your script will be run on PHP 5.3.5 installation. Should you need any PHP extension you must provide a patch to the php.ini with the changes made to add the extensions you've used.
    • In the spirit of Sismo itself, we'd prefer self-contained solutions. Use Symfony or PHP extensions if you need to, and other frameworks if you must!
    • The name of the PHP class doesn't matter, but it must extend Sismo\Notifier and implement the notify() method.
    • You can look at existing Sismo notifiers to see implementation examples, but you cannot implement the same notifier in a different way, e. g. you cannot implement a Growl notifier which is already in master. You can find more instructions on how to extend the notifier on Sismo documentation. It can be found in sismo.sensiolabs.org or github.com/fabpot/Sismo under “Adding a notifier”.


    Competition Entries

    We created 3 categories; creative, inspiring and useful notifiers. None of the submissions selected a category, so we chose the category we thought best described the submission. We received a total of 23 subscriptions, but only 14 of those actually submitted their code or a link to an existing repository.

    Winners

    The competition was designed to inspire developers to contribute to open source projects. We specifically chose a tool that requires existing unit tests for you to use it – a continuous testing tool - to encourage contestants to write tests. Above all, I hope you have enjoyed taking part in this contest. Now, let's look at the winners

    Useful

    Considering Sismo is meant to run locally we chose a Wallpaper Notifier as the most useful. It shows the build result as a small bar added to the desktop wallpaper. This is a very customisable solution; you have control over colours, the size of the final wallpaper considering the screen resolution, and a bunch of other options. The added documentation was also very good.

    Category Winner Useful: Wallpaper Notifier by Javier Eguiluz

    Inspiring

    I have noticed that it has become common in some IRC channels to have a bot notifying the chat participants of the commits as they happen. One of the most popular of these bots is Eggdrop. So we picked an Eggdrop Notifier for the inspiring category. This would be particularly inspiring in open source projects that are just starting to build a community. The participants could see what the selected developers were working on locally.

    Category Winner Inspiring: Eggdrop Notifier by Andrew Graham

    Creative

    We had a few submissions of notifiers that would speak the test results, but this one made me laugh. I guessed immediately what it was because of its name, but still it was very funny when it ran with a failed build: "Houston, we have a problem here!", it said. Nice, funny, creative and original.

    Category Winner Creative: Houston Notifier by Andreas Hucks

    Prizes

    Amongst all the winners, we raffled three prizes: 2 tickets to the PHPNW Conference and an Apple iPad. The prizes go as follows:

    PHPNW tickets: Andrew Graham and Andreas Hucks
    iPad: Javier Eguiluz

    Congratulations to all the winners!

    Conclusions

    For us as organisers, this has been another fun challenge and we look forward to the next (watch this space!). We offer our warm congratulations to all our participants for such a high standard of submissions, and especially to our winners who fought off some stiff competition to emerge victorious. Thanks to all of you and we hope you had as much fun as we did!

    "/>

    Truncated by Planet PHP, read more at the original (another 4453 bytes)

  • Permalink for 'Sismo Challenge: Results'

    Sismo Challenge: Results

    Posted: April 17th, 2012, 2:26am MDT by TechPortal

    We recently wrapped up the first Ibuildings Challenge of 2012; a contest to create a Sismo notifier. At the moment Sismo ships with Growl, DBus, Google Talk and XMPP notifiers. They all extend the Sismo\Notifier to provide feedback to developers in a particular way. The task was to create a new notifier that was useful, creative or inspiring. This post announces the winners and makes some observations based on the submissions we received.

    Contest Key Rules: A Recap
    • You should follow the Symfony code standards as described here.
    • Your script will be run on PHP 5.3.5 installation. Should you need any PHP extension you must provide a patch to the php.ini with the changes made to add the extensions you've used.
    • In the spirit of Sismo itself, we'd prefer self-contained solutions. Use Symfony or PHP extensions if you need to, and other frameworks if you must!
    • The name of the PHP class doesn't matter, but it must extend Sismo\Notifier and implement the notify() method.
    • You can look at existing Sismo notifiers to see implementation examples, but you cannot implement the same notifier in a different way, e. g. you cannot implement a Growl notifier which is already in master. You can find more instructions on how to extend the notifier on Sismo documentation. It can be found in sismo.sensiolabs.org or github.com/fabpot/Sismo under “Adding a notifier”.


    Competition Entries

    We created 3 categories; creative, inspiring and useful notifiers. None of the submissions selected a category, so we chose the category we thought best described the submission. We received a total of 23 subscriptions, but only 14 of those actually submitted their code or a link to an existing repository.

    Winners

    The competition was designed to inspire developers to contribute to open source projects. We specifically chose a tool that requires existing unit tests for you to use it – a continuous testing tool - to encourage contestants to write tests. Above all, I hope you have enjoyed taking part in this contest. Now, let's look at the winners

    Useful

    Considering Sismo is meant to run locally we chose a Wallpaper Notifier as the most useful. It shows the build result as a small bar added to the desktop wallpaper. This is a very customisable solution; you have control over colours, the size of the final wallpaper considering the screen resolution, and a bunch of other options. The added documentation was also very good.

    Category Winner Useful: Wallpaper Notifier by Javier Eguiluz

    Inspiring

    I have noticed that it has become common in some IRC channels to have a bot notifying the chat participants of the commits as they happen. One of the most popular of these bots is Eggdrop. So we picked an Eggdrop Notifier for the inspiring category. This would be particularly inspiring in open source projects that are just starting to build a community. The participants could see what the selected developers were working on locally.

    Category Winner Inspiring: Eggdrop Notifier by Andrew Graham

    Creative

    We had a few submissions of notifiers that would speak the test results, but this one made me laugh. I guessed immediately what it was because of its name, but still it was very funny when it ran with a failed build: "Houston, we have a problem here!", it said. Nice, funny, creative and original.

    Category Winner Creative: Houston Notifier by Andreas Hucks

    Prizes

    Amongst all the winners, we raffled three prizes: 2 tickets to the PHPNW Conference and an Apple iPad. The prizes go as follows:

    PHPNW tickets: Andrew Graham and Andreas Hucks
    iPad: Javier Eguiluz

    Congratulations to all the winners!

    Conclusions

    For us as organisers, this has been another fun challenge and we look forward to the next (watch this space!). We offer our warm congratulations to all our participants for such a high standard of submissions, and especially to our winners who fought off some stiff competition to emerge victorious. Thanks to all of you and we hope you had as much fun as we did!

    "/>

    Truncated by Planet PHP, read more at the original (another 4453 bytes)

  • Permalink for 'And The Winners Are…'

    And The Winners Are…

    Posted: April 16th, 2012, 2:25pm MDT by Brandon Savage
    Yesterday afternoon I used a random number generator to select three winners for The PHP Playbook. I’m excited to announce that the winners of the PHP Playbook are: Péter Halász of the United Kingdom Ashar Javed of Germany Tomasz Kowalczyk of Poland All three winners were excited to be told they had won. Tomasz said [...]
  • Permalink for 'Dynamic Toolbar Menus with ExtJS + PHP'

    Dynamic Toolbar Menus with ExtJS + PHP

    Posted: April 16th, 2012, 10:26am MDT by blog.phpdeveloper.org » PHP

    In Ext JS 4 there’s some handy things that come bundled with it (there’s lots of stuff actually – it’s a pretty large library). Recently, though, I needed to pull in navigation information from a remote source (JSON output from a PHP script). Thankfully, Ext still made this pretty easy with its Toolbar and Menu components with their listeners. Here’s my example code:

    Ext.create('Ext.toolbar.Toolbar', {
                floating: false,
                id: 'menuToolbar',
                cls: 'appMenu',
                height: 30,
                items: [], // dynamically built below
                listeners: {
                    beforerender: function() {
                        var navStore = Ext.create('Ext.data.Store', {
                            fields: ['text'],
                            proxy: {
                                type: 'ajax',
                                url: '/path/to/navigation-output',
                                reader: {
                                    type: 'json',
                                    root: 'navigation'
                                }
                            },
                            autoLoad: true,
                            listeners: {
                                load: function(store,records,success,operation,opts) {
    
                                    var toolbar = Ext.getCmp('menuToolbar');
    
                                    // First the top level items
                                    store.each(function(record) {
    
                                        var menu = Ext.create('Ext.menu.Menu');
                                        Ext.each(record.raw.menu, function(item){
                                            menu.add({
                                                text: item.text
                                            })
                                        })
    
                                        toolbar.add({
                                            xtype: 'button',
                                            text: record.data.text,
                                            menu: menu
                                        });
                                    });
                                }
                            }
                        });
                    }
                }
            });
    

    Then the PHP to make the output is pretty easy (slightly simplified here):

    <?php
    echo json_encode(
        'navigation' => array(
            'text' => 'Option #1',
            'menu' => array(
                array('text' => 'Foo'),
                array('text' => 'Bar'),
                array('text' => 'Baz')
            )
        )
    );
    ?>
    

    Now – a little explaination of what we’re doing here:

    1. In Ext, we create a generic Toolbar object – this is what’s going to contain the “buttons” that act as the top level menu.
    2. There’s a few config options (like an ID, height and a custom class to apply) but the key is in the “listeners” section. This is where Ext looks to for events on the objects. In our case, we’re telling it to, on the “beforerender” event, call this given inline method. This method then makes our store.
    3. For those not familiar with the ideas of “stores”, think of them as Javascript-based database tables (kinda). They pull in data from some source or can be manually populated in memory to prevent you from having to go back and fetch the data every time you need it. in our case, we just make a basic one (Ext.data.Store) that is set up with a proxy to pull from the JSON source (our /path/to/navigation-output). With the “autoLoad” property set to “true” it automatically pulls in the JSON as soon as it’s created.
    4. You’ll see that we’ve, once again, tapped into the “listeners”, this time for the store. Our “load” listener fires when the store data is completely loaded. In here is where we’re going to add our elements into the Toolbar.
    5. As one of the options, we get the current store back and we use it to loop through and get each of the records. Each of these top level records is going to be one of our Toolbar buttons, each with its own menu. You can see as we loop through them, we create an “Ext.menu.Menu” object adding the “text” value to it. This menu is then appended to the button via the “menu” property on the button. The “add” is called again on the button config and it’s dropped into the Toolbar.

    The fun thing about this is that it makes a reusable component that you can use across products/sites without having to hard-code the navigation options into the actual code. There’s probably a simpler way to do this, but this one seemed to make the most sense to me.

Nettuts+

  • Permalink for 'The Essentials of AMD and RequireJS: New on Tuts+ Premium'

    The Essentials of AMD and RequireJS: New on Tuts+ Premium

    Posted: April 16th, 2012, 9:37am MDT by Jeffrey Way

    In this Tuts+ Premium screencast, we’ll review RequireJS, an asynchronous module loader and dependency manager, and AMD, which defines the mechanism and guidelines for declaring and importing modules.

    Become a Premium member to view this screencast, as well as hundreds of other advanced tutorials and screencasts from the Tuts+ network.

    You’ll Learn:
    • What is AMD? Why is it helpful?
    • How to use RequireJS, which implements the AMD spec.
    • How to create, store, and reference modules.
    • How to integrate the use plugin.
    • How to import scripts, which do not register themselves as AMD modules.
    • A lightning-fast run-through of importing and working with Backbone.js.
    Tuts+ Premium

    The recently re-launched Tuts+ Premium is a service that provides top-tier training in a variety of creative fields. Whether you prefer books, visual training, or in depth tutorials, we have you covered. While we unfortunately can’t afford to provide the service for free, it’s only $19 a month – less than you’d spend on dinner.

    I hope you’ll consider checking it out! In addition to learning a huge variety of new skills, it’s also a fantastic way to say thank you to Nettuts+.


  • Permalink for 'Optimize Your CSS With RequireJS'

    Optimize Your CSS With RequireJS

    Posted: April 16th, 2012, 9:21am MDT by Jeffrey Way

    In this lesson, we’ll review the awesome RequireJS optimizer to handle the process of merging and compressing our stylesheets. While preprocessors continue to become increasingly popular, there are still plenty of folks who stick with regular CSS. In these cases, a solid build tool/process is vital.

    Choose 720p for the clearest video. Closing Thoughts

    If you don’t like the idea of using Require.js, alternatively you might consider Grunt (along with the Grunt-CSS plugin), or Jake.


Planet PHP

  • Permalink for 'GlobIterator: Easy access to specific files'

    GlobIterator: Easy access to specific files

    Posted: April 16th, 2012, 7:34am MDT by Stefan Koopmanschap
    For a project I am working on I needed to iterate over all .xml files in a specific directory. I started out with a DirectoryIterator, then considered I didn't want the XML filtering to take place inside my foreach loop. I decided to add a FilterIterator to the setup, but then felt this was not the right solution either. So I turned to my favorite SPL guru, Joshua Thijssen, to see if I was overseeing some kind of filter-option in the DirectoryIterator. I didn't, but I did oversee something else: GlobIterator.
  • Permalink for 'Triangle Startup Weekend 2nd place winner here!'

    Triangle Startup Weekend 2nd place winner here!

    Posted: April 16th, 2012, 6:48am MDT by Michael Kimsal

    I’ve not been to a startup weekend in at least a couple years (2009?  2008?).  The format’s similar, but the process is (mostly) more polished than it was back then.  Given that, I still wasn’t sure what to expect on Friday evening.  I had an idea I considered pitching, but held off for two reasons.  1 – there were 58 other pitches – everyone got tired towards the end.  2 – I wanted to contribute on something besides my own ideas.  That was actually harder than I thought it might be.  Let me explain…

    Like many of the people there, I have ideas, some I’ve worked on, and having other people help could potentially be a big boon.  But it can also be disaster.  If someone challenges your idea, you take it personally.  It’s human nature, and few can rise above it, especially in the short time frame you’re working under.  Better, I thought, to try to be on the other side of things for a while – contributing and improving someone else’s idea for a change.

    So… I listened to the pitches.  I certainly appreciate that people have interests and passions and problems, I was disappointed that so many of the pitch ideas were … somewhat lame.  Some described personal problems than someone had which a) didn’t resonate with me at all and b) just seemed petty.  These are first world problems we have, when “i can’t decide where to go on vacation” is a problem you promote to a group.  I’m over simplifying here, and reviewing the pitch list just now, I’m being a bit overly harsh, but the “first world problem” mentality just felt overwhelming to me Friday.

    There were only a handful that resonated with me personally, and of those, only one seemed *doable* over a weekend (really, just Saturday) and also didn’t strike me as something where the pitcher would actually want to be in total control and micromanage the project:  Kate Lyndegaard’s pitch on “GPS Data Capture”.  Problem was, I couldn’t find Kate after the pitches to discuss further.  We almost didn’t connect, and I’d felt like going home at that point because so few team ideas felt worth pursuing.  Oh, I also didn’t want to be one person on a team of 12 – I wanted to be on a smaller team.

    I met Kate, and she’d come down with her husband (Simon) and his friend (Matt), and they all wanted to work on it with someone.  I became that someone.  It was an interesting dynamic – a husband/wife team, known colleague, then unknown me.  We also had Daniel on our team for a bit, but he was splitting his design talents with another team.  Daniel also contributed a great (real) use case example video he made with Simon(?) on Saturday morning.  I think this video helped cement our pitch and explain the value proposition immensely.  As much as I’d like to think my pitching skills helped, I think the video did the trick.  ;)

    Back to the story.  We grouped up on Friday night, and discussed the idea in more detail  It was clear Kate had thought a lot about this.  She worked in GIS, had experience with capture/collection processes, and had developed a prototype already.  Ugh.  It was in Flex.  Double ugh.  I’m not a platform bigot as much as I used to be, but my limited experience with Flex is that it’s far more complicated for me to do some things than I expect it to be.  Classic chicken/egg, really, as if I spent years with Flex, I might be faster at it.  As it stood, Kate wasn’t a hardcore dev, and wasn’t completely tied to using the Flex app (she was ‘Flex’ible on that point).  At that point my brain wheels started spinning.

    The core basic platform would be a way to assign people the task of collecting defined (yet customizable) information and associating it with a specific point on a map.  On a mobile device.  That was it.  I had 24 hours to make that happen.  In retrospect, our pitch could have been “Google Maps meets Survey Monkey”, but that trivializes it some, while also bringing the baggage of connotation of both those services with it.

    However, I had to – we had to – convince Kate to let us ‘dumb it down’.  Many of the things she’s been planning relate to ‘high end’ GIS stuff: shape files, kml/kmz, extreme accuracy, etc.  The rest of us were looking at this as a consumerization play on commodity hardware, vs building a tool with professional-grade functionality.  There was a bit of pushback from Kate, but in the end we agreed as a team to explore simpler ideas for the weekend.  This wa

    Truncated by Planet PHP, read more at the original (another 5652 bytes)

  • Permalink for 'Deploying a Symfony2 and Composer app on PagodaBox'

    Deploying a Symfony2 and Composer app on PagodaBox

    Posted: April 16th, 2012, 6:09am MDT by Rafael Dohms

    I have been working on a little pet project and wanted to put it up somewhere to show to a few people how it was going. I wanted something really simple so I decided to give the PHP PaaS solutions a try. Its a very simple Symfony 2.1 based app using Composer for vendor management, so I went on a quest to see what could be done and how.

    I have always liked Orchestra, especially because I know the whole crew, but I was left stranded on how I could run the composer commands I needed after deploy. The feature was not done yet, so I moved onto Pagoda Box, thinking I was going to hit the same wall. I was pleasantly surprised that there was a solution and decided to give it a try.

    It was mostly painless, but a few quirks kept me up late chatting with their excellent and very friendly support staff. So I decided to write up a few line about it.

    Boxfile

    The Boxfile defines all the config for your app and that’s where the magic happens. This is basically the extent of changes you need to make to your application.

    Basic configuration

    Some of the configuration is straight forward, so let’s get them out of the way. Be sure to adjust between app and app_dev accordingly.

        web1:
            name: mysf2site
            document_root: web
            default_gateway: app.php
            index_list: [app.php]
            php_version: 5.3.8
    
    Writable directories

    As soon as you deploy a Symfony app you remember that you need to make the cache and logs folders writable or you will get a very nice blowup in your face. Pagoda let’s you do this but there is a couple thing you should know.

    The writable directories configuration is meant for directories your “Web” role will write into. This means uploads, caching and related events, its does not relate to build steps. During the “build” step of your application (this is when you run Composer), everything is writable, so you don’t need to make your vendor folder writable for example.

    Writable folders are emptied after initial deploy. This means if you decide to make your app folder writable because you have the crazy idea that it will be needed for bootstrap.php.cache, your deploy will give you a nice big empty app directory. So remember to only use this config for the folders that need it. Update: The nice folks at Pagoda explained to me that the “empty folder” effect is only after initial deploy, subsequent deploys don’t empty the directories for obvious reasons (i.e. you can use this for uploads).

    This is what it should look like:

    shared\_writable\_dirs:
      - app/cache
      - app/logs
    
    Extensions

    So it might be a good idea to make sure all the extensions are there, this is very easy, and this is the list i came up with:

        php_extensions:
            - intl
            - mbstring
            - xsl
            - apc
            - mysql
            - pdo_mysql
            - zip
    

    Notice zip, this is very important as Composer depends on this extension or falls back onto unzip, which is not a valid executable in a Pagoda server. The rest is standard Symfony stuff and personal choices.

    The Configuration and Database

    Personally I like to keep my parameters.yml file out of my repositories, to this was a challenge here, how do I create or copy in this configuration or how do i keep my config out of there.

    Getting values into the system was a very nice suggestion on the Pagoda Help site. Using ENV variables you can inject this straight into the Symfony2 parameters.yml file, so i setup my database stuff for now with: SYMFONY__DATABASE__NAME which becomes %database.name% in the yml file. Rinse and repeat for all DB variables and create these in the Dashboard with the proper values.

    But I still needed to write the parameters.yml file to the system, and that’s where afer_build comes in. I needed to write multiple lines, so i cheated and went for a few echo calls.

    Update: It appears you do not even need to have a parameters.yml file, you can go straight from ENV to Symfony as @igorwesome pointed out to me and this article

    </pre>
    after_build:
     - "echo 'parameters:' >> app/config/parameters.yml"
     - "echo ' database_driver: pdo_mysql' >>

    Truncated by Planet PHP, read more at the original (another 3473 bytes)

  • Permalink for 'Introducing: PasswordLib'

    Introducing: PasswordLib

    Posted: April 14th, 2012, 12:30pm MDT by Anthony Ferrara
    Today, I'm proud to announce the immediate availability of a new password hashing library for PHP: PasswordLib. The project is a spin-off of another that I started about a year ago, CryptLib. I was unable to find a clean solution to a few problems in CryptLib, so dev work stalled for a while. I realized recently that the password hashing functionality was complete, so if I stripped out the incomplete parts, it would still be a very useful library. And so PasswordLib was born.Read more »

Nettuts+

  • Permalink for 'Nettuts+ Quiz #12: Quirky HTML Tags'

    Nettuts+ Quiz #12: Quirky HTML Tags

    Posted: April 13th, 2012, 2:29pm MDT by Siddharth

    Taking a break from the relatively technical focus of the past few quizzes, we’re going to do something very offbeat today. Yes, Offbeat with a capital O. Be it front end or back end programming, I’m sure you’re working with HTML tags every day. But as the saying goes, can you ‘catch ‘em all?’ Or rather, can you figure out what these rarely used HTML tags do?

    I can already hear you chuckling with mirth, grasshopper. I’ve added a few deprecated tags just to keep you on your toes. Get everything right and prove that your HTML-fu is strong!


    $(document).ready(function(){ $('#quiz-container').jquizzy({ questions: init.questions, resultComments: init.resultComments, twitterStatus: 'Woo! I scored {score} on the Nettuts quiz on quirky HTML tags. Give it a shot!', twitterImage: 'http://d2o0t5hpnwv4c1.cloudfront.net/jquizzy-1.0/img/share.png', twitterUsername: 'envatowebdev', splashImage: 'http://d2o0t5hpnwv4c1.cloudfront.net/1152_quiz12/nettuts.png', }); });


Planet PHP

  • Permalink for 'Setting millisecond-timeouts with curl'

    Setting millisecond-timeouts with curl

    Posted: April 13th, 2012, 6:41am MDT by Stefan Koopmanschap
    I'm currently working on a project where I need to curl to an external server to get some information. If this takes too long, I fall back to a local solution. The timeout for this should be really, really low, so we decided on a 250ms timeout. While testing with this timeout feature, for some reason it *always* used the local fallback. I couldn't figure out why, as when I did a manual curl to the external server, it took 50ms at maximum, way below the timeout value. Turns out it is a problem with libcurl.
  • Permalink for 'Decoupled Content Management on tour'

    Decoupled Content Management on tour

    Posted: April 13th, 2012, 4:14am MDT by Henri Bergius

    It seems the idea of Decoupling Content Management is gaining momentum. On the user interface side, many projects have already adopted the VIE interaction framework and widgets from Create, and in the content repository space projects like PHPCR move forward and there are also interesting new ideas like Apache Oak.

    While much of this has been made possible by the IKS project, it is also great to see the wider CMS community getting more active in the space. Part of this momentum is also apparent in how many communities want to learn more about these ideas.

    Here are some upcoming events where decoupled CMS will be present:

    If your community is interested in learning more, get in touch or follow my tweets from these events. And obviously I'm looking forward to meeting many of you in these events.

  • Permalink for 'PHP 5.4.1RC2 Released for Testing'

    PHP 5.4.1RC2 Released for Testing

    Posted: April 12th, 2012, 4:00pm MDT by PHP: Hypertext Preprocessor
    The PHP development team would like to announce the 2nd release candidate of PHP 5.4.1. Windows binaries can be downloaded from the Windows QA site. THIS IS A RELEASE CANDIDATE - DO NOT USE IT IN PRODUCTION! This is the 2nd release candidate. The release candidate phase is intended as a period of bug fixing prior to the stable release. The release candidate fixes a critical issue when using the internal classes in multiple threads. A complete list of changes since the last release candidate can be found in the NEWS file. Please help us to identify bugs in order to ensure that the release is solid and all things behave as expected by taking the time to test this release candidate against your code base and reporting any problems that you encounter to the QA mailing list and/or the PHP bug tracker. PHP 5.4.1 final will be released on April 26.
  • Permalink for 'PHP: Innocent Villagefolk or a Pillagin’ Pirate?'

    PHP: Innocent Villagefolk or a Pillagin’ Pirate?

    Posted: April 12th, 2012, 9:28am MDT by Pádraic Brady


    A stereotypical caricature of a pirate.

    This is a train of thought article (i.e. it may make sense…or not). You’ve been warned in advance. The CL;DR will be posted to Twitter when Hell freezes over, pigs fly, and Hollywood makes an ensemble casted DC Universe movie. This is what happens when you have a laptop, an editor, a train ride home, and have just realised that the wifi connection is not working.

    In PHP, we’re well insulated from what happens in other programming languages. This is not by accident – mentioning PHP while among a crowd of Java, Ruby, Python or Perl programmers is liable to result in a heated argument, several fistfights and one dead PHP programmer. Death by mobbing is not a pretty way to go. I’m sure a few of us have been there – at a web conference where people dismiss PHP out of hand as a kiddie toy for the weak minded and demented. When everyone around you starts nodding, remember to make yourself as inconspicuous as possible and request armed backup from the local PUG.

    Of course, PHP programmers all know that the other programming languages are just jealous – PHP has no true OOP model, it’s ugly as sin, can’t figure out which parameter order is right, and is several years behind the curve in adopting best practices but the damn thing remains extremely popular, keeps getting faster, has the best reference manual ever invented, more frameworks than grains of sand on a beach, and in recent years has become a hotbed of innovative libraries now that PEAR and its messy aftermath have been displaced by Github. It’s sickening.

    I often wonder why that is. I could go with the usual arguments – PHP is easy to learn, very effective, yada yada yada. Those are the boring reasons we try very hard to believe in. Ruby is easy to learn, very effective, and has even more yadas to go around. It’s still sitting at 11 on the Tiobe Index to PHP’s 6.

    What’s fascinating about some programming languages is their reaction to and life after maturity. PHP is an immature programming language which pretends to be mature (to earn Enterprise cookies) but otherwise couldn’t give a toss. I don’t mean that in a bad sense. PHP continues to exude a sense of adventure as it playfully steals ideas left, right and center from its peers. Most of our foremost advances are “borrowed” years after their adoption elsewhere. What PHP excels at is tireless consumption. Marathon races make one hungry and we can’t help but notice the feasts being exposed by Rubyland or Pythonville as they do their best to sprint past us. Without that thieving spirit, PHP would long since have entered obscurity as a quaint html oriented scripting language used by college students to build cheap websites with flashing text and under construction GIFs.

    To me, PHP is a rogue. If we were playing an RPG, PHP would have pointy ears, a cloak, a couple of daggers and as many lockpicks as it could fit in its inventory (leaving sufficient room for liberated loot, of course). Ruby will never see us coming…our sneak skill is epic. PHP figured out how to keep the W key depressed while crouched in a corner in Elder Scrolls: Morrowind before the game was even designed.

    I’m sure this comes across as being a bit humourous, but is it? Sometimes when I hear about PHP being innovative I almost crack up on the spot from disbelief. As PHP developers we’re not often (as in never) in the limelight generating new programming paradigms and practices – we’re most likely to be found connecting the dots between PHP and some novel idea we stumbled across elsewhere. Our strength lies in our ability to connect the dots sever

    Truncated by Planet PHP, read more at the original (another 3941 bytes)

  • Permalink for 'Lack of fundamentals in web programming education'

    Lack of fundamentals in web programming education

    Posted: April 12th, 2012, 5:42am MDT by Michael Kimsal

    Wasn’t sure what to name this entry, but have had a few discussions with some people over the past month or so about their experiences.  All of them were finishing up “web development” degree programs (under somewhat different nams) at institutions in the area, and all were talking about looking for jobs.

    I was dismayed (but not necessarily shocked) at how little understanding they had about the basics trade skills that are necessary for most real world webdev work.  Now, I’m obviously passing my own judgement here, but bear with me.

    Task/project breakdown – the idea of taking a project requirement and breaking it down in to written steps – whether inline documentation, external ‘requirements’ doc, or tracking in an issue database.  This was not something that any of these people indicated was covered in their classes or coursework.  Whether you’re working alone or on a team, this is a fundamental basic skill that is missing in most jr devs I meet – loading an editor and starting to code is the default mode.

    Version control – none of the people I spoke with had any version control in their class work.  One knew *of* version control, but his internship mentor didn’t feel it was useful because there was just two of them working, and they could easily schedule time to edit the same files on an FTP server without stepping on each other’s changes.  I don’t expect someone to be an svn master or git guru – the specific technologies may change.  One company may use clearcase, another MS TFS, another git, and so on.  The nuances of each will be different, and the dynamics of the projects will be different.  But the core value of using version control, even on projects for yourself, isn’t even being mentioned in some of these courses.

    Testing – this is going to be different based on the project, of course, but a ‘web degree program’ that doesn’t expose students to some testing tools – selenium being the one I’d default do – is doing a poor job of equipping these students to be proficient in their craft.  Put another way, students from a degree program that exposes them to testing concepts will produce better, more desirable/employable students.  However, if *no* programs do this, then the bar is uniformly low across the board.  Exposing students to the concept of unit testing their code – xUnit style – and understanding that code is more testable when it has fewer hard coded stuff in it – these are things that should be being taught.
    Note that, excepting for a ref to selenium, I’m not really advocating a particular technology (and not really even in that case), but concepts.  The need for Android developers may be gone in 5 years (at least, Android as we know it know).  The need for “PHP5 developers” may be radically lower in 5 years.  The need for Ruby3 developers may be through the roof in 5 years, and there’s not even any degree programs *talking* about Ruby3, because it doesn’t exist yet.  The need for developers who understand testing and version control will definitely be strong in 5 years.  It was strong 10 years ago, although the tools were different.  It will be strong 10 years from now.

    These universal lifelong skills that are *fundamental* to the practice of good software development are not seeming to be taught in software development courses at a college/university level.  Some programs will have an emphasis on data structure and algorithms – certainly nothing *wrong* with them – they’re universal truisms too.  But there seems to be an ignoring of the realities of day to day work.  And I’m not just talking about the 4 year ‘big league’ schools – local community colleges that traditionally have a more practical emphasis on ‘vocational skills’ are seemingly ignoring this.

    I don’t remember any of these skills being in course descriptions 20 years ago in my university, and I’m not seeing much reference to the few colleges I searched about for recently, and certainly not getting this from talking to people about to graduate from “web developer” degree programs.  Is this your experience too?  Or am I just getting a statistically skewed sample?

Nettuts+

  • Permalink for 'Toying With the HTML5 FileSystem API'

    Toying With the HTML5 FileSystem API

    Posted: April 11th, 2012, 10:11am MDT by Ivaylo Gerchev

    HTML5 provides us with a whole crop of new possibilities, such as drawing with canvas, implementing multimedia with the audio and video APIs, and so on. One of these tools, which is still relatively new, is the File System API. It gives us access to a sandboxed section of the user’s local file system, thus filling the gap between desktop and web applications even further! In today’s tutorial, we’ll go through the basics of this new and exciting API, exploring the most common filesystem tasks. Let’s get started!

    Introduction

    No longer do we need to download and install a given piece of software in order to use it. Simply a web browser and an internet connection gives us the ability to use any web application, anytime, anywhere, and on any platform.

    In short, web apps are cool; but, compared to desktop apps, they still have one significant weakness: they don’t have a way to interact and organize data into a structured hierarchy of folders – a real filesystem. Fortunately, with the new Filesystem API, this can be changed. This API gives web applications controlled access to a private local filesystem “sandbox,” in which they can write and read files, create and list directories, and so on. Although at the time of this writing only Google’s Chrome browser supports the “full” implementation of the Filesystem API, it still deserves to be studied as a powerful and convenient form of local storage.

    Can I Use Support}

    The Filesystem API comes in two different versions. The asynchronous API, which is useful for normal applications, and the synchronous API, reserved for use with web workers. For the purposes of this tutorial, we will exclusively explore the asynchronous version of the API.

    Step 1 – Getting Started

    Your first step is to obtain access to the HTML5 Filesystem by requesting a LocalFile System object, using the window.requestFileSystem() global method:

    window.requestFileSystem(type, size, successCallback, opt_errorCallback)

    There’s no way for a web application to “break out” beyond the local root directory.

    As the first two parameters, you specify the lifetime and size of the filesystem you want. A PERSISTENT filesystem is suitable for web apps that want to store user data permanently. The browser won’t delete it, except at the user’s explicit request. A TEMPORARY filesystem is appropriate for web apps that want to cache data, but can still operate if the web browser deletes the filesystem. The size of the filesystem is specified in bytes and should be a reasonable upper bound on the amount of data you need to store.

    The third parameter is a callback function that is triggered when the user agent successfully provides a filesystem. Its argument is a FileSystem object. And, lastly, we can add an optional callback function, which is called when an error occurs, or the request for a filesystem is denied. Its argument is a FileError object. Although this parameter is optional, it’s always a good idea to catch errors for users, as there are a number of places where things can go wrong.

    The filesystem obtained with these functions depends on the origin of the containing document. All documents or web apps from the same origin (host, port, and protocol) share a filesystem. Two documents or applications from different origins have completely distinct and disjoint filesystems. A filesystem is restricted to a single application and cannot access another application’s stored data. It’s also isolated from the rest of the files on the user’s hard drive, which is a good thing: there’s no way for a web application to “break out” beyond the local root directory or otherwise access arbitrary files.

    Let’s review an example:

    window.requestFileSystem  = window.requestFileSystem || window.webkitRequestFileSystem;
    
    window.requestFileSystem(window.TEMPORARY, 5*1024*1024, initFS, errorHandler);
    
    function initFS(fs){
      alert("Welcome to Filesystem! It's showtime :)"); // Just to check if everything is OK :)
      // place the functions you will learn bellow here
    }
    
    function errorHandler(){
      console.log('An error occured');
    }
    

    This creates a temporary filesystem with 5MB of storage. It then provides a success callback function, which we will use to operate our filesystem. And, of course, an error handler is also added – just in case something goes wrong. Here, the errorHandler() function is too generic. So if you want, you can create a slightly optimized version, which gives the reader a more descriptive error message:

    function errorHandler(err){
     var msg = 'An error occured: ';
    
      switch (err.code) {
        case FileError.NOT_FOUND_ERR:
          msg += 'File or directory not found';
          break;
    
        case FileError.NOT_READABLE_ERR:
          msg += 'File or directory not readable';
          break;
    
        case FileError.PATH_EXISTS_ERR:
          msg += 'File or directory already exists';
          break;
    
        case FileError.TYPE_MISMATCH_ERR:
          msg += 'Invalid filetype';
          break;
    
        default:
          msg += 'Unknown Error';
          break;
      };
    
     console.log(msg);
    };

    The filesystem object you obtain has a name (a unique name for the filesystem, assigned by the browser) and root property that refers to the root directory of the filesystem. This is a DirectoryEntry object, and it may have nested directories that are themselves represented by DirectoryEntry objects. Each directory in the file system may contain files, represented by FileEntry objects. The DirectoryEntry object defines methods for obtaining DirectoryEntry and FileEntry objects by pathname (they will optionally create new directories or files if you specify a name that doesn’t exist). DirectoryEntry also defines a createReader() factory method that returns a DirectoryReader object for listing the contents of a directory. The FileEntry class defines a method for obtaining the File object (a Blob) that represents the contents of a file. You can then use a FileReader object to read the file. FileEntry defines another method to return a FileWriter object that you can use to write content into a file.

    Phhew…sounds complicated? Don’t worry. Everything will become clearer as we progress through the examples below.

    Step 2 – Working With Directories

    Obviously, the first thing you need to create in a filesystem is some buckets, or directories. Although the root directory already exists, you don’t want to place all of your files there. Directories are created by the DirectoryEntry object. In the following example, we create a directory, called Documents, within the root directory:

    fs.root.getDirectory('Documents', {create: true}, function(dirEntry) {
      alert('You have just created the ' + dirEntry.name + ' directory.');
    }, errorHandler);

    The getDirectory() method is used both to read and create directories. As the first parameter, you can pass either a name or path as the directory to look up or create. We set the second argument to true, because we’re attempting to create a directory – not read an existing one. And at the end, we add an error callback.

    So far, so good. We have a directory; let’s now add a subdirectory. The function is exactly the same with one difference: we change the first argument from ‘Documents’ to ‘Documents/Music’. Easy enough; but what if you want to create a subfolder, Sky, with two parent folders, Images and Nature, inside the Documents folder? If you type ‘Documents/Images/Nature/Sky‘ for the path argument, you will receive an error, because you can’t create a directory, when its immediate parent does not exist. A solution for this is to create each folder one by one: Images inside Documents, Nature inside Images, and then Sky inside Nature. But this is a very slow and inconvenient process. There is a better solution: to create a function which will create all necessary folders automatically.

    function createDir(rootDir, folders) {
      rootDir.getDirectory(folders[0], {create: true}, function(dirEntry) {
        if (folders.length) {
          createDir(dirEntry, folders.slice(1));
        }
      }, errorHandler);
    };
    
    createDir(fs.root, 'Documents/Images/Nature/Sky/'.split('/'));
    

    With this little trick, all we need to do is provide a full path representing the folders which we want to create. Now, the Sky directory is successfully created, and you can create other files or directories within it.

    Now it’s time to check what we have in our filesystem. We’ll create a DirectoryReader object, and use the readEntries() method to read the content of the directory.

    fs.root.getDirectory('Documents', {}, function(dirEntry){<br>
      var dirReader = dirEntry.createReader();
      dirReader.readEntries(function(entries) {<br>
        for(var i = 0; i < entries.length; i++) {
          var entry = entries[i];
          if (entry.isDirectory){
            console.log('Directory: ' + entry.fullPath);
          }
          else if (entry.isFile){
            console.log('File: ' + entry.fullPath);
          }
        }
    
      }, errorHandler);
    }, errorHandler);
    

    In the code above, the isDirectory and isFile properties are used in order to obtain a different output for directories and files, respectively. Additionally, we use the fullPath property in order to get the full path of the entry, instead of its name only.

    There are two ways to remove a DirectoryEntry from the filesystem: remove() and removeRecursively(). The first one removes a given directory only if it is empty. Otherwise, you’ll receive an error.

    fs.root.getDirectory('Documents/Music', {}, function(dirEntry) {
      dirEntry.remove(function(){
        console.log('Directory successfully removed.');
      }, errorHandler);
    }, errorHandler);

    If the Music folder has files within it, then you need to use the second method, which recursively deletes the directory and all of its contents.

    fs.root.getDirectory('Documents/Music', {}, function(dirEntry) {
      dirEntry.removeRecursively(function(){
        console.log('Directory successufully removed.');
      }, errorHandler);
    }, errorHandler);
    Step 3 – Working With Files

    Now that we know how to create directories, it’s time to populate them with files!

    The following example creates an empty test.txt in the root directory:

    fs.root.getFile('test.txt', {create: true, exclusive: true}, function(fileEntry) {
      alert('A file ' + fileEntry.name + ' was created successfully.');
    }, errorHandler);

    The first argument to getFile() can be an absolute or relative path, but it must be valid. For instance, it is an error to attempt to create a file, when its immediate parent does not exist. The second argument is an object literal, describing the function’s behavior if the file does not exist. In this example, create: true creates the file if it doesn’t exist and throws an error if it does (exclusive: true). Otherwise, if create: false, the file is simply fetched and returned.

    Having an empty file is not very useful, though; so let’s add some content inside. We can use the FileWriter object for this.

    fs.root.getFile('test.txt', {create: false}, function(fileEntry) {
      fileEntry.createWriter(function(fileWriter) {
        window.BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder;
        var bb = new BlobBuilder();
        bb.append('Filesystem API is awesome!');
        fileWriter.write(bb.getBlob('text/plain'));
      }, errorHandler);
    }, errorHandler);
    

    Above, we retrieve the test.txt file, and create a FileWriter object for it. We then append content to it by creating a new BlobBuilder object and using the write() method of FileWriter.

    Calling getFile() only retrieves a FileEntry. It does not return the contents of the file. So, if we want to read the content of the file, we need to use the File object and the FileReader object.

    fs.root.getFile('test.txt', {}, function(fileEntry) {
      fileEntry.file(function(file) {
        var reader = new FileReader();
        reader.onloadend = function(e) {
          alert(this.result);
        };
        reader.readAsText(file);
      }, errorHandler);
    }, errorHandler);

    We have written some content to our file, but what if desire to add more at a later date? To append data to an existing file, the FileWriter is used once again. We can reposition the writer to the end of the file, using the seek() method. seek accepts a byte offset as an argument, and sets the file writer’s position to that offset.

    fs.root.getFile('test.txt', {create: false}, function(fileEntry) {
      fileEntry.createWriter(function(fileWriter) {
        fileWriter.seek(fileWriter.length);
        window.BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder;
        var bb = new BlobBuilder();
        bb.append('Yes, it is!');
        fileWriter.write(bb.getBlob('text/plain'));
      }, errorHandler);
    }, errorHandler);
    

    To remove a file from the filesystem, simply call entry.remove(). The first argument to this method is a zero-parameter callback function, which is called when the file is successfully deleted. The second is an optional error callback if any errors occur.

    fs.root.getFile('test.txt', {create: false}, function(fileEntry) {
      fileEntry.remove(function() {
        console.log('File successufully removed.');
      }, errorHandler);
    }, errorHandler);
    
    Step 4 – Manipulating Files and Directories

    FileEntry and DirectoryEntry share the same API methods for copying, moving and renaming entries. There are two methods you can use for these operations: copyTo() and moveTo(). They both accept the exact same parameters:

    copyTo(parentDirEntry, opt_newName, opt_successCallback, opt_errorCallback);
    
    moveTo(parentDirEntry, opt_newName, opt_successCallback, opt_errorCallback);
    

    The first parameter is the parent folder to move/copy the entry into. The second is an optional new name to give the moved/copied entry, which is actually required when you copy an entry in the same folder; otherwise you will get an error. The third and fourth parameters were explained previously.

    Let’s review some simple examples. In the following one, we copy the file test.txt from the root to the Documents directory.

    function copy(currDir, srcEntry, destDir) {
      currDir.getFile(srcEntry, {}, function(fileEntry) {
        currDir.getDirectory(destDir, {}, function(dirEntry) {
          fileEntry.copyTo(dirEntry);
        }, errorHandler);
      }, errorHandler);
    }
    
    copy(fs.root, 'test.txt', 'Documents/');

    This next example moves test.txt to Documents, instead of copying it:

    function move(currDir, srcEntry, dirName) {
      currDir.getFile(srcEntry, {}, function(fileEntry) {
        currDir.getDirectory(dirName, {}, function(dirEntry) {
          fileEntry.moveTo(dirEntry);
        }, errorHandler);
      }, errorHandler);
    }
    
    move(fs.root, 'test.txt', 'Documents/');

    The following example renames test.txt to text.txt:

    function rename(currDir, srcEntry, newName) {
      currDir.getFile(srcEntry, {}, function(fileEntry) {
        fileEntry.moveTo(currDir, newName);
      }, errorHandler);
    }
    
    rename(fs.root, 'test.txt', 'text.txt');
    Learn More

    In this introductory tutorial, we’ve only scratched the surface of the different filesystem interfaces. If you want to learn more and dig deeper into Filesystem API, you should refer to the W3C specifications specifications:

    Now that you have a basic understanding of what the Filesystem API is, and how it can be used, it should be considerably easier to understand the API documentation, which can be a bit confusing at first sight.

    Conclusion

    The Filesystem API is a powerful and easy to use technology, which provides web developers with a whole crop of new possibilities when building web applications. Admittedly, it’s still quite new and not widely supported by all major browsers, but this will certainly change in the future. You might as well get a head start!


Planet PHP

  • Permalink for 'Varnish and saint mode: "no backend connection"'

    Varnish and saint mode: "no backend connection"

    Posted: April 11th, 2012, 5:33am MDT by Gaylord Aulke

    Recently we implemented some quite sophisticated caching mechanisms using varnish. In addition to just caching, backend errors and invalidated pages had to be handled gracefully whenever possible so we implemented grace mode, saint mode and backend probes.

    Everything was working great during development but then we did some real performance testing... The results really gave us some headache because at some point we noticed the following in varnishlog from time to time:

     11 FetchError   c no backend connection

    This error appears when (obviously) no backend is available/healthy. The problem: The health checks at that time reported that the backends were alive. Googling didn't help here as this error didn't seem to be one of the standard issues. So i finally found myself digging in the C code and after some while i found out what was going on.

    The reason we got this error was a combination of a not-yet completely finished backend and the (poorly documented) saint mode:

    We still had quite an amount of 500s returning from the backends because of database inconsistencies and general errors. Now the saint mode maintains a blacklist of URLs per backend. When searching for a backend to handle a request it first checks against this list to see if the URL is blacklisted for specific backends. Varnish will only request a backend that is not blacklisted for the given URL. This is documented.

    The undocumented bit: In order to keep the blacklist compact, Varnish saint mode will blacklist a complete backend server silently (!) once a specific number of blacklisted URLs for this backend is exceeded.

    If you get frequent 500s from different URLs of all your backends, all will be marked unhealthy over time, resulting in a "no backend connection" error for subsequent requests.

    The quick fix was to raise the URL blacklist size (saintmode_threshold). Since this results in longer URL blacklists and thus more memory consumption and longer lookup time, this is not a sustainable solution for production systems. The real solution was to fix all the errors in the beackend.

  • Permalink for 'PHP Sucks! But I Like It!'

    PHP Sucks! But I Like It!

    Posted: April 10th, 2012, 2:30pm MDT by Anthony Ferrara
    I read a rather interesting post yesterday called PHP: a fractal of bad design. It's been getting a lot of traffic among the PHP community lately because it's rather inflammatory. But to be honest, it does make a lot of really good points. It also makes a lot of mistakes and misses a bigger picture.Read more »

Nettuts+

  • Permalink for 'Unveiling the All-New Tuts+ Hub'

    Unveiling the All-New Tuts+ Hub

    Posted: April 10th, 2012, 2:05pm MDT by David Appleyard

    Over the past few weeks, we’ve been working hard behind the scenes to create a central place for our Tuts+ readers to call “home”. Somewhere that shows you the latest content from across all our sites, allows you to filter only those tutorials that interest you, and shares a few statistics about the Tuts+ network.

    Today, we’re very excited to introduce the Tuts+ Hub — read on to find out more about it!

    All Our Latest Tutorials in One Place

    The Tuts+ Hub is a new way to see all the latest content across our whole network. Any new tutorials that have been published since your last visit will be given a “New” banner, and you can quickly filter out the sites that don’t interest you — just toggle the checkboxes at the top of the screen to show/hide content for each site.

    Tuts+ Hub

    We’re also showcasing all our new Tuts+ Premium tutorials — these are shown with a yellow border, so it’s worth keeping an eye out for these if you’re one of our awesome Tuts+ Premium members!

    A Handful of Statistics

    We also thought it would be fun to share a few of our statistics with you. Did you know we’ve published over 11,500 tutorials? Or that we’re approaching half a million comments across the network? It’s a fun way to keep an eye on how Tuts+ is growing (and these stats are updated every day).

    Tuts+ Hub What Do You Think?

    I’d love to hear your feedback on Tuts+ Hub, and any thoughts or comments on what works well/what you’d like to see improved. We’re really happy with how the project turned out and I think you’re going to love it!

    Thanks for being one of our readers and, if you’ve somehow resisted all the way down to this point, head over and check out the Tuts+ Hub!


Planet PHP

  • Permalink for 'It’s About The Customer, Stupid'

    It’s About The Customer, Stupid

    Posted: April 10th, 2012, 7:18am MDT by Brandon Savage
    Another day, another article posted on Hacker News that describes PHP’s failures and complexities as though they actually mattered. The truth is, only programmers care about languages. Only programmers care about the methods, routines, algorithms and organization of programming languages. Only programmers argue about coding styles, whether white space or brackets is the best way [...]

Nettuts+

  • Permalink for 'Techniques for Test-Driving Your JavaScript: New on Premium'

    Techniques for Test-Driving Your JavaScript: New on Premium

    Posted: April 9th, 2012, 2:23pm MDT by Jeffrey Way

    In this hands-on Premium screencast, from scratch, we’ll use test-driven development to build a jQuery plugin. Along the way, we’ll take advantage of Grunt, QUnit, and GitHub to build, test, and distribute our plugin, respectively. If the idea of testing in JavaScript is still foreign to you, you won’t find a better introduction!

    Become a Tuts+ Premium member to watch this 45 minute screencast, as well as hundreds of other advanced videos, tutorials, and courses.

    You’ll Learn How to:
    • Use Ben Alman’s Grunt build tool to expedite the process of generating and building new plugins
    • Take a test-driven approach to creating jQuery plugins – using QUnit
    • Distribute code in seconds with GitHub

    Of course, you’re likely to pick up a variety of other neat tips and tricks along the way!

    Tuts+ Premium

    The recently re-launched Tuts+ Premium is a service that provides top-tier training in a variety of creative fields. Whether you prefer books, visual training, or in depth tutorials, we have you covered. While we unfortunately can’t afford to provide the service for free, it’s only $19 a month – less than you’d spend on dinner.

    I hope you’ll consider checking it out! In addition to learning a huge variety of new skills, it’s also a fantastic way to say thank you to Nettuts+.


  • Permalink for 'Better CoffeeScript Testing With Mocha'

    Better CoffeeScript Testing With Mocha

    Posted: April 9th, 2012, 1:54pm MDT by Andrew Burgess

    Recently, I’ve been doing a considerable amount of CoffeeScript work. One problem I ran into early-on was testing: I didn’t want to have to manually convert my CoffeeScript to JavaScript before I could test it. Instead, I wanted to test from CoffeeScript directly. How’d I end up doing it? Read on to find out!

    You’ll need to have Node.js and Node Package Manager installed.

    Before we continue on, I’ll point out that you need to have a decent knowledge of CoffeeScript for this tutorial; I won’t be explaining the bits and pieces here. If you’re interested in CoffeeScript, you should check out the CoffeeScript tuts available here on Nettuts+, or the CoffeeScript documentation.

    Additionally, you’ll need to have Node.js and the Node Package Manager (npm) installed for this tutorial. If you don’t have ‘em installed, no worries: head over to nodejs.org and download the installer for your platform; then, well, install it!

    Meeting Mocha and Chai

    We’ll be building the beginnings of a todo list application (cliché, I know). These will be CoffeeScript classes. Then, we’ll write some tests with Mocha and Chai to test that functionality.

    Why both Mocha and Chai? Well, Mocha is a testing framework, but it doesn’t include the actual assertions component. That might sound strange: after all, there isn’t much more to a testing library, is there? Well, there is, in Mocha’s case. The features that brought me to the library are two-fold: the ability to run tests from the command line (instead of having an HTML page to run them in the browser), and the ability to run test in CoffeeScripts, without having to convert that code to JavaScript (as least manually: Mocha does it behind the scenes). There are other features, too, that I won’t be talking about here, including:

    • You can easily test asynchronous code.
    • You can watch for especially slow tests.
    • You can output the results in a number of different formats.

    And on, and on. See more at the Mocha home page. To install Mocha simply run npm install -g mocha, and you’re set.

    As for Chai: it’s a great assertion library that offers interfaces for doing both BDD and TDD; you can use it both in the browser or on the command line via node, which is how we’ll use it today. Install it for Node, via npm install -g chai.

    Now that we have our libraries installed, let’s start writing some code.

    Setting Up Our Project

    Let’s begin by setting up a mini project. Create a project folder. Then, create two more folders in that one: src, and test. Our CoffeeScript code will go in the src folder, and our tests will go in, you guessed it, the tests folder. Mocha looks for a test folder by default, so by doing this, we’ll save ourselves some typing later.

    Mocha looks for a test folder by default.

    We’re going to create two CoffeeScript classes: Task, which will be a todo item, and TaskList, which will be a list of todo items (yes, it’s more than an array). We’ll put them both in the src/task.coffee file. Then, the tests for this will be in test/taskTest.coffee. Of course, we could split ‘em into their own files, but we’re just not going to do that today.

    We have to start by importing the Chai library and enabling the BDD syntax. Here’s how:

    chai = require 'chai'
    chai.should()

    By calling the chai.should method, we’re actually adding a should property to Object.prototype. This allows us to write tests that read like this:

    task.name.should.equal "some string"

    If you prefer the TDD syntax, you can do this:

    expect = chai.expect

    … which allows you to write tests like this:

    expect(task.name).to.equal "some string"

    We’ll actually have to use both of these, as you’ll see; however, we’ll use the BDD syntax as much as possible.

    Now we’ll need to import our Task and TaskList classes:

    {TaskList, List} = require '../src/task'

    If you aren’t familiar with this syntax, that’s CoffeeScript’s destructured assignment at work, as well as some of its object literal sugar. Basically, our require call returns an object with two properties, which are our classes. This line pulls them out of that object and gives us two variables named Task and TaskList, each of which points to the respective class.

    Writing Our First Tests

    Great! Now, how about a test? The beauty of the Mocha syntax is that its blocks (describe and it) are identical to Jasmine’s (both being very similar to RSpec). Here’s our first test:

    describe 'Task instance', ->
    	task1 = task2 = null
    	it 'should have a name', ->
    		task1 = new Task 'feed the cat'
    		task1.name.should.equal 'feed the cat'

    We start with a describe call: all these tests are for a Test instance. By setting test1 = test2 = null outside our individual tests, we can use those values for multiple tests.

    Then, in our first test, we’re simply creating a task and checking to see that its name property has the correct value. Before writing the code for this, let’s add two more tests:

    it 'should be initially incomplete', ->
    	task1.status.should.equal 'incomplete'
    it 'should be able to be completed', ->
    	task1.complete().should.be.true
    	task1.status.should.equal 'complete'

    Ok, let’s run these tests to make sure they’re failing. To do this, let’s open a command prompt and cd to your project folder. Then, run this command:

    mocha --compilers coffee:coffee-script

    Mocha doesn’t check for CoffeeScript by default, so we have to use the --compilers flag to tell Mocha what compiler to use if it finds a file with the coffee file extension. You should get errors that look like this:

    If, instead of seeing that, you get the error Cannot find module '../src/task', it’s because your src/task.coffee file doesn’t exist yet. Make said file, and you should get said error.

    Coding Our First Features

    Well, now that we have failing tests, it’s time to write the code, correct? Open that src/task.coffee file and let’s get cracking.

    class Task
    	constructor: (@name) ->

    Just this is enough to get our first test passing. If you aren’t familiar with that parameter syntax, that just sets whatever value was passed to new Task to the @name (or this.name) property. However, let’s add another line to that constructor:

    @status = 'incomplete'

    That’s good. Now, head back to the terminal and re-run our tests. You’ll find that—wait a second, nothing’s changed! Why aren’t our first two tests passing?

    A simple problem, actually. Because the CoffeeScript compiler wraps the code in each file in a IIFE (or, a self-invoking anonymous function), we need to “export” anything we want to be accessible from other files. In the browser, you’d do something like window.Whatever = Whatever. For Node, you can use either global or exports. We’ll be using exports, since 1) that’s considered best practice, and 2) that’s what we prepared for when setting up our tests (remember our require call?). Therefore, at the end of our task.coffee file, add this:

    root = exports ? window
    root.Task = Task

    With that in place, you should find that two of our three tests are now passing:

    To get the last test to pass, we’ll have to add a complete method. Try this:

    complete: ->
    	@status = 'complete'
    	true

    Now, all tests pass:

    Now’s a good time to mention that Mocha has a number of different reports: these are just different ways to output the test results. You can run mocha --reporters to see your options:

    By default, Mocha uses the dot reporter. However, I prefer the spec reporter, so I tack -R spec on the end of command (-R is the reporter-setting flag).

    Adding a Feature

    Let’s add a feature to our Task class: we’ll let tasks be dependent on other tasks. If the “parent” task isn’t completed, the “child” task can’t be done. We’ll keep this feature simple and allow tasks to have only one sub-task. We also won’t check for recursiveness, so while it will be possible to set two tasks to be the parent and child of each other, it will render both tasks incomplete-able.

    Tests first!

    it 'should be able to be dependent on another task', ->
    	task1 = new Task 'wash dishes'
    	task2 = new Task 'dry dishes'
    
    	task2.dependsOn task1
    
    	task2.status.should.equal 'dependent'
    	task2.parent.should.equal task1
    	task1.child.should.equal task2
    
    it 'should refuse completion it is dependent on an uncompleted task', ->
    	(-> task2.complete()).should.throw "Dependent task 'wash dishes' is not completed."

    Task instances are going to have a dependsOn method, which tasks the task that will become their parent. Tasks that have a parent task should have a status of “dependent.” Also, both tasks get either a parent or child property that points to the appropriate task instance.

    In the second test there, we say that a task with an incomplete parent task should throw an error when its complete method is called. Notice how test syntax works: we need to call should off of a function, and not the result of the function: therefore, we wrap the function in parentheses. This way, the test library can call the function itself and check for the error.

    Run those tests and you’ll see that both fail. Coding time!

    dependsOn: (@parent) ->
    	@parent.child = @
    	@status = 'dependent'

    Again, very simple: we just set the task parameter to the parent task, and give it a child property which points to this task instance. Then, we set the status of this task to be “dependent.”

    If you run this now, you’ll see that one of our tests is passing, but the second isn’t: that’s because our complete method doesn’t check for an uncompleted parent task. Let’s change that.

    complete: ->
    	if @parent? and @parent.status isnt 'completed'
    		throw "Dependent task '#{@parent.name}' is not completed."
    	@status = 'complete'
    	true

    Here’s the completed complete method: if there’s a parent task, and it isn’t completed, we throw an error. Otherwise, we complete the task. Now, all tests should pass.

    Building the TaskList

    Next, we’ll build the TaskList class. Again, we’ll start with a test:

    describe 'TaskList', ->
        taskList = null
        it 'should start with no tasks', ->
            taskList = new TaskList
            taskList.tasks.length.should.equal 0
            taskList.length.should.equal 0

    This is old-hat to you by now: we’re creating a TaskList object and checking its tasks and length properties to makes sure their both at zero. As you might guess, tasks is an array that holds the tasks, while length is just a handy property that we’ll update when adding or removing tasks; it just saves us from having to write list.tasks.length.

    To make this test pass, we’ll make this constructor:

    class TaskList
    	constructor: () ->
    		@tasks = []
    		@length = 0

    Good start, and that gets our test passing.

    We’ll want to be able to add tasks to a task list, right? We’ll have an add method that can take either a Task instance, or a string which it will convert to a Task instance.

    Our tests:

    it 'should accept new tasks as tasks', ->
        task = new Task 'buy milk'
        taskList.add task
        taskList.tasks[0].name.should.equal 'buy milk'
        taskList.length.should.equal 1
    it 'should accept new tasks as string', ->
        taskList.add 'take out garbage'
        taskList.tasks[1].name.should.equal 'take out garbage'
        taskList.length.should.equal 2

    First, we add an actual Task object, and check the taskList.tasks array to verify that it’s been added. Then, we add a string, and make sure that a Task object with the right name was added to the tasks array. In both cases, we check the length of taskList as well, to make sure that it’s being property updated.

    And the function:

    add: (task) ->
        if typeof task is 'string'
            @tasks.push new Task task
        else
            @tasks.push task
        @length = @tasks.length

    Pretty self-explanatory, I think. And now our tests pass:

    Of course, we might want to remove tasks from our list, right?

    it 'should remove tasks', ->
    	i = taskList.length - 1
    	taskList.remove taskList.tasks[i]
    	expect(taskList.tasks[i]).to.not.be.ok

    First, we call the remove method (yet to be written, of course), passing it the last task currently in the list. Sure, we could just hardcode the index 1, but I’ve done it this way because that makes this test flexible: if we changed our previous tests or added more tests above this one, that might have to change. Of course, we have to remove the last one because otherwise, the task after it will take its place and there’ll be something at that index when we’re expecting there to be nothing.

    And speaking of expecting, notice that we’re using the expect function and syntax here instead of our usual should. This is because taskList.tasks[i] will be undefined, which doesn’t inherit from Object.prototype, and therefore we can’t use should.

    Oh, yeah, we still need to write that remove function:

    remove: (task) ->
        i = @tasks.indexOf task
        @tasks = @tasks[0...i].concat @tasks[i+1..] if i > -1
        @length = @tasks.length

    Some fancy array footwork combined with CoffeeScript’s ranges and array splicing shorthand closes this deal for us. We’re simply splitting off all the items before the one to remove and all the items after it; the we concat those two arrays together. Of course, we’ll update @length accordingly. Can you say “passing tests”?

    Let’s do one more thing. We want to print our a (relatively) nice-looking list of the current tasks. This will be our most complex (or at least, our longest) test yet:

        it 'should print out the list', ->
            taskList = new TaskList
            task0 = new Task 'buy milk'
            task1 = new Task 'go to store'
            task2 = new Task 'another task'
            task3 = new Task 'sub-task'
            task4 = new Task 'sub-sub-task'
    
            taskList.add task0
            taskList.add task1
            taskList.add task2
            taskList.add task3
            taskList.add task4
    
            task0.dependsOn task1
            task4.dependsOn task3
            task3.dependsOn task2
    
            task1.complete()
    
            desiredOutput = """Tasks
    
    - buy milk (depends on 'go to store')
    - go to store (completed)
    - another task
    - sub-task (depends on 'another task')
    - sub-sub-task (depends on 'sub-task')
    
    """
    		taskList.print().should.equal desiredOutput

    What’s going on here? First, we’re creating a new TaskList object so that we start from scratch. Then, we create five tasks and add them to taskList. Next, we set up a few dependencies. Finally we complete one of our tasks.

    We’re using CoffeeScript’s heredoc syntax to create a multi-line string. As you can see, we’re keeping it pretty simple. If a task has a parent task, it’s mentioned in parentheses after the task name. If a task is completed, we put that, too.

    Ready to write the function?

    print: ->
        str = "Tasks\n\n"
        for task in @tasks
            str += "- #{task.name}"
            str += " (depends on '#{task.parent.name}')" if task.parent?
            str += ' (complete)' if task.status is 'complete'
            str += "\n"
        str

    It’s actually pretty straightforward: we just look over the @tasks array and add ‘em to a string. If they have a parent, we add that, and if they’re complete, we add that too. Notice that we’re using the modifier form of the if statement, to tighten up our code. Then, we return the string.

    Now, all our tests should pass:

    Wrapping Up

    Try adding a few features to get the hang of it all.

    That’s the extent of our little project today. You can download the code from the top of this page; in fact, why don’t you try adding a few features to get the hang of it all? Here are a few ideas:

    • Prevent Task instances from being able to depend on each other (recursive dependencies).
    • Make the TaskList::add method throw an error if it receives something other than a string or a Task object.

    These days, I’m finding CoffeeScript more and more attractive, but the biggest downside to it is that it must be compiled to JavaScript before it’s useful. I’m grateful for anything that negates some of that workflow breaker, and Mocha definitely does that. Of course, it’s not perfect (since it’s compiling to JS before running the code, line numbers in errors don’t match up with your CoffeeScript line numbers), but it’s a step in the right direction for me!

    How about you? If you’re using CoffeeScript, how have you been doing testing? Let me know in the comments.


Planet PHP

  • Permalink for 'Last Chance To Win “The PHP Playbook”!'

    Last Chance To Win “The PHP Playbook”!

    Posted: April 9th, 2012, 8:31am MDT by Brandon Savage
    Back in March, I announced that I was giving away three copies of The PHP Playbook to three lucky winners. Since I’m selecting winners on April 15th, this is your last week to register to win your copy! Since not everyone can win, I’m also excited to announce that PHP Architect, the publisher of my [...]
  • Permalink for 'Roo.XComponent introduction'

    Roo.XComponent introduction

    Posted: April 8th, 2012, 4:00pm MDT by Alan Knowles
    Article originally from rooJSolutions blog
    [www.roojs.com] With a nice long Easter holiday, I finally got a chance to hack on some of those todo items that I'd been putting off for quite a while. One of the core mini tasks was to enable mtrack information inside of my main email/accounting do everything platform. 
    The Pman codebase, as I've mentioned before forms the core of pretty much all applications I work on now, mostly intranet or extranet focused web applications, that work like desktop applications. All of these applications are built up of various componenents, for example the Accouting module has Components like general ledger, managing invoices, timesheet and tracking editing and a pricing management component. 
    The whole premise of the Pman project codebase on the Javascript side, is to register all the components sometime after the page is loaded, then after the user has logged in, or authentication has been checked, it will create and render all these components in sequence, appending them to the container panels.
    In the case of the Accounting module, there is a default top level module called 'Pman', which the Accounting 'Tab' is added to, then all the sub components are added to that. This whole design was done a couple of years ago, and has been working very well, it's reliable and adding extra componenets, is just a mater creating a file then saying what the parent is and in what sequence it will appear.
    Read on to find out how this all works...
  • Permalink for 'Javascript Templating, AngularJS and Roo.XTemplate'

    Javascript Templating, AngularJS and Roo.XTemplate

    Posted: April 8th, 2012, 4:00pm MDT by Alan Knowles
    Article originally from rooJSolutions blog
     Ok, as I said earlier, a nice Easter break, meant I could get back to coding for fun. The other issue I had to deal with over the weekend was how to do the templating for the Javascript application. 
    Having written a template engine for PHP, I can pretty much say that not using a template engine (which automatically escapes output) is essential for outputing html. It makes everything more maintainable, and reduces the risks that as a error prone human being, you are likely to open your application up to exploits.
    Since most of the display logic on my applications is moving away from PHP generating html to PHP generating JSON, and the Javascript UI rendering this data and displaying it to the user. There has been one area I've slacked off on, that being sorting out a solution for using this JSON data from the PHP backend and rendering a elegant front end in html to show the end user.
    Obviously this is not going to be indexed via google (Somehow JSON / Javascript interfaces are not very google friendly). But for applications that require authentication this not only helps scale the application under load, but also make it far easier to maintain.
    My first effort to solve this issue was based on the original Template code in Roo (Roo.Template) however initially I decided to do the implementation in PHP. The concept was to take a group of 'html' template files, and use the PHP to convert those files into 'Javascript functions'. so calling the generated javascript function with 'data' as the argument, it would return the html to be rendered.
    This basic implementation supported things like conditional inclusion, embedding Javascript, nested functions, looping and much more. It was however horribly crude and rather fragile if the template syntax was invalid. I used this for a few files relating to the ticket rendering in web.mtrack, however, I was never really happy with the solution.
    Read on for my opinion / review of Anjular and the introduction to the updated Roo.XTemplate

Nettuts+

  • Permalink for 'CSS Refreshers: Borders'

    CSS Refreshers: Borders

    Posted: April 6th, 2012, 7:56am MDT by Jeffrey Way

    Sure, we’re all familiar with borders. Is there anything new that could possibly be introduced? Well, I bet there’s quite a few things in this article that you never knew about!

    Not only can CSS3 be used to create rounded corners, but plain-ole’ CSS can also be wrestled into displaying custom shapes. That’s right; in the past, before these techniques were discovered, we might have resorted to using absolutely positioned background images to display circles or arrows. Thankfully – as we gleefully take one more step away from Photoshop – this is no longer the case.

    The Basics

    You’re likely familiar with the most basic use of borders.

    border: 1px solid black;
    

    The above code will apply a 1px border to an element. Plain and simple; but we can also modify the syntax a bit.

    border-width: thick;
    border-style: solid;
    border-color: black;
    

    In addition to passing a specific value to border-width, three keywords may alternatively be used: thin, medium, and thick.

    image

    While it might initially seem unnecessary to ever make use of the long-hand form, there are a handful of cases when it’s advantageous, such as when you need to update some aspect of a border when a designated event occurs.

    Perhaps you need to change the color of a border when the user hovers over a specific element. Using the shorthand form would require that you repeat the pixel values.

    .box {
        border: 1px solid red;
    }
    
    .box:hover {
        border: 1px solid green;
    }
    

    A more elegant and DRY approach would be to specifically update the border-color property.

    .box {
        border: 1px solid red;
    }
    
    .box:hover {
        border-color: green;
    }
    

    Additionally, as you’ll find shortly, this long-hand technique is helpful when creating custom shapes with CSS.

    Border-Radius

    border-radius is the golden child of CSS3 – the first new property to gain widespread use in the community. What this translates to is that, excluding Internet Explorer 8 and below, all browsers can display rounded corners.

    Previously, it was necessary to use vendor prefixes for both Webkit and Mozilla, in order for the styling to be correctly applied.

    -webkit-border-radius: 10px;
    -moz-border-radius: 10px;
    border-radius: 10px;
    

    These days, however, we can slice off the vendor versions without worry, and simply stick with the official form: border-radius.

    image

    As one might expect, we can also specify custom values for each side of a box.

    image
    border-top-left-radius: 20px;
    border-top-right-radius: 0;
    border-bottom-right-radius: 30px;
    border-bottom-left-radius: 0;
    

    In the code above, setting border-top-right-radius and border-bottom-left-radius to zero would be superfluous, unless the element is inheriting values which need to be reset.

    Much like margin or padding, these settings can be condensed into a single property, if necessary.

    /* top left, top right, bottom right, bottom left */
    border-radius: 20px 0 30px 0;
    

    As an example (and as web designers do so often), the shape of a lemon can be reproduced with CSS and the border-radius property, like so:

    .lemon {
       width: 200px; height: 200px; 
    
       background: #F5F240;
       border: 1px solid #F0D900;
       border-radius: 10px 150px 30px 150px;
    }
    
    image Beyond the Basics

    Many designers happily stick with the knowledge outlined thus far in this chapter; however, there’s a few ways we can push it further!

    Multiple Borders

    There’s a variety of techniques that we can refer to, when tasked with applying multiple borders to an element.

    Border-Style

    While solid, dashed, and dotted are the most frequent values for the border-style property, there’s also a few others that we can make use of, including groove and ridge.

    border: 20px groove #e3e3e3;
    

    Or, with the long-hand form:

    border-color: #e3e3e3;
    border-width: 20px;
    border-style: groove;
    
    image

    While this is certainly helpful, a ridge or groove effect isn’t really multiple borders.

    Outline

    The most popular technique for creating two borders is to take advantage of the outline property.

    .box {
       border: 5px solid #292929;
       outline: 5px solid #e3e3e3;
    }
    
    image

    This method works wonderfully, however, it’s limited to two borders. Should you need to create a layered, gradient-esque, effect, a different approach will be necessary.

    Pseudo Elements

    When the outline technique doesn’t suffice, an alternate approach is to take advantage of the :before and :after pseudo elements, and apply any necessary additional borders to the generated content.

    .box {
      width: 200px; height: 200px;
      background: #e3e3e3;
      position: relative;
    
      border: 10px solid green;
    }
    
    /* Create two boxes with the same width of the container */
    .box:after, .box:before {
      content: '';
      position: absolute;
      top: 0; left: 0; bottom: 0; right: 0;
    }
    
    .box:after {
      border: 5px solid red;
      outline: 5px solid yellow;
    }
    
    .box:before {
      border: 10px solid blue;
    }
    
    image

    This perhaps isn’t the most elegant approach, but it certainly gets the job. One caveat is that it’s easy to confuse the order in which the border colors will be applied. A certain level of “guess and check” is often required to apply the correct sequence.

    Box-Shadow

    The cool kids way to create an infinite number of borders is to take advantage of the spread parameter in the box-shadow CSS3 property.

    .box {
        border: 5px solid red;
         box-shadow:
           0 0 0 5px green,
           0 0 0 10px yellow,
           0 0 0 15px orange;
    }
    
    image

    In this case, we’re being clever and are using box-shadow in a way that might not necessarily have been intended when the specification was originally written.

    By setting the x, y, and blur components to 0, we can instead use the spread value to create solid borders at the desired locations. Because box-shadows can be stacked, through the use of a comma, the number of possible levels is infinite.

    This technique gracefully degrades quite nicely. In older browsers, which do not recognize the box-shadow property, this will simply render the single red 5px border.

    Remember: designs needn’t be identical in all browsers. Write your CSS for the most modern of browsers, and then provide suitable fallbacks, accordingly.

    Modifying Angles

    In addition to passing a single value to border-radius, we can alternatively provide two – separated by a / – to specify unique values for both the horizontal and vertical radii.

    For example…

    border-radius: 50px / 100px; /* horizontal radius, vertical radius */
    

    …is equivalent to:

    border-top-left-radius: 50px 100px;
    border-top-right-radius: 50px 100px;
    border-bottom-right-radius: 50px 100px;
    border-bottom-left-radius: 50px 100px;
    

    This technique is particularly helpful when you need to mimic a subtle, lengthy curve, rather than a generic rounded corner. For instance, the following code allows us to slightly break away from a square shape, resulting in more of a curled, paper-like effect.

    .box {
        width: 200px; height: 200px;
        background: #666;
    
        border-top-left-radius: 15em 1em;
        border-bottom-right-radius: 15em 1em;
    
    }
    
    image CSS Shapes

    Perhaps the neatest use of borders is when they’re cleverly applied to elements, which have a zero width and height. Confusing, huh? Let’s see a demonstration.

    For the next several examples, assume the following markup…

    <div class="box"></div>
    

    …and the following base styling:

    .box {
       width: 200px;
       height: 200px;
       background: black;
    }
    

    The most frequently referenced example, when demonstrating how CSS shapes might be used in a project, is to create the obligatory arrow.

    The key to understanding how an arrow might be formed with CSS is to set a unique border-color to each side, and then reduce both the width and height values for the container to 0.

    Assuming a div with a class of arrow as the container:

    .arrow {
      width: 0; height: 0;
    
      border-top: 100px solid red;
      border-right: 100px solid green;
      border-bottom: 100px solid blue;
      border-left: 100px solid yellow;
    }
    

    As demonstrated at the beginning of this chapter, a cleaner syntax would be to not use the all-encompassing short-hand version:

    .arrow {
      width: 0; height: 0;
    
      border: 100px solid;
      border-top-color: red;
      border-right-color: green;
      border-bottom-color: blue;
      border-left-color: yellow;
    }
    

    We can even reduce this further, by grouping the color values.

    .arrow {
      width: 0; height: 0;
    
      border: 100px solid;
      border-color: red green blue yellow;
    }
    
    image

    Interesting, right? It makes perfect sense, though, when we take a step back. That’s the only possible way that the colors could align, assuming a width and height of zero for the container. Now, what if we set all of the border-colors to transparent, except for the blue side?

    .arrow {
      width: 0; height: 0;
    
      border: 100px solid;
      border-bottom-color: blue;
    }
    
    image

    Excellent! But it doesn’t seem too semantic to create an .arrow div, all for the purpose of adding an arrow to the page. Instead, pseudo elements can be used to apply the arrow after or before the associated element.

    Creating a Speech Bubble

    To create a 100% CSS speech bubble, we begin with the markup.

    <div class="speech-bubble">Hi there!</div>
    

    Next, some base styling should be applied.

    .speech-bubble {
        position: relative;
        background-color: #292929;
    
        width: 200px;
        height: 150px;
        line-height: 150px; /* vertically center */
    
        color: white;
        text-align: center;
    }
    
    image

    The arrow will be applied using the after psuedo-element.

    .speech-bubble:after {
        content: '';
    }
    

    The :before and :after psuedo elements can be used to insert generated content either before or after an element’s content.

    At this point, it’s simply a matter of reproducing the arrow, and positioning it in the proper location. We start by absolutely positioning the content, resetting the width and height, and applying the border colors.

    .speech-bubble:after {
      content: '';
      position: absolute;
    
      width: 0;
      height: 0;
    
      border: 10px solid;
      border-color: red green blue yellow;
    }
    
    image

    Because we know that we want the arrow to point downward, the image above demonstrates that all but the red (or top) border should either be omitted, or set to transparent.

    .speech-bubble:after {
      content: '';
      position: absolute;
    
      width: 0;
      height: 0;
    
      border: 10px solid;
      border-top-color: red;
    }
    
    image

    When creating CSS shapes, because we can’t use the width property to specify how wide the arrow should be, the border-width property should be used instead. In this case, the arrow should be slightly larger; so the border-width can be increased to 15px. We’ll also position the arrow at the bottom and center of the container, by using the top and left properties, respectively.

    .speech-bubble:after {
      content: '';
      position: absolute;
    
      width: 0;
      height: 0;
    
      border: 15px solid;
      border-top-color: red;
    
      top: 100%;
      left: 50%;
    }
    
    image

    Almost there; the final step is to update the color of the arrow to be the same as the container’s background. The positioning also needs to be modified to account for the width of the borders (15px). While we’re here, we’ll also apply a subtle border-radius to make the container appear to be more bubble-like.

    .speech-bubble {
       /* … other styles */
       border-radius: 10px;
    }
    
    .speech-bubble:after {
      content: '';
      position: absolute;
    
      width: 0;
      height: 0;
    
      border: 15px solid;
      border-top-color: #292929;
    
      top: 100%;
      left: 50%;
      margin-left: -15px; /* adjust for border width */
    }
    
    image

    Not bad, ay? Abstract this code away to a few reusable classes, and you’re good to go for all future projects.

    /*
       Speech Bubbles
       Usage: Apply a class of .speech-bubble and .speech-bubble-DIRECTION
       <div class="speech-bubble speech-bubble-top">Hi there</div>
    */
    
    .speech-bubble {
      position: relative;
      background-color: #292929;
    
      width: 200px;
      height: 150px;
      line-height: 150px; /* vertically center */
    
      color: white;
      text-align: center;
      border-radius: 10px;
    
      font-family: sans-serif;
    }
    
    .speech-bubble:after {
      content: '';
      position: absolute;
    
      width: 0;
      height: 0;
    
      border: 15px solid;
    }
    
    /* Position the Arrow */
    
    .speech-bubble-top:after {
      border-bottom-color: #292929;
    
      left: 50%;
      bottom: 100%;
      margin-left: -15px;
    }
    .speech-bubble-right:after {
      border-left-color: #292929;
    
      left: 100%;
      top: 50%;
      margin-top: -15px;
    }
    
    .speech-bubble-bottom:after {
      border-top-color: #292929;
    
      top: 100%;
      left: 50%;
      margin-left: -15px;
    }
    
    .speech-bubble-left:after {
      border-right-color: #292929;
    
      top: 50%;
      right: 100%;
      margin-top: -15px;
    }
    
    image Bonus: Better Vertical Centering

    One downside to using line-height to vertically center text is that you’re limited to a single line. Should the text require two or more lines, each line height will be far too large. A clever solution is to set a display of table to the speech bubble, and a display of table-cell to the paragraph that wraps the text. This then allows us to align the text to the middle, accordingly.

    <div class="speech-bubble speech-bubble-top">
        <p>Text goes here.</p>
    </div>
    

    Next, the modified CSS.

    .speech-bubble {
     /* other styles */
    
      display: table;
    }
    
    .speech-bubble p {
      display: table-cell;
      vertical-align: middle;
    }
    
    image

    If references to display: table bring back terrible memories of old-fashioned, table-based layouts, don’t worry. These properties merely refer to the style in which an element should display.

    We’re not limited to triangles; CSS is capable of producing all sorts of shapes – even hearts and biohazard signs!

    image
    .biohazard {
      width: 0; height: 0;
    
      border: 60px solid;
      border-radius: 50%;
    
      border-top-color: black;
      border-bottom-color: black;
      border-left-color: yellow;
      border-right-color: yellow;
    }
    
    Summary

    Though it’s true that the simple border: 1px solid black syntax goes a long way, if we’re clever, we can create a variety of helpful effects, icons, and shapes. Who would have thought that borders could be so powerful? The key is to remember that the styling for common shapes or speech bubbles should only be created once, and then abstracted away to utility classes for future usage.


  • Permalink for 'JavaScript Fundamentals: New Premium Course'

    JavaScript Fundamentals: New Premium Course

    Posted: April 5th, 2012, 1:42pm MDT by Jeremy McPeak

    I’m pleased to announce that Jeremy McPeak’s latest course, JavaScript Fundamentals, is now available on Tuts+ Premium! As the author of countless books, including JavaScript: 24 Hour Trainer and Professional AJAX, Jeremy is the perfect person to show you the ropes!

    JavaScript Fundamentals

    With over five hours of content, you’ll learn everything from the absolute basics, all the way up to event delegation. And, with Jeremy’s teaching style, nobody gets left behind.

    Take the final course quiz to ensure that you’ve mastered the skills in each lesson. Tuts+ Premium

    The recently re-launched Tuts+ Premium is a service that provides top-tier training in a variety of creative fields. Whether you prefer books, visual training, or in depth tutorials, we have you covered.

    While we unfortunately can’t afford to provide the service for free, it’s only $19 a month – less than you’d spend on dinner.

    But the best part is that, every month, we’re adding as many as five new in depth courses on the skills that you want to learn. What’s on the near horizon? JavaScript Testing with Jasmine, Professional Screencasting, Cleaner Code With CoffeeScript, Test-Driven Development in Rails, and countless more.

    I hope you’ll consider checking it out! In addition to learning a huge variety of new skills, it’s also a fantastic way to say thank you to Nettuts+.


Planet PHP

  • Permalink for 'The MVC Paradox'

    The MVC Paradox

    Posted: April 5th, 2012, 11:27am MDT by Bradley Holt

    Use of the Model View Controller (MVC) design pattern is generally accepted as a best practice in modern web applications. Like all design patterns, MVC is a reusable solution to a common problem. The MVC pattern is intended to address the following concerns:

    1. Support for multiple types of clients
    2. Reduce duplicate code when supporting multiple types of clients
    3. Isolating domain logic from the user interface

    Note that items 2 and 3 are both dependent on item 1. Support for multiple types of clients is the single driving force behind the MVC design pattern. Following are some examples of client types:

    • Web Browsers
    • API Clients
    • Admin Processes (e.g. CLI, cron, daemon)
    • Unit Tests
    • Native GUI

    Realistically, how many of these different client types do you need to support? If you’re taking a RESTful approach, then Web Browsers and API Clients can be combined into one type of client, which we can just call User Agents. Likely you’re not building a Native GUI. This leaves you with the following three types of clients to support:

    • User Agents
    • Admin Processes
    • Unit Tests

    Do you really need to use the MVC design pattern in order to support User Agents, Admin Processes, and Unit Tests? Likely not. That’s not to say that there aren’t benefits to isolating domain logic from the user interface. However, if you don’t need to support multiple types of clients you should really question your use of the MVC design pattern. There are many approaches one can take to separating the domain logic and the user interface, of which MVC is just one.

    This bring me to The MVC Paradox. Modern MVC web frameworks inadvertently encourage the coupling of domain logic and user interface. If you don’t need to support multiple types of clients, then decoupling the domain logic from the user interface is the only reason left to use the MVC design pattern.

    Modern MVC web frameworks often involve a lot of boilerplate code just to support the primary client type of User Agents. This boilerplate code typically does little to help with supporting the other client types of Admin Processes and Unit Tests. As a result of the overhead introduced by this extra boilerplate code, developers often find themselves creating Fat Controllers (a side-effect of The MVC Paradox). Controllers take on too many responsibilities, both vertically and horizontally. Vertically, Controllers start to handle domain logic that should be pushed down to the Model layer. Horizontally, multiple concerns get stuffed into a handful of Controllers. These different horizontal concerns should be separated out into multiple Controllers (the Single Responsibility Principle). The overhead introduced by modern MVC web frameworks leads directly to these problems.

    In contrast, take a look at the Slim PHP 5 micro framework. While not a completely RESTful framework, it does a pretty good job of addressing the concerns I’ve laid out in this post. Here is the “Hello world” example from Slim’s homepage:

    <?php
    require 'Slim/Slim.php';
    $app = new Slim();
    $app->get('/hello/:name', function ($name) {
        echo "Hello, $name!";
    });
    $app->run();
    ?>

    There is very little boilerplate code involved in handling a User Agent’s request. Minting and handling new routes is incredibly simple. Placing your entire front-end application layer in one file may seem absurd at first. However, it has the nice side-effect of making it painfully obvious if you start to handle domain logic outside of your Model layer or if one route is doing too many things. If your front-end application is large enough, then you can organize your routes into separate files.

    This post is not intended to discourage you from using an MVC web framework. There are certainly times when such a framework is useful. As with any technology decision, carefully consider what problem you’re trying to solve and what technology will best address your problem set. Sometimes your technology choice can undermine the very purpose of using that technology in the first place, as is the case with The MVC Paradox.

Nettuts+

  • Permalink for 'Build a Contacts Manager Using Backbone.js: Part 5'

    Build a Contacts Manager Using Backbone.js: Part 5

    Posted: April 5th, 2012, 10:47am MDT by Dan Wellman

    Welcome back to the Building a content viewer with Backbone series. Over the first four parts, we looked at almost every major component that ships with the latest version of Backbone including models, controllers, views and routers.

    In this part of the tutorial, we’re going to hook our application up to a web server so that we can store our contacts in a database. We won’t be looking at LocalStorage; this is a popular means of persisting the data that Backbone apps use, but the fact is there are already a number of excellent tutorials available on this subject.

    Getting Started

    We’ll need a webserver and a database for this part of the tutorial. I use Microsoft’s VWD as an editor, which ships with a built-in web server and works well with MSSQL server, so this is what we’ll be using. In truth, it doesn’t really matter which stack you decide to go with.

    Installing and configuring either of these technologies (VWD and MSSQL server) is beyond the scope of this tutorial, but it’s relatively straight-forward to do and there are plenty of good guides out there.

    Once installed, you’ll want to set up a new database containing a table to store the data in. The table columns should mirror the different properties our models use, so there should be a name column, an address column, etc. The table can be populated with the example data we’ve used throughout the series so far.

    One column that should appear in our new table, but which we haven’t used in our local test data is an id, which should be unique to each row in the table. For ease of use, you probably want to set this to auto-increment when the data is added to the table.

    Backbone Sync

    In order to communicate with the server, Backbone gives us the Sync module; this is the only major module that we haven’t used yet and so understanding it will complete our knowledge of the fundamentals of the framework.

    Calling the sync() method results in a request being made to the server; by default, it assumes either jQuery or Zepto is in use and delegates the request to whichever of them is present to actually perform. It also assumes a RESTful interface is awaiting on the back-end so by default makes use of POST, PUT, GET, DELETE HTTP methods. As we’ve seen, Backbone can be configured to fall back to old-school GET and POST methods with additional headers which specify the intended action.

    As well as being able to call sync() directly, models and collections also have methods that can be used to communicate with the server; models have the destroy(), fetch(), parse() and save() methods, and collections have fetch() and parse(). The destroy() fetch() and sync() methods all defer to sync() whether being used with models or collections. The parse() method, called automatically whenever data is returned by the server, is by default a simple no-op which just returns the response from the server, but can be overridden if we wish to pre-process the response before consuming it.

    Page Load Caveat

    The way model data is bootstrapped into the page will vary depending on the back-end technology being used.

    The Backbone documentation for the fetch() method (of a collection) states that this method should not be used on the initial page load to request the required models from the server. It goes on to elaborate in the FAQ section that a page should have the required modules already available to the page on load to avoid the initial AJAX request.

    This is a great idea and while we don’t explicitly have to follow the advice, doing so will make our application just a little bit snappier, and that can only be a good thing.

    The way model data is bootstrapped into the page will vary depending on the back-end technology being used. We’re going to be using .net in this example, so one way of doing this would be to dynamically create a <script> element containing the required model data, and inject it into the page. To do this we’ll need to convert our index.html file to index.aspx instead (we’ll also need an index.aspx.cs code-behind or class file too). But doing this raises a new issue.

    Using Underscore Microtemplates in an ASPX Page

    We can lift the ‘Mustache-style’ example straight off of the Underscore documentation page.

    The problem with Underscore templates is that they use <%= to specify placeholders in the template that are replaced with actual data when the template is consumed. This is the same syntax that ASPX pages use to run dynamic .Net code within HTML tags. The Underscore templates that we’ve used in this example so far prevent the ASPX page from running correctly and instead it displays a server error.

    Fortunately there are several ways around this problem, the simplest way being to change the syntax used to specify the placeholders used in the templates. Underscore exposes the templateSettings property for this very purpose, allowing us to easy specify a regular expression used to match the symbols we wish to use. We can lift the ‘Mustache-style’ example straight off of the Underscore documentation page in fact; at the start of our app.js file (within the very outer function) we can just add the following code:

    _.templateSettings = {
        interpolate: /\{\{(.+?)\}\}/g
    };

    All this does is supply a new regular expression to the interpolate method, which allows us to use the alternative syntax {{ property }} instead of <%= property %>. We should also at this point go through the templates and change all of the original template tags to use the new syntax.

    Although this is not something we’ve used in our templates so far, there are also additional symbols that Underscore can use. We can evaluate JavaScript using <% and can escape data using <%-. If we wish to use these in our templates and have replaced the interpolate property, we should also configure the evaluate and escape Underscore properties as well.

    Bootstrapping the Model Data

    We can now think about delivering the model data that is stored in a database to our page when the page is initially rendered. We can easily do this be adding a simple method to the class file for our ASPX page that reads the records from the database and creates a list of objects where each object represents a single contact. We can then serialise the list into a JavaScript array and inject it into the page. As long as the array has the same format as the dummy array we used in the first four parts of this tutorial, we won’t have to change our front-end code.

    As a placeholder for the array, we can just add a new <script> element to the body of the page, directly before the reference to app.js, which calls the method in the code-behind:

    <script>
        var contacts = <%= getData() %>
    </script>

    The actual logic in the code-behind that performs the database read and list serialisation could vary wildly depending on the implementation, and is somewhat beyond the scope of this tutorial – we’re more interested in getting that initial payload on the page than we are about how we actually get it. Feel free to check out the class file in the accompanying code download for probably the quickest and easiest, but by no means the best, way to do it.

    At this point, we should be able to remove the contacts array that held our dummy data from app.js, run the page (through the built-in WVD webserver, or IIS) and see exactly the same page, with almost the same functionality, as we saw at the end of part 4. Yay!

    Syncing Our App With the Server

    In this example, I’ve used a .net 4.0 ASMX file to handle the requests from the front-end. In order for the back-end to see the data sent to it, we should configure the emulateHTTP and emulateJSON Backbone properties. Add the following lines of code directly after where we changed Underscore’s template syntax:

    Backbone.emulateHTTP = true;
    Backbone.emulateJSON = true;

    Whether or not you’ll need to configure these properties when building a Backbone app for real depends entirely on the back-end technology you choose to work with.

    So, our application could modify the data in several ways; it could change the attributes of a contact that already exists, it could add an entirely new contact, or it could delete a contact that already exists.

    The logic to do all of these things on the front-end already exists, but now that a server is involved, the behaviour of the page has already changed. Although the page will render as it did before, if we try to delete a contact, Backbone will throw an error complaining that a url has not been defined. The reason for this is because we used the destroy() method in the deleteContact() method of our ContactView class.

    Let’s look at how to restore the delete functionality. The first thing we should do then is define a url attribute for our models. Add the property to the Contact class that defines an individual model:

    url: function () {
        return "/ContactManager.asmx/ManageContact?id=" + this.get("id");
    }

    We specify a function as the value of the url property, which returns the URL that should be used to make the requests to. In this example, we can use an asmx web service file to handle the requests. We also add the name of our web method (ManageContact) and add the id of the model as a query string parameter.

    Now if we delete one of the contacts when we run the page a POST request is made to the web service. An X [HTTP-Method-Override] header is added to the request which specifies that the intended HTTP method was DELETE. We can use this in our web service logic to determine what action to take on the database.

    Next we can update the saveEdits() method of the ContactView class so that it notifies the web service when a contact is edited; change the line of code that uses the set() method so that it appears like this:

    this.model.set(formData).save();

    All we do is chain the save() method on to the set() method. The save() method delegates to the sync() method which makes a POST request to the server. As before the id of the model is sent as a query string and an X [HTTP-Method-Override] is used to specify the intended PUT method. This time however, the Content-Type header is set to application/x-www-form-urlencoded (if we didn’t configure the emulateJSON property it would be application/json) and the model data is sent as a form data, which we can use to make whatever changes are necessary.

    All that is left to do on the front-end is to update the addContact() method of the DirectoryView class. Previously in this method we had an if statement that checked the type of the model being added to see if the select menu needed to be updated. We should now change that if statement so that it appears as follows:

    if (_.indexOf(this.getTypes(), formData.type) === -1) {
        this.$el.find("#filter").find("select").remove().end().append(this.createSelect());
    }
    
    this.collection.create(formData);

    We’ve trimmed the if statement down to remove the else condition, making the code a bit tidier. We’ve also removed the add() method and added the create() method in its place. The create() method will actually add the new model to the collection automatically without us manually creating a new instance of our model’s class, and it will also make a request to the server, once again delegating to sync().

    This time the X [HTTP-Method-Override] header does not need to be set, because POST is the method that we would use were the request being made to a RESTful interface anyway. As with the save() method, the model data passed to the create() method is delivered to the server as form data.

    As with the server-side code used at the start of this part of the tutorial to bootstrap the initial model data into our app, the code used to process and handle the requests made by Backbone is beyond the scope of the tutorial. We’re interested only in the front-end here. As before, the Web service used for this demo is included in the code archive and is fully commented, so check it out if you’re interested. I’ve also included a database backup, which you should be able to restore in order to get going with the demo data.

    Summary

    In this part of the tutorial, we looked at some of the methods we can use which delegate to Backbone’s sync() method in order to communicate with a back-end that can persist the changes made using the front-end of the application.

    We saw how Backbone by default makes RESTful requests to a specified URL and how we can configure it in order to work with legacy servers that do not operate on REST principles. We also looked at some of the methods that delegate to sync() in order to communicate with the server. Specifically, we covered the remove(), save() and create() methods and looked at what is sent to the server and how.

    We also looked at how easy it is to change the symbols that Underscore uses in order to interpolate data into a template. This now concludes the Contact Manager tutorial; while there are many more features we could add to the application, we have now covered the basics of what it takes to build a fully-functional application using the excellent Backbone.js. Thanks for reading.


Planet PHP

  • Permalink for 'Will PHP development Migration to Git improve non-Core Developer Contribution Interest? - Lately in PHP podcast episode 22'

    Will PHP development Migration to Git improve non-Core Developer Contribution Interest? - Lately in PHP podcast episode 22

    Posted: April 5th, 2012, 6:32am MDT by PHP Classes
    Will PHP development Migration to Git improve non-Core Developer Contribution Interest? - Lately in PHP podcast episode 22 By Manuel Lemos The PHP development migrated to a Git repository. With the integration with GitHub it became easier for non-core developers to submit pull requests with bug fixes and new feature improvements to PHP.

    Will this new possibility make it PHP core developers accept more contributions from non-core developers? That is one of the main topics discussed by Manuel Lemos and Ernani Joppert in the episode 22 of the Lately in PHP podcast.

    They also talk about the upcoming PHP 5.4.1 release, as well about the repercussion of a recently article that aims to encourage more PHP developers to embrace Object Oriented Programming, and the top packages of the PHP Programming Innovation Award edition of 2011.

    Listen to the podcast or read the transcript to learn more about this and other interesting PHP topics.
  • Permalink for 'Working at 10gen'

    Working at 10gen

    Posted: April 5th, 2012, 6:00am MDT by Derick Rethans
    Working at 10gen London, UK Thursday, April 5th 2012, 13:00 BST mongodb-logo.png

    As of today I am working for 10gen, the company behind MongoDB. I have been contracting with them for a few months to work on the PHP driver for MongoDB. I am now making the switch to a full time position.

    I am responsible for supporting MongoDB in the PHP ecosystem through driver development, integration with open source tools, community support, and developer advocacy. For now, I will concentrate to get the driver into a better shape, and speaking about MongoDB and PHP.

    I have already given a few talks on the subject, and if you would like me to speak at your user group or conference, please let me know. If you have any comments on using MongoDB with PHP, I would love to hear them too.

    I am looking forwards with the awesome team at 10gen. Both with team in London, as well as with the folks in Palo Alto, New York and Dublin. 10gen is also hiring a few more people for a similar position in New York and Palo Alto. Have a look at the job posting here if you are interested.

    Flattr this
  • Permalink for 'Book Review: MongoDB and PHP'

    Book Review: MongoDB and PHP

    Posted: April 5th, 2012, 1:36am MDT by Lorna Mitchell

    Despite having been toying with MongoDB and PHP for quite a while, I've only just picked up and read the "MongoDB and PHP" by Steve Francia, published by O'Reilly (disclaimer: I've collaborated with Steve on a few articles and he sent me a copy of the book to read)

    My first impressions are that this isn't a heavy book. I don't have the physical version but I'll have to look out for it at the next O'Reilly stand that I see. That said, it covered everything I think you need to get your PHP application using MongoDB and manages to throw in good chunk of advice about what to look out for when you do implement something in the real world.

    The book warms up its PHP audience by slating both Ruby on Rails and ORMs in general, which does let you know where the author stands on those topics! MongoDB is introduced with an intelligent comparison to memcache, which is a great way of framing the problem in a way we're more likely to be familiar with, and the book also strikes comparisons with MySQL which I liked a lot.

    The tone of the book is quite informal and approachable, the sample data raised a smile when I saw that we were storing "superpowers" for different users in the collection :) Much as I agree with Steve on many things, seeing him assert that developers should understand database indexes made me feel as if I was among friends, even though I wasn't familiar with all of the MongoDB elements that were shown. This book also does a great job of deferring to other resources where that is appropriate; in particular where some features of MongoDB will change rapidly and the online documentation is well-maintained.

    Plenty of the more advanced concepts were also covered, and with nice examples. MongoDB has both indexes and an explain function so we can work on the way it performs - very valuable knowledge as we move to a new platform and get to know it. The basics of querying and designing schemas were covered, along with the aggregate functions offered by MongoDB and an overview of map reduce. Being able to do these operations on nested arrays is slightly counter-intuitive if you're used to relational data, but the book includes examples on doing so.

    There is no hiding from the very lovely, very technical, features available in MongoDB and although this book doesn't drill into all the possible use cases of each one, it does cover some advanced topics such as sharding and GridFS which was completely new to me. Steve shows his hands-on experience with his words of warning on avoiding request injection in MongoDB, and also gives a brief showcase of some of the abstraction layers and other community-origin tools that have already sprung up around the MongoDB ecosystem.

    Overall I thought the book was light and digestible, it was upbeat to read and I came away feeling empowered to put MongoDB into my PHP projects in new ways. Making a complex topic sound encouraging isn't always easy so that's quite an achievement!

    Lorna is an independent web development consultant, writer and trainer, open source project lead and community evangelist. This post was originally published at LornaJane

Nettuts+

  • Permalink for 'Best of Tuts+ in March 2012'

    Best of Tuts+ in March 2012

    Posted: April 4th, 2012, 4:27pm MDT by David Appleyard

    Each month, we bring together a selection of the best tutorials and articles from across the whole Tuts+ network. Whether you’d like to read the top posts from your favourite site, or would like to start learning something completely new, this is the best place to start!

    Psdtuts+ — Photoshop Tutorials
    • Our First Look at Photoshop CS6 – Now Available in Beta Our First Look at Photoshop CS6 – Now Available in Beta

      Today, Adobe announced some big news. Photoshop CS6 is now available for download in Beta. For the last several months, we have been speculating about what features we can expect to see in Photoshop CS6. This speculation was fueled by the Photoshop team’s release of several sneak peek videos that revealed some exciting new features. Now that the speculation is over and Photoshop CS6 Beta is available for us to download and try, we have been able to make a careful examination of some of its new features.

      Visit Article

    • Create a Royal Gold Text Effect in Photoshop Using Layer Styles Quick Tip: Create a Royal Gold Text Effect in Photoshop Using Layer Styles

      In this quick tutorial we will show you how to create a royal gold text effect using layer styles in Photoshop. Let’s get started!

      Visit Article

    • Create a Clean Twitter App Interface in Photoshop Create a Clean Twitter App Interface in Photoshop

      In this tutorial we will create a clean Twitter app interface in Photoshop using layer styles and basic vector shapes. Let’s get started!

      Visit Article

    • Nettuts+ — Web Development Tutorials
    • Sass vs. LESS vs. Stylus: Preprocessor Shootout Sass vs. LESS vs. Stylus: Preprocessor Shootout

      Wielding the true power of a CSS preprocessor is an adventure. There are countless languages, syntaxes, and features, all ready for use right now.

      Visit Article

    • Sexy Code Snippet Management With Gists Sexy Code Snippet Management With Gists

      I’ve always struggled to find the perfect code snippet management tool…until now (and it’s free). I’ll show you my preferred workflow, using GitHub Gists and Sublime Text 2.

      Visit Article

    • Create Instagram Filters With PHP Create Instagram Filters With PHP

      In this tutorial, I’ll demonstrate how to create vintage (just like Instagram does) photos with PHP and ImageMagick. Wait? What? Yes, you can do this very thing with PHP and ImageMagick, and that’s just scratching the surface!

      Visit Article

    • Vectortuts+ — Illustrator Tutorials
    • Create a Psychedelic, Funky Line Art Portrait Create a Psychedelic, Funky Line Art Portrait

      In today’s Illustrator tutorial, I’m going to show you how I created a retro, psychedelic, funky, 70s inspired portrait using link art, bold colors and the handy Swirl Tool.

      Visit Article

    • Brainstorming Head Design, a Focus on the Eye Line Quick Tip: Brainstorming Head Design, a Focus on the Eye Line

      Varying the horizontal axis line (the eyeline) and adjusting the spacing of the eyes are two excellent methods used to brainstorm new character designs. In this tutorial, we look at a few simple, but effective, techniques you can employ to give your characters personality while making them both fresh and visually interesting.

      Visit Article

    • 15+ InDesign Tutorials for Magazine and Layout Design InDesign Tutorials for Magazine and Layout Design

      Do you want to learn to how to design a magazine in InDesign? Discover industry standard workflows for print design professionals, magazine layout design tips, and follow how to design a magazine cover layout that attracts attention. These are just a few of the topics you’ll find in this roundup of best InDesign magazine and layout tutorials.

      Visit Article

    • Webdesigntuts+ — Web Design Tutorials
    • The Benefits and Pitfalls of Gamification The Benefits and Pitfalls of Gamification

      Gamification is becoming a hot commodity around the web, but what is it? Is it being used correctly? Let’s have a look at various aspects of gamification and how they can be used and misused.

      Visit Article

    • Starting Out Building a Responsive Layout With Skeleton: Starting Out

      Dave Gamache’s Skeleton Boilerplate provides the perfect foundations upon which to build responsive websites rapidly and reliably. We’re going to use Skeleton and build a responsive page based on the Magazine design featured on Webdesigntuts+ recently. We’ll be looking at everything from multiple background images, through to media queries, flexible media and mobile-friendly navigation. Let’s get started!

      Visit Article

    • Stitch up Your Layout Quick Tip: Stitch up Your Layout

      In this Quick Tip we’re going to create a cool stitching effect in Photoshop. We won’t be using brushes, we won’t be relying on patterns – we’re going to use a really simple and fast alternative.

      Visit Article

    • Phototuts+ — Photography Tutorials
    • How to Photograph Birds of Prey in White How to Photograph Birds of Prey in White

      The first thing people say when they see my Birds of Prey Portrait Sessions is “nice Photoshop cutout work”. In fact, it’s not a cutout, the birds are photographed against a white background. Let me show you how.

      Visit Article

    • Camera Exposure Modes Explained Camera Exposure Modes Explained

      If you’re just getting started with photography, the letters on your camera’s dial might feel like hieroglyphics. With a variety of modes, it can be hard to pick what’s right for the current shooting situation. Today, we’re going to explain common camera modes so that you can pick the right one for any situation and grow out of using auto mode.

      Visit Article

    • A Photographer’s Guide to Visiting Nepal A Photographer’s Guide to Visiting Nepal

      Nepal is a country wrapping in mystique for many. The home of the highest mountain in the world and a civilization known for living in the harsh conditions of the Himalayas, Nepal has much to offer the photographic traveler. Lush jungles cover areas of Southern Nepal which is the location of the birth place of Buddha, founder of one of the oldest religions in the world still practiced today. To the East travel becomes more rugged as compared to the more arid regions of the West.

      Visit Article

    • Cgtuts+ — Computer Graphics Tutorials
    • Creating The Always Popular “Invisibility” Effect With Maya & After Effects Creating The Always Popular “Invisibility” Effect With Maya & After Effects

      In this tutorial from James Whiffin you’ll learn how to create a truly awesome invisibility effect using Maya and After Effects. James will cover creating a fractal material in Maya to use as a transition for the cloaking effect, and how to composite displacement maps inside of After Effects, using the luma values of ambient occlusion and depth map layers to achieve this popular effect in our shot.

      Visit Article

    • The Complete Workflow Creating An Animated Fish Swarm In Blender Using Particles: The Complete Workflow

      In this new two part tutorial from Frederik Steinmetz, you’ll learn how to create a truly unique fish swarm animation using Blender. Frederik will guide you through the entire process of Modeling, Texturing, Rigging and Animating a realistic school of mackerels. You’ll then learn how to create a spiraling, tornado like effect for the swarm using particles.

      Visit Article

    • An Introduction To UVMapping In 3d Studio Max Using The Unwrap UVW Modifier An Introduction To UVMapping In 3d Studio Max Using The Unwrap UVW Modifier

      So UVMapping… you hate it, I hate it. But unfortunately it’s a necessary step in the process of completing most cg projects. In this tutorial we’ll look at creating uvs using the ‘Unwrap UVW’ modifier in 3D Studio Max, and discuss what uv mapping is, why it’s necessary and some ways to approach it.

      Visit Article

    • Aetuts+ — After Effects Tutorials
    • The Naked Truth About 3D Rotations The Naked Truth About 3D Rotations

      Third of the series: “Naked Truth About…” In this video I am showing issues with rotations in 3D space and ways to deal with them. Have you ever wondered what is the difference between Rotation and Orientation? We set two keyframes for rotations and the layer rotates strangely. Has it ever happened to you? Those problems are NOT After Effects specific. This video explains the way rotations in 3D space work. Once you understand the concept – it will be easier for you to tame rotations not only in After Effects, but also in other applications. Have fun.

      Visit Article

    • Quick Tip – Implementing Droplets and Watch Folders Quick Tip – Implementing Droplets and Watch Folders

      When working with video files on a daily basis, alot of time is spent converting videos into different formats, whether for web, archive, or editing purposes. Add onto that the interruption of opening and closing programs to convert your files and you’ll end up spending less time being creative and more on technical chores. In this quick tip tutorial, we look at two simple ways to save you time by automating the process of conversion using droplets and watch folders.

      Visit Article

    • Helpful Tips For Improving Promotional Documentary Video Helpful Tips For Improving Promotional Documentary Video

      Promotional video content for the web is a powerful way to communicate a message and it is used by many companies and organizations. It allows communication in a variety of forms including spoken word and visual imagery but it also facilitates a connection with the audience on a more subconscious level. A promotional video containing a product, message or guidance must look professional – but before you spend your annual marketing budget employing a production company, ask yourself if you can achieve appropriate results by applying the hints and tips below.

      Visit Article

    • Audiotuts+ — Audio & Production Tutorials
    • A Guide to Producing an Epic Orchestral Track A Guide to Producing an Epic Orchestral Track

      Although I’m not a huge fan of epic productions, they are definitely the thing that producers/directors/game developers search for nowadays. Now, as a whole, epic orchestral tracks can be heard on movies, TV, commercials, video games, trailers. They always support tension, battle, chase – all of these extremely dynamic moments that always catch the attention of the customer. This tutorial is a guide that I do hope will help you create your own epic orchestral track. Let’s get started!

      Visit Article

    • How to Minimize Noise In Your Mixes How to Minimize Noise In Your Mixes

      Home recordings are infamous for having noise. Background noise from outside and indoor noises from the air conditioning and people shuffling around in the next room. Home recording studios are usually never sound isolated enough. Even though you might have a great sounding room, with acoustic treatment carefully placed all over, you’re still going to run into sound isolation issues.

      The biggest issue is noise, and in the following tutorial I’ll run through a couple of ways you can minimize the amount of annoying hiss and noise from your home recordings.

      Visit Article

    • Making An Electro/Dubstep Bass Patch In FM8 Making An Electro/Dubstep Bass Patch In FM8

      If you fancy a bit of departure form virtual analog, subtractive synths you could try dabbling in FM (Frequency Modulation) synthesis. Native Instruments FM8 is the perfect way to get involved with this edgy sound creation method. Lets take a look at how to create a typical roughed up bass patch that you could use for Electro house or Dubstep.

      Visit Article

    • Activetuts+ — Flash, Flex & ActionScript Tutorials
    • Build a Stage3D Shoot-’Em-Up: Sprite Test Build a Stage3D Shoot-’Em-Up: Sprite Test

      In this tutorial series (part free, part Premium) we’ll create a high-performance 2D shoot-em-up using the new hardware-accelerated Stage3D rendering engine. We will be taking advantage of several hardcore optimization techniques to achieve great 2D sprite rendering performance. In this part, we’ll build a high-performance demo that draws hundreds of moving sprites on-screen at once.

      Visit Article

    • A jQuery- and Flash-Style Library for HTML5 Canvas oCanvas: A jQuery- and Flash-Style Library for HTML5 Canvas

      With the advent of tools like Adobe Edge and libraries like EaselJS, more resources are becoming available for developers looking to create interactive HTML5 content. Many of these tools are being geared specifically for Flash developers to make the transition from ActionScript to HTML5 canvas a smooth one. This article will overview oCanvas, an HTML5 library that developers might not only find invaluable but also very easy to use.

      Visit Article

    • How to Build a Python Bot That Can Play Web Games How to Build a Python Bot That Can Play Web Games

      In this tutorial we’ll explore the ins and outs of building a Computer Vision-based game bot in Python, which will be able to to play the popular Flash game Sushi Go Round. You can use the techniques taught in this tutorial to create bots for automatically testing your own web games.

      Visit Article

    • Wptuts+ — WordPress Tutorials
    • Using Custom Image Sizes in Your Theme and Resizing Existing Images to the New Sizes Using Custom Image Sizes in Your Theme and Resizing Existing Images to the New Sizes

      In this tutorial you will learn how to generate custom sized images for you to use in your WordPress theme. Why use custom image sizes? So you won’t have to edit every image you upload to the Media Library. This way every image uploaded will get all the custom defined image sizes generated automatically. It can be inserted into the post or page using the Media Gallery or from the loop. Continue reading to find out how.

      Visit Article

    • The Complete Guide To The WordPress Settings API, Part 4: On Theme Options The Complete Guide To The WordPress Settings API, Part 4: On Theme Options

      In the last article, we took a deep dive into the various types of menus that are supported by the WordPress API. Although they aren’t necessarily part of the Settings API, they play a key part in development especially when working on more advanced plugins and themes.

      Visit Article

    • The header.php – What Needs to Go in It and What Doesn’t The header.php – What Needs to Go in It and What Doesn’t

      In this tutorial, let’s talk about the header.php, an essential file for any WordPress theme. I’ll show you a nice header file example and give tips about what needs to go in it and what doesn’t.

      Visit Article

    • Mobiletuts+ — Mobile Development Tutorials
    • Project Overview D Game Development with ShiVa3D Suite: Project Overview

      Curious about 3D game development? Now is the time to learn! This five-part tutorial series will demonstrate how to build a simple game with ShiVa3D Suite, a cross-platform 3D game engine and development tool. This series was originally intended for Tuts+ Premium members only, but will instead be given away to the community for free with each portion published back-to-back over the next 5 days. Read on to begin your journey into 3D programming!

      Visit Article

    • Creating Android-Compliant Libraries Android Essentials: Creating Android-Compliant Libraries

      Android libraries can be packaged and reused in other Android applications using the new Android Library feature of the Android SDK. In this quick tutorial, you will learn how to create simple Android library files that can be reused in multiple projects and increase developer efficiency.

      Visit Article

    • Enabling Google Analytics to Gather App Statistics Enabling Google Analytics to Gather App Statistics

      Google Analytics is a service provided by Google that makes it easy to track what users do. The Google Analytics team released an Analytics SDKs for mobile platforms including Android, iOS (Apple), and mobile websites. In this tutorial, learn how to include and enable this technology within your Android projects to gather important information about how users are using your applications.

      Visit Article


Planet PHP

  • Permalink for 'Boston PHP Northeast Conference Call for Papers Closing!'

    Boston PHP Northeast Conference Call for Papers Closing!

    Posted: April 4th, 2012, 2:25pm MDT by Bradley Holt

    The Boston PHP Northeast Conference’s Call for Papers will be closing on Thursday, April 12th so be sure to get your talk submissions in before then! The conference will be taking place on Saturday, August 11th and Sunday, August 12th at Microsoft’s NERD Center in Cambridge, MA and will be focused around four tracks:

    • Core PHP
    • Web Development
    • Training
    • User Experience (UX)

    Boston PHP will be hosting the event in partnership with other northeast regional user groups including the Burlington, Vermont PHP Users Group (which I organize) and the Atlantic Canadian PHP User Group. If you have any questions or are interested in sponsoring then please send a message to Boston PHP.

  • Permalink for 'On Book And Content Pricing'

    On Book And Content Pricing

    Posted: April 4th, 2012, 6:05am MDT by Brandon Savage
    Yesterday, an (understandably) frustrated gentlemen tweeted a link saying the fact that my book’s print and ebook editions were priced the same, was “greed.” While this was a bit hyperbolic to be sure (and the price being identical was in fact a mistake that has now been corrected), it sparked a discussion about book pricing [...]
  • Permalink for 'Quick setup for PHP development trees'

    Quick setup for PHP development trees

    Posted: April 4th, 2012, 3:33am MDT by Johannes Schlüter

    As PHP has moved to git recently everybody who works on the PHP source has to recreate his work environment. When working on PHP I have a few requirements for my working dirs. For one I want to be able to use different branches (like 5.3, 5.4 and master) at the same time and I want to quickly test different PHP configurations, like builds using thread-safety or debug mode on or off.

    A simple approach for this is to use out-of-tree builds, something like that:

    $ git clone ....php-src.git
    $ (cd php-src && ./buildconf)
    $ mkdir build-master-minimal
    $ cd build-master-minimal
    $ ../php-src/configure --disable-all
    $ make

    This allows having both requirements full-filled as you can have build dirs for each branch and each configuration. Nice, but in the long run quite confusing as you always have to make sure php-src has the correct branch checked out, matching the build dir you're currently building in, else you will create a mess.

    Thankfully there is a nice solution to have multiple checkouts using git-new-workdir. So one can easily setup the branches and build dirs. Now it's still quite some repetitive work to create a structure using different branches and a set of different build dirs for each branch. Therefore I've created a simple shell script to do this quickly on my different machines and pushed the script to github in case anybody wants to have a similar structure, and maybe improve the script. But be warned: The script is really an ad hoc thing for me to get started.

Nettuts+

  • Permalink for 'Persisting a Todo List With MongoDB and Geddy'

    Persisting a Todo List With MongoDB and Geddy

    Posted: April 3rd, 2012, 8:06am MDT by Daniel Erickson

    In this three part tutorial, we’ll be diving deep into creating a to do list management app in Node.js and Geddy. This is the last entry in the series, where we’ll be persisting our todo items to MongoDB.

    As a quick refresher, last time, we created our todo resource and made a working to do list application, but the data only existed in memory. In this tutorial, we’ll fix that!

    Intro to MongoDB

    MongoDB is a NoSQL document store database created by the folks over at 10gen. It’s a great database for Node apps because it stores its data in a JSON-like format already, and its queries are written in JavaScript. We’ll be using it for our app, so let’s get it set up.

    Installing MongoDB

    Go to [www.mongodb.org] and download the latest version for your OS. Follow the instructions in the readme from there. Make sure that you can start mongod (and go ahead and leave it running for the duration of this tutorial)

    It’s worth noting that you’ll need to have mongo running any time you want your app running. Most people set this up to start up with their server using an upstart script or something like it.

    Done? alright, let’s move on.

    MongoDB-Wrapper

    For our app, we’ll be using a module that wraps the mongodb-native database driver. This greatly simplifies the code that we’ll be producing, so let’s get it installed. cd into your app and run this command:

    npm install mongodb-wrapper

    If all goes well you should have a mongodb-wrapper directory in your node_modules directory now.

    Setting up Your Database

    Mongo is a really easy DB to work with; you don’t have to worry about setting up tables, columns, or databases. Simply by connecting to a database, you create one! And just by adding to a collection, you make one. So let’s set this up for our app.

    Editing your init.js file

    We’re going to need access to our DB app-wide, so let’s setup our code in config/init.js. Open it up; it should look like this:

    // Add uncaught-exception handler in prod-like environments
    if (geddy.config.environment != 'development') {
      process.addListener('uncaughtException', function (err) {
        geddy.log.error(JSON.stringify(err));
      });
    }
    geddy.todos = [];
    geddy.model.adapter = {};
    geddy.model.adapter.Todo = require(process.cwd() + '/lib/model_adapters/todo').Todo;
    

    Let’s add in our db code at the very top (and remove the geddy.todos array while we’re at it):

    var mongo = require('mongodb-wrapper');
    
    geddy.db = mongo.db('localhost', 27017, 'todo');
    geddy.db.collection('todos');
    
    // Add uncaught-exception handler in prod-like environments
    if (geddy.config.environment != 'development') {
      process.addListener('uncaughtException', function (err) {
        geddy.log.error(JSON.stringify(err));
      });
    }
    geddy.model.adapter = {};
    geddy.model.adapter.Todo = require(process.cwd() + '/lib/model_adapters/todo').Todo;

    First, we require the mongodb-wrapper module. Then, we set up our database, and add a collection to it. Hardly any set up at all.

    Rewriting Your Model-Adapter

    Geddy doesn’t really care what data backend you use, as long as you’ve got a model-adapter written for it. This means that the only code that you’ll have to change in your app to get your todos into a database is in the model-adapter. That said, this will be a complete rewrite of the adapter, so if you want to keep your old in-memory app around, you’ll want to copy the code to another directory.

    Editing Your Save Method

    Open up your model-adapter (lib/model_adapters/todo.js) and find the save method. It should look something like this:

    this.save = function (todo, opts, callback) {
      if (typeof callback != 'function') {
        callback = function(){};
      }
      var todoErrors = null;
      for (var i in geddy.todos) {
        // if it's already there, save it
        if (geddy.todos[i].id == todo.id) {
          geddy.todos[i] = todo;
          todoErrors = geddy.model.Todo.create(todo).errors;
          return callback(todoErrors, todo);
        }
      }
      todo.saved = true;
      geddy.todos.push(todo);
      return callback(null, todo);
    }

    Make it look like this:

    this.save = function (todo, opts, callback) {
      // sometimes we won't need to pass a callback
      if (typeof callback != 'function') {
        callback = function(){};
      }
      // Mongo doesn't like it when you send functions to it
      // so let's make sure we're only using the properties
      cleanTodo = {
        id: todo.id
      , saved: todo.saved
      , title: todo.title
      , status: todo.status
      };
      // Double check to see if this thing is valid
      todo = geddy.model.Todo.create(cleanTodo);
      if (!todo.isValid()) {
        return callback(todo.errors, null);
      }
      // Check to see if we have this to do item already
      geddy.db.todos.findOne({id: todo.id}, function(err, doc){
        if (err) {
          return callback(err, null);
        }
        // if we already have the to do item, update it with the new values
        if (doc) {
          geddy.db.todos.update({id: todo.id}, cleanTodo, function(err, docs){
            return callback(todo.errors, todo);
          });
        }
        // if we don't already have the to do item, save a new one
        else {
          todo.saved = true;
          geddy.db.todos.save(todo, function(err, docs){
            return callback(err, docs);
          });
        }
      });
    }

    Don’t be too daunted by this one; we started with the most complex one first. Remember that our save method has to account for both new todos and updating old todos. So let’s walk through this code step by step.

    We use the same callback code as we did before – if we don’t have a callback passed to us, just use an empty function.

    Then we sanitize our todo item. We have to do this because our todo object has JavaScript methods on it (like save), and Mongo doesn’t like it when you pass it objects with methods on them. So we just create a new object with just the properties that we care about on it.

    Then, we check to see if the todo is valid. If it’s not, we call the callback with the validation errors. If it is, we continue on.

    In case we already have this todo item in the db, we check the db to see if a todo exists. This is where we start to use the mongodb-wrapper module. It gives us a clean API to work with our db. Here we’re using the db.todos.findOne() method to find a single document that statisfies our query. Our query is a simple js object – we’re looking for a document whose id is the same as our todos id. If we find one and there isn’t an error, we use the db.todos.update() method to update the document with the new data. If we don’t find one, we use the db.todos.save() method to save a new document with the todo item’s data.

    In all cases, we call a callback when we’re done, with any errors that we got and the docs that the db returned to us being passed to it.

    Editing the all method

    Take a look at the all method, it should look like this:

    this.all = function (callback) {
      callback(null, geddy.todos);
    }

    Let’s make it look like this:

    this.all = function (callback) {
      var todos = [];
      geddy.db.todos.find().sort({status: -1, title: 1}).toArray(function(err, docs){
        // if there's an error, return early
        if (err) {
          return callback(err, null);
        }
        // iterate through the docs and create models out of them
        for (var i in docs) {
          todos.push( geddy.model.Todo.create(docs[i]) )
        }
        return callback(null, todos);
      });
    }

    Much simpler than the save method, don’t you think? We use the db.todos.find() method to get all the items in the todos collection. We’re using monogdb-wrapper’s api to sort the results by status (in decending alphabetical order) and by title (in ascending alphabetical order). Then we send that to an array, which triggers the query to start. Once we get our data back, we check to see if there are any errors, if there are, we call the callback with the error. If there aren’t any errors we continue on.

    Then, we loop through all the docs (the documents that mongo gave back to us), create new todo model instances for each of them, and push them to a todos array. When we’re done there, we call the callback, passing in the todos.

    Editing the load method

    Take a look at the ‘load’ method, it should look something like this:

     this.load = function (id, callback) {
      for (var i in geddy.todos) {
        if (geddy.todos[i].id == id) {
          return callback(null, geddy.todos[i]);
        }
      }
      callback({message: "To Do not found"}, null);
    };

    Let’s make it look like this:

    this.load = function (id, callback) {
      var todo;
      // find a todo in the db
      geddy.db.todos.findOne({id: id}, function(err, doc){
        // if there's an error, return early
        if (err) {
          return callback(err, null);
        }
        // if there's a doc, create a model out of it
        if (doc) {
          todo = geddy.model.Todo.create(doc);
        }
        return callback(null, todo);
      });
    };

    This one is even simpler. We use the db.todos.findOne() method again. This time, that’s all we have to use though. If we have an error, we call the callback with it, if not, we continue on (seeing a pattern here yet?). If we have a doc, we create a new instance of the todo model and call the callback with it. That’s it for that one.

    Editing the remove method

    Take a look at the remove method now, it should look like this:

    this.remove = function(id, callback) {
      if (typeof callback != 'function') {
        callback = function(){};
      }
      for (var i in geddy.todos) {
        if (geddy.todos[i].id == id) {
          geddy.todos.splice(i, 1);
          return callback(null);
        }
      }
      return callback({message: "To Do not found"});
    };

    Let’s make it look like this:

    this.remove = function(id, callback) {
      if (typeof callback != 'function') {
        callback = function(){};
      }
      geddy.db.todos.remove({id: id}, function(err, res){
        callback(err);
      });
    }

    The remove method is even shorter than it used to be. We use the db.todos.remove() method to remove any documents with the passed in id and call the callback with an error (if any).

    Time for the Magic

    Let’s go test our app: cd into your project’s directory and start up the server with geddy. Create a new todo. Try editing it, have it fail some validations, and try removing it. It all works!

    Conclusion

    I hope you’ve enjoyed learning about Node.js, MongoDB and especially Geddy. I’m sure by now you’ve got a million ideas for what you could build with it, and I’d love to hear about them. As always, if you have any questions, leave a comment here or open up an issue on github.


Planet PHP

  • Permalink for 'Developing A ZF2 Blog'

    Developing A ZF2 Blog

    Posted: April 3rd, 2012, 7:45am MDT by Matthew Weier O'Phinney

    This post tells a story.

    A long time ago, I set out to write my own blog platform. Yes, WordPress is a fine blogging platform, as is Serendipity (aka "s9y", and my previous platform). And yes, I know about Habari. And, for those of you skimming ahead, yes, I'm quite aware of Jekyll, thank you anyways.

    Why write something of my own? Well, of course, there's the fact that I'm a developer, and have control issues. Then there's also the fact that a blog is both a simple enough domain to allow easily experimenting with new technology and paradigms, while simultaneously providing a complex enough domain to expose non-trivial issues.

    When I started this project, it was a technology-centered endeavor; I wanted to play with document databases such as CouchDB and MongoDB, and with caching technologies like memcached and redis.

    Not long after I started, I also realized it was a great playground for me to prototype ideas for ZF2; in fact, the original DI and MVC prototypes lived as branches of my blog. (My repository is still named "zf2sandbox" to this day, though it technically houses just my site.)

    Over time, I had a few realizations. First, my actual blog was suffering. I wasn't taking the time to perform security updates, nor even normal upgrades, and was so far behind as to make the process non-trivial, particularly as I had a custom theme, and because I was proxying to my blog via a ZF app in order to facilitate a cohesive site look-and-feel. I needed to either sink time into upgrading, or finish my blog.

    My second realization, however, was the more important one: I wanted a platform where I could write how I want to write. I am a keyboard-centric developer and computer user, and while I love the web, I hate typing in its forms. Additionally, my posts often take longer than a typical browser session -- which leaves me either losing my work in a GUI admin, or having to write first in my editor of choice, and then cut-and-paste it to the web forms. Finally, I want versions I can easily browse with standard diffing tools.

    When it came down to it, my blog content is basically static. Occasionally, I'll update a post, but it's rare. Comments are really the only dynamic aspect of the blog... and what I had with s9y was not cutting it, as I was getting more spam than I could keep up with. New commenting platforms such as Livefyre and Disqus provide more features than most blogging platforms I know, and provide another side benefit: because they are javascript-based, you can simply drop in a small amount of markup into your post once -- meaning your pages can be fully static!

    Add these thoughts to the rise of static blogging platforms such as the aforementioned Jekyll, and I had a kernel of an idea: take the work I'd done already, and create a static blog generator.

  • Permalink for 'Upgrade woes III: Suhosin and PHP 5.4.0'

    Upgrade woes III: Suhosin and PHP 5.4.0

    Posted: April 2nd, 2012, 7:20am MDT by Dr. Christopher Kunz - PHP

    To complete the trinity of infamy: There is no Suhosin for PHP 5.4.0 either.


    The patch is no longer bundled with distribution PHP. I have fired a mail to i0n1c about this but he seems to be in transit currently. The extension (0.9.33) does not compile with PHP 5.4.0 because of the copious API changes. 

  • Permalink for 'Upgrade woes II: eAccelerator and PHP 5.4.0'

    Upgrade woes II: eAccelerator and PHP 5.4.0

    Posted: April 2nd, 2012, 7:15am MDT by Dr. Christopher Kunz - PHP

    The “eAccelerator” project seems to be in hiatus. There haven’t been any changes to the downloadable files since 2010 (version 0.9.6.1). With PHP 5.4.0 released and a major bump in the Zend API coming with it, I was not expecting eAccelerator 0.9.6.1 to compile. And sure enough, it fails quite soon into the make process. 


    eaccelerator.net is an Apache placeholder page, the SF site is not maintained anymore - time to let go.


    So, no eAccelerator for PHP 5.4.0 (FWIW, anyway...) and onwards.


    "Upgrade woes II: eAccelerator and PHP 5.4.0" vollständig lesen
  • Permalink for 'Upgrade woes I: Gallery3 and PHP 5.4.0'

    Upgrade woes I: Gallery3 and PHP 5.4.0

    Posted: April 2nd, 2012, 6:37am MDT by Dr. Christopher Kunz - PHP

    I recently upgraded this machine to Debian Wheezy (mainly to fix odd kernel crash issues that occured a couple times now) and this included a new PHP version. 5.4.0 has been stable for a month now, so I was eager to give it a spin. 


    Almost all applications worked without any changes, apart from the popular “Gallery” script. Gallery3 just stopped working after upgrading to PHP 5.4.0. I maintain a fairly large gallery here, so it was vital for me to keep it running.


    After restarting Apache, the application greeted me with this error:


    Notice: Undefined offset: 1 in /home/www/htdocs/gallery3.christopher-kunz.de/system/libraries/I18n.php on line 60


    Fatal error: Uncaught exception ‘Kohana_PHP_Exception’ with
    message ‘Undefined offset: 1’ in
    /home/www/htdocs/gallery3.christopher-kunz.de/system/libraries/I18n.php:60
    Stack
    trace:
    #0
    /home/www/htdocs/gallery3.christopher-kunz.de/system/libraries/I18n.php(60):
    Kohana_PHP_Exception_Core::error_handler(8, ‘Undefined offse...’,
    ’/home/www/htdoc...’, 60, Array)
    #1
    /home/www/htdocs/gallery3.christopher-kunz.de/system/libraries/I18n.php(93):
    I18n_Core::get_text(’Undefined offse...’)
    #2
    /home/www/htdocs/gallery3.christopher-kunz.de/system/core/Kohana_Exception.php(42):
    __(’Undefined offse...’, NULL)
    #3
    /home/www/htdocs/gallery3.christopher-kunz.de/system/libraries/Kohana_PHP_Exception.php(60):
    Kohana_Exception_Core->__construct(’Undefined offse...’)
    #4
    /home/www/htdocs/gallery3.christopher-kunz.de/system/libraries/Kohana_PHP_Exception.php(95):
    Kohana_PHP_Exception_Core->__construct(8, ‘Undefined offse...’,
    ’/home/www/htdoc...’, 60)
    #5 [internal function]:
    Kohana_PHP_Exception_Core::shutdown_handler(NULL)
    #6 /home/www/htdocs/gall in /home/www/htdocs/gallery3.christopher-kunz.de/system/libraries/I18n.php on line 60


    Updating Gallery to the current version 3.0.2 didn’t fix the issue. Neither did the latest Git checkout, and my locales were all fine and dandy. When googling for the error, I found a thread where the original Gallery author debugged this issue in an earlier version of Gallery. That thread gave me a hint that the issue might have been caused by an incorrect php.ini setting.


    From wheezy on, Debian is packaging libapache2-mod-php5filter instead of the old libapache2-mod-php5. This new module has a new subdirectory in /etc/php5/ and thus brings a new configuration. I found that the way to fix the I18n.php issue is setting a timezone like this:



    1. vi /etc/php5/apache2filter/php.ini

    2. Search for “timezone”

    3. Change the commented line to:
      date.timezone = CET
      (or whatever your local time zone is)

    4. Restart Apache: service restart apache2


    After this, there was no more PHP notice and sad smiley - but there was no Gallery, either. All I got was a blank screen and no error was logged. Cranking up error_reporting and even trying the method described in the Gallery3 debugging guide did not yield any usable output.


    Googling helped, again. It seems that the output buffering functions have changed in 5.4.0. What was right for 5.3 seems to be broken now - so output buffering methods in Gallery3 have to be tweaked slightly.



    1. Change to your gallery3 root directory.

    2. vi system/core/Kohana.php

    3. :530 (go to line 530)

    4. Comment out the ob_end_clean() call

    5. Save & exit

    After applying this hotfix, everything started working again.

    So, the TL;DR version to fix Gallery3 in Debian Wheezy with PHP 5.4.0:



    • set date.timezone = <your-timezone> in php.ini and restart Apache

    • comment-out line 530 in gallery3/system/core/Kohana.php

    Hope this helps anyone.

    "Upgrade woes I: Gallery3 and PHP 5.4.0" vollständig lesen
  • Permalink for 'Monitoring Symfony Applications'

    Monitoring Symfony Applications

    Posted: April 2nd, 2012, 2:02am MDT by Liip

    For one of our projects we wanted to be able to check the system health once we go live. Our idea was to have a system that let us see the status of the services like MySQL or Memcached from the point of view of the application itself. Since our project was developed in PHP using the Symfony framework we decided to create a new Symfony bundle where we could implement this functionality. The bundle is called LiipMonitorBundle and can be obtained here.

    So one goal of our bundle was to do something more advanced than a simple "Ping" to a server –for that we can just use Nagios. We wanted that the bundle could do something like: "Let's write a session object to Redis, updating the user membership status, read it back and see that the data stored in the server is correct". So we can know more than just a simple "ping redis". Also when we get a report that the system is misbehaving we want to be able to run the health checks from the point of view of the app itself. For example we can ping Redis and see that is up and running but that doesn't mean our application is using it properly.

    A second goal was that the health checks themselves should be easy to write and easy to run. Also they should be totally independent from the bundle itself. So the bundle should provide functionality for auto discovering health checks, for running them and for giving reports, but it should not provide any health checks. That means that the health checks should be implemented by the applications themselves.

    In regard to how to run the checks we added two possibilities: via web using a REST API and by using the command line. Also since each health check has an id that identifies it, we can run the checks all together or individually. If the checks succeed you get an "OK" message for each of them. If they fail you get a "KO" plus the message from the Exception that made the test fail.

    Now, what are health checks, how do you implement them? Health checks are simply a PHP class that implements the CheckInterface from the MonitorBundle. This interface has two methods: CheckInterface::check and CheckInterface::getName. The method getName just returns the Health Check name while the method check implements the actual logic for the health check. The bundle documentation explains these in detail.

    Once we implement a health check we have to add it as a service to our Service Container and tag it as monitor.check. By doing just that our health check is ready and available to be picked up by the bundle's Health Check Runner.

    Running health checks from the command line is quite easy, just execute the following command and you will see the results right away:

    $ ./app/console monitor:health
    Jackrabbit Health Check: OK
    Redis Health Check: OK
    Memcache Health Check: KO - No configuration set for session.save_path
    PHP Extensions Health Check: OK
    

    As you can see there the bundle ran four Health Checks of which only the Memcache one failed.

    Health Checks are not only for your applications, you could also ship them inside your bundles and let the bundle auto-discover them. This means that for example if you create your own bundle that say connects to a RabbitMQ, your bundle could provide the health checks required to see that your connection with RabbitMQ is working as expected.

    As for the technology the bundle has a couple of peculiarities. Since the bundle provides also a REST API that allows us to run health checks and get the replies as JSON objects we built a web app for it that's implemented using Ember.js. Ember.js is an MVC javascript framework that deserves a post on it's own. You can learn more about it here. The views for the Ember.js app are rendered by Symfony with a template engine agnostic solution. By doing that the bundle doesn't require for you to use Twig or the PHP templating engine from Symfony. We had to provide that feature since we have apps that use Twig for frontend views and PHP for backen views.

    All in all we've got an easy to use bundle that was quite well received by the Symfony community, counting 49 followers on Github and 2 forks. From one of those forks we already merged pull request. Apart from that it spawned a new bundle called LiipMonitorExtraBundle that serves as a repository of reusable Health Checks for and by the community. Is time that you fork it and contribute your own health checks.

    P. S.: As a side note a week after the bundle was released a new Java web framework came to life with exactly the same concept. That framework was created by @coda an engineer that works at Yammer.

  • Permalink for 'Some videos'

    Some videos

    Posted: April 1st, 2012, 4:33pm MDT by Johannes Schlüter

    Over the years a few videos of my presentations and some interviews were published. I've collected the ones I found and put them on a single web page. The oldest is from 2009 the latests just from February this year. Enjoy.

    If you have another video which I missed: Please let me know!

  • Permalink for 'A New Paradigm Rises to Save the Modern Web'

    A New Paradigm Rises to Save the Modern Web

    Posted: April 1st, 2012, 11:00am MDT by Court Ewing
    A New Paradigm Rises to Save the Modern Web

    This was my April Fools day post for 2012. To clarify a few things:

    • As far as I know, array-oriented programming is not a thing. I sure hope it never becomes a thing.
    • The code that I provided may have some cool components, but it is not good overall. It is very inflexible and extremely fragile. I broke it a half dozen times just trying to make simple changes, and it took me 10x longer to write than would be necessary in another coding style.
    • Verbosity should not be a goal of any paradigm. If you choose to be verbose with your code, so be it. Good paradigms, like object-oriented and functional programming, empower you to make that sort of decision yourself.
    • If you dig the usage of anonymous functions here, then I highly recommend that you try out some functional programming. It is fun.
    • The new array syntax in PHP 5.4 is rad as hell.
    • No core developers were harmed in the making of this blog article.

    April Fools!

    Programming on the web has come a long way since the wild-west early days of the 90s, and nowhere has this been more evident than in the PHP community. The earliest "apps" made with PHP were little more than some odd scripting bits that helped web pioneers and hobbyists to more easily maintain their html websites. At the turn of the century, larger, procedural PHP apps started to pop up that would eventually change the web as we knew it. Less than a decade later, the widespread adoption of object-oriented programming throughout most web development communities had led to some of the most sophisticated triumphs of software engineering (or hackery) in history.

    But just as procedural coding proved insufficient for developing the types of applications that the consumers of the web demanded, the usefulness of object-oriented programming is rapidly reaching its limits. Object-oriented programming ultimately results in highly complex, bloated, and inconsistent code bases that cannot sustain the growing demand they will no doubt receive. Once an object-oriented app reaches a certain mass, those problems begin to create cracks in its very foundation.

    To free us from these constraints, some look to new systems that boast event-driven, functional foundations such as node.js. Communities behind these systems make bold claims about the impact they will have on the web of tomorrow, but while this approach certainly has its benefits, it suffers from the very huge obstacle of being completely incompatible with their existing app architectures. To truly revolutionize the web as a whole, a new system or paradigm must allow users to incrementally update their existing apps and workflows.

    Fortunately, there is now a new paradigm that originated within the PHP community that is rapidly changing the way we develop web and mobile apps. Array-oriented programming (AOP) combines all of the structure of object-oriented systems with the ease-of-use and efficiency that could exist in procedural apps, and it does so in a highly consistent way. Best of all, it can be done in any programming language that supports arrays, and it can be used to build entirely new apps or even incrementally refactored into existing apps regardless of whether they were procedural or object-oriented to begin with.

    Array-oriented programming is based on one driving principle, an entire program structure and flow is defined as an array. It really is as simple as it sounds.

    AOP is not a new concept, but it is just now gaining traction in the web development community. There are countless articles scattered across the web that go into great detail about the technical intricacies of this revolutionary paradigm, so I won't bore you by driving in all of those same points. Instead, let's take a look at a complete array-oriented program:

    <?php
    $app = array(</p>
    
    <pre><code>'session' => array(),
    'request' => array(
        'method' => 'GET',
        'uri' => '',
        'data' => array()
    ),
    'response' => array(
        'body' => '',
        'headers' => array()
    ),
    'errors' => array(
        404 => function(&$request, &$response) {
            $response['body'] = '404 Not Found';
            $response['headers'][] = 'Status: 404';
    

    Truncated by Planet PHP, read more at the original (another 6752 bytes)

  • Permalink for 'A New Paradigm Rises to Save the Modern Web'

    A New Paradigm Rises to Save the Modern Web

    Posted: April 1st, 2012, 7:38am MDT by Court Ewing
    A New Paradigm Rises to Save the Modern Web

    Programming on the web has come a long way since the wild-west early days of the 90s, and nowhere has this been more evident than in the PHP community. The earliest "apps" made with PHP were little more than some odd scripting bits that helped web pioneers and hobbyists to more easily maintain their html websites. At the turn of the century, larger, procedural PHP apps started to pop up that would eventually change the web as we knew it. Less than a decade later, the widespread adoption of object-oriented programming throughout most web development communities had led to some of the most sophisticated triumphs of software engineering (or hackery) in history.

    But just as procedural coding proved insufficient for developing the types of applications that the consumers of the web demanded, the usefulness of object-oriented programming is rapidly reaching its limits. Object-oriented programming ultimately results in highly complex, bloated, and inconsistent code bases that cannot sustain the growing demand they will no doubt receive. Once an object-oriented app reaches a certain mass, those problems begin to create cracks in its very foundation.

    To free us from these constraints, some look to new systems that boast event-driven, functional foundations such as node.js. Communities behind these systems make bold claims about the impact they will have on the web of tomorrow, but while this approach certainly has its benefits, it suffers from the very huge obstacle of being completely incompatible with their existing app architectures. To truly revolutionize the web as a whole, a new system or paradigm must allow users to incrementally update their existing apps and workflows.

    Fortunately, there is now a new paradigm that originated within the PHP community that is rapidly changing the way we develop web and mobile apps. Array-oriented programming (AOP) combines all of the structure of object-oriented systems with the ease-of-use and efficiency that could exist in procedural apps, and it does so in a highly consistent way. Best of all, it can be done in any programming language that supports arrays, and it can be used to build entirely new apps or even incrementally refactored into existing apps regardless of whether they were procedural or object-oriented to begin with.

    Array-oriented programming is based on one driving principle, an entire program structure and flow is defined as an array. It really is as simple as it sounds.

    AOP is not a new concept, but it is just now gaining traction in the web development community. There are countless articles scattered across the web that go into great detail about the technical intricacies of this revolutionary paradigm, so I won't bore you by driving in all of those same points. Instead, let's take a look at a complete array-oriented program:

    <?php
    $app = array(</p>
    
    <pre><code>'session' => array(),
    'request' => array(
        'method' => 'GET',
        'uri' => '',
        'data' => array()
    ),
    'response' => array(
        'body' => '',
        'headers' => array()
    ),
    'errors' => array(
        404 => function(&$request, &$response) {
            $response['body'] = '404 Not Found';
            $response['headers'][] = 'Status: 404';
        }
    ),
    'routes' => array(
        'GET /' => function(&$request, &$response, &$session) {
            $name = isset($session['name']) ? $session['name'] : 'World';
            ob_start();
            // not shown, but your standard php template
            include '../template/home.phtml';
            $response['body'] = ob_get_contents();
            ob_end_clean();
        },
        'POST /' => function(&$request, &$response, &$session) {
            if (isset($request['data']['name'])) {
                $session['name'] = $request['data']['name'];
    

    Truncated by Planet PHP, read more at the original (another 5614 bytes)

Nettuts+

  • Permalink for 'Getting Cozy With Underscore.js'

    Getting Cozy With Underscore.js

    Posted: March 31st, 2012, 2:36pm MDT by Siddharth

    As JavaScript is slowly moving out of the browser, several tools have emerged that significantly improve JavaScript’s robustness.

    One such tool is called Underscore.js and that’s what we’re going to take a look at today. Let’s get started!

    Meet Underscore.js

    So what exactly does Underscore do?

    Underscore is a utility-belt library for JavaScript that provides a lot of the functional programming support that you would expect in Prototype.js (or Ruby), but without extending any of the built-in JavaScript objects.

    One of the nicer things about working in Python or Ruby are the fancy constructs like map that make life a lot easier. The current version of JavaScript, sadly, is fairly barebones when it comes to low level utilities.

    As you read above, Underscore.js is a nifty little JavaScript library that brings in a ridiculous amount of functionality at a mere 4kb.

    Underscore in Action

    “Enough yapping about the library”, I can hear you say. Right you are! Let’s take a look at Underscore in action first before I resume my yapping.

    Let’s assume you have a random array of test scores and you need a list of those with 90+ score. You’d usually write up something like so:

    var scores = [84, 99, 91, 65, 87, 55, 72, 68, 95, 42],
    topScorers = [], scoreLimit = 90;
    
    for (i=0; i<=scores.length; i++)
    {
    	if (scores[i]>scoreLimit)
    	{
    		topScorers.push(scores[i]);
    	}
    }
    
    console.log(topScorers);
    

    It’s pretty simple and even with optimization, it’s fairly verbose for what we’re trying to do.

    Let’s look at what we can achieve with Underscore next.

    
    var scores = [84, 99, 91, 65, 87, 55, 72, 68, 95, 42],
    topScorers = [], scoreLimit = 90;
    
    topScorers = _.select(scores, function(score){ return score > scoreLimit;});
    
    console.log(topScorers);
    

    I don’t know about you but I just had a nerdgasm. That’s some incredibly concise and readable code right there.

    Sweet but Do I Really Need This?

    Well, it all depends on what you’re trying to do. If your use of JavaScript is limited to merely playing around with the DOM, then the answer is mostly no since jQuery does most of what you’d want to do.

    Yes.

    On the other hand, if you’re dealing with non-DOM code or even complex, think MVC, front end code, Underscore is an absolute boon.

    While some of the functionality exposed by the library is slowly making its way into the ECMA specifications, it’s not available in all browsers and making your code work cross browser is another nightmare on its own. Underscore provides you with a nice set of abstractions that work everywhere.

    And if you’re a performance oriented person, as you should be, Underscore falls back to native implementations, if available, to make sure performance is as optimal as possible.

    Getting Started

    Just grab the source here, include it in your page and you’re good to go.

    If you were expecting a big set up process, you’re going to be sorely disappointed. Just grab the source here, include it in your page and you’re good to go.

    Underscore creates and exposes all its functionality via a single object, in global scope. This object is the titular underscore character, _.

    If you’re wondering, yes, this is quite similar to how jQuery works with the dollar [$] symbol. And just like jQuery, you can remap this character in case you run into conflicts. Or if you’re like me and have an irrational love for the tilde.

    Functional or Object Oriented?

    While the official marketing blurb for the library states that it adds functional programming support, there is actually another way of doing things.

    Let’s take our earlier code as an example:

    
    var scores = [84, 99, 91, 65, 87, 55, 72, 68, 95, 42], topScorers = [], scoreLimit = 90;
    
    topScorers = _.select(scores, function(score){ return score > scoreLimit;});
    
    console.log(topScorers);
    

    This method above is the functional, or procedural, approach. You can also use a more straightforward, probably more apparent, object oriented approach.

    
    var scores = [84, 99, 91, 65, 87, 55, 72, 68, 95, 42], topScorers = [], scoreLimit = 90;
    
    topScorers = _(scores).select(function(score){ return score > scoreLimit;});
    
    console.log(topScorers);
    

    There is no real ‘right’ way to do things but keep in mind that you can jQuery-esque method chaining with the latter method.

    Checking Out the Functionality

    Underscore provides a little more than 60 functions that span a number of functionalities. At their core, they can be classified into groups of functions that operate on:

    • Collections
    • Arrays
    • Objects
    • Functions
    • Utilities

    Let’s take a look at what each does and if applicable,one or two of my favorites from each section.

    Collections

    A collection can either be an array or an object, an associate array in JavaScript if I’m to be semantically correct.

    Underscore provides a lot of methods that operate on collections. We saw the select method earlier. Here are a few more incredibly useful ones.

    Pluck

    Let’s say you have a nice little array containing key value pairs and you’d like to extract just a specific property from each. With Underscore, it’s a cinch.

    
    var Tuts = [{name : 'NetTuts', niche : 'Web Development'}, {name : 'WPTuts', niche : 'WordPress'}, {name : 'PSDTuts', niche : 'PhotoShop'}, {name : 'AeTuts', niche : 'After Effects'}];
    var niches = _.pluck(Tuts, 'niche');
    
    console.log(niches);
    
    // ["Web Development", "WordPress", "PhotoShop", "After Effects"]
    

    Using pluck is as simply as passing in the target object or array as well as which property to pick out. Here, I’m merely extracting the niche for each site.

    Map

    Map creates an array from a collection where each element can be mutated or otherwise changed through a function.

    Let’s take the earlier example and extend it a bit.

    
    var Tuts = [{name : 'NetTuts', niche : 'Web Development'}, {name : 'WPTuts', niche : 'WordPress'}, {name : 'PSDTuts', niche : 'PhotoShop'}, {name : 'AeTuts', niche : 'After Effects'}];
    
    var names = _(Tuts).pluck('name').map(function (value){return value + '+'});
    
    console.log(names);
    
    // ["NetTuts+", "WPTuts+", "PSDTuts+", "AeTuts+"]
    

    Since I noticed the names missing the plus sign at the end, I’m adding them in the extracted array.

    You’re not limited to simple concatenation here. You’re free to modify the passed value to your heart’s desires.

    All

    all is useful if you need to check every value in a collection passes a certain criteria. To check whether a student has passed in every subject, for example.

    
    var Scores = [95, 82, 98, 78, 65];
    var hasPassed = _(Scores).all(function (value){return value>50; });
    
    console.log(hasPassed);
    
    // true
    
    Arrays

    Underscore has a bunch of functions that work exclusively on arrays which is highly welcome since, compared to other languages, JavaScript provides awfully few methods dealing with arrays.

    Uniq

    This method basically parses an array and removes all duplicate elements providing you with only unique elements.

    
    var uniqTest = _.uniq([1,5,4,4,5,2,1,1,3,2,2,3,4,1]);
    
    console.log(uniqTest);
    
    // [1, 5, 4, 2, 3]
    

    This comes in extremely handy when you’re parsing huge datasets and need to weed out the duplicates. Keep in mind that only the first instance of an element is counted so the original order is kept.

    Range

    An extremely handy method that lets you create a ‘range’ or list of numbers. Let’s look at a super quick example.

    
    var tens = _.range(0, 100, 10);
    
    console.log(tens);
    
    // [0, 10, 20, 30, 40, 50, 60, 70, 80, 90]
    

    The method’s parameters are, in order, starting value, ending value and step value. If you’re wondering, using a negative step value leads to a decrementing range.

    Intersection

    This method compares two arrays to each others and returns the list of elements that are found in all of the passed arrays i.e. an intersection in set theory.

    Let’s extend the earlier example to see how this works.

    
    var tens = _.range(0, 100, 10), eights = _.range(0, 100, 8), fives = _.range(0, 100, 5);
    
    var common = _.intersection(tens, eights, fives );
    
    console.log(common);
    
    // [0, 40, 80]
    

    Easy, right? You just pass in the list of arrays to compare and Underscore does the rest.

    Objects

    In addition to the fairly expected is checks, Underscore provides various methods to clone, extend and other manipulate objects.

    Here are a few of my favorites.

    Keys and Values

    Have a massive object where you need only the keys or only the values? It’s so darn easy with Underscore.

    
    var Tuts = { NetTuts : 'Web Development',  WPTuts : 'WordPress',  PSDTuts : 'PhotoShop', AeTuts : 'After Effects'};
    var keys = _.keys(Tuts), values = _.values(Tuts);
    
    console.log(keys + values);
    
    // NetTuts,WPTuts,PSDTuts,AeTutsWeb Development,WordPress,PhotoShop,After Effects
    
    Defaults

    This method is quite useful when you need to create objects with sensible defaults when one might not be used when creating it.

    
    var tuts = { NetTuts : 'Web Development'};
    var defaults = { NetTuts : 'Web Development', niche: 'Education'};
    
    _.defaults(tuts, defaults);
    
    console.log(tuts);
    
    // Object { NetTuts="Web Development", niche="Education"}
    
    Functions

    As wonky as it sounds, Underscore has functions that work on functions. Most of the functions tend to be fairly complicated to explain here, so we’ll take a look at the simplest.

    Bind

    this is an elusive part of JavaScript and tends to leave a lot of developers really confused. This method seeks to make it a bit easier to tackle.

    
    var o = { greeting: "Howdy" },
    	f = function(name) { return this.greeting +" "+ name; };
    
      var greet = _.bind(f, o); 
    
      greet("Jess")
    

    It’s a bit confusing so stay with me here. The bind functions basically lets you keep the value of this whenever and wherever the function is called.

    This is specially useful when you’re working with event handlers where this is hijacked.

    Utilities

    And to further sweeten the deal, Underscore provides a ton of utility functions. Since we’re fairly out of time, let’s just look at the biggie.

    Templating

    There are already a ton of templating solutions out there but Underscore makes its solution worth a look by being fairly tiny in its implementation whilst being fairly powerful.

    Let’s take a look at a quickie example.

    
    var data =   {site: 'NetTuts'}, template =   'Welcome! You are at <%= site %>';
    
    var parsedTemplate = _.template(template,  data );
    
    console.log(parsedTemplate);
    
    // Welcome! You are at NetTuts
    

    First up, we create the data to populate the template followed by the template itself. By default, Underscore uses ERB style delimiters though this is entirely customizable.

    With those in place, we can simply call the template passing in our template and the data. We store the result in a separate string to be used later to update content, as needed.

    Keep in mind that this is an extremely simple demonstration of Underscore’s templating. You can find use any JavaScript code inside the template using the delimiters. When you need to iterate over complex objects, say JSON sources, you can pair up with Underscore’s excellent collection functions to create templates rapidly.

    Still Not Convinced That You Should Pick This

    jQuery and Underscore go hand in hand.

    No, no, you’ve got it all wrong! If anything, jQuery and Underscore complement each other well and go hand in hand. Really!

    See, jQuery does a few things extremely well. DOM manipulation and animation are chief amongst those. It doesn’t deal with anything in the higher or lower levels. If frameworks like Backbone or Knockout deal with the higher level issues, Underscore tackles all the relatively bare metal ones.

    For even more perspective, jQuery has little purpose outside the browser as the bulk of its functionality deals with the DOM. Underscore, on the other hand, can be used on the browser or on the server side without any issues. In fact, Underscore has the most number of Node modules dependent on it.

    Well, that’s about it for today. Considering the scope of Underscore, we’ve barely scratched the surface here. Make sure to check out more of the library and let me know if you have any questions in the comments below. Thank you so much for reading!


  • Permalink for 'Join Us on Facebook for Exclusive Freebies, Discounts & Wallpapers!'

    Join Us on Facebook for Exclusive Freebies, Discounts & Wallpapers!

    Posted: March 30th, 2012, 7:31am MDT by David Appleyard

    We’re excited to let you know about our all-new Facebook page designs, and we’re kicking off a big promotion to offer lots of awesome content for our Facebook fans! Read on to find out how to access our exclusive tutorials, book discounts, and all-new wallpaper pack…

    All-New Facebook Page Designs

    We’ve launched a series of awesome re-designs across our Facebook pages with new cover images, and the updated timeline design! Now is the perfect time to swing by and take a look:

    Exclusive Freebies & Discounts Facebook Freebies

    We’ve also announced a series of awesome freebies and discounts for all our fans on Facebook. All you need to do is head over to the page for your favourite site, and hit “Like”. It’s that easy! Here’s what you’ll receive as one of our fans:

    An Exclusive Tutorial

    Each of our Facebook pages has a brand new, exclusive tutorial that isn’t available anywhere else. These are all top-notch educational content, of the standard you’ve come to expect from Tuts+!

    Bonus Resources & Assets

    We’ve collected some of our favourite freebies, resources and assets, and put them all in one place for you to download. Whether you’re looking for an icon set, a texture pack, or a bunch of WordPress cheat sheets, they’re now all available in one place.

    10% Off Your Next Rockable Purchase

    Rockable Press publishes a wide array of different books for creative professionals — everything from the latest web development techniques, to photography and freelancing!

    As our Facebook fan, we’d like to offer you a 10% discount on any purchase from Rockable. Just use your exclusive coupon code when checking out through eJunkie!

    Our All-New Tuts+ Wallpaper Pack

    And if that wasn’t enough, how about a Facebook exclusive wallpaper pack for your favourite Tuts+ site? It comes in 11 different styles, and sizes are included for a desktop monitor, iPhone, and iPad.

    Don’t forget that each of our Facebook pages has a unique set of freebies… You can check out each page for a different set of downloads!

    Check out the Nettuts+ Facebook Page


Planet PHP

  • Permalink for 'Tech Culture: More Legos and Less Punch Buggy '

    Tech Culture: More Legos and Less Punch Buggy

    Posted: March 29th, 2012, 1:26pm MDT by Elizabeth Naramore

    Recently I was a guest on a panel podcast hosted by Cal Evans that included Laura Thomson, Beth Tucker, and Anna Filina. It was entitled “Sexism in Tech” and was a response to some of the recent goings-on in the tech community. It was a very fun podcast, and I encourage you to give it a listen. Even if you’re tired of hearing about the issue, I promise there will be something there you can take away, because we didn’t just rehash the same old conversations.

    While we talked about many things related to being a woman in a male-dominated field, one of the main things we talked about was this feeling of empathy. And it got me thinking about a few things.

    So, my kids love to play the Punch Buggy Game. If you don’t know the game, it goes like this: when you’re driving around, if you see a VW Beetle, you call it out and punch the person next to you in the arm. In our car, it usually goes something like this:

    Kid #1: “Punch buggy red!” *punch* “No punch backs.”

    Kid #2: “Ouch that hurt!”

    Kid #1: “No, it didn’t.”

    Kid #2: “Yes, it did!”

    Kid #1: “No, it didn’t!”

    Me: “Alright, no more playing Punch Buggy if you all can’t get along.”When someone posts something controversial or “offensive” on the Internet, it’s kind of like playing a game of Punch Buggy, except it goes something like this:Person #1: “Here’s this thing that I think is fine.”

    Person #2: “Hey, that was offensive to me.”

    Person #1: “No, it wasn’t.”

    Person #2: “Yes, it was!”

    Person #1: “No, it wasn’t!”The thing with punching someone in the arm is, you really don’t know if you hurt them in the process. You aren’t that person, and you’re not feeling that pain. You can imagine what it would feel like for you if you were the one being punched and how you’d react. And if it’s different than how the other person reacts then clearly there is something wrong with them. But I can give the same punch in the arm to Mike Tyson and an 83 year old woman, and I can pretty much guarantee it will not feel the same to each of them. (No, I’m not advocating punching 83 year old women in the arm, for the record.)

    My point is that unless you are a true empath, you can’t feel the other person’s emotions. So for you to tell me that something doesn’t offend me, or that a punch doesn’t hurt me, well, that’s kind of ridiculous, isn't it.

    Just as there is a range of pain, there is a range of offensiveness. A punch from Mike Tyson will elicit a pretty similar reaction in everybody, just like there are things that happen that offend a large number of people. But generally speaking, what may be offensive to one person may or may not be offensive to another.

    The farther away you are from a situation, the harder it is to empathize. If you’ve not been a minority in a group before (especially in a career-type setting), then it is hard to even imagine what that’s like. A male friend recently came to me and told me about a childcare situation he was in where he was the only male. In this group of females, he was already feeling a bit apprehensive when one of them made a joke about him being a pedofile, and why was he there, etc. etc. He didn’t think the woman meant anything malicious, but was instead just clueless. Unfortunately, her insensitivity left my friend feeling hurt and even more awkward than before. Even though he loved working with kids, it tainted his whole experience, and made him question whether or not he even wanted to continue. A few synapse connections later, my friend came to me and said “now I know what you guys must feel like in this industry. I’m really sorry on behalf of us all.” In our game of Punch Buggy, my friend realized that a punch in the arm can hurt, even if the other person didn't mean for it to.

    Now, in contrast to Punch Buggy, when my kids play with Legos, it usually goes something like this:Kid #1: “Hey look at this car I made.”

    Kid #2: “Oh, that’s cool! I like the window."

    Kid #1: That’s supposed to be a door.”

    Kid #2: “Ohhh, yeah. I get it. Ok.”

    The dynamic the kids have when putting all things aside and just being creative is completely different than the Pu

    Truncated by Planet PHP, read more at the original (another 1241 bytes)

Nettuts+

  • Permalink for 'Recently in Web Development (March ’12 Edition)'

    Recently in Web Development (March ’12 Edition)

    Posted: March 29th, 2012, 1:25pm MDT by Siddharth

    Web development is an industry that’s in a state of constant flux with technologies and jargon changing and mutating in an endless cycle. Not to mention the sheer deluge of information one has to process everyday.

    In this series, published monthly, we’ll seek to rectify this by bringing you all the important news, announcements, releases and interesting discussions within the web development industry in a concise package. Join me after the jump!

    News and Releases

    All of the important news in a single place: releases, announcements, companies bickering, security issues and all related hoopla.

    Nettuts image PHP 5.4 is Out

    The venerable PHP language is now at version 5.4 with a lot of new features and additions including a built-in server and traits.

    Make sure to check out the release notes as well as our dedicated article on what’s new with the release.

    Release Notes
    PHP 5.4 is Here! What You Must Know

    Nettuts image Basic but Critical Rails Vulnerability Found

    Rails used to have a certain stigma attached to some time back — the infamous ‘Rails doesn’t scale. Now there’s another that threatens to easily overrun the earlier.

    Earlier this month, an enterprising Egor Homakov discovered a vulnerability due to the way Rails handles mass assignments of attributes. As a result, quite possibly numerous Rails based apps were open to easy attacks which leads us to our next story…

    Read more

    Nettuts image Github Gets Broken Into

    As a result of the vulnerability in Rails, mentioned above, Github got hacked with Egor gaining commit access and other admin privileges to every repository.

    How Egor announced his breakin

    Github’s response

    Nettuts image PHP Moves to Github

    In even more Github related news, the PHP project now has a copy for your checking out needs at Github now. The repo seems to be actively developer, as expected.

    Read more

    Nettuts image Chrome Overtakes IE, for a Day

    Oh how the mighty have fallen! For a single day earlier this month, Chrome overtook IE’s marketshare. Now though, things are back with IE claiming 34.8% while Chrome has 30.9%.

    Read more

    Nettuts image Python 3.3 and Django 1.4 Released

    For the Pythonistas, a couple of big releases this month.

    Django, one of my favorite Python frameworks, as well as Python itself got updated this month. Make sure to check out the changelogs below — both boast some massive feature additions.

    Python 3.3

    Django 1.4

    Nettuts image Amazon Drops Prices on AWS Services

    The Amazon palette of web apps have really made web development a lot easier over the past few years. In addition to constantly adding features, Amazon also cuts their prices a lot keeping our costs in line with savings from Moore’s law.

    Read more

    Nettuts image HaXe — a New Programming Language

    haXe is a new language that can be compiled to all popular programming platforms with its fast compiler – JavaScript, Flash, NekoVM, PHP, C++, C# and Java. It’s open source to boot!

    Read more

    New Kids on the Block

    As web developers, the sheer amount of resources we can tap into increases exponentially with time. Here is just a quick look at some recently created resources that deserve your attention — everything from new books to scripts and frameworks.

    Tower.js

    Full Stack Web Framework for Node.js and the Browser. Built on top of Node’s Connect and Express, modeled after Ruby on Rails. Built for the client and server from the ground up.

    Github Repo

    Graphene

    Graphene is a realtime dashboard & graphing toolkit based on D3 and Backbone.

    It was made to offer a very aesthetic realtime dashboard that lives on top of Graphite (but could be tailored to any back end, eventually).

    Github Repo

    Heatmap.js

    heatmap.js is a JavaScript library that can be used to generate web heatmaps with the html5canvas element based on your data. The heatmaps are fully customizable.

    Github Repo

    ShellJS

    ShellJS is a portable (Windows included) implementation of Unix shell commands on top of the Node.js API. You can use it to eliminate your shell script’s dependency on Unix while still keeping its familiar and powerful commands.

    Github Repo

    Messenger.js

    Messenger.js is a library that makes network communication via JSON dead simple and insanely fast!

    Github Repo

    Kalendae

    Kalendae is an attempt to do something that nobody has yet been able to do: make a date picker that doesn’t suck. It’s fully portable, no dependencies. No jQuery, no Prototype, no MooTools; just add the script and the stylesheet and you’re good to go.

    Github Repo

    AtomizeJS

    AtomizeJS is a JavaScript library for writing distributed programs, that run in the browser, without having to write any application specific logic on the server.

    Github Repo

    Cassovary

    Cassovary is a simple “big graph” processing library for the JVM. Most JVM-hosted graph libraries are flexible but not space efficient. Cassovary is designed from the ground up to first be able to efficiently handle graphs with billions of nodes and edges.

    Github Repo

    Surface JS

    Surface is a JS library intended to help manage single-page applications (or “Ajaxy” apps). It promotes decoupling of components and provides tools for navigating between “screens” and integrating with the browser history.

    Github Repo

    Noty

    noty is a jQuery plugin that makes it easy to create alert, success, error and confirmation messages as an alternative the standard alert dialog. Each notification is added to a queue. (Except growl like notifications)

    Github Repo

    Best of the Internet

    Often, you’re not really looking for a tutorial as much as you’re looking for a rant, an opinion or the musings of a tired developer or just something cool with absolutely zero real world use. This sections contains links to precisely those — interesting and cool stuff from the developer community.

    Nettuts image Interpreted Languages: PHP, Perl, Python, Ruby

    A side by side reference sheet of how to do common functions in PHP, Perl, Python and Ruby. Wonderfully useful if you have to learn the cesspool that is PERL.

    Read more

    Nettuts image Apache 2.4 Faster Than Nginx?

    Is the latest version of Apache faster than Nginx? Find out in this shootout!

    Read more

    Nettuts image Your Favourite Programming Language is Not Good Enough

    @fhaard explains why you’re a wuss if you’re too emotionally attached to a programming language. A great read!

    Read more

    Nettuts image PHP is Insecure (and Other Enterprise Open-Source F.U.D.)

    Benjamin Balter systematically disassembles a lot of false assumptions around the PHP platform. This is definitely something to link to the snooty Rails developer in your social circle — everyone probably has come in touch with this mythical brogrammer.

    Read more

    Nettuts image What’s the Difference Between a URI and a URL?

    One of those questions that I was too ashamed to ask. Thankfully, I ran into this StackOverflow post which does a stellar job of explaining the difference.

    Read more

    Nettuts image Why You Should Never, Ever, EVER Use Linked-list in Your Code Again

    This is one for the relatively low level programmer. It’s easy to forget that we have plenty of data structures other than arrays and hashes when it comes to web development but if you’re remotely interested in a different paradigm, this is a great read.

    Read more

    Wrapping Up

    Well, that’s about all the major changes that happened in our industry lately.

    Do you want us to cover more standard news? A focus on upcoming scripts maybe? Or just more interesting posts and discussions from the community? Let us know in the comments and thank you so much for reading!


Planet PHP

  • Permalink for 'Behat + FuelPHP = RESTful Testing Happiness'

    Behat + FuelPHP = RESTful Testing Happiness

    Posted: March 29th, 2012, 4:11am MDT by blog.phpdeveloper.org » PHP

    If you’ve been following my recent posts, you know I’ve been working more lately with Behat for resting some REST services. In this post I showed you how to get things set up for some testing. In this post, I’ll show you how to use a custom class that I’ve put together to make a reusable system for testing REST.

    For those that want to cut to the chase, I’ve posted some example code to github showing the code for the two different sides of the equation – the Behat testing and the PHP framework side (I went with FuelPHP because I was already familiar with it and it makes RESTful interfaces dead simple). The key is in the FeatureContextRest.php file that uses the Guzzle client to make the HTTP requests over to the framework. It provides some handy contexts that make it easy to create Scenarios.

    So, still with me? Good – I’ll show you how to get my sample scripts installed so you can see my example in action. In the repository you’ll find two different directories – “fuel” and “behat”. In each you’ll find some files:

    behat

    • features/index.features:
      An example set of Scenarios that use the REST testing contexts to create, find and deleting a “User” from the system
    • features/bootstrap/FeaturesContextRest.php:
      The key to the puzzle, the implementation of some context methods for use in Behat

    fuelphp

    • fuelphp/classes:
      These are the example models and controllers you can drop into your Fuel install to have them “magically” work (with any recent version of the framework).

    This is assuming you already have Behat installed and working and have set up FuelPHP on a host somwhere. For our example, we’ll just use [behat-test.localhost:8080″] Here’s what to do:

    1. Start by copying over the FeaturesContextRest.php file to the “features/bootstrap” directory of your Behat installation alongside the default FeaturesContext.php.
    2. Copy over the behat.yml configuration file into your testing root (the same level as the “features” directory) and update the base_url value for your hostname.
    3. Take the “classes” directory and copy over its contents to the location of your FuelPHP installation – if you’re familiar with the structure of the framework, this is simple…it just goes in “app/classes”.
    4. You’ll need a database to get this working, so you’ll need to get the FuelPHP ORM stuff configured and working in your install. Be sure to update your config.php to automatically load the “orm” module.
    5. Make a database for the project and use the init.sql to create the “users” table.
    6. To test and be sure our models/controllers are working right, hit your host in a browser, calling the “User” action like: [behat-test.localhost:8080] This should call what’s in Controller_User::get_index(). It’ll probably just return an empty result though, since there’s nothing for it to pull.
    7. To use the FeaturesContextRest.php, be sure that you include that file into your default FeaturesContext.php file and that your class “extends FeaturesContextRest”.

    So, if all has gone well, you have all the pieces in place to get started. Let’s start with a sample Scenario to show you how it all works:

    Scenario: Creating a new User
    	Given that I want to make a new "User"
    	And that its "name" is "Chris"
    	When I request "/user/index.json"
    	Then the response is JSON
    	And the response has a "userId" property
    	And the type of the "userId" property is numeric
    	Then the response status code should be 200
    

    If you’ve used Mink in the past, so of this will seem familiar. This doesn’t use Mink, however, and I’ve opted to use Guzzle as the client for the backend to replace some of the browser interactions. Really, we don’t need all of the fancy interface interaction Mink gives, so this streamlined

    Truncated by Planet PHP, read more at the original (another 1017 bytes)

  • Permalink for 'Using OAuth2 for Google APIs with PHP'

    Using OAuth2 for Google APIs with PHP

    Posted: March 29th, 2012, 12:48am MDT by Lorna Mitchell

    I've been working on something recently where I'm pulling information from lots of places onto a dashboard. Each API has its own little quirks so I'm trying to write up the ones that weren't idiot-proof, mostly so I can refer back to them later when I need to maintain my system!

    I've written about Google and OAuth before, but that was OAuth v1.0, and they are introducing OAuth2 for their newer APIs; in this example I was identifying myself in order to use the Google Plus API (which turns out not to do anything you'd expect it to do, but that's a whole separate blog post!).

    OAuth 1 vs OAuth 2

    OAuth 2 doesn't need an extension or any particular library as it doesn't have the signing component that OAuth 1 had, and OAuth 2 also has fewer round trips. It does require SSL however, because the requests are in the clear.

    As for pretty much everything, you first of all need to register for an API key; Google offers an APIs Console which is where you'll find and create all the details you need to use.

    Use Identification

    For a server-side application like this, we'll use the authorization grant flow of OAuth 2, which involves sending the user over to google to log in and grant access to our application (note there is no request token requirement in OAuth 2). We send them with our API key and a callback URL - google sends them back with a code. Here's my code which forwards the user to request access:

    $url = "https://accounts.google.com/o/oauth2/auth";
     
    $params = array(
        "response_type" => "code",
        "client_id" => "yourkey.apps.googleusercontent.com",
        "redirect_uri" => "https://localhost/oauth2callback.php",
        "scope" => "https://www.googleapis.com/auth/plus.me"
        );
     
    $request_to = $url . '?' . [http_build_query(] params);
     
    header("Location: " . $request_to);

    The user will be forwarded back to us at the URL we specified in the redirect_uri field, and when they arrive, they'll have a code parameter on the URL which we need to grab. We then use this code to get the actual access token to use with the service. Here's the code from my application which does this bit:

    if(isset($_GET['code'])) {
        // try to get an access token
        $code = $_GET['code'

    Truncated by Planet PHP, read more at the original (another 4361 bytes)

  • Permalink for 'PHP's Source Code For PHP Developers - Part 4 - Arrays'

    PHP's Source Code For PHP Developers - Part 4 - Arrays

    Posted: March 28th, 2012, 8:59am MDT by Anthony Ferrara
    Part 4 of the PHP's Source Code for PHP Developers series is up over on Nikic's Blog.  In it, he discusses how arrays are handled in PHP internals.  He talks a lot about hash tables and symbol tables, and how they work together to make PHP a working language.  Part 5 will be back over here, and we'll talk about objects and classes!  Enjoy!
  • Permalink for 'The Power of Technical Debt'

    The Power of Technical Debt

    Posted: March 28th, 2012, 8:30am MDT by Anthony Ferrara
    Lately, I've found myself in a number of discussions about Technical Debt and how it applies to project development. Overall, I think it's a very powerful tool that -- when used wisely -- can be a great asset to any team. It seems to me that most of the people that I've been talking to really don't agree, and see Technical Debt as a plague that should be eliminated at first sight. So, I figured I'd share my opinions, and see what you think...Read more »
  • Permalink for 'Understanding PHP's internal array implementation (PHP's Source Code for PHP Developers - Part 4)'

    Understanding PHP's internal array implementation (PHP's Source Code for PHP Developers - Part 4)

    Posted: March 28th, 2012, 1:00am MDT by Nikita Popov

    Welcome back to the fourth part of the “PHP’s Source Code for PHP Developers” series, in which we’ll cover how PHP arrays are internally represented and used throughout the code base.

    In case you missed them, here are the previous parts of this series:

    Everything is a hash table!

    Basically, everything in PHP is a hash table. Not only are hash tables used in the underlying implementation of PHP arrays, they are also used to store object properties and methods, functions, variables and pretty much everything else.

    And because the hash table is so fundamental to PHP, it is worth having a deeper look into how it works.

    So, what is a hash table?

    Remember that in C arrays are basically chunks of memory, which you can access by index. Thus arrays in C only have integer keys and have to be continuous (i.e. you can’t have a key 0 and the next key is 1332423442). There is no such thing as an associative array.

    And this is where hash tables come in: They convert string keys into normal integer keys using a hash function. The result can then be used as an index into a normal C array (aka chunk of memory). The problem here obviously is that the hash function can have collisions, i.e. multiple string keys can yield the same hash. For example in a PHP array with up to 64 elements the strings "foo" and "oof" would have the same hash.

    This problem is solved by not storing the value directly at the generated index, but storing a linked list of possible values instead.

    HashTable and Bucket

    So, after the basic concept of hash tables is clear, let’s have a look at the structures actually used in PHP’s hash table implementation:

    The first one is the HashTable:

    typedef struct _hashtable {
        uint nTableSize;
        uint nTableMask;
        uint nNumOfElements;
        ulong nNextFreeElement;
        Bucket *pInternalPointer;
        Bucket *pListHead;
        Bucket *pListTail;
        Bucket **arBuckets;
        dtor_func_t pDestructor;
        zend_bool persistent;
        unsigned char nApplyCount;
        zend_bool bApplyProtection;
    #if ZEND_DEBUG
        int inconsistent;
    #endif
    } HashTable;

    Let’s quickly go through it:

    • nNumOfElements specifies how many values are currently stored in the array. This is also the number that count($array) returns.

    • nTableSize specifies the size of the internal C array. It is always the next power of 2 greater or equal to nNumOfElements. E.g. if an array stores 32 elements, the internal C array also has a size of 32. But if one more element is added, i.e. the array then contains 33 elements, the internal C array is resized to 64 elements.

      This is done to always keep the hash table efficient in space and time. It is clear that if the internal array is too small there will be many collisions and the performance will degrade. If the internal array is too big on the other hand, we’d be wasting memory. The power-of-2 size is a good compromise.

    • nTableMask is the table size minus one. This mask is used to adjust the generated hashes for the current table size. For example the actual hash for "foo" (through the DJBX33A hashing function) is 193491849. If we currently have a table size of 64, we obviously can’t use that as an index into the array. Instead we only take the lower bits of the hash by applying the table mask:

         hash  |   193491849 |   0b1011100010000111001110001001
       & mask  | &        63 | & 0b0000000000000000000000111111
      ---------------------------------------------------------
       = index | =         9 | = 0b0000000000000000000000001001
    • nNextFreeElement is the next free integer key, which is used when you append to an array using $array[] = xyz.

    • pInternalPointer stores the current position in the array. This is used for foreach iteration and can be ac

    Truncated by Planet PHP, read more at the original (another 13700 bytes)

  • Permalink for 'Brooklyn Beta 2012'

    Brooklyn Beta 2012

    Posted: March 27th, 2012, 1:29pm MDT by Chris Shiflett

    Brooklyn Beta is becoming more than a conference.

    It's still a conference, too, and although I never did recap last year's conference like I wanted to, I did collect a bunch of posts, photos, and videos on Gimme Bar. Also, Nate Bolt and Captain & the Fox collaborated on a really cool video that captures the spirit of it. I love it. Check it out:

    If you were there last year, you might like to know that Joel Rose launched New Classrooms, Tony Fadell launched Nest, and Todd Park was named the new CTO of the United States. Pretty cool stuff.

    We've settled on the dates for this year's conference. October 10th, 11th, and 12th. We're planning some other events to take place the same week, so although we're keeping the conference just as small as last year, there are going to be other reasons to be in Brooklyn that week. We've also ordered some good weather, and we're gonna keep our fingers crossed all summer, so it should be a great time to be in Brooklyn. Really hope to see you there.

    The big announcement today is something we're calling Summer Camp. It's our attempt to provide some early funding and guidance to designer-developer teams. For all the details, see Tina's blog post or the Summer Camp site. We've answered some frequently asked questions that haven't even been asked yet. Yeah.

    This is a pretty big deal for us, and we've got a lot of people to thank. Thanks to MailChimp, Hoefler & Frere-Jones, Engine Yard, and Etsy for being so eager to support us. (If you're interested in sponsoring, please get in touch.) Thanks to Eli Rousso, FFFunction, and Nate Abele for helping us with the new site. Last but not least, thanks to our incredible advisors for their support and vote of confidence. And, of course, thanks to everyone who's attended Brooklyn Beta and helped make it something special. We really appreciate it.

Nettuts+

  • Permalink for 'Creating a Todo List App With Node.js and Geddy'

    Creating a Todo List App With Node.js and Geddy

    Posted: March 27th, 2012, 8:58am MDT by Daniel Erickson

    In this three part tutorial, we’ll be diving deep into creating a to do list management app in Node.js and Geddy. This is the second part in the series, where we’ll be creating a simple to do list management app.

    Recap

    As a quick refresher, last time we installed Node and Geddy, generated a new app, and learned how to start up the server. In this tutorial we’ll build upon what we did last time, so make sure you’ve completed that one before continuing.

    Generating the Todo Resource

    Geddy has a built in resource generator; this will allow us to automatically generate a model, controller, views, and routes for a specific resource. Our to do list app will only have one resource: todo. To generate it, just cd into your app’s directory (cd path/to/your/todo_app) and run:

    geddy resource todo

    You should now have these files added to your app:

    • app/models/todo.js
    • app/controllers/todos.js
    • app/views/todos/
      • index.html.ejs
      • show.html.ejs
      • edit.html.ejs
      • add.html.ejs

    Your config/router.js should also have this appended to it:

    router.resource('todos');
    What it all does

    If you’re new to MVC this all might seem a little daunting to you. Don’t worry though, it’s really simple once you figure it out.

    models/todo.js: This file is where we’ll define our todo model. We’ll define a number of properties that all todo’s have. We’ll also write some data validations here.

    controllers/todos.js: This file is where all the /todos/ routes end up. Each action in this controller has a corresponding route:

    GET      /todos/            => index
    POST     /todos/            => create
    GET      /todos/:id         => show
    PUT      /todos/:id         => update
    DELETE   /todos/:id         => remove
    GET      /todos/:id/add     => add
    GET      /todos/:id/edit    => edit

    views/todos/: Each file in here corresponds to one of the GET routes that we showed you above. These are the templates that we use to generate the front end of the app. Geddy uses EJS (embedded JavaScript) as it’s templating language. It should look familiar if you’ve ever used PHP or ERB. Basically, you can use any JavaScript that you’d like in your templates.

    Getting a feel for the routes

    Now that we’ve generated a bunch of code, let’s verify that we’ve got all the routes that we need. Start the app again (geddy), and point your browser to [localhost:4000] You should see something like this

    Go ahead and try that for the other GET routes too:

    • http://localhost:4000/todos/something
    • http://localhost:4000/todos/add
    • http://localhost:4000/todos/something/edit

    All good? Alright, let’s continue.

    Creating the Todo Model

    In Geddy (and most other MVC frameworks), you use models to define the kind of data that your app will work with. We just generated a model for our todos, so let’s see what that gave us:

    var Todo = function () {
      // Some commented out code
    };
    
    // Some more commented out code
    
    Todo = geddy.model.register('Todo', Todo);

    Models are pretty simple in Geddy. We’re just creating a new constructor function for our todos and registering it as a model in geddy. Let’s define some properties for our todos. Delete all the commented out code and add this to the contructor function:

    var Todo = function () {
      this.defineProperties({
        title: {type: 'string', required: true}
      , id: {type: 'string', required: true}
      , status: {type: 'string', required: true}
      });
    };

    Our todos will have a title, an id, and a status, and all three will be required. Now let’s set some validations for our todos.

    var Todo = function () {
    
      this.defineProperties({
        title: {type: 'string', required: true}
      , id: {type: 'string', required: true}
      , status: {type: 'string', required: true}
      });
    
      this.validatesPresent('title');
      this.validatesLength('title', {min: 5});
    
      this.validatesWithFunction('status', function (status) {
        return status == 'open' || status == 'done';
      });
    
    };

    We’re validating that the title is present, that the title has a minimum length of 5 characters, and we’re using a function to validate that the status is either open or done. There are quite a few valitation functions that are built in, go ahead and check the project out on [github.com] to learn more about them.

    Creating the Todo Model Adapter

    Now that we’ve set up our todo model, we can create somewhere to store our models. For the purposes of this tutorial, we’re just going to keep the data in memory. We’ll hang a todos array off of our global geddy object to stick the data in. In the next part of this series, we’ll start to get these persisted in a database.

    Editing Your init.js File

    Open up your config/init.js file. All that should be in there now is a global uncaught exception handler:

    // Add uncaught-exception handler in prod-like environments
    if (geddy.config.environment != 'development') {
      process.addListener('uncaughtException', function (err) {
        geddy.log.error(JSON.stringify(err));
      });
    }

    Right after that block of code, let’s hang our array off the geddy global:

    geddy.todos = [];

    There, now we’ve got a place to store our todos. Remember, this is in your application-memory, so it will disappear when you restart the server.

    Creating the Model-adapter

    A model-adapter provides the basic save, remove, load, and all methods a model needs. Our data source is pretty simple (just an array!), so writing our model adapter should be pretty simple too.

    Create a directory in lib called model_adapters and create a file in lib/model_adapters called todo.js. Let’s open up that file and add in some boilerplate code:

    var Todo = new (function () {
    })();
    exports.Todo = Todo;

    All we’re doing here is setting up a new blank object to be exported out to whatever ends up requiring this file. If you’d like to know a bit more about how Node’s require method works, this article has a pretty good overview. In this case, our init.js file will do the requiring.

    Require the model adapter in init.js

    So we set up a new Todo model-adapter object. It’s pretty barren right now, but we’ll get to that soon. For now, we’ll have to go back to init.js and add some code so that it’s loaded into our app when it starts up. After the geddy.todos = []; in config/init.js add these two lines:

    geddy.model.adapter = {};
    geddy.model.adapter.Todo = require(process.cwd() + '/lib/model_adapters/todo').Todo;

    We created a blank model-adapter object, and added the Todo model adapter onto it.

    Saving Todos

    Now that we have our model and model adapter in place, we can start in on the app logic. Let’s start with adding to do items to our to do list.

    Edit the save method on the adapter to save a todo instance

    When working with data, the first place you should go is the model adapter. We need to be able to save an instance of our Todo model to our geddy.todos array. So open up lib/model_adapters/todo.js and add in a save method:

    var Todo = new (function () {
      this.save = function (todo, opts, callback) {
    
        if (typeof callback != 'function') {
          callback = function(){};
        }
    
        todo.saved = true;
        geddy.todos.push(todo);
        return callback(null, todo);
    
      }
    })();

    All we have to do is set the instance’s saved property to true and push the item into the geddy.todos array. In Node, it’s best to do all I/O in a non-blocking way, so it’s a good idea to get in the habit of using callbacks to pass data around. For this tutorial it doesn’t matter as much, but later on when we start persisting things, it’ll come in handy. You’ll notice that we made sure that the callback is a function. If we don’t do that and use save without a callback, we’d get an error. Now let’s move on to the controller create action.

    Edit the create action to save a todo instance

    Go ahead and take a look at the create action in app/controllers/todos.js:

    this.create = function (req, resp, params) {
      // Save the resource, then display index page
      this.redirect({controller: this.name});
    };

    Pretty simple, right? Geddy has stubbed it out for you. So let’s modify it a little bit:

    this.create = function (req, resp, params) {
      var self = this
        , todo = geddy.model.Todo.create({
            title: params.title
          , id: geddy.string.uuid(10)
          , status: 'open'
          });
      todo.save(function (err, data) {
        if (err) {
          params.errors = err;
          self.transfer('add');
        }
        else {
          self.redirect({controller: self.name});
        }
      });
    };

    First, we create a new instance of the Todo model with geddy.model.Todo.create, passing in the title that our form will post up to us, and setting up the defaults for the id and status.

    Then we call the save method that we created on the model adapter and redirect the user back to the /todos route. If it didn’t pass validation, or we get an error, we use the controller’s transfer method to transfer the request back over to the add action.

    Edit add.html.ejs

    Now it’s time for us to set up the add template. Take a look at app/views/todos/add.html.ejs, it should look like this:

    <div class="hero-unit">
      <h3>Params</h3>
      <ul>
      <% for (var p in params) { %>
        <li><%= p + ': ' + params[p]; %></li>
      <% } %>
      </ul>
    </div>

    We won’t be needing that

      for our use case, so let’s get rid of it for now. Make your add.html.ejs look like this:

      <div class="hero-unit">
        <%= partial('_form', {params: params}); %>
      </div>
      An Intro to Partials

      Partials give you an easy way to share code between your templates.

      You’ll notice that we’re using a partial in this template. Partials give you an easy way to share code between your templates. Our add and edit templates are both going to use the same form, so let’s create this form partial now. Create a new file in the views/todos/ directory called _form.html.ejs. We use an underscore to easily tell if this template is a partial. Open it up and add in this code:

      <%
        var isUpdate = params.action == 'edit'
          , formTitle = isUpdate ? 'Update this To Do Item' : 'Create a new To Do Item'
          , action = isUpdate ? '/todos/' + todo.id + '?_method=PUT' : '/todos'
          , deleteAction = isUpdate ? '/todos/' + todo.id + '?_method=DELETE' : ''
          , btnText = isUpdate ? 'Update' : 'Add'
          , doneStatus = isUpdate ? 'checked' : ''
          , titleValue = isUpdate ? todo.title : ''
          , errors = params.errors;
      %>
      <form id="todo-form" class="form-horizontal" action="<%= action %>" method="POST">
        <fieldset>
          <legend><%= formTitle %></legend>
          <div class="control-group">
            <label for="title" class="control-label">Title</label>
            <div class="controls">
              <input type="text" class="span6" placeholder="enter title" name="title" value='<%= titleValue %>'/>
              <%  if (errors) { %>
                <p>
                <% for (var p in errors) { %>
                  <div><%=  errors[p];  %></div>
                <% } %>
                </p>
              <% } %>
            </div>
          </div>
          <% if (isUpdate) { %>
            <div class="control-group">
              <label for="status">Status</label>
              <div class="controls">
                <select name="status">
                  <option>open</option>
                  <option>done</option>
                </select>
              </div>
            </div>
          <% } %>
          <div class="form-actions">
            <input type="submit" class="btn btn-primary" value="<%= btnText %>"/>
            <% if (isUpdate) { %>
              <button type="submit" formaction="<%= deleteAction %>" formmethod="POST" class="btn btn-danger">Remove</button>
            <% } %>
          </div>
        </fieldset>
      </form>

      Whoa, that’s a lot of code there! Let’s see if we can walk through it. Since two different templates are going to be using this partial, we’ve got to make sure the form looks right in both of them. Most of this code is actually boilerplate from Twitter’s Bootstrap. It’s what allows this app to look so good right off the bat (and on mobile devices too!).

      To make this app look even better, you can use the CSS file provided in the demo app download.

      The first thing we did was set up some variables for us to use. In the add action we’re passing a params object down to the template in the respond method call. This gives us a few things – it tells us what controller and action this request has been routed to, and gives us any query parameters that were passed in the url. We set up the isUpdate variable to see if we’re currently on the update action, and then we set up a few more variables to help clean up our view code.

      From there, all we did was make a form. If we’re on the add action, we just render the form as is. If we’re on the edit action, we fill in the form to let the user update the fields.

      Notice that the form will send a POST request to the /todos/ with a _method=PUT parameter. Geddy uses the standard method override parameter to allow you to send PUT and DELETE requests up from the browser without having to use JavaScript. (on the front end at least!)

      The last little detail we need to take a look at is that “Remove” button. We’re using html5’s formaction attribute to change the action for this form. You’ll notice that this button’s formaction sends a POST request up to the /todos/:id route with a _method=DELETE parameter. This will hit the remove action on the controller, which we’ll get to later.

      Restart your server (geddy) and visit [localhost:4000] to see your template in action. Create a To Do item while you’re at it.

      Listing all Todos

      Now that we have user input To Do items being added into our geddy.todos array, we should probably list them somewhere. Let’s start in on the all method in the model-adapter.

      Edit the all method on the adapter to list all todos

      Let’s open lib/model_adapters/todo.js again and add an all method right above thesave` method:

      this.all = function (callback) {
        callback(null, geddy.todos);
      }

      This is probably the simplest model-adapter method that we’ll create today, all it does is accept a callback and call it with the an error (which is always null for now, we’ll upgrade this method in the next tutorial), and geddy.todos.

      Edit the index action to show all todos

      Open up /app/controllers/todos.js again and take a look at the index action. It should look something like this:

      this.index = function (req, resp, params) {
        this.respond({params: params});
      };

      This part is really simple, we just use the all method that we just defined on the model-adapter to get all the todos and render them:

      this.index = function (req, resp, params) {
        var self = this;
        geddy.model.adapter.Todo.all(function(err, todos){
          self.respond({params: params, todos: todos});
        });
      };

      That’s it for the controller, now onto the view.

      Edit index.html.ejs

      Take a look at /app/views/todos/index.html.ejs, it should look like this:

      <div class="hero-unit">
        <h3>Params</h3>
        <ul>
        <% for (var p in params) { %>
          <li><%= p + ': ' + params[p]; %></li>
        <% } %>
        </ul>
      </div>

      Looks a lot like the add.html.ejs template doesn’t it. Again, we won’t need the params boilerplate here, so take that out, and make your index.html.ejs template look like this:

      <div class="hero-unit">
        <h2>To Do List</h2>
        <a href="/todos/add" class="btn pull-right">Create a new To Do</a></p>
      </div>
      <% if (todos &amp;&amp; todos.length) { %>
        <% for (var i in todos) { %>
        <div class="row todo-item">
          <div class="span8"><h3><a href="/todos/<%= todos[i].id; %>/edit"><%= todos[i].title; %></a></h3></div>
          <div class="span4"><h3><i class="icon-list-alt"></i><%= todos[i].status; %></h3></div>
        </div>
        <% } %>
      <% } %>

      This one is also pretty simple, but this time we’ve got a loop in our template. In the header there we’ve added a button to add new todo’s. Inside the loop we’re generating a row for each todo, displaying it’s title (as a link to it’s edit page), and it’s status.

      To check it out, go to [localhost:4000] .

      Editing a Todo

      Now that we have a link to the edit page, we should probably make it work!

      Create a load method in the model adapter

      Open up your model adapter again (/lib/model_adapters/todo.js). We’re going to add in a load method so that we can load a specific todo and use it in our edit page. It doesn’t matter where you add it, but for now let’s put it between the all method and the save method:

      this.load = function (id, callback) {
        for (var i in geddy.todos) {
          if (geddy.todos[i].id == id) {
            return callback(null, geddy.todos[i]);
          }
        }
        callback({message: "To Do not found"}, null);
      };

      This load method takes an id and a callback. It loops through the items in geddy.todos and checks to see if the current item’s id matches the passed in id. If it does, it calls the callback, passing the todo item back. If it doesn’t find a match, it calls the callback with a error. Now we need to use this method in the todos controller’s show action.

      Edit the edit action to find a todo

      Open up your todos controller again and take a look at it’s edit action. It should look something like this:

      this.edit = function (req, resp, params) {
        this.respond({params: params});
      };

      Let’s use the load method that we just created:

      this.edit = function (req, resp, params) {
        var self = this;
        geddy.model.Todo.load(params.id, function(err, todo){
          self.respond({params: params, todo: todo});
        });
      };

      All we’re doing here is loading the todo and sending it down to the template to be rendered. So let’s take a look at the template.

      Edit edit.html.ejs

      Open up /app/views/todos/edit.html.ejs. Once again we’re not going to need the params boilerplate, so let’s remove it. Make your edit.html.ejs look like this:

      <div class="hero-unit">
        <%= partial('_form', {params: params, todo: todo}); %>
      </div>

      This should look very similar to the add.html.ejs file we just edited. You’ll notice that we’re sending a todo object down to the partial as well as the params this time. The cool thing is, since we already wrote the partial, this is all we’ll have to do to get the edit page to show up correctly.

      Restart the server, create a new todo and click the link to see how this works. Now let’s make that update button work!

      Edit the save method in the model-adapter

      Open up the model-adapter again and find the save method. we’re going to be adding a bit to it so that we can save over existing todos. Make it look like this:

      this.save = function (todo, opts, callback) {
        if (typeof callback != 'function') {
          callback = function(){};
        }
        var todoErrors = null;
        for (var i in geddy.todos) {
          // if it's already there, save it
          if (geddy.todos[i].id == todo.id) {
            geddy.todos[i] = todo;
            todoErrors = geddy.model.Todo.create(todo).errors;
            return callback(todoErrors, todo);
          }
        }
        todo.saved = true;
        geddy.todos.push(todo);
        return callback(null, todo);
      }

      This loops over all the todo’s in geddy.todos and if the id is already there, it replaces that todo with the new todo instance. We’re doing some stuff here to make sure that our validations work on update as well as create – in order to do this we have to pull the errors property off of a new model instance and pass that back in the callback. If it passed validations, it’ll just be undefined and our code will ignore it. If it didn’t pass, todoErrors will be an array of validation errors.

      Now that we have that in place, let’s work on our controller’s update action.

      Edit the update action to find a todo, change the status, and save it

      Go ahead and open up the controller again and find the ‘update’ action, it should look something like this:

      this.update = function (req, resp, params) {
        // Save the resource, then display the item page
        this.redirect({controller: this.name, id: params.id});
      };

      You’ll want to edit it to make it look like this:

      this.update = function (req, resp, params) {
        var self = this;
        geddy.model.adapter.Todo.load(params.id, function (err, todo) {
          todo.status = params.status;
          todo.title = params.title;
          todo.save(function (err, data) {
            if (err) {
              params.errors = err;
              self.transfer('edit');
            }
            else {
              self.redirect({controller: self.name});
            }
          });
        });
      };

      What we’re doing here is loading the requested todo, editing some of it’s properties, and saving the todo again. The code we just wrote in the model-adapter should handle the rest. If we get an error back, that means the new properties didn’t pass validation, so we’ll transfer the request back to the edit action. If we didn’t get an error back, we’ll just redirect the request back over to the index action.

      Go ahead and try it out. Restart the server, create a new todo, click on it’s edit link, change the status to done, and see that it get’s updated in the index. If you want to verify that you have your validations working, try changing the title to something shorter than 5 characters.

      Now let’s get that “Remove” button working.

      Removing a Todo

      By now we’ve got a working to do list application, but if you start using it for a while, it’s going to get tough to find the todo item that you’re looking for on that index page. Let’s make that “Remove” button work so we can keep our list nice and short.

      Create a remove method in the model-adapter

      Let’s open up our model-adapter again, this time we’re going to want to add a remove method in there. Add this right after the save method:

      this.remove = function(id, callback) {
        if (typeof callback != 'function') {
          callback = function(){};
        }
        for (var i in geddy.todos) {
          if (geddy.todos[i].id == id) {
            geddy.todos.splice(i, 1);
            return callback(null);
          }
        }
        return callback({message: "To Do not found"});
      }

      This one is pretty simple, it should look a lot like the load method. It loops through all the todos in geddy.todos to find the id that we’re looking for. It then splices that item out of the array and calls the callback. If it doesn’t find it in the array, it calls the callback with an error.

      Let’s use this in our controller now.

      Edit the remove action

      Open up your controller again and fing the remove action. It should look something like this:

      this.remove = function (req, resp, params) {
        this.respond({params: params});
      };

      Edit it to make it look like this:

      this.remove = function (req, resp, params) {
        var self = this;
        geddy.model.adapter.Todo.remove(params.id, function(err){
          if (err) {
            params.errors = err;
            self.transfer('edit');
          }
          else {
            self.redirect({controller: self.name});
          }
        });
      }

      We pass the id that we got from the params in the form post into the remove method that we just created. If we get an error back, we redirect back to the edit action (we’re assuming the form posted the wrong info). If we didn’t get an error back, just send the request over to the index action.

      Thats it! We’re done.

      You can test the remove feature by restarting your server, creating a new todo item, clicking on it’s link, then clicking on the “Remove” button. If you did it right, you should be back on the index page with that item removed.

      The Next Steps

      In the next tutorial we’ll use [i.tv] ’s awesome mongodb-wrapper module to persist our todo’s into MongoDB. With Geddy, this will be easy; all we’ll have to change is the model-adapter.

      If you have any questions, please leave a comment here, or open up an issue on github.


Planet PHP

  • Permalink for 'Slides: MySQL 5.6 Global Transaction Identifier and PECL/mysqlnd_ms for session consistency'

    Slides: MySQL 5.6 Global Transaction Identifier and PECL/mysqlnd_ms for session consistency

    Posted: March 27th, 2012, 8:19am MDT by Ulf Wendel
    Why do we have to bother about built-in GTID support in MySQL 5.6 at all? Sure, it is a tremendous step forward for a lazy primary copy system like MySQL Replication. Period. GTIDs make server-side failover easier (slides). And, load balancer, including PECL/mysqlnd_ms as an example of a driver ...
  • Permalink for 'Table Inheritance with Doctrine'

    Table Inheritance with Doctrine

    Posted: March 27th, 2012, 7:47am MDT by Liip
    Introduction

    Lately we had several projects where we had to store in a database very different items that shared a common state.

    As an example take the RocketLab website you are reading: Events and BlogPosts are aggregated in the LabLog list as if they were similar items. And indeed they all have a Title, a Date and a Description.

    But if you get the detail page of an Event or a BlogPost you can see that they actually don't contain the same information: a BlogPost contains essentially formatted text when an Event contains more structured information such as the place where the event will take place, the type of event it is, if people need to register to attend, etc..

    Still we have to access those entities sometimes as similar items (in the LabLog list) or as different items (in the events list and in the blog posts list).

    Naïve database model

    Our first idea, and it was not that bad, Drupal does just the same, was to have a database table with the common fields, a field containing the type of item (it's either an event or a blog post) and a data field where we serialized the corresponding PHP object. This approach was ok until we had to filter or search LabLog items based on fields that were contained in the serialized data.

    Indeed SQL does not know anything about PHP serialized data, thus you cannot use any of it's features on that data.

    So how do you get all the LabLog items that are Events, happen in April 2012 and are "techtalks"? The only way is to go through all the Events records of April, unserialize the data and check if it's a techtalk event. In SQL you would normally only do a single request to find those items.

    A better database model

    There is a better way to model this in a database, it's called table inheritance. It exists in two forms: single table inheritance and multiple table inheritance.

    Multiple table inheritance

    Multiple table inheritance requires to use three tables instead of a single one. The idea is to keep the common data in a "parent" table, which will reference items either in the Event table or in the BlogPost table. The type column (called the discriminator) helps to find out if the related item should be searched in the Event table or in the BlogPost table. This is called multiple table inheritance because it tries to model the same problem as object inheritance using multiple database tables.

    Multiple table inheritance

    When you have a LabLogItem you check the type field to know in which table to find the related item, then you look for that item with the ID equals to related_id.

    Single table inheritance

    Alternatively the same can be modelled in a single table. All the fields are present for all the types of LabLogItem but the one that do not pertain to this particular type of item are left empty. This is called single table inheritance.

    Single table inheritance

    Single or multiple table inheritance

    The difference is really only in how the data is stored in the database. On the PHP side this will not change anything. One may notice that single table inheritance will promote performance because everything is in a single table and there is no need to use joins to get all the information. On the other hand, multiple table inheritance will allow a cleaner separation of the data and will not introduce "dead data fields", i.e. fields that will remain NULL most of the time.

    Table inheritance with Symfony and Doctrine

    Symfony and Doctrine make it extremely easy to use table inheritance. All you need to do is to model your entities as PHP classes and then create the correct database mapping. Doctrine will take care of the hassle of implementing the inheritance in the database server.

    Please note that the code I present here is not exactly what we use in RocketLab; we are developers and as such we always have to make things harder. But the idea is there...

    The parent entity

    In the case of RocketLab we created a parent (abstract) entity, called LabLogItem, that contains the common properties.

    /**
     * This class represents a LabLog item, either a BlogPost or an Event.
     * It is abstract because we never have a LabLog entity, it's either an event or a blog post.
     * @ORM\Entity
     * @ORM\Table(name="lablog")
     * @ORM\InheritanceType("SINGLE_TABLE")
     * @ORM\DiscriminatorColumn(name="type", type="string")
     * @ORM\DiscriminatorMap( {"event" = "Event", "blogpost" = "BlogPost"} )
     */
    abstract class LabLogItem
    {
        /**
         * @ORM\Id
         * @ORM\Column(type="integer")
         * @ORM\GeneratedValue(strategy="AUTO")
         */
        protected $id;
    
        /**
         * @ORM\Column(type="date")
         */
        protected $da

    Truncated by Planet PHP, read more at the original (another 4637 bytes)

  • Permalink for 'Podcast About Sexism in Tech: What I Learned'

    Podcast About Sexism in Tech: What I Learned

    Posted: March 27th, 2012, 7:30am MDT by Anna Filina

    I had the pleasure of discussing with fellow members of the PHP community a very sensitive topic: sexism in tech. I have been invited to a special episode of Voices of the ElePHPant with Elizabeth (Beth) Tucker Long, Elizabeth (Liz) Naramore and Laura Thomson. Cal Evans was the host. The podcast’s page features links for some of the topics discussed.

    The purpose of this post is not to transcribe the podcast, but to share with you what I learned from this conversation and what I personally took away from it.

    The Culture and the Issues

    Although many say that the culture does not make women flee or prevent them from joining, Laura argued that it may, at the very least, prevent women from contributing. While it would seem that the culture doesn’t want to change, Liz said that many men participate in criticism against sexist behavior, which shows that the community actually cares for an attitude change. She also supported empathy and respect as opposed to only increasing the number of women in tech, which is also a big part of the desired change.

    I have a problem with the way some of the sexism issues are brought to attention. I believe Twitter to be a poor medium: no body language, no intonation and only 140 characters at a time. When someone is being impolite or curses, a dialog is hard to establish and important issues often get overlooked because of that. Beth agreed with me that swearing and getting confrontational is not helpful, but we do need to address the problems regardless.

    Brand Hygiene and Admitting Wrongs

    We agreed that the nature of the brand or the gender of the perpetrator do not matter. Having women dancing around in underwear, when associated with a brand, will project a certain image of that brand. It’s up to the brand to decide whether it is the image that it is looking for.

    I came to understand that no matter in what manner issues are raised, they should be treated as basic customer service issues. A company should not take it personal. Implied economic threats (by bringing employers into a discussion) are unethical and need to be avoided at all costs.

    Liz taught us that it’s ok to apologize, even if we didn’t mean to offend. “When you bump into someone on the street, whether or not you meant it, you say that you’re sorry.” I hope that nerds will find it easier to admit a wrong with this analogy in mind.

    Will the Industry Mature?

    Liz argued that if left to our own devices, no change will come. Beth stated that sexist behavior is not appropriate, no matter how young you are. “Young people have the same capacity to reason as older people.” Also, such behavior is not limited to young people and it’s unfair to blame it all on them. In the meantime, Laura said, we must be allowed to be creative and enjoy our industry. That means calling out people who step out of line.

    Conclusion

    We have come to an agreement that spending all our efforts criticizing bad behavior takes effort away from doing something about it. It’s alright to point out something inappropriate to help people recognize when they have done something wrong. According to Beth, the real way to solve this problem is to “mentor and encourage people who are feeling excluded or discouraged and help them out, be it women or other minority group that’s feeling left out”.

    It’s good to have groups that help these minorities, as long as it doesn’t exclude others, because then they will be separated once more. One such group is PHP Women.

    I will personally be presenting a PHP Workshop for Women with the support of Montreal Girl Geeks next month. I will post a link as soon as we have details about the venue. I’m still looking for training assistants as well. Tentative date is April 26th.

  • Permalink for 'Linkify: turning URLs into clickable links in PHP'

    Linkify: turning URLs into clickable links in PHP

    Posted: March 26th, 2012, 4:31pm MDT by Arnold Daniels

    Turning links like www.example.com and [twitter.com] into clickable links. Sounds like an easy task, right? We’ll there are a few problems that might arise, especially if the text is already html formatted.

    This function first takes out all potential dangers, by extracting links and tags and replacing them with a placeholder. It than extracts all URLs and replaces them with a placeholder, storing the full html link. At the end it replaces all placeholders with the links and tags.

    <script src="https://gist.github.com/2000705.js">

    This is also a nice example for how to use PHP closures.

Nettuts+

  • Permalink for 'AJAX User Table Management in CodeIgniter: New on Premium'

    AJAX User Table Management in CodeIgniter: New on Premium

    Posted: March 26th, 2012, 12:11pm MDT by Sam Stevens

    Learn how to use CodeIgniter and the jQuery library to create a slick, AJAX-utilizing management page for a typical “Users” table, and discover some of the awesome features of jQuery UI.

    This Tuts+ Premium exclusive tutorial will guide you through the process of creating a slick, AJAX-utilizing management page for a typical “Users” table in a MySQL database. We will cover a range of topics, in both CodeIgniter and jQuery, including creating and using Models, Controllers and Views, the Form Validation class, and jQuery UI.

    preview preview Tuts+ Premium

    The recently re-launched Tuts+ Premium is a service that provides top-tier training in a variety of creative fields. Whether you prefer books, visual training, or in depth tutorials, we have you covered. While we unfortunately can’t afford to provide the service for free, it’s only $19 a month – less than you’d spend on dinner.

    I hope you’ll consider checking it out! In addition to learning a huge variety of new skills, it’s also a fantastic way to say thank you to Nettuts+.


Planet PHP

  • Permalink for 'Zend phpcloud.com at NYPHP'

    Zend phpcloud.com at NYPHP

    Posted: March 26th, 2012, 8:09am MDT by Daniel Krook
    Tomorrow night we’ll again host Edward Kietlinski at New York PHP. He’ll talk about the latest offerings from Zend to bring your PHP applications to their developer cloud. Soon, you’ll also be able to deploy your production-ready applications to the IBM SmartCloud. RSVP now for Tuesday night’s meeting at IBM in midtown Manhattan. Or, if [...]
  • Permalink for 'Using JIRA's REST API to Create a Dashboard'

    Using JIRA's REST API to Create a Dashboard

    Posted: March 26th, 2012, 1:35am MDT by Lorna Mitchell

    If you read this blog often, you'll know that I am:

    • crazy about APIs
    • living with some accessibility issues

    Put these two things together and what do you get? Actually don't answer that! Today what you get is an example of integrating with JIRA's REST API, because their recent "upgrade" locked me out of the issue listings pages completely and I really do need to be able to see a list of bugs! Their bug editing screen is quite usable, so it's just the list that I need here, but you could easily call their other API methods as you need to.

    These examples are PHP and use the PECL_HTTP">[http">PECL_HTTP] extension, because it's awesome, but these examples could be easily adapted to use another language or library.

    What's The REST URL?

    We have hosted JIRA from Atlassian, which I think is now called Jira Studio, because they give free pretty-much-unlimited licenses to open source projects, and for that I don't think I'll ever be able to thank them enough. Not enough organisations recognise the value of open source!

    Our "normal" JIRA URL: http://joindin.jira.com.

    The URL to access the RESTful service: https://joindin.jira.com/rest/api. Note this requires SSL.

    Getting a List of Issues

    This should be easy, but many services make it hard. Not this one, here's my code:

    $request = new [HttpRequest();] $request->setUrl('https://joindin.jira.com/rest/api/latest/search');
    $request->send();
     
    $issue_list = json_decode($request->getResponseBody());

    Now I have all the issues in $issue_list - this is paginated, you can control how many issues you get in a list; the default is 50 I think. You can also pass in any search query - basically the same as the search options that you see in JIRA itself. This uses a language called JQL, and you can find some JQL documents here.

    I added some parameters to only show me open and reopened issues, so my code sample now looks like this:

    $request = new [HttpRequest();] $request->setUrl('https://joindin.jira.com/rest/api/latest/search');
    $params = array(
        "jql" => "status in (open, reopened)"
    );
    $request->setQueryData($params);
    $request

    Truncated by Planet PHP, read more at the original (another 8250 bytes)

Nettuts+

  • Permalink for 'Create Instagram Filters With PHP'

    Create Instagram Filters With PHP

    Posted: March 24th, 2012, 4:53pm MDT by Dejan Marjanovic

    In this tutorial, I’ll demonstrate how to create vintage (just like Instagram does) photos with PHP and ImageMagick. Wait? What? Yes, you can do this very thing with PHP and ImageMagick, and that’s just scratching the surface!

    We Made Digital Vintage Photos, Before it Was Cool

    Once upon a time – technically 22 years ago (5 years before PHP) – ImageMagick was released. Since then, it has evolved to a platform independent software suite that can create, edit, compose, or convert raster images (over 100 formats supported!). You can use it to resize, flip, mirror, rotate, distort, shear and transform images, adjust image colors, apply various special effects, or draw text, lines, polygons, ellipses and Bézier curves. It truly has everything you will ever need, when dealing with image manipulation in web development, video processing, panorama generating, etc. Please note, however: it is not a GUI image editor.

    ImageMagick is command-line Photoshop for web.

    Image Manipulation With PHP

    PHP comes bundled with GD (GIF Draw/Graphics Draw), which is a library for the dynamic creation of images. It can be used for simpler image operation, such as resizing, cropping, adding watermarks, creating thumbnails (Jeffrey wrote about it), applying basic photo filters – you’ve probably used it before. Unfortunately, if you want to create something more complex with GD, like Instagram effects, you can’t. Luckily, though, we have ImageMagick!

    GD vs. ImageMagick

    These two can’t compare on higher levels, therefore, we will use simple example, like resizing. Let’s imagine that we’ve uploaded a new 1024×768 photo.jpg image, and we want to dynamically resize it to 640×480 pixels.

    GD

    In the example below, we have to call six functions, and possibly perform some calculations if we have variable aspect ratio.

    $im = imagecreatefromjpeg('photo.jpg');
    
    $ox = imagesx($im);
    $oy = imagesy($im);  
    
    $nx = 640;
    $ny = 480;
    
    $nm = imagecreatetruecolor($nx, $ny);  
    
    imagecopyresized($nm,$im,0,0,0,0,$nx,$ny,$ox,$oy);  
    
    imagejpeg($nm, 'photo.jpg');
    
    ImageMagick

    IM (short for ImageMagick) has a nice wrapper, called Imagick – a native PHP extension to create and modify images using the ImageMagick API. The only downside is: you will likely have to install it from PECL, which can sometimes be a problem for shared hosting.

    $image = new Imagick('photo.jpg');
    $image->resizeImage(640, 480, imagick::FILTER_LANCZOS, 0.9);
    

    Even simpler, command-line usage with PHP (this is what we are going to use):

    exec('mogrify -resize 640x480 photo.jpg');
    

    That’s it! Excellent.

    Installing ImageMagick

    Although nearly every good hosting company has ImageMagick installed, you probably don’t have one on a local machine, simply because it isn’t shipped with PHP.
    Installing ImageMagick is a cinch, though. Go to the ImageMagick Download page, choose your platform (Unix/Mac/Win), and select recommended package. Simply follow the simple instructions; you can’t make a mistake here.

    Once finished, go to your terminal/command-prompt, type in convert and hit Enter, If you receive a list of options instead of “Command not found”, you’re good go! Note that you don’t need to configure anything in PHP.

    How Does Instagram Work?

    Well, to be honest, I don’t know what system the Instagram team are using for image processing. ImageMagick is also available for iOS; perhaps that is the magic of how Instagram works? To quote Kevin Systrom, Instagram CEO and co-founder:

    It’s really a combination of a bunch of different methods. In some cases, we draw on top of images, in others we do pixel math. It really depends on the effect we’re going for.

    For instance, Lomo-fi really isn’t much more than the image with boosted contrast. Whereas Toaster is one of the most complex (and slow, yet popular) filters we have with multiple passes and drawing.

    I’d give up more info, but it’s our secret sauce :) Maybe some day…

    “Maybe some day…” isn’t good enough for us, Mr Systrom. Challenge accepted!

    Show Me Teh Codez!

    We are going to mimic gotham (return of gotham), toaster (the complex one), nashville (the popular one), lomo (lomo-fi isn’t that good) and kelvin (lord kelvin – original) filters.

    Instagraph – the PHP Class

    I have created a little PHP wrapper class to make the process of filtering images as simple as possible. In these filters, as you know, we have lots of…

    • colortone: will color tone an image in highlights and/or shadows. For example, we want to change black to purple.
    • vignette: edges of photo fade out or desaturate gradually. We can even reverse this, or use colors for vignette.
    • border: will add a border to the photo. For example, we want a white or black or any color border of a certain width; note that the width of the border will add up to the photo dimensions.
    • frame: will read specified frame and stretch in to fit to photo. We need this for the Nashville and kelvin filters.
    • tempfile: creates temporary file (copy of original image), to work with.
    • output: simply renames the working copy.
    • execute: we will send all commands through this method to prevent errors that can occur while working with the shell.

    I’ve made all of these mentioned, so we can skip to fun part. Create a new file, called instagraph.php, and copy & paste the code below.

    /**
     * Instagram filters with PHP and ImageMagick
     *
     * @package    Instagraph
     * @author     Webarto &lt;dejan.marjanovic@gmail.com>
     * @copyright  NetTuts+
     * @license    [creativecommons.org] CC BY-NC
     */
    class Instagraph
    {
    
        public $_image = NULL;
        public $_output = NULL;
        public $_prefix = 'IMG';
        private $_width = NULL;
        private $_height = NULL;
        private $_tmp = NULL;
    
        public static function factory($image, $output)
        {
            return new Instagraph($image, $output);
        }
    
        public function __construct($image, $output)
        {
            if(file_exists($image))
            {
                $this->_image = $image;
                list($this->_width, $this->_height) = getimagesize($image);
                $this->_output = $output;
            }
            else
            {
                throw new Exception('File not found. Aborting.');
            }
        }
    
        public function tempfile()
        {
            # copy original file and assign temporary name
            $this->_tmp = $this->_prefix.rand();
            copy($this->_image, $this->_tmp);
        }
    
        public function output()
        {
            # rename working temporary file to output filename
            rename($this->_tmp, $this->_output);
        }
    
        public function execute($command)
        {
            # remove newlines and convert single quotes to double to prevent errors
            $command = str_replace(array("\n", "'"), array('', '"'), $command);
            $command = escapeshellcmd($command);
            # execute convert program
            exec($command);
        }
    
        /** ACTIONS */
    
        public function colortone($input, $color, $level, $type = 0)
        {
            $args[0] = $level;
            $args[1] = 100 - $level;
            $negate = $type == 0? '-negate': '';
    
            $this->execute("convert
            {$input}
            ( -clone 0 -fill '$color' -colorize 100% )
            ( -clone 0 -colorspace gray $negate )
            -compose blend -define compose:args=$args[0],$args[1] -composite
            {$input}");
        }
    
        public function border($input, $color = 'black', $width = 20)
        {
            $this->execute("convert $input -bordercolor $color -border {$width}x{$width} $input");
        }
    
        public function frame($input, $frame)
        {
            $this->execute("convert $input ( '$frame' -resize {$this->_width}x{$this->_height}! -unsharp 1.5×1.0+1.5+0.02 ) -flatten $input");
        }
    
        public function vignette($input, $color_1 = 'none', $color_2 = 'black', $crop_factor = 1.5)
        {
            $crop_x = floor($this->_width * $crop_factor);
            $crop_y = floor($this->_height * $crop_factor);
    
            $this->execute("convert
            ( {$input} )
            ( -size {$crop_x}x{$crop_y}
            radial-gradient:$color_1-$color_2
            -gravity center -crop {$this->_width}x{$this->_height}+0+0 +repage )
            -compose multiply -flatten
            {$input}");
        }
    
        /** RESERVED FOR FILTER METHODS */
    
    }
    
    Instagram Filters

    We will go over the filters, one by one; I will explain the necessary PHP methods and Imagemagick commands, including examples. Make sure you update your PHP class with these new methods (paste below RESERVED FOR FILTER METHODS comment). The photo frames are provided in the download package; they are just PNG transparent images without extensions. Feel free to make your own! So let’s begin…

    Original

    Here we simply have a photo of my dogs enjoying the day at the beach. This is straight out of my camera.

    terry and linda on the beach Gotham

    The Gotham filter produces a black&white, high contrast image with bluish undertones. In real life, this would be created with a Holga camera and Ilford X2 film.

    public function gotham()
    {
        $this->tempfile();
        $this->execute("convert $this->_tmp -modulate 120,10,100 -fill '#222b6d' -colorize 20 -gamma 0.5 -contrast -contrast $this->_tmp");
        $this->border($this->_tmp);
        $this->output();
    }
    

    In English: create a working file, load the image into memory, improve brightness a bit, (almost) desaturate, change the remaining colors to deep purple, gamma correction (value below 1 darkens image), add more contrast, add more contrast, and save everything to a file. Add a 20px black border. Simple, eh?

    Gotham filter Toaster

    The Toaster filter resembles old Polaroid shots; it features vivid colors with pink/orange glow out of the center. By the words of Instagram CEO, it’s one of the most difficult effects to create; we’ll take his word for it.

    public function toaster()
    {
        $this->tempfile();
        $this->colortone($this->_tmp, '#330000', 100, 0);
    
        $this->execute("convert $this->_tmp -modulate 150,80,100 -gamma 1.2 -contrast -contrast $this->_tmp");
    
        $this->vignette($this->_tmp, 'none', 'LavenderBlush3');
        $this->vignette($this->_tmp, '#ff9966', 'none');
    
        $this->output();
    }
    

    In English: create a working file, load the image into memory, change blacks to dark red, enhance brightness, desaturate by a fifth, perform gamma correction (make image brighter), add more contrast, add more contrast, save. Lastly, add a grayish vignette (desaturates edges a bit), and an “inverted” orange vignette for color burn effect.

    Tip: You can even add a white border for a full effect; just add $this->border($this->_tmp, 'white'); before $this->output();.

    Toaster filter Nashville

    Nashville has a nice washed out 80s fashion photo feel. It produces image with a magenta/peach tint. It additionally adds a frame to get that slide look. It’s easily one of the most popular Instagram filters.

    public function nashville()
    {
        $this->tempfile();
    
        $this->colortone($this->_tmp, '#222b6d', 100, 0);
        $this->colortone($this->_tmp, '#f7daae', 100, 1);
    
        $this->execute("convert $this->_tmp -contrast -modulate 100,150,100 -auto-gamma $this->_tmp");
        $this->frame($this->_tmp, __FUNCTION__);
    
        $this->output();
    }
    

    In English: create a working file, load the image into memory, change blacks to indigo, change whites to peach color, enhance contrast, enhance saturation by half, gamma auto-correction. Add a frame from a PNG file.

    Nashville filter Lomo

    Lomography is all about making high contrast photos with vignettes and soft focus (everywhere you go). In real life, they are mostly made with Holga, LOMO LC-A or so called toy cameras (cameras with plastic lens). This effect is pretty easy to recreate; we will simply enhance the red and green channels’ contrast by a third, and add a vignette. Feel free to experiment as you wish.

    public function lomo()
    {
        $this->tempfile();
    
        $command = "convert {$this->_tmp} -channel R -level 33% -channel G -level 33% $this->_tmp";
    
        $this->execute($command);
        $this->vignette($this->_tmp);
    
        $this->output();
    }
    

    Create a working file, load the image into memory, enhance red channel contrast by a third, enhance red channel again, apply a vignette.

    Tip: If you prefer lomo effect without vignette, just comment or remove that section of code.

    Lomo filter Kelvin

    Named after Lord Kelvin, this effect applies a strong peach/orange overlay, and adds a washed out photo frame.

    public function kelvin()
    {
        $this->tempfile();
    
        $this->execute("convert
        ( $this->_tmp -auto-gamma -modulate 120,50,100 )
        ( -size {$this->_width}x{$this->_height} -fill 'rgba(255,153,0,0.5)' -draw 'rectangle 0,0 {$this->_width},{$this->_height}' )
        -compose multiply
        $this->_tmp");
        $this->frame($this->_tmp, __FUNCTION__);
    
        $this->output();
    }
    

    In English: create a working file, load the image into memory, normalize, enhance brightness by a fifth, desaturate by half, create an peach/orange color overlay, and apply the multiply blending mode. Lastly, add a frame, using the PNG file.

    Kelvin filter How to Use

    It’s easy to use these effects! I’ll assume that you saved all the code within instagraph.php file. Now, create a file, called filter.php and copy the code below that suits you.

    If you want to apply only one filter on an image, you can do it this way:

    require 'instagraph.php';
    
    try
    {
        $instagraph = Instagraph::factory('input.jpg', 'output.jpg');
    }
    catch (Exception $e)
    {
        echo $e->getMessage();
        die;
    }
    
    $instagraph->toaster(); // name of the filter
    

    That’s it! Now, if you want to apply all filters to one image, use this code:

    require 'instagraph.php';
    
    try
    {
    $instagraph = Instagraph::factory('input.jpg', 'output.jpg');
    }
    catch (Exception $e)
    {
        echo $e->getMessage();
        die;
    }
    
    // loop through all filters
    
    foreach(array('gotham', 'toaster', 'nashville', 'lomo', 'kelvin') as $method)
    {
        $instagraph->_output = $method.'.jpg'; // we have to change output file to prevent overwrite
        $instagraph->$method(); // apply current filter (from array)
    }
    

    Now, just open it in your browser and enjoy the results!

    Performance

    Performance is certainly an important part of every application. Because the average time to apply a filter to an image is roughly 1 second, we can safely say it is pretty fast!

    ImageMagick Resources

    To learn more about ImageMagick, here’s a list of links to all the commands and options that were used in these filter methods:

    • convert:
    • modulate: vary the brightness, saturation, and hue
    • contrast: enhance or reduce the image contrast
    • size: width and height of image
    • fill: color to use when filling a graphic primitive
    • draw: annotate the image with a graphic primitive
    • compose: set image composite operator
    • channel: apply option to select image channels
    • level: adjust the level of image contrast
    • auto-gamma: automagically adjust gamma level of image
    • gamma: level of gamma correction

    Additionally, here’s a list of ImageMagick scripts, tutorials and examples:

    Summary

    In this tutorial, we learned a bit about Imagemagick, and demonstrated the power of it by creating filters that are similar to the ones generated by Instagram. We created Instagraph!

    If you need any help, or need assistance creating additional filters, such as Tilt Shift or Earlybird, let me know within the comments, and I’ll do my best to assist!


Planet PHP

  • Permalink for 'Improving Query Performance'

    Improving Query Performance

    Posted: March 23rd, 2012, 7:29pm MDT by Paul Reinheimer

    Some aspects of Natural Load Testing's site have never really performed that well. The site was under incredibly rapid development so I didn't want to invest too much time in making performance tweaks on code or even architecture that might change in the next week.

    No joke, we've re-written our load tester at least three times. Two complete re-writes in the same language, then we switched languages to get better threading performance

    I think we hit some sort of limit in the past week or two, and things got much worse. Pages that used to be snappy jumped up to taking 10 seconds to load. Clearly something needed to be done.

    When our load tester runs, we generate a run id, here's an example: 21_20111116_4ec4802b9e7b8_000016. That's the user id of whomever launched the test, the date, a unique identifier, and the id of the spawned worker. I wanted something unique, and easy to track if anything went wrong, and that certainly fit the bill.

    Unfortunately it also left me executing plenty of queries along the lines of: SELECT min(`test_results`.`timestamp`)AS `min`, max(`test_results`.`timestamp`)AS `max`, sum(`test_results`.`response_time`) / 1000 AS `diff`, count(`test_results`.`run_id`)AS `completed_requests`, `test_results`.`run_id`, sum(`response_size`) as `total_transferred`, max(`test_results`.`response_time`) AS `longest` FROM `test_results` WHERE `test_results`.`run_id` LIKE('21_20111116_4ec4802b9e7b8_%') GROUP BY `test_results`.`run_id` ORDER BY `test_results`.`run_id` ASC one key problem there is the WHERE `test_results`.`run_id` LIKE('21_20111116_4ec4802b9e7b8_%'). Even indexed, that query has a hard time. I tried a few optimization techniques with different index types or other options, but the query was still hurting.

    The solution was to break up that run_id into its components: the run id, and the worker id. This wasn't quite as pain free as it could have been (user IDs with different lengths forced me to go through this in several iterations) but I'm quite happy with the results. MySQL is performing a HASH index on the new run_id column, which seems perfect for this situation (there's no web interface to do anything other than an exact lookup on that column).

    Results

    Before: 10 rows in set (11.49 sec)
    After: 10 rows in set (0.00 sec)
    Sometimes you need to look further than simple indexes and query optimizations to solve problems.

  • Permalink for 'pewpew - PHP's Embedded Webserver'

    pewpew - PHP's Embedded Webserver

    Posted: March 23rd, 2012, 4:26pm MDT by PHP-GTK Community

    screenshot for pewpew This is a tiny tool that allows you to launch the built in PHP 5.4 HTTP test server with a few clicks. It allows you to select which PHP binary you want to use (in case you have multiple on your system) and the document root of the test server.

    read more

  • Permalink for 'Svbtle Versus Obtvse'

    Svbtle Versus Obtvse

    Posted: March 23rd, 2012, 1:36pm MDT by Chris Shiflett

    I just read a post by Daniel Howells about these two stories on Hacker News:

    Before I make my small point, let me give you the quick synopsis. Briefly, Dustin Curtis made his own blogging platform, opened it up to a few friends, and blogged about it. Someone else submitted it to Hacker News, and that's where the story takes a turn.

    The Hacker News community quickly attacked Dustin's persona (he describes himself as a superhero) and the exclusivity of his blogging platform. I don't have a strong opinion about these criticisms, but I do believe them to be knee-jerk reactions based upon the false premise that Dustin was seeking the amount of attention he received.

    This is what I object to.

    Dustin made something and blogged about it. There's nothing wrong with that, and as someone who loves blogs, it's exactly what I want people like Dustin to do. The only difference is that someone submitted his post to Hacker News, and it got a lot of attention. The mistake the Hacker News community routinely makes is to assume the author of whatever they read is making a big deal about something.

    As I've said before, I really like the way Trent describes blogs:

    There's something sacred about reading a blog post on someone else's site. It's like visiting a friend's house for a quick meal 'round the breakfast table. It's personal — you're in their space, and the environment is uniquely suited for idea exchange and uninterrupted conversation. In many ways, we should be treating our blogs like our breakfast tables. Be welcoming & gracious when you host, and kind & respectful when visiting.

    No matter how popular someone's blog is, or how popular a particular post is, it's still their blog. It's their breakfast table.

    Let's all try to remember that the next time we pay them a visit.

  • Permalink for 'From the Start: Setting up Behat testing'

    From the Start: Setting up Behat testing

    Posted: March 23rd, 2012, 7:37am MDT by blog.phpdeveloper.org » PHP

    In a previous post I showed you how to use HTTP Auth with the Goutte driver in Behat testing. I want to take a step back and show you how I even got to that point with a simple guide to installing the tool and creating your first tests. In a future post, I’ll show the (super simple) integration you can do with Jenkins to execute the tests and plug in the results.

    First off, a definition for those not sure what Behat is:

    Behat was inspired by Ruby’s Cucumber project and especially its syntax part (Gherkin). It tries to be like Cucumber with input (Feature files) and output (console formatters), but in core, it has been built from the ground on pure php with Symfony2 components.

    And, for those not sure what Cucumber is:

    Cucumber lets software development teams describe how software should behave in plain text. The text is written in a business-readable domain-specific language and serves as documentation, automated tests and development-aid – all rolled into one format.

    These are both tools that implement something called behavior-driven development, the practice of approaching testing from a more natural angle, allowing tests to be written in “plain English” (or the language of your choosing with Behat) and executed at a domain level rather than a code level (as unit tests would). Behat makes this super simple and it really only takes a few minutes to get it up and running.

    For my examples, I’m going to be working on a Linux-based system (CentOS actually) but the same kinds of ideas apply to other platforms too, just modified slightly for things like pathing. So, let’s get started…first off, the installation. Personally, I recommend the Composer method for installation – it just makes it easier to get everything you need without having to think hardly at all.

    Here’s a set of commands (linux command line) to get everything set up for a basic project structure:

    mkdir behat-testing-ftw; cd behat-testing-ftw;
    curl -s [getcomposer.org] | php
    vi composer.json
    

    Inside the composer.json file, enter the stuff from the Behat instructions here (the JSON format), then we can run composer on it:

    php composer.phar install
    

    At this point you should see a bunch of things being installed in the “Installing dependencies” section (at the time of this post, that includes things like symfony/finder, symfony/dependency-injection and behat/gherkin). Once this is finished, you should have a directory structure similar to:

    Chriss-MacBook-Pro:behat-testing-ftw chris$ ls
    bin		composer.json	composer.lock	composer.phar	vendor
    

    Behat should be magically installed in the bin/ directory – to test it out, try this:

    Chriss-MacBook-Pro:behat-testing-ftw chris$ bin/behat
    

    If all goes well, you should see a big red error talking about “features” not existing. This is good – we’ll fix this now by making the testing base for Behat. Thankfully, it makes this easy too:

    Chriss-MacBook-Pro:behat-testing-ftw chris$ bin/behat --init
    +d features - place your *.feature files here
    +d features/bootstrap - place bootstrap scripts and static files here
    +f features/bootstrap/FeatureContext.php - place your feature related code here
    

    Your directory should now look like this:

    Chriss-MacBook-Pro:behat-testing-ftw chris$ ls
    bin		composer.json	composer.lock	composer.phar	features	vendor
    

    The new features directory is where your Behat tests will live. If you look in there now, there’s not much – just a bootstrap directory with a FeatureContext.php file in it. This file is where you’ll define any custom rules you might need to use outside of the pre-defined ones Behat (and later Mink) come with. If you re-run Behat again, you should see:

    Chriss-MacBook-Pro:behat-testing-ftw chris$ bin/behat
    No scenarios
    No steps
    0m0.001s
    

    So, let’s give Behat something to do now – Behat tests are organized in “feature” files. Let’s make a simple one for illustration and call it “sample.features” and put some content in it:

    cd features
    vi sample.feature
    

    And put the following inside it:

    Feature: Testing Behat install
            This is a testing feature to see

    Truncated by Planet PHP, read more at the original (another 3956 bytes)

Nettuts+

  • Permalink for 'Build a Contacts Manager Using Backbone.js: Part 4'

    Build a Contacts Manager Using Backbone.js: Part 4

    Posted: March 22nd, 2012, 1:00pm MDT by Dan Wellman

    In part four of this series, we saw how easy it is to add and remove models from our collection, and keep the page updated in sync with the changes. In this part, we’re going to look at editing existing model data.

    Getting Started

    We’ll start out by adding another simple button to the template, which will enable editing of its data:

    <button class="edit">Edit</button>

    As we are adding this button to our existing template, we can also add an entirely new template that can be used to render an editable form in which the model data can be changed. It’s very similar to the exiting template, and can be added to the page after the existing template:

    <script id="contactEditTemplate" type="text/template">
    <form action="#">
        <input type="file" value="<%= photo %>" />
        <input class="name" value="<%= name %>" />
        <input id="type" type="hidden" value="<%= type %>" />
        <input class="address" value="<%= address %>" />
        <input class="tel" value="<%= tel %>" />
        <input class="email" value="<%= email %>" />
        <button class="save">Save</button>
        <button class="cancel">Cancel</button>
    </form>
    </script>

    The new template consists mostly of <input> elements that expose the editable data. We don’t need to worry about labels for the elements, but instead use the data from the model as the default values of each input. Note that we’re using a hidden form field to store the type attribute of the model, we’ll use this to set the value of a <select> that we need to add using our script instead of having the template render it.

    Next we can bind some event handlers for the new buttons we’ve added; update the events object in the ContactView class so that it contains the following new bindings:

    "click button.edit": "editContact",
    "change select.type": "addType",
    "click button.save": "saveEdits",
    "click button.cancel": "cancelEdit"

    Don’t forget to add the trailing comma to the end of the existing binding! These are very similar to the bindings we’ve used before; each key:value pair simply specifies an event to listen for and a selector to match the element that triggers the event as the key, and the event handler to execute on detection of the event as the value.

    Switching a Contact Into Edit Mode

    In the same way that we stored a reference to the template function under the template property of our ContactView class, we should also store a reference to the template function that we’ll use to switch the contact into edit mode. Add editTemplate directly after the template property:

    editTemplate: _.template($("#contactEditTemplate").html()),

    Now we can add the event handlers themselves, which should also go into the ContactView class after the existing deleteContact() method. First, we’ll add the editContact() method:

    editContact: function () {
        this.$el.html(this.editTemplate(this.model.toJSON()));
    
        var newOpt = $("<option/>", {
            html: "<em>Add new...</em>",
            value: "addType"
        }),
    
        this.select = directory.createSelect().addClass("type")
            .val(this.$el.find("#type").val()).append(newOpt)
            .insertAfter(this.$el.find(".name"));
    
        this.$el.find("input[type='hidden']").remove();
    },

    We start out by rendering our new editTemplate that we added to the page using Underscore’s template() method in the same way that we added each contact using the standard display template.

    In order to make editing the type of contact easier we can render a select box that lets the user switch easily between existing types, but we also want to cater for the possibility that the user may want to add a new type. To allow for this, we’ll create a special option for the select box with the text Add new... and a value of addType.

    We then create the new <select> element using the createSelect() method of our master view, which if you recall from the last part in this tutorial will return a <select> element containing an <option> for each unique type in the collection. We give it a class name, and to get the <select> element to show the existing type of the contact being edited we set its value to the value of the hidden <input> we added in our template. We then insert the new <select> after the <input> for the contact’s name. The new select element is added as a property of the view instance so that we can interact with it easily.

    Once we’ve added the <select> element for the contact’s type, we can then remove the hidden field so that it doesn’t interfere with saving the edit, which we’ll look at shortly.

    At this point, we should now be able to click the edit button in any of our contacts and have the contents of that contact converted into a form:

    Adding a New Type

    One of the event bindings we added was for the change event of the type select box, so we can add a handler which replaces the <select> box with a standard <input> element:

    if (this.select.val() === "addType") {
        this.select.remove();
    
        $("<input />", {
            "class": "type"
        }).insertAfter(this.$el.find(".name")).focus();
    }

    When the <select> element’s value changes we first check whether its value is addType and if so, we remove the element from the page and create a new <input> element to replace it. We then insert the new element using jQuery’s insertAfter() method and focus it ready for text entry.

    Updating the Model

    Next we can add the handler that will take the changes made in the edit form and update the data in the model. Add the saveEdits() method directly after the editContact() method that we just added:

    saveEdits: function (e) {
    	e.preventDefault();
    
        var formData = {},
            prev = this.model.previousAttributes();
    
        $(e.target).closest("form").find(":input").add(".photo").each(function () {
    
            var el = $(this);
            formData[el.attr("class")] = el.val();
        });
    
        if (formData.photo === "") {
            delete formData.photo;
        }
    
        this.model.set(formData);
    
        this.render();
    
        if (prev.photo === "/img/placeholder.png") {
            delete prev.photo;
        }
    
        _.each(contacts, function (contact) {
            if (_.isEqual(contact, prev)) {
                contacts.splice(_.indexOf(contacts, contact), 1, formData);
            }
        });
    },

    First of all, we create an empty element to store the data that has been entered into the form, and also store a copy of the previousAttributes of the model that belongs to the view we’re working with. The previousAttributes property of models is a data store that Backbone maintains for us so that we can easily see what an attribute’s previous attribute data was.

    We then get each input element from the form using a combination of jQuery’s find() method and the :input filter, which gives us all of the form fields. We don’t want the cancel or save <button> elements though, so we remove them from the selection using jQuery’s not() method.

    Once we have our collection of fields, we iterate over them using jQuery’s each() method and for each item in the collection, we add a new key to our formData object using the current item’s class, and a new value using the current item’s value.

    When we convert the editable contact back into a normal contact, we don’t want to lose the default photo if a new photo has not been chosen. To make sure we don’t lose the default photo, we can delete the photo property from our formData object if its value is blank.

    Backbone models have a setter method that can be used to set any attribute.

    Backbone models have a setter method that can be used to set any attribute. In order to update the model’s data we just call its set() method passing in the formData object that we have prepared. Once this is done we call the view’s render() method and our newly updated model will be rendered back to the page, with any updated information from the form.

    As we have done previously, we need to update the data stored in our original contacts array so that filtering the view doesn’t lost any changes we have made. We do this in a very similar way as before, first checking whether the photo property has the default value and removing it if so, and then using a combination of Underscore’s each() and isEqaul() methods to find the item in the contacts array that has changed. This is where we use the previousAttributes that we saved earlier; we can’t use the current model anymore because its attributes have just been updated.

    We use the native JavaScript’s splice() function to update the contacts array. As before, we obtain the index of the item to update using Underscore’s indexOf() method as the first argument to splice() and set the function to update a single item using the second argument. This time we supply our formData object as the third argument. When splice() receives three (or more) arguments, the third argument is the data to replace the data that has just been removed.

    Cancelling the Edit

    We have one button left that we need to add a handler for – the cancel button. This method will be very simple and will just switch the contact back into non-edit mode, using the original data from the model. Add this method after the saveEdits() method:

    cancelEdit: function () {
        this.render();
    },

    That’s all we need to do! We already have a method that takes a model and renders it as a view on the page, so we simply call this method and the original model data will be used to recreate the original contact. This is useful because even if someone changes the data in the form fields while the contact is in edit mode, when the cancel button is clicked, these changes will be lost.

    Summary

    In this part of the tutorial we’ve looked at how we can update the data of an existing model rather than creating a whole new model. To do this we essentially just need to call a model’s set() method and pass in the new attributes that we wish to set.

    As with Backbone however, we’ve only covered a small fraction of what these libraries provide, there is so more that we can use when building complex applications on the front-end.

    As we saw however, we also need to think about how we can change the view to allow the visitor to enter the data that will be set as the new attributes. In this example, we achieved this by creating another template to handle rendering a form pre-filled with the existing attribute data which the user can overtype to change.

    Over the course of this series, we’ve looked at all of the major components of Backbone including Models, Collections, Views and Routers and Events. We’ve also looked at some of the methods and properties provided by Backbone that we can use to interact with the different constructs to produce an integrated, functioning application, albeit a basic one.

    As well as learning some Backbone basics, one of the most important aspects of the tutorial was in how the application is structured, with all of our code organised in a logical and consistent way. Applications written in this style can be much easier to return to and maintain on the long-term. Much of our functionality was event driven, either in response to the actions of the visitor in the form of UI event handlers, but some were also driven by changes to the collection and triggered manually at the appropriate point in our code.

    We’ve also looked at some of the utilities provided by Underscore which has given us easy ways to work with the objects and array that form the foundation of our application. As with Backbone however, we’ve only covered a small fraction of what these libraries provide, there is so more that we can use when building complex applications on the front-end.


  • Permalink for 'How to Create a Helpful Plugin With Twitter Anywhere'

    How to Create a Helpful Plugin With Twitter Anywhere

    Posted: March 21st, 2012, 7:48pm MDT by Ben Howdle

    Twitter Anywhere is a “one-script-include” solution from Twitter to bring the power of their communication platform to your website. We’ll be building a small jQuery script that utilizes Twitter Anywhere for your users.

    Step 1: Registering Your Application

    The first step in the Twitter Anywhere process is to create an application. The registration can be found here. The only field that might cause any level of confusion is the Callback URL. This is to be used when Twitter authenticates the user; it specifies where on your site you want to send the authenticated user back to. For most smaller applications, your website’s homepage will likely be sufficient, however, for larger applications, you may want to direct the user back to an area that serves appropriate content for authenticated users.

    One important setting worth noting is the Application Type. Now this won’t appear in the Application creation process, but will be available by going to your apps, finding your new application, clicking the Settings tab next to Details, and changing the radio button from “Read Only” to “Read and Write” in the Application Type sections.

    To be honest, it’s embarrassing for me to admit how much time went by, while debugging, before I decided to look here!

    Step 2: What’s the Script Going to Do?

    Using Twitter Anywhere, we’re going to concentrate today on the Tweet Box feature. The Tweet Box provides excellent transparency between your website and Twitter, allowing users to tweet directly to their account without leaving your website, and, more importantly, continuing to interact with your content.

    The jQuery script we’re going to write today could easily be adapted into a jQuery or WordPress plugin. The script will detect the user highlighting a piece of text in say, your blog post, and display a “Tweet this” button. Once the user clicks this button, the script will take the highlighted text and call the Tweet Box function from Twitter Anywhere, inserting the highlighted text as the tweet body.

    The user can then either leave the tweet as it is – with a link back to the page they’re on – or they can edit any part of it before tweeting.

    Security is vital here; the slightest bit of misuse, and the user will revoke access in their settings – and not likely return to give your application a second chance. So, always give the user a preview of exactly what will be posted to their account; it’s generally a good practice to make them press the button before processing the tweet.

    Tweeting Direct Image Links

    The script will also allow for the user to click on any of your images, and achieve the same Tweet Box effect. In this particular instance, the tweet will reference the direct URL to the image.

    Step 3: Setting Up the JavaScript Files
    <script src=" [https:] <script src=" [https:] <script src=" [platform.twitter.com] <script src=" [path-to-script] 

    As you can see above, we need to include a few JavaScript files to make our plugin function correctly.

    • We’ll be using jQuery for its ease of use and nice selector engine.
    • We’ll use jQuery UI for basic user interaction; when the Tweet Box pops up, we can allow the user to drag it around with their mouse.

    • The next JavaScript include is the Twitter Anywhere file itself. Luckily for us, it’s fairly lightweight, coming in at just over 7KB. As you can see, you’ll need to supply your API key, which can be found in the Settings of the App page from earlier in this article.
    • The last file is our own script; this will hold all of our jQuery code and Tweet Box function calls.
    Step 4: Beginning Our Code
    $(document).ready(function(){
    
    });
    

    We’ll start in our JavaScript file by containing everything within jQuery’s document ready method. Everything in here will fire after the DOM has fully loaded, saving us from any potential errors.

    function getSelectionText() {
        var text = "";
    
        if (window.getSelection) {
            text = window.getSelection().toString();
        } else if (document.selection && document.selection.type != "Control") {
            text = document.selection.createRange().text;
        }
        return text;
    }
    

    The above piece of code will allow you to grab the highlighted text from the user once they have selected it. This code is a fairly standard function, and can be found (and documented) all over the internet.

    $('.post').mouseup(function(){
    	$('#tweetThis').show();
    });
    

    We can then begin to interact with the user with a mouse up event. In this particular page of HTML, I have created a div with a class of ‘post‘. For the tutorial, we are simply targeting this div so that the code doesn’t run every time the user mouses up on the page. Once the user mouses up within this div, we will display a button to the user that allows them to tweet the highlighted text.

    $("#anywhere").draggable();
    

    This method uses jQuery UI to allow the user to drag the Tweet Box around at their leisure. We don’t pass any options to it as the default functionality will suffice for what we’re doing.

    $('#tweetThis').click(function(){
    		$('#tbox').empty();
    		var text = getSelectionText();
    
    		if(text != ''){
    			twttr.anywhere(function (T) {
    			    T("#tbox").tweetBox({
    			      height: 100,
    			      width: 400,
    			      defaultContent: '"' + $.trim(text) + '" - ' + document.title + ' - ' + window.location.href
    			    });
    			});
    
    			$('#anywhere').show();
    
    		}
    
    	});
    

    Here is where the meat of our plugin’s functionality will take place. On click of the “Tweet This” button, we will begin by emptying the contents of the Tweet Box. This allows the user to highlight a different piece of text and tweet that instead.

    The next line will declare a variable to hold the user’s selected text from our function call. We then do a quick check to determine if the user actually selected any text, and proceed with our Tweet Box initialization.

    From the official documentation:

    “The @Anywhere JavaScript file establishes a single global object (twttr). To use @Anywhere, call the anywhere method, and pass in a callback. The callback will receive an instance of the Twitter API Client (named “T” by convention) as its only argument. All @Anywhere features are available as members of the Twitter API Client.”

    This means that you can call any of these methods on the Twitter API Client (“T”): Auto-linkification of Twitter usernames, Hovercards, Follow buttons, Tweet Box, User login & signup. Your application can make multiple calls to the ‘anywhere‘ method, so don’t be afraid about limiting the functionality of your site!

    As you can see, we then target “#tbox“, to be filled with Twitter’s Tweet Box feature. As you might have noticed, if you work with jQuery, it uses similar CSS selectors when querying the DOM.

    If we were to call .tweetBox(); without any options, then the Tweet Box would take it properties from the defaults outlined in the Documentation. We use the defaultContent property to insert the user’s selected text into a Tweet, along with the current page title and location. We use jQuery’s $.trim function to get rid of any unwanted whitespace from the user’s selection, which would cost them characters in their Tweet.

    We can then display the created Tweet Box to the user, ready for them to approve and tweet!

    Step 5: Tweeting Image URLs
    $('img').click(function(){
    	var url = $(this).attr('src');
    
    	twttr.anywhere(function (T) {
    
    	    T("#tbox").tweetBox({
    	      height: 100,
    	      width: 400,
    	      defaultContent: 'Check out this image: ' + url
    	    });
    
    	});
    
    	$('#anywhere').show();
    
    });
    

    The code above provides the user with the ability to tweet a direct image URL to their account. We set up the Tweet Box exactly as before but, we use the ‘src‘ of the ‘img‘ element this time as the dynamic variable instead of highlighted text.
    This could easily be adapted for HTML5 videos, if you desire to target them instead of images.

    A Bit Little Housekeeping
    $('#hide').click(function(){
    	$('#tbox').empty();
    	$('#anywhere').hide();
    	$('#tweetThis').hide();
    });
    

    The above code simply allows the user to get rid of the Tweet Box after they have tweeted or if they change their mind about tweeting. We empty the div element ready for the next selected text or image URL.

    Step 6: Possible Use Cases

    This sort of functionality would lend itself perfectly to a blog.

    Having this code adapted into a WordPress plugin would allow users to tweet quotes from your articles, increasing exposure and spreading your content across the internet.

    The image URL tweeting would fit nicely on a photography or web design portfolio site where the user can tweet your pieces of work. Or, this script could be turned into a properly formed jQuery plugin for use on any website; static; CMS driven or Tumblr – the possibilities are endless.

    Final Thoughts

    The Twitter Anywhere platform is a fantastic way to layer Twitter functionality onto your site.

    The Twitter Anywhere platform is a fantastic way to layer Twitter functionality onto your site. From personal experience, I think it is just that: a layer. I wouldn’t feel comfortable building an entire application with it. The documentation is rather slim, and the first thing you may notice when using it yourself is how much potential it has, how much functionality could be in there, and how it’s partially lacking right now.

    For example, currently, you can retrieve a user’s Favorites count – just the count, no content. This extra functionality would make Twitter Anywhere stand up level with the Server Side REST API that exists already, powering very complex, vast applications.

    Good luck with this platform and try to find an interesting use case for some of its easy-to-implement features! In the meantime, check out the demo Copybot. Thanks for reading!


Planet PHP

  • Permalink for 'Behat and HTTP Auth (and Goutte)'

    Behat and HTTP Auth (and Goutte)

    Posted: March 21st, 2012, 1:44pm MDT by blog.phpdeveloper.org » PHP

    So I’ve been trying out Behat for some REST testing recently and came across an interesting situation – I needed to send HTTP Auth credentials as a part of my test. Of course, there’s a method for this on the Session object (setBasicAuth) but it’s not implemented as a default phrase. It took me a bit to make it to the (now logcial) point that I needed to set these before I used the “Given I am on…” phrase to go to the page.

    So, to accomplish this, I set up a custom “Given” phrase to set them: “Given that I log in with ‘username’ and ‘password’” so that my full Scenario looks like:

    Scenario: Get the main Index view
            Given that I log in with "myuser" and "mypass"
            And I am on "/index/view"
            Then the response should contain "TextFromPageTitle"
    

    And the code is super simple:

    /**
     * Features context.
     */
    class FeatureContext extends Behat\Mink\Behat\Context\MinkContext
    {
        /**
         * @Given /^that I log in with "([^"]*)" and "([^"]*)"$/
         */
        public function thatILogInWithAnd($username, $password)
        {
            $this->getSession()->setBasicAuth($username,$password);
        }
    }
    

    Hope this helps someone else out there trying to send HTTP Auth pre-connection. I’m sure there’s probably an easier way that I’m missing, but this seemed the simplest to me.

  • Permalink for 'Best of PHP scripts for the PDF file creation'

    Best of PHP scripts for the PDF file creation

    Posted: March 21st, 2012, 1:11pm MDT by Web Development Blog » PHP Scripts
    Dynamic PDF generation or html to PDF conversions are a common tasks for many web applications. Creating order documents for your eCommerce application, coupons for your sales and marketing campaign or a PDF version from your web pages, are just some examples. You can use PHP class script to create dynamic PDF files. This list is a bout the most popular PHP classes, PDF import functions and PHP scripts with the abbility to convert valid html code into PDF files.
  • Permalink for 'Best of PHP scripts for PDF file creation'

    Best of PHP scripts for PDF file creation

    Posted: March 21st, 2012, 1:11pm MDT by Web Development Blog » PHP Scripts
    Dynamic PDF generation or html to PDF conversions are a common tasks for many web applications. Creating order documents for your eCommerce application, coupons for your sales and marketing campaign or a PDF version from your web pages, are just some examples. You can use PHP class script to create dynamic PDF files. This list is a bout the most popular PHP classes, PDF import functions and PHP scripts with the abbility to convert valid html code into PDF files.
  • Permalink for 'Best of PHP scripts for creating PDF files'

    Best of PHP scripts for creating PDF files

    Posted: March 21st, 2012, 1:11pm MDT by Web Development Blog » PHP Scripts
    Dynamic PDF generation or html to PDF conversions are a common tasks for many web applications. Creating order documents for your eCommerce application, coupons for your sales and marketing campaign or a PDF version from your web pages, are just some examples. You can use PHP class script to create dynamic PDF files. This list is a bout the most popular PHP classes, PDF import functions and PHP scripts with the abbility to convert valid html code into PDF files.
  • Permalink for 'PHP's Source Code For PHP Developers - Part 3 - Variables'

    PHP's Source Code For PHP Developers - Part 3 - Variables

    Posted: March 21st, 2012, 8:30am MDT by Anthony Ferrara
    In this third post of the PHP's Source Code for PHP Developers series, we're going to expand on the prior posts to help understand how PHP works internally.  In the first post of the  series, we looked at how to view PHP's source code, how it's structured as well as some basic C pointers for PHP developers.  The second post introduced functions into the mix.  This time around, we're going to dive into one of the most useful structures in PHP: variables.

    Read more »
  • Permalink for 'New full-time gig at fruux'

    New full-time gig at fruux

    Posted: March 21st, 2012, 7:44am MDT by Evert Pot

    fruux_logo.png

    I've been at this for a bit, but now it's official: I'm now based in Münster, and working at fruux as a co-founder / tech-lead.

    The feeling of having this amount of control over a product is great. We've also recently got funded from High-Tech Gründerfonds and netSTART Venture and moved into a new office so things are indeed pretty serious. We have some flexibility to focus on making a great product, in what we feel is 'the right way' (whatever that may mean). It will be an exciting time :)

    So if you were looking at SabreDAV, and needed something way easier to use, fruux may be a good option. Regardless, for SabreDAV the future is bright too, as there will be plenty of cross-pollination.

    Also, if you're looking for a job, or know someone who's looking: drop me a line! We're in the market for good PHP and front-end developers.

  • Permalink for 'Rocking Your Job Interview'

    Rocking Your Job Interview

    Posted: March 21st, 2012, 6:24am MDT by Brandon Savage
    One of the things about the PHP field is that developers are highly sought after, and good developers are prized. While anyone can slap “PHP Developer” on their resume, most companies have gotten good at weeding out the pretenders from the real deal. This means that for a highly qualified developer, interviewing should be an [...]
  • Permalink for 'Why is it better to develop in PHP with classes (OOP)?'

    Why is it better to develop in PHP with classes (OOP)?

    Posted: March 21st, 2012, 5:49am MDT by PHP Classes
    Why is it better to develop in PHP with classes (OOP)? By Manuel Lemos Some developers code their PHP projects writing classes of objects.

    Others also write classes but do it just because they see others doing it without being able to explain why classes are a good thing.

    Others do not write classes but reuse other people code written in the form of classes.

    Others completely refuse to write or reuse other developer classes because they do not see much point in doing it.

    Read this article to learn why it is better to develop your PHP projects based on object classes.

    You may also learn how to convert your global code based classes into properly written classes that you can reuse in multiple projects besides other benefits of using Object Oriented Programming in PHP.
  • Permalink for 'Webinar: "Writing Testable Code"'

    Webinar: "Writing Testable Code"

    Posted: March 21st, 2012, 4:57am MDT by Qafoo - PHP
    Last week, I gave an live webinar about "Writing Testable Code" in the PHP world, on behalf of Qafoo and Zend, for which the recording is now available online! You can watch the whole 1 hour session online on the Zend website. In addition, for example if you don't like videos, you can find the slides for download in our talks section.
  • Permalink for 'New in Xdebug 2.2: Colours on the command line'

    New in Xdebug 2.2: Colours on the command line

    Posted: March 21st, 2012, 3:43am MDT by Derick Rethans
    New in Xdebug 2.2: Colours on the command line London, UK Wednesday, March 21st 2012, 09:43 GMT

    This is the first article in a series about new features in Xdebug 2.2. Besides support for PHP 5.4, there are a few that might be of interest.

    Xdebug has overloaded var_dump() with xdebug_var_dump() for a long time and the overloaded function could be configured with a few configuration settings. There is xdebug.var_display_max_data to configure how much of a string should be shown; xdebug.var_display_max_children to configure how many children in an array should be shown and xdebug.var_display_max_depth to configure how many levels "deep" the var_dump() should go on for. This functionality was available for when PHP had its html_errors setting on as is usually the case in a web environment1.

    Xdebug 2.2 adds this same functionality to the non-html environment: the command line. Now the overloaded var_dump() and native xdebug_var_dump() functions also accept the three aforementioned settings:

    derick@whisky:~$ php \
            -dxdebug.var_display_max_data=8 \
            -dxdebug.var_display_max_children=4 \
            -r 'var_dump( "a longer string", array( 1, 2, 3, 4, 5, 6, 7 ) );'
    
    

    outputs:

    string(15) "a longer"...
    array(7) {
      [0] =>
      int(1)
      [1] =>
      int(2)
      [2] =>
      int(3)
      [3] =>
      int(4)
    
      (more elements)...
    }
    
    

    Now, to be fair. This is all a side effect; and merely an add-on to a patch by Michael Maclean. He wrote a patch that adds colours to the output on the command line by using ANSI escape codes. This patch also made the overloaded var_dump() listen to the limiting settings for variable display. After his patch, the following was the behaviour on the command line as long as stdout is a tty and xdebug.cli_color is set to 1.

    cli-color-linux.png

    I have extended this so that the settings regarding data display also work without xdebug.cli_color set to 1. Further more, in Xdebug 2.2.0RC1, setting xdebug.cli_color to 2 forces the colours from being shown, even if stdout is not a tty.

    Initially, the colour coding of errors and var_dump() output, would only work on a Unix system where ANSI escape codes are commonly supported. After the release of Xdebug 2.2.0RC1, Chris Jones submitted a bug report suggesting that this functionality could also be available on the Windows console. I wasn't aware that Windows could do this anymore since they dropped ANSI.SYS but apparently there is a tool, ANSICON, that reimplements this. From the next release, Xdebug 2.2.0RC2, Xdebug will now also check whether the ANSICON environment variable is set, just like Xdebug would check whether stdout is a tty on a Unix platform. As a result, the equivalent console output as shown before looks like the following on Windows (providing ANSICON is installed):

    cli-color-windows.png

    Now the only thing left is adding complete documentation for this feature ;-)

    As always, if you think Xdebug is a valuable tool, have a look at [xdebug.org] .

    "/>

    Truncated by Planet PHP, read more at the original (another 541 bytes)

  • Permalink for 'PHP's Source Code for PHP Developers - Part 3 - Variables'

    PHP's Source Code for PHP Developers - Part 3 - Variables

    Posted: March 21st, 2012, 1:00am MDT by Nikita Popov

    The third part of the PHP’s Source Code for PHP Developers series can be found on ircmaxell’s blog. It introduces how PHP values are internally represented and how they are used in the source code.

    The fourth part, which will again be published on this blog, will cover how arrays are implemented in PHP.

  • Permalink for 'Testing persistent connection and thread-safety features in PHP'

    Testing persistent connection and thread-safety features in PHP

    Posted: March 20th, 2012, 3:23pm MDT by Johannes Schlüter

    By default PHP provides shared-nothing environments to ensure that whatever happens to PHP's state in one request has no effect on other requests, so all function tables are cleaned up, all file handles are closed etc. In a few rare cases this is not what people like, for that PHP introduced "persistent connections" of different kinds. Testing those is a bit annoying as you have to configure a webserver and ensure to hit the same instance over the course of a test and then use a load generator, probably one which can detect a failure. Additionally by having a webserver in the game there is more code being executed, which might mean an additional source for trouble while debugging. An alternative might be using FastCGI, while that adds it's own issues for such a test.

    To solve this for myself I, some time ago, wrote a PHP SAPI module called pconn and pushed it to github. (A SAPI is the component in PHP which implements the communication with the web server or whatever triggers PHP requests) The general idea was to have a lightweight SAPI which does nothing but emulate a bunch of requests. I had it some where on my list of things to blog about, but well, low prio.

    Now some time later it seems like Derick was doing some stuff with persistent connections, too, and figured that the new embedded web server is a good thing for such tests, too. While he didn't know about my solution, as one could see in a short discussion on twitter we had:

    In other news, the new CLI web server in PHP 5.4 is brilliant for debugging issues with extensions that span more than one request.

    — Derick Rethans (@derickr) March 15, 2012

    @derickr for that you could also use github.com/johannes/pconn… which also does multithreading -)

    — Johannes Schlüter (@phperror) March 15, 2012

    @phperror: You need to write about that stuff :-þ

    — Derick Rethans (@derickr) March 15, 2012

    Now I've contradicted myself: Above I was proudly writing about this being lightweight and easy to debug, but in the tweet I mentioned threading. And well threading always includes lots of trouble to code. But yeah, over time I figured out that this was a good foundation to solve a second issue which has has to be done for PHP: PHP can be run in threaded environments, which in general is not advised. When doing that the old party rule applies: What happens in a thread stays in thread. Different threads should not impact the requests handled in other threads. Now testing for race conditions is even harder than testing persistent connections and additional web server code hurts even more. So my little SAPI became a lot bigger and can now be compiled in two modes. Either simple and short in non threaded mode or with all the extra stuff in threaded-mode which will allow running PHP requests in parallel threads in loops.

    In case you find yourself working on some PHP extensions where this might help: Check the github repository and the README and drop me a line if anything is unclear.

Nettuts+

  • Permalink for 'Getting Started With Node.js and Geddy'

    Getting Started With Node.js and Geddy

    Posted: March 20th, 2012, 8:55am MDT by Daniel Erickson

    In this three part tutorial series, we’ll be diving deep into the process of creating a to-do list management app in Node.js and Geddy from scratch. In this introductory article, we’ll review how to install Node.js on Windows and OS X, getting Geddy installed, and generating our first app. Ready?

    What is Node?

    If you’ve been developing web apps for the last couple of years, you’re likely already familiar with Node.js, but let’s go over it – just in case you’re new to the scene.

    Node.js is a platform built on Chrome’s JavaScript runtime for easily building applications in JavaScript that run on the server. Node.js uses an event-driven, non-blocking I/O model, which makes it perfect for building real time apps.

    What is Geddy?

    Geddy should feel very familiar to you.

    Geddy is a simple and structured MVC (model, view, controller) framework for Node.js. You can use it to quickly create web apps and JSON APIs. If you’ve done any level of work with Ruby on Rails or PHP’s CodeIgniter, Geddy should feel very familiar to you; it’s got a restful router, template rendering, controllers, and models.

    Installing Node.js

    Node.js runs on Windows, OS X, and Linux. I’ll show you how to get set up on both Windows and OS X. if you’re on Linux I’ll assume that you’ve got Node installed, know how to get it installed, or know someone that can help you with the process.

    First, go to [nodejs.org] and click the download button. Find the installer link for your operating system, and download it. Follow the installation prompt to get installed. If you’re on Windows, you may need to reboot your computer to get the ‘node’ command on to your path.

    You should now have both Node and npm (Node Package Manager) installed.

    Installing Geddy with npm

    Node has a great package manager built right in. It’s called, npm, and, as of this writing, there are nearly 8,000 packages available. Check out [toolbox.no.de] to browse through them if you’d like. For this tutorial, however, we’ll use npm to install Geddy (our framework) and Jake (the build tool that Geddy uses):

    Jake is a JavaScript build program for Node.js.

    • Open up your terminal
    • type npm install -g geddy jake

    That’s it! Now that you’ve got Geddy installed, let’s see about generating your first app.

    Generating a Geddy App

    Geddy uses a global executable to generate apps/resources, and to start up your app server. This will all take place on the command line, so open up your terminal again. Before we generate our app, let’s cd to a good location to store your app. This can be anywhere on your machine, though, I prefer to do my development in my ~/dev/ directory.

    cd path/to/the/place/you/code

    Next, we’ll use geddy to generate our app structure. We’ll be creating a to-do application, so we’ll call ours, todo_app

    geddy app todo_app

    All done. Now what did that do for us?

    An Overview of Our Generated App

    If you take a look within the newly created todo_app directory, you’ll see that Geddy has generated a fair bit of code for you. Your directory structure should look a bit like this:

    • app/
      • controllers/
      • models/
      • views/
    • config/
    • lib/
    • log/
    • node_modules/
    • public/

    Let’s step through these one by one:

    app: Here’s where most of the magic happens. Most of your app’s logic will be located in one of the three directories contained in this one.

    app/controllers: All of your app’s controllers (the part that ties your models to your views) go here. You’ll also notice that there’s already two controller files in there: application.js (which all controllers inherit from) and main.js (the controller that ties your / route to your app/views/main/index.html.ejs template).

    app/models: Here’s where you’ll be storing your models – there’s nothing in there yet, but we’ll adding one in during the next tutorial.

    app/views: All of your app’s templates are stored here. For now, you’ll see that you have an application.html.ejs file in the layouts directory – this file is the main template for your app, all of your front-end wrapper code should go in here. You should also have an index.html.ejs file in the main directory. This is what get’s rendered by the main controller’s index action when you hit the / route.

    config: The configuration files for your app goes here. You should have the development.js, production.js, environment.js, router.js and init.js files in there. The init.js file is a file that runs just after the app gets started, before any requests come in. This can be used to add functions and properties that need to be app-wide. The router.js file is used to create routes for your application. Routes tie URLs to controller actions. For global settings, you’ll want to edit the environment.js file. For production and development settings, edit the corresponding config files.

    lib: This is the place where you can put any file’s that you’d like to use all over your app.

    log: All of your logs will be stored here. You should get an access.log, a stdout.log, and a stderr.log after you run your app.

    node_modules: This is where the modules that you install will be stored. Think of it as a lib for other people’s code.

    public: Finally, here’s where all of your front end specific stuff will live. All you css files, images, and front-end js files will be in here. You’ll notice that Twitter’s bootstrap and jQuery come pre-packaged with all Geddy apps.

    Starting Up Your New Geddy App

    Now that we have an app generated, I’ll demonstrate how to start it up. First, open the terminal again, and navigate to your app’s directory:

    cd ~/path/to/code/todo_app

    Once you’re there, start the app up by using the geddy command:

    geddy

    You should see some output that looks a bit like this:

    Now that we’ve started up the server, go ahead and check it out in browser. Visit http://localhost:4000, and take a look!

    Bonus: Because Geddy uses Bootstrap out of the box, with it’s responsive layout enabled, our app will immediately display nicely in a mobile browser. Resize your browser window to verify this.

    The Next Step

    This concludes the first part of our tutorial series on Node.js and Geddy. In the next one, I’ll demonstrate how to generate a todo resource (which will give us a better base to build our app upon), and go into the details of building a real app with Geddy. If you have any questions, feel free to leave a comment here or open an issue on GitHub. Stay tuned!


Planet PHP

  • Permalink for 'A few more conferences I’ll be at soon…'

    A few more conferences I’ll be at soon…

    Posted: March 20th, 2012, 3:49am MDT by John Mertic

    I’m excited to announce two more conference stops for me this spring!

    First, is my return to POSSCON in Columbia, SC, at the end of March on the 28th and 29th. I’ll be doing a great talk and live demo on building an application on the Sugar platform, but the big draw for this show is to see our very own CEO and Open Source legend Larry Augustin keynoting on ‘Open Source – Now and in the Future‘. He’s a great speaker and comes with amazing insight from someone who helped coined the term back in the 90′s. Plus, as a conference POSSCON is top notch, with a great array of speakers representing the best of open source catering to making it work in the business world.

    Then, I’ll make a trip over the pond in mid April for the inaugural Whisky Web conference in Edinburgh, UK. I had a chance to meet the organizers back at PHPBenelux in January, and I must say they won me over with the promise of free whiskey ;-) .

    But seriously, for a one day conference the content and speaker list is excellent. I’m grateful to be one of them, debuting a new talk on “Lessons Learned From Testing Legacy Code”, where I’ll hopefully give some good advice on making that crazy legacy app you’ve been thrown into not fight you from trying to make it testable.

    Look forward to meeting up with friends and colleagues at these two events upcoming, as well as meeting new faces as well.


  • Permalink for 'RIPS static source code analyser'

    RIPS static source code analyser

    Posted: March 19th, 2012, 3:02pm MDT by Gareth Heyes

    RIPS is a static source code analyser and is one awesome piece of coding by @fluxreiners. Use it now to scan your PHP files for vulnerabilities. It can detect XSS, SQLi, File disclosure, LFI/RFI, RCE and lots more and it’s free. I’m downloading the current version now 0.52, so should you!

  • Permalink for 'REST APIs as Data Backends'

    REST APIs as Data Backends

    Posted: March 19th, 2012, 5:00am MDT by Brandon Savage
    Some months ago, the Socorro team agreed that our current mix of REST API middleware calls and direct SQL calls from the web interface simply wasn’t meeting our needs. We were faced with an increasing number of data sources, including the coming addition of Elastic Search to the data storage system, and maintenance was becoming [...]
  • Permalink for 'Open Advice'

    Open Advice

    Posted: March 19th, 2012, 4:51am MDT by Henri Bergius

    Open Advice coverI seem to have not blogged about this, but Open Advice, our book on Free and Open Source Software: what we wish we had known when we started, was published last month.

    The book was edited by Lydia Pintscher and includes essays from 42 authors, many of whom you'll recognize if you tend to go to FOSS conferences. The LWN book review concludes:

    Open Advice is a book that will be helpful to those who are new to FOSS, but, because of the individual voices, styles, and tones, it doesn't read like a "how to". It could even be recommended to those who aren't necessarily interested in contributing, but are curious about what this "free software thing" is all about. It is, in short, a great book for a variety of audiences and the (mostly) two or three page essays make it easy to read, while the anecdotes and recollections personalize it. The authors, editor, and everyone else who helped should be very pleased with the result. Readers will be too.

    I probably shouldn't give the ending away, but my essay on cross-project collaboration, a subject I've also blogged about, ends with:

    Good luck with breaking down the project boundaries! In most cases it works if your ideas are good and presented with an open mind. But even if you do not find a common ground, as long as your implementation solves the use case for you it has not been in vain. After all, delivering software, and delivering great user experience is what counts.

    The book is licensed under CC-BY-SA, and is available as free download in ePub, mobi and PDF formats, and as paperback from Lulu. The book sources are available on GitHub, patches welcome!

  • Permalink for 'PHP migrates to Git'

    PHP migrates to Git

    Posted: March 18th, 2012, 5:00pm MDT by PHP: Hypertext Preprocessor
    The migration of the PHP source code from Subversion to Git is complete. You can clone or fork the source from our GitHub mirror, and we also now support pull requests made via GitHub. The source is also available via git.php.net, and full instructions on cloning the php-src tree can be found at php.net/git. One immediate benefit is that future PHP release tags will be signed by the PHP development team. We will be releasing GPG keys for verification purposes in the next few days. More information on the migration and the new workflow can be found at the Moving to Git FAQ on the PHP Wiki. Please note that the PHP manual, including translations, continues to be hosted in Subversion for the time being and will be migrated to Git at a later date. Many thanks to David Soria Parra for his hard work on making the conversion to Git a reality, and to Alexander Moskaliov, Florian Anderiasch and Johannes Schlüter for their work on the scripts required to support the conversion. Let the forking begin!

Nettuts+

  • Permalink for 'Nettuts+ Quiz #11: Do You Know SQL?'

    Nettuts+ Quiz #11: Do You Know SQL?

    Posted: March 17th, 2012, 12:44pm MDT by Siddharth

    In 2012, we plan to take our quizzes to a whole new level with ones aimed at all languages and catering to all competencies and tastes. This month, we’re covering a little SQL.

    With more frameworks being bundled with an ORM, SQL is quickly becoming a lost art and is mostly relegated to the nerdiest of our clan — those pesky database people. Why not take today’s quiz and see whether you DB-chops have really gone the way of the dodo?


    $(document).ready(function(){ $('#quiz-container').jquizzy({ questions: init.questions, resultComments: init.resultComments, twitterStatus: 'Woo! I scored {score} on the Nettuts quiz on SQL. Give it a shot!', twitterImage: 'http://d2o0t5hpnwv4c1.cloudfront.net/jquizzy-1.0/img/share.png', twitterUsername: 'envatowebdev', splashImage: 'http://d2o0t5hpnwv4c1.cloudfront.net/1148_quiz11/promo.png', }); });


Planet PHP

  • Permalink for 'Hosted MySQL: Amazon RDS (and backups)'

    Hosted MySQL: Amazon RDS (and backups)

    Posted: March 17th, 2012, 10:52am MDT by till

    Among all the different technologies in our stack, we also use MySQL. While we still run MySQL (or Percona-Server) ourselves, we selected a managed solution to power parts of our production infrastructure: a Multi-AZ setup with Amazon's RDS.

    AZ is Amazon-speak for "availability zone", essentially a datacenter. RDS stands for: Relational Database Service.

    Judging from my experience with our own setups where EBS is in the mix, I have to say that Amazon does an outstanding job hiding these potential issues with RDS from us. Looking at the price tag of the setup can be intimidating at first, but as far as TCO is concerned, RDS is the complete package: managed from every which way and painless for the most part.

    RDS in a nutshell

    RDS is pretty awesome — it's basically a highly available MySQL setup with backups and optional goodness like read-slaves. RDS is one of the best services as far as Amazon Webservices are concerned: 90% of what anyone would need from RDS, Amazon allows you to do with a couple clicks. For tuning, it gets a little less shiny and maybe even messy, but even changing parameters is possible.

    Another pretty important feature is growing and shrinking RDS. Change your storage and either apply the change right away or wait for your next maintenance window. It should be noted that these changes are rarely instant (or "right away"), which doesn't make it any less awesome. So even though for example resizing the storage is not an instant operation (of course), it still puts a whole new definition into the word elastic.

    The package

    A standard RDS setup gives you a managed database instance with a DNS hostname and database credentials to log in.

    Access from instances is granted using database security groups, which work just like the regular security groups (on AWS). In non-AWS-language, this translates to firewall policies.

    Pricing

    As far as pricing is concerned, AWS is always a little tough to understand: the baseline is 0.88 USD per hour for a multi-az deployment which totals to 633.6 USD a month (large instance class). Since we opted for reservation (a 1,200 USD one time fee for a three (3) year term), we were able to drop that price to 0.56 USD per hour.

    Aside from instance costs there are storage costs as well: 0.20 USD per GB (100 GB will cost you and me about 20 USD) and 0.10 USD per million I/O requests (aka the "i/o rate"). On our multi-az RDS we selected 100 GB for total storage initially but since we currently use only about 60 GB, we just end up paying about 12 USD per billing period.

    While storage costs are somewhat easy to predict, the "i/o rate" is not. But it's also not a major factor. I'm unable to provide exact numbers currently because we have three RDS servers (1 multi-az deployment, 1 read-slave and another single-az deployment) and the numbers are aggregated on the billing statement but our total is 368,915,692 IOs which runs at roughly 36 USD per month.

    Vendor lockin

    Anyway — if RDS is awesome, what's the catch? A closed environment.

    The primary advantage and disadvantage of RDS is that we don't get access to the server and our own backups.

    Of course there are backups and we can use them to restore (or rollback) our RDS setup from within AWS. There are options using the AWS console and I believe using their API as well. But in the end there is no way to export this backup and load it into a non-RDS-setup. And add to that: replicating from or into RDS is not possible either. Which makes migrations and backups an unnecessary pain in the butt.

    Aside from not getting access to our own backup, we also don't get access to the actual instances. Which makes sense for AWS, but it means we need to rely on in my opinion questionable metrics like Cloudwatch. Questionable because there is no way for the customer to verify the data. AWS uses their own metrics (and scale) and it's often not obvious to me how well Cloudwatch works even on regular AWS EC2 instance.

    I've seen instances which became unavailable, but Cloudwatch is reporting A-OK (green). I'm not sure how beta Cloudwatch is, but we decided on Silverline (more on that in another blog post) for instance monitoring. Since Silverline requires a local client, it's unfortunately not an option for RDS.

    What's pain?

    Aside from the monitoring and backup quirks, one of the real pain points of Amazon RDS is that a lot of the collective MySQL knowledge is not available to us. The knowledge which is manifested in books, blogs, various monitoring solutions and outstanding tools like Percona's backup tools are not available to people who run Amazon RDS setups.

    Truncated by Planet PHP, read more at the original (another 5195 bytes)

  • Permalink for 'VIE and Create: an update'

    VIE and Create: an update

    Posted: March 16th, 2012, 11:55am MDT by Henri Bergius

    It is again time to write an update on the state of IKS's two main components for the semantic editing part of Decoupled Content Management:

    • VIE is the base semantic interaction library that handles the site's content model through RDFa annotations and Backbone.js synchronization
    • Create is a new kind of web editing interface built on top of that.

    As the IKS project has entered its fourth year, both of these projects have gained maturity and contributions from many IKS partners and early adopters.

    New UI for Create

    While Create can be used for building any sort of custom user experiences (as seen in the CMS integration examples below), it also ships with a default user interface. Nemein's Riku Virta has designed a new UI concept that is currently being discussed on the CreateJS mailing list.

    This interface builds on top of the original Create UI and Liip's UX work, and aims to provide more area for CMS-specific functionality and better touchscreen support:

    create_new_ui.png

    See the full UI concept in the slideshow on Google Plus.

    We hope that we will be able to land this new UI still within the March-April timeframe.

    VIE: 2.0 and onwards

    VIE is now nearing the 2.0 release, with the first RC expected for the end of this month. After that we'll have a hackathon in Saarbrucken, Germany where the plan is to focus on things that we've targeted for a 2.1.

    The main feature of VIE 2.1 is a new way of handling RDF literals. This will make it easier to interface with services like DBpedia that give us data in multiple different languages. This will enable you to do things like:

    var eiffel = vie.entities.get('dbp:Eiffel_Tower');
    console.log(eiffel.get('label')); // Eiffel Tower
    
    vie.setLanguage('fi');
    console.log(eiffel.get('label')); // Eiffel-torni
    

    The final API for this is still being discussed on the VIE mailing list.

    Create and Hallo are now easier to integrate

    Both Create and Hallo, our minimalist rich text editing tool now provide merged JavaScript files for easier integration. You can find the merged files, and also minified versions in:

    Thanks to contributions from Alkacon, Create's widget selection mechanism is now much more configurable. This allows CMS developers to provide different editing tools for different types of information.

    The currently bundled editing interfaces provide integration with Hallo, and also with the 0.20 version of Aloha Editor (though you will need to install Aloha separately to use it due to licensing restrictions).

    CMS developers will also benefit from Blogsiple, the new integration testbed for Create and VIE. Blogsiple aims to be a very simple blog system built on top of Node.js that shows all the necessary integration points for supporting the whole range of VIE and Create features.

    CMS adoption

    As both VIE and Create improve, so does their adoption in different Content Management Systems. For example, here is the new OpenCms user interface built on these tools:

    Polymedia's video annotation example is also interesting demonstration of VIE in a completely different kind of CMS environment, as is WordLift by InSideOut10.

    The IKS Early Adopter program is still open if you're interested in getting support for using these tools in your CMS. There will also be an IKS event in Salzburg on June 12-13 where we will be able to show more.

  • Permalink for 'PHP's Source Code for PHP Developers - Part 2 - Function Definitions'

    PHP's Source Code for PHP Developers - Part 2 - Function Definitions

    Posted: March 16th, 2012, 7:52am MDT by Anthony Ferrara
    Part 2 of the PHP's Source Code for PHP Developers series is up over on Nikic's Blog.  In it, he discusses how internal PHP functions are defined, and how to figure out what they do.  Part 3 will be back over here and will cover how variables work internally (The ZVAL).  Enjoy!
  • Permalink for 'DocBlox Is Unmasked ... It Is Really phpDocumentor 2 !'

    DocBlox Is Unmasked ... It Is Really phpDocumentor 2 !

    Posted: March 16th, 2012, 7:10am MDT by Chuck Burgess
    DocBlox Is Unmasked ... It Is Really phpDocumentor 2 !
  • Permalink for 'wetter.com - Relaunch with symfony2, Assetic, Varnish and Twig'

    wetter.com - Relaunch with symfony2, Assetic, Varnish and Twig

    Posted: March 16th, 2012, 4:15am MDT by Gaylord Aulke
    After a lot of hard work, on march 10 a complete rebuild of wetter.com went online. The site is #1 or #2 in germany for weather forecasts since years with millions of visits/day. It was built completely new on PHP 5.4, Symfony 2, MySQL, SolR, Varnish and NginX. The task to re-build the whole site from scratch was given to our partner TFT (Tomorrow Focus Technologies) who invited 100 DAYS into the project to develop the symfony2 parts. This post describes the experiences we made when developing and launching this large scale application.

    Continue reading "wetter.com - Relaunch with symfony2, Assetic, Varnish and Twig"
  • Permalink for 'Understanding PHP's internal function definitions (PHP's Source Code for PHP Developers - Part 2)'

    Understanding PHP's internal function definitions (PHP's Source Code for PHP Developers - Part 2)

    Posted: March 16th, 2012, 1:00am MDT by Nikita Popov

    Welcome to the second part of the “PHP’s Source Code For PHP Developers” series.

    In the previous part ircmaxell explained where you can find the PHP source code and how it is basically structured and also gave a small introduction to C (as that’s the language PHP is written in). If you missed that post, you probably should read it before starting with this one.

    What we’ll cover in this article is locating the definitions of internal functions in the PHP codebase, as well as understanding them.

    How to find function definitions

    For a start, let’s try to find out how the strpos function is defined.

    The first thing to try, is to go to the PHP 5.4 source code root and type strpos into the search box at the top of the page. The result will be a huge listing of strpos occurrences in the PHP source code.

    As this doesn’t really help us much, we use a little trick: Instead of searching for just strpos, we search for "PHP_FUNCTION strpos" instead (don’t forget the quotes, they are important).

    Now we are left with only two entries:

    /PHP_5_4/ext/standard/
        php_string.h 48   PHP_FUNCTION(strpos);
        string.c     1789 PHP_FUNCTION(strpos)

    First thing to notice is that both occurrences are in the ext/standard folder. This is exactly where one would expect to find them, as the strpos function (together with pretty much all other string, array and file functions) is part of the standard extension.

    Now open both links in new tabs and see what code hides behind them.

    You’ll find that the first link leads you to the php_string.h file, which is full of code looking like this:

    // ...
    PHP_FUNCTION(strpos);
    PHP_FUNCTION(stripos);
    PHP_FUNCTION(strrpos);
    PHP_FUNCTION(strripos);
    PHP_FUNCTION(strrchr);
    PHP_FUNCTION(substr);
    // ...

    This is exactly how a typical header file (a file ending in .h) looks like: A plain list of functions which are defined elsewhere. We aren’t really interested in this, as we already know what we’re looking for.

    The second link is much more interesting: It leads to the string.c file, which contains the actual source code of the function.

    Before I’ll walk you through the code step by step, I’d recommend you to try and understand the function by yourself. It’s a really simple function and most things should be clear even if you don’t know the exact details.

    The skeleton of a PHP function

    All PHP functions share the same basic structure. At the top there are a few variable declarations, then there is a zend_parse_parameters call, then comes the main logic, with RETURN_*** and php_error_docref calls intermixed.

    So, let’s start with the variable declarations:

    zval *needle;
    char *haystack;
    char *found = NULL;
    char  needle_char[2];
    long  offset = 0;
    int   haystack_len;

    The first line declares needle as being a pointer to a zval. A zval is PHP’s internal representation of an arbitrary PHP value. How exactly it looks will be the subject of the next post.

    The second line declares haystack as a pointer to a character. At this point you’ll have to remember that in C, arrays are represented by pointers to their first value. I.e. the haystack will point to the first character of the $haystack string you passed in. Then haystack + 1 will point to the second character, haystack + 2 to the third, and so on. So one could read in the whole string by always incrementing the pointer by one.

    The problem arising here is that PHP has to know when the string ends. Otherwise it would always keep incrementing the pointer without ever stopping. In order to deal with this, PHP also stores an explicit length, here in the haystack_len variable.

    The last declaration of interest to us at this point is the offset variable, which will be used to store the third parameter of the function: the offset to start searching at. It is declared as a

    Truncated by Planet PHP, read more at the original (another 9814 bytes)

  • Permalink for 'Mailchimp Signup Form for WordPress'

    Mailchimp Signup Form for WordPress

    Posted: March 15th, 2012, 3:05pm MDT by Web Development Blog » PHP Scripts
    For your website's newsletter is Mailchimp for sure one of the best email marketing systems online. They offer a great interface with many options to build email templates and subscription forms. There is also a plugin for Wordpress which works great out of the box. If you need to do some customization or integration work for your site or web application you need to use the API system. I wrote in the past a tutorial about how to use the Mailchimp API for your contact form script and today I show you how to integrate the script in Wordpress.

Nettuts+

  • Permalink for 'Intelligent ActiveRecord Models'

    Intelligent ActiveRecord Models

    Posted: March 15th, 2012, 3:00pm MDT by AdamBardsley

    ActiveRecord models in Rails already do a lot of the heavy lifting, in terms of database access and model relationships, but with a bit of work, they can do more things automatically. Let’s find out how!

    Step 1 - Create a Base Rails App

    This idea works for any sort of ActiveRecord project; however, since Rails is the most common, we’ll be using that for our example app. The app we’ll be using has lots of Users, each of whom can perform a number of actions on Projects .

    If you’ve never created a Rails app before, then read this tutorial, or syllabus, first. Otherwise, fire up the old console and type rails new example_app to create the app and then change directories to your new app with cd example_app.

    Step 2 - Create Your Models and Relationships

    First, we generate the user that will own:

    
     rails generate scaffold User name:text email:string password_hash:text
    

    Likely, in a real world project, we’d have a few more fields, but this will do for now. Let’s next generate our project model:

    
     rails generate scaffold Project name:text started_at:datetime started_by_id:integer completed_at:datetime completed_by_id:integer
    

    We then edit the generated project.rb file to describe the relationship between users and projects:

    
     class Project < ActiveRecord::Base
      belongs_to :starter, :class_name =>"User", :foreign_key =>"started_by_id"
      belongs_to :completer, :class_name =>"User", :foreign_key =>"completed_by_id"
     end
    

    and the reverse relationship in user.rb:

    
     class User < ActiveRecord::Base
      has_many :started_projects, :foreign_key =>"started_by_id"
      has_many :completed_projects, :foreign_key =>"completed_by_id"
     end
    

    Next, run a quick rake db:migrate, and we’re ready to begin getting intelligent with these models. If only getting relationships with models was as easy in the real world! Now, if you’ve ever used the Rails framework before, you’ve probably learned nothing… yet!

    Step 3 - Faux Attributes Are Cooler Than Faux Leather

    The first thing we’re going to do is use some auto generating fields. You’ll have noticed that when we created the model, we created a password hash and not a password field. We’re going to create a faux attribute for a password that will convert it to a hash if it’s present.

    So, in your model, we’ll add a definition for this new password field.

    
     def password={new_password)
      write_attribute(:password_hash, SHA1::hexdigest(new_password))
     end
    
     def password
      ""
     end
    

    We only store a hash against the user so we’re not giving out the passwords without a bit of a fight.

    The second method means we return something for forms to use.

    We also need to ensure that we have the Sha1 encryption library loaded; add require 'sha1' to your application.rb file after line 40: config.filter_parameters += [:password].

    As we’ve changed the app at the configuration level, reload it with a quick touch tmp/restart.txt in your console.

    Now, let’s change the default form to use this instead of password_hash. Open _form.html.erb in the app/models/users folder:

    
     <div class="field">
      <%= f.label :password_hash %><br />
      <%= f.text_area :password_hash %>
     </div>
    

    becomes

    
     <div>
      <%= f.label :password %><br/>
      <%= f.text_field :password %>
     </div>
    

    We’ll make it an actual password field when we’re happy with it.

    Now, load http://localhost/users and have a play with adding users. It should look a bit like the image below; great, isn’t it!

    User Form

    Wait, what’s that? It overwrites your password hash every time you edit a user? Let’s fix that.

    Open up user.rb again, and change it like so:

    
     write_attribute(:password_hash, SHA1::hexdigest(new_password)) if new_password.present?
    

    This way, only when you supply a password does the field get updated.

    Step 4 - Automatic Data Guarantees Accuracy or Your Money Back

    The last section was all about changing the data that your model gets, but what about adding more information based on things already known without having to specify them? Let’s have a look at that with the project model. Begin by having a look at [localhost]

    Make the following changes quickly.

    *app/controllers/projects_controler.rb* line 24

    
     # GET /projects/new
     # GET /projects/new.json
     def new
      @project = Project.new
      @users = ["--",nil] + User.all.collect { |u| [u.name,u.id] }
    
      respond_to do |format|
       format.html # new.html.erb
       format.json { render :json =>@project }
      end
     end
    
     # GET /projects/1/edit
     def edit
      @project = Project.find(params[:id])
      @users = ["--",nil] + User.all.collect { |u| [u.name,u.id] }
     end
    

    *app/views/projects/_form.html.erb* line 24

    
     <%= f.select :started_by_id, @users %>
    

    *app/views/projects/_form.html.erb* line 24

    
     <%= f.select :completed_by , @users%>
    

    In MVC frameworks, the roles are clearly defined. Models represent the data. Views display the data. Controllers get data and pass them to the view.

    Who Enjoys Filling Out Date/time Fields?

    We now have a full functioning form, but it bugs me that I have to set the start_at time manually. I’d like to have it set when I assign a started_by user. We could put it in the controller, however, if you’ve ever heard the phrase “fat models, skinny controllers” you’ll know this makes for bad code. If we do this in the model, it’ll work anywhere we set a the starter or completer. Let’s do that.

    First edit app/models/project.rb, and add the following method:

    
     def started_by=(user)
      if(user.present?)
       user = user.id if user.class == User
       write_attribute(:started_by_id,user)
       write_attribute(:started_at,Time.now)
      end
     end
    

    This code ensures that something has actually been passed. Then, if it’s a user, it retrieves its ID and finally writes both the user *and* the time it happened – holy smokes! Let’s add the same for the completed_by field.

    
     def completed_by=(user)
      if(user.present?)
       user = user.id if user.class == User
       write_attribute(:completed_by_id,user)
       write_attribute(:started_at,Time.now)
      end
     end
    

    Now edit the form view so we don’t have those time selects. In app/views/projects/_form.html.erb, remove lines 26-29 and 18-21.

    Open up http://localhost/projects and have a go!

    Spot the Deliberate Mistake

    Whoooops! Someone (I’ll take the heat since it’s my code) cut and paste, and forgot to change the :started_at to :completed_at in the second largely identical (hint) attribute method. No biggie, change that and everything is go… right?

    Step 5 - Help Your Future Self by Making Additions Easier

    So apart from a little cut-and-paste confusion, I think we did fairly good job, but that slip up and the code around it bothers me a bit. Why? Well, let’s have a think:

    • It’s cut and paste duplication: DRY (Don’t repeat yourself) is a principle to follow.
    • What if someone wants to add another somethingd_at and somethingd_by to our project, like, say, authorised_at and authorised_by>
    • I can imagine quite a few of these fields being added.

    Lo and behold, along comes a pointy haired boss and asks for, {drumroll}, authorised_at/by field and a suggested_at/by field! Right then; let’s get those cut and paste fingers ready then… or is there a better way?

    The Scary Art of Meta-progamming!

    That’s right! The holy grail; the scary stuff your mothers warned you about. It seems complicated, but actually can be pretty simple – especially what we’re going to attempt. We’re going to take an array of the names of stages we have, and then auto build these methods on the fly. Excited? Great.

    Of course, we’ll need to add the fields; so let’s add a migration rails generate migration additional_workflow_stages and add those fields inside the newly generated db/migrate/TODAYSTIMESTAMP_additional_workflow_stages.rb.

    
    class AdditionalWorkflowStages < ActiveRecord::Migration
     def up
      add_column :projects, :authorised_by_id, :integer
      add_column :projects, :authorised_at, :timestamp
      add_column :projects, :suggested_by_id, :integer
      add_column :projects, :suggested_at, :timestamp
     end
    
     def down
      remove_column :projects, :authorised_by_id
      remove_column :projects, :authorised_at
      remove_column :projects, :suggested_by_id
      remove_column :projects, :suggested_at
     end
    end
    

    Migrate your database with rake db:migrate, and replace the projects class with:

    
     class Project < ActiveRecord::Base
     # belongs_to :starter, :class_name =>"User"
    
     # def started_by=(user)
     # if(user.present?)
     #   user = user.id if user.class == User
     #   write_attribute(:started_by_id,user)
     #   write_attribute(:started_at,Time.now)
     # end
     # end
     #
     # def started_by
     # read_attribute(:completed_by_id)
     # end
    
     end
    

    I’ve left the started_by in there so you can see how the code was before.

    
     [:starte,:complete,:authorise,:suggeste].each do |arg|
      ..MORE..
      end
    

    Nice and gentle – goes through the names(ish) of the methods we wish to create:

    
     [:starte,:complete,:authorise,:suggeste].each do |arg|
    
      attr_by = "#{arg}d_by_id".to_sym
      attr_at = "#{arg}d_at".to_sym
      object_method_name = "#{arg}r".to_sym	  
    
      ...MORE...
     end
    

    For each of those names, we work out the two model attributes we’re setting e.g started_by_id and started_at and the name of the association e.g. starter

    
     [:starte,:complete,:authorise,:suggeste].each do |arg|
    
      attr_by = "#{arg}d_by_id".to_sym
      attr_at = "#{arg}d_at".to_sym
      object_method_name = "#{arg}r".to_sym	  
    
      belongs_to object_method_name, :class_name =>"User", :foreign_key =>attr_by
    
     end
    

    This seems pretty familiar. This is actually a Rails bit of metaprogramming already that defines a bunch of methods.

    
     [:starte,:complete,:authorise,:suggeste].each do |arg|
    
      attr_by = "#{arg}d_by_id".to_sym
      attr_at = "#{arg}d_at".to_sym
      object_method_name = "#{arg}r".to_sym	  
    
      belongs_to object_method_name, :class_name =>"User", :foreign_key =>attr_by
    
      get_method_name = "#{arg}d_by".to_sym
    
      define_method(get_method_name) { read_attribute(attr_by) }
    
     end
    

    Ok, we come to some real meta programming now that calculates the ‘get method’ name – e.g. started_by, and then creates a method, just as we do when we write def method, but in a different form.

    
     [:starte,:complete,:authorise,:suggeste].each do |arg|
    
      attr_by = "#{arg}d_by_id".to_sym
      attr_at = "#{arg}d_at".to_sym
      object_method_name = "#{arg}r".to_sym	  
    
      belongs_to object_method_name, :class_name =>"User", :foreign_key =>attr_by
    
      get_method_name = "#{arg}d_by".to_sym
    
      define_method(get_method_name) { read_attribute(attr_by) }
    
      set_method_name = "#{arg}d_by=".to_sym
    
      define_method(set_method_name) do |user|
       if user.present?
        user = user.id if user.class == User
        write_attribute(attr_by,user)
        write_attribute(attr_at,Time.now)
       end
      end
    
     end
    

    A little bit more complicated now. We do the same as before, but this is the set method name. We define that method, using define(method_name) do |param| end, rather than def method_name=(param).

    That wasn’t so bad, was it?

    Try it Out in the Form

    Let’s see if we can still edit projects as before. It turns out that we can! So we’ll add the additional fields to the form, and, hey, presto!

    app/views/project/_form.html.erb line 20

    
     <div class="field">
      <%= f.label :suggested_by %><br/>
      <%= f.select :suggested_by, @users %>
     </div>
    
     <div class="field">
      <%= f.label :authorised_by %><br/>
      <%= f.select :authorised_by, @users %>
     </div>
    

    And to the show view… so we can see it working.

    *app/views-project/show.html.erb* line 8

    
     <p>
      <b>Suggested at:</b> <%= @project.suggested_at %>
     </p>
    
     <p>
      <b>Suggested by:</b> <%= @project.suggested_by_id %>
     </p>
    
     <p>
      <b>Authorised at:</b> <%= @project.authorised_at %>
     </p>
    
     <p>
      <b>Authorised by:</b> <%= @project.authorised_by_id %>
     </p>
    

    Have another play with http://localhost/projects, and you can see we have a winner! No need to fear if someone asks for another workflow step; simply add the migration for the database, and put it in the array of methods… and it gets created. Time for a rest? Maybe, but I’ve just two more things to make note of.

    Step 6 - Automate the Automation

    That array of methods seems quite useful to me. Could we do more with it?

    First, let’s make the list of method names a constant so we can access it from outside.

    
     WORKFLOW_METHODS = [:starte,:complete,:authorise,:suggeste]
     WORKFLOW_METHODS.each do |arg|....
    

    Now, we can use them to auto create form and views. Open up the _form.html.erb for projects, and let’s try it by replacing lines 19 -37 with the snippet below:

    
     <% Project::WORKFLOW_METHODS.each do |workflow| %>
      <div class="field">
      <%= f.label "#{workflow}d_by" %><br/>
      <%= f.select "#{workflow}d_by", @users %>
      </div>
     <% end %> 
    

    But app/views-project/show.html.erb is where the real magic is:

    
     <p id="notice"><%= notice %></p>
    
     <p>
      <b>Name:</b>: <%= @project.name %>
     </p>
    
     <% Project::WORKFLOW_METHODS.each do |workflow|
      at_method = "#{workflow}d_at"
      by_method = "#{workflow}d_by_id"
      who_method = "#{workflow}r"
     %>
    
     <p>
      <b><%= at_method.humanize %>:</b>: <%= @project.send(at_method) %>
     </p>
    
     <p>
      <b><%= who_method.humanize %>:</b>: <%= @project.send(who_method) %>
     </p>
    
     <p>
      <b><%= by_method.humanize %>:</b>: <%= @project.send(by_method) %>
     </p>
    
     <% end %>
    
     <%= link_to 'Edit', edit_project_path(@project) %> |
     <%= link_to 'Back', projects_path %>
    

    This should be fairly clear, although, if you’re not familiar with send(), it’s another way to call a method. So object.send("name_of_method") is the same as object.name_of_method.

    Final Sprint

    We’re almost done, but I’ve noticed two bugs: one is formatting, and the other is a bit more serious.

    The first is that, while I view a project, the whole method is showing an ugly Ruby object output. Rather than adding a method to the end, like this

    
     @project.send(who_method).name
    

    Let’s modify User to have a to_s method. Keep things in the model if you can, and add this to the top of the user.rb, and do the same for project.rb as well. It always makes sense to have a default representation for a model as a string:

    
     def to_s
      name
     end
    

    Feels a bit mundane writing methods the easy way now, eh? No? Anyhow, on to more serious things.

    An Actual Bug

    When we update a project because we send all of the workflow stages that have been assigned previously, all our time stamps are mixed up. Fortunately, because all our code is in one place, a single change will fix them all.

    
     define_method(set_method_name) do |user|
      if user.present?
       user = user.id if user.class == User
    
       # ADDITION HERE
       # This ensures it's changed from the stored value before setting it
       if read_attribute(attr_by).to_i != user.to_i
        write_attribute(attr_by,user)
        write_attribute(attr_at,Time.now)
       end
      end
     end
    
    Conclusion

    What have we learned?

    • Adding functionality to the model can seriously improve the rest of you code
    • Meta programming isn’t impossible
    • Suggesting a project might get logged
    • Writing smart in the first place means less work later
    • No-one enjoys cutting, pasting and editing and it causes bugs
    • Smart Models are sexy in all walks of life

    Thank you so much for reading, and let me know if you have any questions.


Planet PHP

  • Permalink for '“PHP Playbook” Giveaway!'

    “PHP Playbook” Giveaway!

    Posted: March 15th, 2012, 11:00am MDT by Brandon Savage
    When I started writing my book, I wanted to help PHP developers have a greater understanding of the tools, tips and tricks available when working as part of a team. That goal became The PHP Playbook. I’m excited that the book has been so well received, and I’m excited that I’ve finally received my promotional [...]
  • Permalink for 'The IDEs of March'

    The IDEs of March

    Posted: March 15th, 2012, 11:00am MDT by Rafael Dohms

    Last Year, Chris Shiflett started the “Ideas of March” movement, and Jon Tangerine quickly coined the “Ides of March” twist and some people followed him. This year, here we are again and while reading my twitter feed I saw Cal Evans’ post with Jon Tangerine’s line. Of course it was early and I read “IDEs”. Since last year I defended the Ideas of March with why you should blog, and I still believe the reasons stand, this year I’ll just make my own twist and talk about IDEs. Yes, its a shameless sorry attempt at a joke.

    “My IDEs of March is PHPStorm” — @rdohms

    This year I decided that NetBeans was just too heavy and when it started getting lost in my Symfony projects I decided it was time to shop around again. I asked a few people what their choice IDE was and then got into testing them. I wanted a full fledged IDE, I still use TextMate on the side for quick editing and for some html stuff, but I wanted the full deal: auto complete, debugging, profiling … .

    A huge group of people suggested PHPStorm, which is a paid IDE and that had turned me off the first time I saw it. This time I decided to go deeper and try it out, after all my IDE had gone completely bananas, so i gave it a full work day which i ended up spending more time tweaking then coding. I tweaked a bit of colors, settings and such and by the second day it actually felt very comfortable to work with, and most important faster and lighter then my previous IDEs.

    I had a few problems, sure, they were fixed in the next release, I decided to try out the Early Access version and was blown away. Day after day it felt more comfortable. A few tweaks to shortcuts, and I started looking at other features. And then, i fell in love. To sum up a few nice things:

    • Inspections: a series of inspections that can validate, code, phpDoc and little things like unused vars. The nice twist is it can generate a search-result like report, letting you go fix stuff file by file.
    • PHPUnit coverage plugin: this is cool, this plugin reads a clover.xml report and highlights the actual files in the IDE for code coverage. It also does that natively in the new version, but you must run tests inside the IDE.
    • Test folder highlight: you can tag test folders and test files have a slight color in the tabs, actually handy.
    • Support got {@inheritDoc}

    Those are a few topics, but it really feels nice, has not freaked out on me yet, cleans up memory use pretty well and is just fast and responsive. The company behind it is awesome as well, they are willing to give free licenses to OpenSource developers, which is a plus in my book.

    So, take this March the 15th and make it your IDEs of March day, and try out a new IDE.

    © Rafael Dohms for Rafael Dohms, 2012. | Permalink | 2 comments
    Want more on these topics ? Browse the archive of posts filed under PHP, Tools.

  • Permalink for 'Ideas of March'

    Ideas of March

    Posted: March 15th, 2012, 8:06am MDT by Chris Shiflett

    I love blogs. A year ago today, I tried to start a sort of blogging revival. To my great surprise and delight, it kinda worked. For a while, I could find really interesting stuff to read every day by just browsing through my planet or #ideasofmarch on Twitter. It was great.

    As time passed, commitment waned. When I noticed it was almost that time of year again, I decided this was a tradition worth keeping, so here I am. I'm using this opportunity to renew my commitment to blog more, and hopefully this year's Ideas of March can provide an opportunity to let everyone know blogs are still alive and well. And appreciated.

    If you'd like to participate, here's how:

    • Write a post called Ideas of March.
    • Write about why you like blogs.
    • If you don't already blog regularly, pledge to blog more the rest of the month.
    • Share your thoughts on Twitter with the #ideasofmarch hashtag.

    I hope you'll join us, and if you do, please leave a comment. (Comments are great, too!)

    Chris Cornutt is maintaining a list of this year's Ideas of March posts.

  • Permalink for 'Ideas of March'

    Ideas of March

    Posted: March 15th, 2012, 7:50am MDT by Sean Coates

    A year ago, I posted about Ideas of March, which Chris got rolling.

    In it, I pledged to blog more.

    Today, I am not so proud to say that I have mostly failed to do so. If I had to come up with a reason, I'd have to say that, personally, 2011 turned out a whole lot different than I was expecting, back then—and not in a good way.

    Over the last year, however, I did post a few things that I think were interesting, and worth of a re-read (at risk of making this post into a clip show):

    PHP Community Conference …a post about why I was excited about going to the PHP Community Conference in Nashville, last May. It turned out to be even better than I expected, and I'm really excited that plans are coming together for a 2012 edition. Gimme Bar no longer on CouchDB and Gimme Bar on MongoDB …a pair of posts describing some problems we had with CouchDB, and our smooth transition to MongoDB. We're still on MongoDB, and for the most part, I still really like it. I'd hinted about these posts in last year's Ideas of March post. Webshell …on Webshell which I still use almost daily, but has most certainly fallen out of a reasonable upkeep schedule. I really need to find some time to clean out the cobwebs. If you use HTTP and know JavaScript, you should check it out. Aficionado's Curse/Pessimistic Optimism …a post that I'm particularly proud of; mostly because I've finally managed to document (and coin a term, I hope) for why things seem so bad, but aren't actually so bad. HTTP/1.0 and the Connection header …finally, over Christmas, I managed to post about HTTP things (-:

    I was really hoping to do more. Last year, I suggested that I might turn my talk on Fifty tips, tricks and tools into a series of small blog posts, and I'd still like to do this. Hopefully in 2012. I also have a list of other things that I'm really interested in writing about. It's just matter of making time to do so. I plan to do that, this year. Starting with this post.

    I'd also like to get around to writing a thing or two about beer, this year…

    Much of what I said last year is still on my mind. I still miss the blogs we kept, 5+ years ago. Let's fix that.

    </navelgazing>

  • Permalink for 'Ideas of March'

    Ideas of March

    Posted: March 15th, 2012, 6:26am MDT by blog.phpdeveloper.org » PHP

    It’s March 15th and you know what that means….only a month left for the procrastinators to do their taxes in the US. Well, actually, that’s not what I’m really talking about here. Last year a whole host of people write up posts titled “Ideas of March” and this year’s no different. Several members of the PHP community are jumping in with there thoughts on blogging – here’s some of mine.

    Blogging is great, don’t get me wrong…I love it when I can Google for something and find that someone, somewhere has done exactly what I need. This historical record of shared knowledge is one of the things that makes the web great. Of course, it can also sometimes do more harm than good. “But I thought you were going to write about how blogging is a good thing,” you ask. Well, I believe it inherently is, but with a few caveats:

    • Blogs are only as good as their authors:
      Not everyone out there is a clear, excellent writer (I know I’m not) and, as a result, sometimes the message of a post can get lost in poor wording. What’s a solution to this? Blog more often! That’s right, it’s just like anything else – the more you do something, the better at it you get. You start getting into a certain frame of mind when you’re fingers to the keys and you learn little “mind tricks” (no Jedi here) on how to best get your message across. You don’t have to be an amazing writer to be a clear one.

    • Dates, Versions & Code:
      This one’s a tough one, especially for us tech bloggers. I can’t tell you the number of times that I’ve found what I thought I needed in my Google results only to go over to a post and discover that I have no idea when it was written. The URL gives no clue and there’s not a date to be found. This drives me nuts and if your blog dosen’t have dates on the post, go change that. Right now. I’ll wait here.

      Additionally, something that can make for a lot less frustration for people coming to your posts later are two things – somehow tagging or mentioning what version of a language the post relates to (“this post was written against PHP 5.2.5″) and trying to keep the code up to date. Yes, I know this second request requires a bit more commitment on your part, but people would sing your praises if you took the time to do it. Even if it’s just an update to a post that say, “I found a better way to do this…” in a more recent version of the language/tool.

    • More than just a “brain dump”:
      I’ve seen several people use their blogs as a sort of “brain dump” – a place for them to post things that they just want to remember later on. This is all well and good, but don’t forget that blogs aren’t just about code snippets and tutorials. Sometimes you need to share a bit about you and what you’re passionate about too. Take some time to sit and reflect on what you do on a daily basis and think about how knowing that process could help others. I’d encourage you to write not only code-related posts, but also keep the rest of the world up to date on the interesting things you’re doing. Nothing builds communities like people sharing more than just code.

    Finally, I’d like to end this post jammed full of suggestions with one final challenge – get out there and share. My recommendations aside, if all you do is write up one or two posts this month (and keep going) with a few paragraphs each, I think the web would be a better place. Sharing knowledge is what it’s all about and if you discover something, no matter how small, you could be sharing exactly what someone needs. Remember, just because you think it’s simple, doesn’t mean someone new to the tech does….get out there and share!

Nettuts+

  • Permalink for 'Build a Contacts Manager Using Backbone.js: Part 3'

    Build a Contacts Manager Using Backbone.js: Part 3

    Posted: March 14th, 2012, 1:59pm MDT by Dan Wellman

    Welcome to part three of our series that focuses on building applications using Backbone. If you haven’t read parts one and two, I strongly recommend that you do — just so you know where we’re at and what we’ve covered so far.

    In part one, we took a basic look and models, views and collections. In part two, we looked at routers, events and the history modules. In this part, we’re going to look further at interactions and see how we can add or remove models from a collection.

    Adding Models to a Collection

    If you cast your mind back to part one, you’ll remember how we added all of our models to the collection when the collection was initialised. But how can we add individual models to a collection after the collection has already been initialised? It’s actually really easy.

    We’ll add the ability for new contacts to be added which will involve an update to the underlying HTML and our master view. First, the HTML; add the following mark-up to the contacts container:

    <form id="addContact" action="#">
        <label for="photo">photo:</label><input id="photo" type="file" />
        <label for="type">Type:</label><input id="type" />
        <label for="name">Name:</label><input id="name" />
        <label for="address">Address:</label><input id="address" />
        <label for="tel">Tel:</label><input id="tel" />
        <label for="email">Email:</label><input id="email" />
        <button id="add">Add</button>
    </form>

    This simple form will enable users to add a new contact. The main point is that the id attributess of the <input> elements match the attribute names used by our models, which makes it easier to get the data in the format we want.

    Next, we can add an event handler to our master view so that the data into the form can be harvested; add the following code after the existing key:value pair in the events object:

    "click #add": "addContact"

    Don’t forget to add the trailing comma to the end of the existing binding! This time we specify the click event triggered by the element with an id of add, which is the button on our form. The handler we are binding to this event is addContact, which we can add next. Add the following code after the filterByType() method from part two:

    addContact: function (e) {
        e.preventDefault();
    
        var newModel = {};
        $("#addContact").children("input").each(function (i, el) {
            if ($(el).val() !== "") {
                newModel[el.id] = $(el).val();
    		}
        });
    
        contacts.push(formData);
    
        if (_.indexOf(this.getTypes(), formData.type) === -1) {
           	this.collection.add(new Contact(formData));
            this.$el.find("#filter").find("select").remove().end().append(this.createSelect());
        } else {
            this.collection.add(new Contact(formData));
        }
    }

    As this is an event handler, it will automatically receive the event object, which we can use to prevent the default behaviour of the <button> element when it is clicked (which would be to submit the form and reload the page – not what we want). We then create a new empty object, and use jQuery’s each() method to iterate over each <input> element in our addContact form.

    In the callback function supplied to each(), we first check that the field has had text entered into it and if so, we add a new property to the object with a key equal to the id of the current element, and a value equal to its current value. If the field is empty, the property will not be set and the new model will inherit any defaults that may have been specified.

    Next, we can update our local data store with the new contact. This is where we would probably save the new data to the server — if we had a server in place to receive such requests. At this point we don’t, so we’ll just update the original array for now so that if the view is filtered, the new data is not lost. All we need to do then is use the collection’s add() method to add the new data to the collection. We can create the new model to pass into the collection within the call to add().

    Lastly, we need to update the <select> element so that if the new contact has a different type, that type is available for filtering. However, we only want to re-render the <select> if a new type has been added. We can use Underscore’s indexOf() method to search through an array for a particular value. Like the native JavaScript indexOf() method for strings, this method will return -1 if the value is not found. We pass the array to search as the first argument to indexOf(), and the value to look for as the second.

    If the value is not found, the type specified must be new so we find the existing select box and remove it before appending a new one generated by our createSelect() method. If the type is found, we can just add the new model without needing to re-render the select.

    Rendering the New Model

    Now that we’ve added a new model to the collection, we should render it on the page. To do this we can bind another handler, this time to listen for the add event. Add the following line of code to the initialize() method of the collection:

    this.collection.on("add", this.renderContact, this);

    We use the on() method once more to attach the event listener and as we already have a method that creates and displays individual views, we just specify that function as the handler. We also set the master view as the this object within the handler as we did with previous handlers. At this point, we should now be able to complete the form, and have the new contact rendered to the page:

    One thing to note is that if the addContact form fields are left completely blank, the resulting model will be almost entirely devoid of attributes, which will cause problems when we try to manipulate the model later on. One way to avoid this is to provide defaults for the majority of model attributes, just like we provided the default photo attribute. If there are no sensible defaults we can use, like for a contact’s name for example, we can just supply an empty string. Update the defaults object in the Contact class to include defaults for our other attributes:

    name: "",
    address: "",
    tel: "",
    email: "",
    type: ""
    Deleting Models From the Collection

    Now that we know how to add models to the collection, we should look at how they can be removed as well. One way that we could enable deleting of individual models is by adding a delete button to each contact, so this is what we’ll do; first we need to update the template for each individual view so that it contains a delete button. Add a new button to the end of the template:

    <button class="delete">Delete</button>

    That’s all we’ll need for this example. The logic to remove an individual model can be added to the view class that represents an individual contact, since the view instance will be associated with a particular model instance. We’ll need to add an event binding and an event handler to remove the model when the button is clicked; add the following code to the end of the ContactView class:

    events: {
        "click button.delete": "deleteContact"
    },
    
    deleteContact: function () {
    	var removedType = this.model.get("type").toLowerCase();
    
        this.model.destroy();
    
        this.remove();
    
        if (_.indexOf(directory.getTypes(), removedType) === -1) {
            directory.$el.find("#filter select").children("[value='" + removedType + "']").remove();
        }
    }

    We use the events object to specify our event binding, as we did before with our master view. This time we are listening for click events triggered by a <button> that has the class name delete. The handler bound to this event is deleteContact, which we add after the events object.

    First we store the type of the contact that we just deleted. We should make this value lowercase as we did before to ensure there are no case issues when the contacts viewer is in use.

    We then call the destroy() method on the model associated with this, the instance of the view. We can also remove the HTML representation of the view from the page by calling jQuery’s remove() method, which has the added bonus of cleaning up any event handlers attached to the view.

    Finally, we get all of the types of the models in the directory collection and check to see if the type of the contact that was just removed is still contained within the resulting array. If it isn’t, there are no more contacts of that type and we should therefore remove that option from the select.

    We select the element to remove by first finding the select box, then using an attribute selector to select the <option> with a value attribute that matches the removedType variable that we saved at the start of the method. If we remove all of the contacts of a certain type and then check the <select> element, we should find that the type is no longer in the drop-down:

    Removing the Model’s Data

    Ok, that subheading is a bit misleading; what I mean is that as well as removing the model and the view, we should also remove the original data in our contacts array that the model was originally built from. If we don’t do this, the model that was removed will come back whenever it is filtered. In a real-world application this is probably where we would sync with a sever in order to persist the data.

    The functionality to remove the item from the original array can reside within our master view; the collection will fire a remove event when any of the models are removed from the collection, so we can simply bind a handler for this event to the collection in the master view. Add the following line of code directly after the existing bindings:

    this.collection.on("remove", this.removeContact, this);

    You should be quite familiar with this statement by now, but as a reminder, the first argument of the on() method is the event we are listening for, the second is the handler to execute when the event occurs, and the third is the context to use as this when the handler is executed. Next we can add the removeContact() method; after the addContact() method add the following code:

    removeContact: function (removedModel) {
        var removed = removedModel.attributes;
    
        if (removed.photo === "/img/placeholder.png") {
            delete removed.photo;
        }
    
        _.each(contacts, function (contact) {
            if (_.isEqual(contact, removed)) {
                contacts.splice(_.indexOf(contacts, contact), 1);
            }
        });
    }

    Backbone helpfully passes our handler the model that has just been removed from the collection. We store a reference to the collection of attributes so that we can compare the model that has been removed with the items in our original contacts array. The original items in the contacts array didn’t have the photo property defined, but as this is specified as a default property, all of our models will inherit the property and will therefore fail any comparison with the objects in the contacts array.

    In this example, we need to check whether the photo property of the model is the same as the default value, and if it is, we remove the photo property.

    Once this is done we can iterate over each item in the contacts array and test it to see if it is the same as the model that was removed from the collection. We can compare each item with the object we store in the removed variable using Underscore’s isEqual() method.

    If the isEqual() method returns true, we then call the native JavaScript splice() method on the contacts array, passing in the index of the item to be removed, and the number of items to remove. The index is obtained using Underscore’s indexOf() method that we used earlier on.

    Now when a delete button is clicked, the view, model and original data will be erased from existence. We can also filter the view then go back to the view of all contacts, and the contact that was removed will still not be displayed.

    Doing Something With the Form

    So, we kinda just dumped the addContact form onto the page there didn’t we? To close off this part of the tutorial, we can do something to keep it hidden until a link is clicked. We can add the following link to the <header> element:

    <a id="showForm" href="#">Add new contact</a>

    To make the link show the form, we’ll need to hide it first and then use a UI event handler to show it. The binding can be added to the events object in the DirectoryView class:

    "click #showForm": "showForm"

    Our showForm() method can be as simple as follows (although you’ll probably want to do a bit more with it than we do here!):

    showForm: function () {
        this.$el.find("#addContact").slideToggle();
    }
    Summary

    In this tutorial, we looked solely at how new models can be added to a collection and how models can be removed from a collection. We saw that the Backbone methods used to add and remove models are, unsurprisingly, the add() and remove() methods.

    We also saw how we can bind handlers to the events that are fired automatically when these methods are used in order to update the UI and collection as necessary.

    We also looked at some more helpful Underscore utility functions that we can use to work with our data, including _indexOf() which returns that index of an item in an array, and isEqual() which can be used to deep-compare two objects to see if they are identical.

    Like in the last part of this tutorial, we also saw how can write our classes in such a way in that their functionality can be shared and reused whenever possible. When we added a new model for example, we made use of the existing renderContact() method defined in our DirectoryView class to handle rendering the HTML for the new contact.

    So we’ve seen how to add models and remove them, join me in the next part of this series where we’ll look at how to edit existing model data.


Planet PHP

  • Permalink for 'PHP-FPM FastCGI Process Manager with Apache 2'

    PHP-FPM FastCGI Process Manager with Apache 2

    Posted: March 13th, 2012, 5:00pm MDT by Christopher Jones

    I've published some vanilla PHP 5.4.0 RPMs to make new feature testing easier.

    Along with all the PHP 5.4 goodies, the php-fpm "FastCGI Process Manager" is available for the first time on oss.oracle.com. Php-fpm is an alternative FastCGI interface to PHP with various extra features such as load dependent spawning of processes. (For other features, see php-fpm.org). Php-fpm has been getting more and more traction in the PHP community and the EXPERIMENTAL flag was removed in PHP 5.4. You might want to test it out.

    To use php-fpm with the default Apache web server, first install Oracle Linux 5.8 (64bit) using Oracle's free, public yum repository public-yum.oracle.com.

    Install Apache, if not already installed:

      yum install [httpd] 

    Download and install the PHP 5.4 RPMs from oss.oracle.com/projects/php:

      rpm -i php54-common-5.4.0-1.el5.x86_64.rpm php54-fpm-5.4.0-1.el5.x86_64.rpm
    

    Other extensions can also be installed, depending on the functionality you want to test.

    Download and build FastCGI for Apache:

      wget [www.fastcgi.com]   tar -zxf mod_fastcgi-current.tar.gz
      cd mod_fastcgi-2.4.6
      cp Makefile.AP2 Makefile
      make top_dir=/usr/lib64/httpd
    

    Install FastCGI as root:

      make top_dir=/usr/lib64/httpd install
    

    Edit /etc/httpd/conf/httpd.conf and comment out any existing references to PHP you might previously have added for testing:

    # LoadModule php5_module        modules/libphp5.so
    # AddType application/x [httpd-php] .php
    

    Add the php-fpm configuration to httpd.conf:

      LoadModule fastcgi_module modules/mod_fastcgi.so
    
      <IfModule mod_fastcgi.c>  
        FastCGIExternalServer /usr/sbin/php-fpm -host 127.0.0.1:9000
        AddHandler php-fastcgi .php  
    
        #<LocationMatch "/status">
        #  SetHandler php-fastcgi-virt
        #  Action php-fastcgi-virt /usr/sbin/php-fpm.fcgi virtual
        #</LocationMatch>
    
        Action php-fastcgi /usr/sbin/php-fpm.fcgi  
        ScriptAlias /usr/sbin/php-fpm.fcgi /usr/sbin/php-fpm  
    
        <Directory /usr/sbin>  
          Options ExecCGI FollowSymLinks  
          SetHandler fastcgi-script  
          Order allow,deny  
          Allow from all  
        </Directory>  
      </IfModule> 
    

    Start php-fpm and Apache:

      service php-fpm start
      service [httpd] start
    

    Test it out with your favorite script or create a file pi.php:

      <?php
        phpinfo();
      ?>
    

    Save it in /var/www/html/pi.php or in $HOME/public_html/pi.php, if you have configured UserDir in httpd.conf.

    In a browser load http://localhost/pi.php or http://localhost/~yourname/pi.php.

    This will show the PHP configuration values.

    To test php-fpm's built-in statistics, edit httpd.conf and uncomment the four lines of the LocationMatch section:

      <LocationMatch "/status">
        SetHandler php-fastcgi-virt
        Action php-fastcgi-virt /usr/sbin/php-fpm.fcgi virtual
      </LocationMatch>
    

    Edit /etc/php-fpm.conf and uncomment the line:

      pm.status_path = /status
    

    Restart php-fpm and Apache:

      service php-fpm restart
      service [httpd] restart
    

    Run some load on the system:

      ab -c 10 -t 60 [localhost]  
    

    Now http://localhost/status gives you the status of the server:

      pool:                 www
      process manager:      dynamic
      start time:           13/Mar/2012:14:25:53 -0700
      start since:          26
      accepted conn:        50001
      listen queue:         0
      max listen queue:     6
      listen queue len:     128
      idle processes:       2
      active processes:     1
      total processes:      3
      max active processes: 5
      max children reached: 1
    

    The php-fpm.conf file documents other output formats for the statistics. It also shows the extensive functionality available with php-fpm.

    Documentation on php-fpm is not ideal, but you can see some at [php.net] . The php-fpm.org site has more, including a forum and wiki

    Truncated by Planet PHP, read more at the original (another 633 bytes)

  • Permalink for 'PHP 5.4.0 RPMs for 64bit Oracle Linux 5.x are available'

    PHP 5.4.0 RPMs for 64bit Oracle Linux 5.x are available

    Posted: March 13th, 2012, 4:06pm MDT by Christopher Jones

    I've published some vanilla PHP 5.4.0 RPMs to make new feature testing easier for Oracle Linux 5.x 64 bit users. The standard set of RPMs is at oss.oracle.com/projects/php. The OCI8 extension is also available (this requires the free Oracle Instant Client 11.2 from ULN or OTN.)

    Some of the features of PHP 5.4 are:

    • Improved memory usage and performance. Some impressive preliminary reports of the benefits include: [news.php.net] and [news.php.net] .

    • File Upload progress support is natively implemented.

    • Support for Traits now allows code reuse:

          trait t1 {
      	function m1() { echo "hi"; }
      	function m2() { echo "bye"; }
          }
      
          class my_c1 {
      	use t1;
      	/*...*/
          }
      
          class my_c2 extends c2 {
      	use t1;
      	/*...*/
          }
      
    • A built-in HTTP server for development is included:

        php -S 127.0.0.1:8888
      
    • Improvements were made to the interactive PHP shell (when PHP is compiled with readline).

    • A shortened array syntax was introduced: $a = [1,2,3];

    • The default character set for several internal functions was changed to UTF-8.

    • Support for multibyte languages is now configurable at run-time instead of compile-time.

    • The value echo tag "<?=" is now always on.

    • Binary number support was added.

    • DTrace support was added.

    • A new typehint indicates a function argument must be callable.

    • Session entropy uses /dev/urandom or /dev/arandom by default for extra security if either is present at compile time.

    • Function call results can now be immediately dereferenced as arrays: foo()[0]

    • Class members can be accessed on instantiation: (new foo)->method()

    For more changes see the migration documentation.

Nettuts+

  • Permalink for 'Easy Form Generation Using FuelPHP'

    Easy Form Generation Using FuelPHP

    Posted: March 13th, 2012, 11:00am MDT by Sahan Lakshitha

    Thanks to FuelPHP’s fieldset class, working with forms couldn’t be easier. With a few lines of code, you can easily generate and validate a form. Today, we’re going to learn how to do just that!

    The Fieldset class is used to create a form and handle its validation in an object-oriented way. It uses the Form and Validation classes. This class, itself, is only meant to model the fieldset and its fields, while the other two classes perform the brunt of the work.

Setup Fuel

We need a FuelPHP installation with an RM package enabled. I’m going to use a MySQL database with a sample table. While the Fieldset class can be configured to use a normal model, using an ORM will save us some time.

If you haven’t reviewed the first couple parts of the FuelPHP series here on Nettuts+, now is a great time to check out part one and two, by Phil Sturgeon.

Set up a database connection at fuel/app/config/development/db.php.

		return array(
		  'default' => array(
		 	 'connection'  => array(
		 		 'dsn'  	=> 'mysql:host=localhost;dbname=blog',
		 		 'username' => 'root',
		 		 'password' => 'root',
		 	 ),
		  ),
		);
		

Enable the ORM package through fuel/app/config.php

			'packages'  => array(
				'orm',
			),
		

And, finally, here’s the SQL for the table I’m using for this tutorial.

			CREATE TABLE  `blog`.`posts` (
			`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
			`post_title` VARCHAR( 100 ) NOT NULL ,
			`post_content` TEXT NOT NULL ,
			`author_name` VARCHAR( 65 ) NOT NULL ,
			`author_email` VARCHAR( 80 ) NOT NULL ,
			`author_website` VARCHAR( 60 ) NULL,
			`post_status` TINYINT NULL
			) ENGINE = INNODB;
		
Model

We need a model for our controller to interact with the posts table. Go ahead and create a post.php inside app/classes/model/. Create a Model_Post class and make sure it extends \Orm\Model. The ORM will automatically use the posts table in our database since we have used the singular of “posts”. If you want to set a different table, set up a static property called $_table_name.

		class Model_Post extends \Orm\Model
		{
			protected static $_table_name = 'posts'; //set the table name manually
		}
	
Setting Up the Properties

We should specify the columns of our posts table within our model. At the same time, we can also set up labels, form validation rules to use with our fieldset class to generate the form. All of these go in an associated array, called $_properies. With everything in place, our final model should look like so:

	class Model_Post extends \Orm\Model
	{
		protected static $_table_name = 'posts';

		protected static $_properties = array(
			'id',
			'post_title' => array( //column name
				'data_type' => 'string',
				'label' => 'Post Title', //label for the input field
				'validation' => array('required', 'max_length'=>array(100), 'min_length'=>array(10)) //validation rules
			),
			'post_content' => array(
				'data_type' => 'string',
				'label' => 'Post Content',
				'validation' => array('required')
			),
			'author_name' => array(
				'data_type' => 'string',
				'label' => 'Author Name',
				'validation' =>  array('required', 'max_length'=>array(65), 'min_length'=>array(2))
			),
			'author_email' => array(
				'data_type' => 'string',
				'label' => 'Author Email',
				'validation' =>  array('required', 'valid_email')
			),
			'author_website' => array(
				'data_type' => 'string',
				'label' => 'Author Website',
				'validation' =>  array('required', 'valid_url', 'max_length'=>array(60))
			),
			'post_status' => array(
				'data_type' => 'string',
				'label' => 'Post Status',
				'validation' => array('required'),
				'form' => array('type' => 'select', 'options' => array(1=>'Published', 2=>'Draft')),
			)

		);
	}
	

Let’s examine what options we can use. data_type simply holds the fields’s type. It could be either string, integer or mysql_date. The value for the label property will be shown as the field label once the form is generated. validation accepts an array of validation rules. By default, these fields will be text input fields. Using the form, you can make it a select or texarea.

The ORM treats the column named id as the primary and will not be shown when generating a form. If your table’s primary key column is different, use the $_primary_key property to specify it.

	/**
	 * Post Model
	 */
	class Model_Post extends \Orm\Model
	{
		protected static $_table_name = 'posts';

		protected static $_primary_key = array('id'); //you can set up multiple columns, .. $_primary_key => array('id', 'user_id')
	}
	
Controller

Now that the model is ready, let’s create the controller. Controllers should be placed within fuel/app/classes/controller/. I’ve created a controller, called Controller_Posts (posts.php) and extended it from Controller_Template.

		/**
		 * Post Controller fuel/app/classes/controller/posts.php
		 */
		class Controller_Posts extends \Controller_Template
		{
			//list posts
			function action_index()
			{

			}

			//add new one
			function action_add()
			{

			}

			//edit
			function action_edit($id)
			{

			}
		}
	

Users will be able to see a list of posts, add new ones, or edit an existing one. Because I’m using the template controller, I can use a base template file to work with. Templates go in fuel/app/views/template.php

	<!DOCTYPE html>
	<html>
	<head>
	    <meta [http-equiv="Content-type"] content="text/html; charset=utf-8" />
	    <?php echo Asset::css('bootstrap.css'); ?>
	</head>

	<body>

		<div id="content">

			<p>
				<?php
					echo \Html::anchor('posts/index', 'Listing'), '&nbsp;', \Html::anchor('posts/add', 'Add');
				?>
			</p>

			<?php if(isset($messages) and count($messages)>0): ?>
			<div class="message">
				<ul>
				<?php
					foreach($messages as $message)
					{
						echo '<li>', $message,'</li>';
					}
				?>
				</ul>
			</div>
			<?php endif; ?>

			<?php echo $content; ?>
		</div>

	</body>
	</html>
	

This is merely standard HTML markup with the Twitter bootstrap. The $content variable will have the content. We can set an array of messages and if we do, it will be printed as an unordered list.

Adding New Posts

This is where the fun begins. We’re going to generate the form for adding new posts. As you might have guessed, we’ll be working with the action_add() method. Let’s generate the form and pass it to our template.

	//add new one
	function action_add()
	{
		$fieldset = Fieldset::forge()->add_model('Model_Post');
		$form     = $fieldset->form();

		$this->template->set('content', $form->build(), false); //false will tell fuel not to convert the html tags to safe string.
	}
	

Fieldset::forge() will return a new instance of the fieldset class. It’s the same as doing new Fieldset. However, using the forge method here, we can name our instances. If we call an instance twice with the same name, an existing instance will be returned if available [the Factory pattern]. To name your instance, pass the name to the forge method. Fieldset::forge('new_post')

Using the add_model method, we pass the model which we want the forms to be generated from. Fieldset will grab the data from $_properties to generate the form. Calling the form() method from the fieldset object will return an instance from Form class, and by calling the build() method, we can get a html (string) output of the form.

		$this->template->set('content', $form, false);
	

Finally, we pass the $form to the template as content. Another method of passing variables to a template is $this->template->content = $form.

Fire up your browser and navigate to http://path_to_site/index.php/posts/add. You should see a form identical to this.

No submit button? Let’s fix that. We need to add a new field to our form object.

		$form->add('submit', '', array('type' => 'submit', 'value' => 'Add', 'class' => 'btn medium primary'));
	

Using the add method we can add additional fields to our form. First parameter is our new fields name, second is for label, for the third parameter we pass an array of attributes.

After adding this, our action_add() will look like this.

	function action_add()
	{
		$fieldset = Fieldset::forge()->add_model('Model_Post');
		$form     = $fieldset->form();
		$form->add('submit', '', array('type' => 'submit', 'value' => 'Add', 'class' => 'btn medium primary'));

		$this->template->set('content', $form->build(), false);
	}
	

And our form..

Validation and Saving

Now that we have a nice form, let’s validate it and save to the database. The fieldset object includes an instance from FuelPHP’s validation class. All the rules has been applied and ready to go.

	function action_add()
	{
		$fieldset = Fieldset::forge()->add_model('Model_Post');
		$form     = $fieldset->form();
		$form->add('submit', '', array('type' => 'submit', 'value' => 'Add', 'class' => 'btn medium primary'));

		if($fieldset->validation()->run() == true)
		{
			$fields = $fieldset->validated();

			$post = new Model_Post;
			$post->post_title     = $fields['post_title'];
			$post->post_content   = $fields['post_content'];
			$post->author_name    = $fields['author_name'];
			$post->author_email   = $fields['author_email'];
			$post->author_website = $fields['author_website'];
			$post->post_status    = $fields['post_status'];

			if($post->save())
			{
				\Response::redirect('posts/edit/'.$post->id);
			}
		}
		else
		{
			$this->template->messages = $fieldset->validation()->errors();
		}

		$this->template->set('content', $form->build(), false);
	}
	

$fieldset->validation() returns a validation class instance and by accessing its run() method we can check if validation is passed. If so, we add a new post to our database. $fieldset->validated() will return an array of validated fields. If validation is passed and post is saved, the user will be redirected to the edit page, otherwise pass the validation errors to our template as message variable.

If you try to submit some invalid data, you will get an output like so:

Everything seems fine except for one issue: data we submit doesn’t appear after the page refresh. Not to worry, one method call and you’re done.

	$fieldset = Fieldset::forge()->add_model('Model_Post')->repopulate(); //repopulate method will populate your form with posted data
	

Cool, huh? Add some valid data and it will redirect to the action_edit() method, which is not ready yet.

Editing a Post

Editing a section is pretty much the same as our add post section. Except we need to populate the data with an existing post. I’m going to duplicate the action_add code.


	function action_edit($id)
	{
		$post = \Model_Post::find($id);

		$fieldset = Fieldset::forge()->add_model('Model_Post')->populate($post); //model post object is passed to the populate method
		$form     = $fieldset->form();
		$form->add('submit', '', array('type' => 'submit', 'value' => 'Save', 'class' => 'btn medium primary'));

		if($fieldset->validation()->run() == true)
		{
			$fields = $fieldset->validated();

			//$post = new Model_Post;
			$post->post_title     = $fields['post_title'];
			$post->post_content   = $fields['post_content'];
			$post->author_name    = $fields['author_name'];
			$post->author_email   = $fields['author_email'];
			$post->author_website = $fields['author_website'];
			$post->post_status    = $fields['post_status'];

			if($post->save())
			{
				\Response::redirect('posts/edit/'.$id);
			}
		}
		else
		{
			$this->template->messages = $fieldset->validation()->errors();
		}

		$this->template->set('content', $form->build(), false);
	}
	

With some small modifications to our action_add() method, we have our edit method. repopulate() method has been replaced by populate() method. Using the populate method, we can populate a form with an existing post’s data.

In this case, we grab the post from our database using the $id parameter, then pass it to the requisite method. We don’t need $post = new Model_Post; anymore because we are not adding any thing to the database. The $post object we create in the beginning is used to assign the new values. Once edited it will redirect back to its edit screen. We’re done! Add some posts, and try editing them.

Listing Pages

Let’s build up the listing section so users can see all the posts in one place.

The listing is handled by the action_index() method

	//list posts
	function action_index()
	{
		$posts = \Model_Post::find('all');

		$view  = \View::forge('listing');
		$view->set('posts', $posts, false);

		$this->template->content = $view; //In config file View objects are whitelisted so Fuelphp will not escape the html.
	}
	

Model_Post::find('all') will return an array of posts objects for all of our posts. Using View::forge(), a new view object is instantiated. The parameter for View::forge() is the name for our specific view. It’s located at app/views/listing.php. The array of posts object ($posts) is then passed to our view. The Listing view will take care of the listing and finally we assign the view to $this->template->content.

In the view, we loop through $posts and generate the list.

	<?php
	/**
	 * Listing view, views/listing.php
	 */
	if($posts):
		foreach($posts as $post):
	?>

	<div class="post">
		<h2><?php echo $post->post_title; ?> <small><?php echo \Html::anchor('posts/edit/'.$post->id, '[Edit]');?></small></h2>
		<p><?php echo $post->post_content; ?></p>
		<p>
			<small>By <?php echo $post->author_name; ?></small><br />
			<small><?php echo $post->author_email; ?></small><br />
			<small><?php echo $post->author_website; ?></small><br />
		</p>
	</div>

	<?php
		endforeach;
	endif;
	?>
	

If you have any posts in the database, it will look something like this.

Some Final Modifications

Everything seems to be working correctly; however, there are some minor issues. The generated form has a text field for the post content, which would be better off as a textarea.

	//Model_Post
	'post_content' => array(
		'data_type' => 'string',
		'label' => 'Post Content',
		'validation' => array('required'),
		'form' => array('type' => 'textarea') //will give us a textarea
	),
	

You can pass all the field types text, textarea, select, radio etc. For select or radio elements, you can set the options. Setting options for a select using another table is also possible. If you want to change the default layout, place a form config file in fuel/app/config/form.php If you’re not sure about what to put in there, copy stuff from fuel/core/config/form.php. Fuel uses this file to generate the forms.

Summary

I hope you now have a clear understanding of the fieldset class. If you have any questions, please let me know in the comments below. Thank you so much for reading!


Planet PHP

Nettuts+

  • Permalink for 'Automate Your Projects With Apache Ant'

    Automate Your Projects With Apache Ant

    Posted: March 12th, 2012, 8:00am MDT by Andrew Burgess

    Ever find yourself doing boring, repetitive tasks as a web developer? Today, I’m going to show you how you can cut those meta-tasks out of your development cycle with a little bit of automation. In this tutorial, you’ll learn how to easily perform those repetitive tasks with Apache Ant.


    March of 2011 Intro: What is Ant?

    Ant makes it incredibly easy to define a set of tasks that you can then execute with a few commands.

    Ant is a piece of software that was originally built for automating software builds. It’s made by Apache (yes, as in Apache server), and its primarily purpose is to build Java applications. When you’re building software (or, in our case, websites/apps), you do several tasks that are identical each time you build or publish or deploy your project. It’s a waste of your valuable time to do this manually. Ant makes it incredibly easy to define a set of tasks that you can then execute with a few short-and-sweet commands through the terminal.

    Ready? Let’s Get started!

    Step 0: Creating our Dummy Project

    Before we get to Ant, we need to have a project to work with here. Here’s the index.html file I’m using:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8" />
        <title>Dummy Project</title>
        <link rel="stylesheet" href="css/reset.css"  />
        <link rel="stylesheet" href="css/grid.css"   />
        <link rel="stylesheet" href="css/custom.css" />
    </head>
    <body>
        <div>
            <h1> Demo Page </h1>
            <p> There are three CSS files and three JavaScript files in this project.
            <ul>
                <li><a href=" [meyerweb.com] Meyer's Reset</a></li>
                <li><a href=" [www.blueprintcss.org] from the Blueprint CSS</a></li>
                <li>A custom stylesheet</li>
            </ul>
            <ul>
                <li> <a href=" [jquery.com">jQuery<]             <li> <a href=" [javascript.crockford.com] Crockford's Top Down Operator Precedence files tokens.js and parse.js.</a></li>
            </ul>
            <p> All these files are uncompressed; that's the point of this tutorial, after all. </p>
        </div>
        <script src="js/jquery-latest.js"></script>
        <script src="js/tokens.js"></script>
        <script src="js/parse.js"></script>
    </body>
    </html>
    

    As you can see, this explains the rest of the project. If you download the project (link at the top), you’ll get the CSS and JavaScript files.

    So, what are we going to do with this project? As you can see, we’ve got multiple CSS and JavaScript files linked up in this project. What we’ll do is compile and compress each into its respective file and FTP it all up to a server. Before all of that, we’ll start by installing Ant.

    Step 1: Installing Ant

    Installing Ant can be a rather daunting task. Thankfully, both the Windows and Mac installation process is pretty similar. If you’re on Linux, I’m going to assume you either have Ant installed already, know how, or can figure it out without my hand-holding.

    If you’re on a Mac, you probably already have Ant installed; however, some of the more advanced tasks (in our case, FTP) won’t work. So, we’ll install the latest version.

    Before we begin, I’ll point you to the full instructions that Apache offers: you can get them here. (Unfortunately, that’s the whole manual for Ant; I can’t do any better, as it’s done with frames. You’ll see the “Installing Apache Ant” link in the left frame.) What I tell you below can all be found in there (and more besides), but my version is a little more web-developer friendly.

    First off, let’s make sure we have the right Java dependencies. Whether you’re on Windows or Mac, you’ll need the Java Development Kit (JDK) – at least version 1.4. You can download it here. If you’re not sure which version of the JDK you have, run the command java -version in the terminal / command line. As I understand it, the JDK version number is the same as the Java version number.

    Now, let’s download the latest version of Ant. You can get it from the download page for the binary distribution (of course, you can get the source and compile it yourself, if that’s how you roll). You’ll find the links half-way down the page:

    Download Links

    Once you’ve downloaded and unzipped it, we have to install it. This is what you’ll get:

    Ant Unzipped

    The first part of the installation differs with your platform. Let’s start with the Windows steps:

    Windows-Specific Install Bits

    First, you’ll have to choose the folder in which you’d like to install Ant. I went with C:\ant, but it’s up to you. Create that folder, and move the bin, lib, and etc folders from your download folder to that folder. You’ll also want to move fetch.xml and get-m2.xml.

    Once you’ve done that, you’ll have to setup some environmental variables. If you aren’t sure how to do this, you can find instructions here (Make these system variables—although, truthfully, it shouldn’t matter). This is what you’ll need to set up:

    • You’ll need a variable called ANT_HOME; this should point to the folder to which you moved the Ant components. Example: C:\ant.
    • You’ll need a variable called JAVA_HOME; this might already be there, but if it’s not, it should point to the folder holding your Java install. Mine is C:\Program Files\Java\jdk1.6.0_18.
    • You’ll need to modify you’re Path variable. This is a list of folders the command line searches through to find the commands you want to execute. DON’T overwrite this competely; just add ;%ANT_HOME%\bin to the end of it. Don’t miss that semicolon; that’s what separates the paths in the list. You might be able to guess that the %ANT_HOME% bit references the variable we made earlier.

    Now, you’ve got Ant installed on Windows! There’s one more important step, though; so skip pver the Mac piece and keep following along.

    Mac-Specific Install Bits

    You’ve already got ant installed on your Mac; you can see this by running the command which ant on the terminal. This will output something along the lines of /usr/bin/ant, as the path to the Ant executable you use. However, if you actually go to that folder, you’ll find that it’s just a symlink to the real stuff.

    Path to Ant

    As you can see, for me it’s linked to /usr/share/java/ant-1.8.1/bin/ant. Now, you could use this, but when I tried to, I wasn’t able to use the FTP component. Rather than install Ant somewhere else and mess with the symlink, I chose to do this: move what was in the usr/share/java/ant-1.8.1 folder into a subfolder called _old and move the new stuff in. You’ll have to move the bin, lib, and etc folders, plus the fetch.xml and get-m2.xml files. Now, that symlink will point to the updated version of ant. If you run ant -version in the terminal, you should see that you’ve got version 1.8.2 (or whatever version is latest at the time you’re reading this).

    Back to All OS Instructions

    There’s one more step to finish the installation. There are several optional components that don’t come with Ant, but that we’ll need for our project, and that you may want to use down the road. Let’s get them now.

    You’ll start by opening a command line or terminal and changing to the directory that you’ve just installed Ant in. More importantly, it’s the directory you put the fetch.xml file in. Now, run this command:

    ant -f fetch.xml -Ddest=system

    This will download and install quite a few optional components; this isn’t one of those blink-and-it’s-over commands: it could take a few minutes.

    Now, you’ve got Ant installed and ready to run; let’s get to work.

    Step 2: Creating the build.xml File

    Ant uses an XML file to store the tasks for the current project.

    Ant uses an XML file to store the tasks for the current project; when you’re in that project’s directory on the command line, you’ll be able to run the command ant TASK_NAME_HERE, and it will find the appropriate task within the XML file and execute it.

    If you’re not familiar with XML, don’t worry. XML stands for eXtensible Markup Language, and it’s very similar to HTML. It uses tags and attributes to define data. Actually, it’s more similar to XHTML (RIP), in that the rules are strict: all tags and attributes must be lowercase, values are quoted, a doctype is required, etc. Don’t worry though, you’ll get the hang of it.

    The XML file that Ant looks for by default should be named build.xml; you’ll want to put it in your project folder.

    So what exactly is going in the XML file? Here’s a start:

    <?xml version="1.0"?>
    <project name="Compress, Concatenate, and FTP CSS and JS" default="initialize">
    
    </project>
    

    Looks like HTML, eh? The first line is an XML doctype. Next, we have the root node, which is a project. I’ve added two attributes to it: a name, which just explains what our list of tasks will do; and a default, which defines the default task to run.

    See, here’s how the default task idea works. Let’s say we create a task called call_mom. We could run that from the terminal by doing this:

    ant call_mom

    If you find that most of the time you run Ant on a project, you’re calling the same task, you’ll want to make it the default. In our case, we’ve set initialize as the default task, the one that will run if we don’t tell ant to run anything.

    ant initialize
    ant

    These are both the same.

    Now that we’ve got our build.xml file, let’s create our first task.

    Step 3: Writing our First Task

    Tasks are called targets within the build.xml file. Check this out:

    <target name="call_mom">
        <echo> Hi Mom! </echo>
    </target>

    Plug this into your build.xml file and run ant call_mom on the console. You should output that looks something like this:

    Buildfile: /path/to/your/build.xml
    
    call_mom:
         [echo]  Hi Mom! 
    
    BUILD SUCCESSFUL
    Total time: 0 seconds

    In its output, Ant will have an entry for all the tasks that are run. Then, any output from those tasks will be displayed, tabbed in under the appropriate task name. As you can see, we’ve called the echo task, which prints out whatever we put inside it.

    But how did I know echo was a task? Well, you can get a list of the built-in tasks here in the documentation. This is a good time to point out that many tasks have several ways they can be called. For example, we could also have done: . What I show you isn’t the only way to do things.

    Now that you’re starting to warm into the ideas of Ant, let’s talk about properties.

    Step 4: Creating a Properties Files

    Ant has properties, which are very like variables in a programming language.

    As you use Ant more, you might find that you have a boilerplate build.xml file that you only tweak slightly. One of these tweaks might be file/folder names. Ant has properties, which are very like variables in a programming language. You can create them this way (this is done inside a task).

    <property name="js_dir" value="js" />
    <!-- or -->
    <property name="css_dir">stylesheets</property>

    You can also move all these properties out into a separate file, and import the file. That’s what we’ll do here. This brings us to creating our first (real) task:

    <target name="get_properties">
        <property file="ant.properties" />
        <echo>Imported Properties</echo>
    </target>

    We’ve called our task get_properties. It involves two actions: first, we use the property task to import the file (we can do that with the file attribute). Then, we echo a message saying that it was successful. It’s that simple.

    Of course, we’ll need to create the ant.properties file. This is super-simple; here’s the one we’ll use today:

    css_dir = css
    js_dir = js
    assets_dir = assets

    You might think this actually makes it harder, because our variables names are longer than the values themselves. Well, that’s true, but it gives us some flexibility in the use of our build.xml file, makes it more reusable and more shareable.

    Step 5: Creating Some More Tasks

    Okay, now let’s get serious. We’ve obviously got quite a few more tasks to create before we have a useful build.xml file.

    Here’s a list of the tasks we need to create:

    • One to compile the CSS files.
    • One to compress the CSS file.
    • One to compile the JavaScript files.
    • One to compress the JavaScript file.
    • One to upload everything to our server.
    • One to initialize the other tasks.
    • One to clean up what the others do.

    We’re going to use a few different tactics to do all this, to give to a good overview of how Ant works.

    Compiling the CSS and JavaScript

    Let’s start with the compiling tasks; these take a set of files and concatenate them all into one file. Ant has a built-in task named concat that does this.

    <target name="concat_css">
        <concat destfile="${assets_dir}/style.css">
            <filelist id="files" dir="${css_dir}">
                <file name="reset.css" />
                <file name="grid.css" />
                <file name="custom.css" />
            </filelist>
        </concat>
    </target>

    I’ve named this task concat_css. Inside, we’re only running the concat task. As you can see, the file they will be concatenated into (destfile, or destination file) will be in assets/style.css. You’ll notice that I’m use the assets_dir properties, which will substitute the correct value in. You must wrap usages of properties in the dollar-sign-and-braces notation.

    Inside the concat task, we define a filelist This is just one of the ways that we can grab a bunch of files. I’m using it here because it allows me to define the order I’d like these files concatenated. I’m giving it an id, which gives us access to the file set in the same way we’d use a parameter (although we won’t be doing that). It also has the attribute dir, which tells the task which folder to find the files in. Then, inside, just define the appropriate file nodes, with their name attribute holding the filename.

    There’s your first real task! Hopefully, it makes sense. While we’re at it, the JavaScript one isn’t too different:

    <target name="concat_js">
        <concat destfile="${assets_dir}/script.js">
            <filelist id="files" dir="${js_dir}">
                <file name="jquery-latest.js" />
                <file name="tokens.js" />
                <file name="parse.js" />
            </filelist>
        </concat>
    </target>
    Compressing the CSS and JavaScript

    Compression gets a bit trickier, because it’s not built into Ant. However, Ant supports outside tasks via java .jar files. This is incredibly handy for us, because YUI Compressor is available as a .jar file (that’s the only way it’s available). You can download it on the YUI Library download page. You’ll want to save it to a smart location, and maybe rename it. I’ve saved it to MY_USER_FOLDER/bin/yui.jar. Do what pleases you.

    Now, YUI Compressor will compress both JavaScript and CSS. What we can do here is create one compress task, and then call it from two more specific tasks. We can do this because Ant has support for calling other tasks and passing in parameters. Let’s see how this works:

    <target name="compress">
        <java jar="/Users/andrew/bin/yui.jar" fork="true">
            <arg value="${file}" />
            <arg value="-o" />
            <arg value="${file}" />
        </java>
        <echo>${file}</echo>
    </target>

    We’re using the java command here. This is very similar to running the jar file from the command line. The jar attribute points to the jar file. If the fork attribute is true, the jar will be run in a Java virtual machine separate from the one Ant is running on. Then, inside the java node, we define the arguments. On the command line, we would pass in input.file -o output.file. So, we do the same thing here.

    But, where’s the file property coming from? From here:

    <target name="compress_css" depends="concat_css">
        <antcall target="compress">
            <param name="file" value="${assets_dir}/style.css" />
        </antcall>
    </target>

    This is our CSS compression task. First, notice that the target node has a second attribute: depends. You can probably guess that this means that the compress_css tasks depends on the concat_css task, so it must be run first. This way, we can call compress_css and it will automatically call concat_css first.

    Now, what’s going on inside? We’re executing an antcall task, which simply calls another task within our build.xml file—in this case, that’s our compress task. Inside that, we can create as many parameters as we need to, each having a name and a value. Yep, this is very much like calling a function. This is the file parameter that we use within our compress task.

    And here’s the JavaScript version:

    <target name="compress_js" depends="concat_js">
        <antcall target="compress">
            <param name="file" value="${assets_dir}/script.js" />
        </antcall>
    </target>

    Don’t forget, this one is dependant on concat_js.

    Getting the Ball Rolling

    Way back at the top—on our root project node—we set the default task as initialize. We haven’t created that task yet, so let’s do it now.

    <target name="initialize" depends="get_properties,clean_up">
        <mkdir dir="${assets_dir}" />
        <antcall target="compress_css" />
        <antcall target="compress_js"  />
        <echo>Done!</echo>
    </target>

    This task depends on two other tasks (one of which we haven’t created yet); we just use a comma separated list to require multiple tasks.

    Inside, the first task is to create our assets directory, with the mkdir task (just like on the command line). Next, we make two antcalls, one to compress the CSS, and one to compress the JavaScript. Remember, these two tasks depend on their respective concatenation functions, so they will call those. Finally, we’ll echo a message letting the user know that we’re done.

    Cleaning Up

    What about that clean_up task that initialize depends on? It’s pretty simple:

    <target name="clean_up" depends="get_properties">
        <delete dir="${assets_dir}" />
    </target>

    It merely deletes the assets directory. This isn’t completely necessary, but you might find it useful.

    Uploading the Project

    Let’s create one more task; we want to upload our project to a server. Thanks to the ftp command, this is a cinch.

    <target name="upload_files" depends="initialize">
        <ftp server="your_server.com"
             userid="your_user_name"
             password="your_password"
             port="21"
             remotedir="/public_html"
             passive="yes"
             binary="no">
            <fileset dir=".">
                <include name="assets/*"   />
                <include name="index.html" />
            </fileset>
        </ftp>
    </target>

    We’re calling this task upload_files, and it depends on initialize. We’re using the FTP task here. As you can see, all the important info is stored in the attributes. If you’ve worked with FTP clients before, all these options should be familiar.

    • Inside the ftp node, we’ve created a collection of files that we want to upload. In this case, we’re using a fileset element.
    • We have a dir attribute on the filset node that defines the root directory for what we want to collect.
    • Then, inside, we use the include node to get the specific files: we just pass as the name attribute the file(s) we want to get. In our example, we’re getting everything the assets directory and its contents, and the index.html file.

    Once you fill in your server information in this task, it should upload those files for you!

    Notice how we’ve arranged these tasks, though. If we run ant on the command line, we’re concatenate and compress the CSS and JavaScript, but we won’t upload it; that’s not the default. If we want to upload it, we can run ant upload_files; since that depends on initialize, we don’t have to call initialize first. Of course, we can call any individual task we’d like (for example: ant compress_js).

    Conclusion: Wrapping It Up

    Before we close, there are a few odds and ends I’d like to mention:

    • Notice that I didn’t use the depends task to daisy-chain tasks together. You could do that, but I’ve chosen to keep that to actual dependant tasks, and create the initialize task to call the others. This just seems more correct semantically.
    • What I’ve shown you is just a small sliver of what Ant is capable of. If you want to learn more, start by checking out the tasks overview. This will show you all the built-in tasks. You’ll also realize that there are many ways to do the same this (as I showed you with the echo task). The patterns I’ve used are by no means the “one right way.” Also, the Ant Wiki is a great resource.
    • It might be nice if we could have a task that will parse the HTML, find the stylesheets and scripts, and get them in the correct order. Unfortunately—since Ant wasn’t written for web developers—that’s not built in. We’d have to create an antlib (an extension), and that would be written in Java. For now, we’ll have to hard-code out lists of stylesheets and scripts.

    And that’s a wrap! I hope you’ve learned some new techniques that will save you time in the future. If you have any questions, feel free to post them below! Thank you so much for reading!


Planet PHP

  • Permalink for 'Smoothing with Holt-Winter '

    Smoothing with Holt-Winter

    Posted: March 10th, 2012, 4:10am MST by Ian Barber

    In one of his talks at QCon, John Allspaw mentioned using Holt-Winter exponential smoothing on various monitoring instances. Wikipedia has a good entry on the subject, of course, but the basic idea is to take a noisy/spikey time series and smooth it out, so that unexpected changes will stand out even more. That's often initially done by taking a moving average, so say averaging the last 7 days of data and using that as the current day's value. More complicated schemes weight that average, so that the older data contributes less.

    Simple exponential smoothing effectively takes this weighted average further, with more recent values being exponentially more important than older ones. However, this has problems in the face of a long term trend, so double exponential includes a factor for the general tendencies in the data (e.g. an increasing trend over time). Triple exponential, which we've using here, also includes a factor to consider seasonal changes, so I thought I'd give that one a go at implementing. Each of those three smoothing aspects have their own weighting factor, alpha, beta and gamma, that control how much of an impact they have, and by setting each to 0 we can have the same code do any one of the three algorithms. Below I've broken out the function into it's component parts, but you can see the whole thing on github

    We'll give it a go on some web data that has an unexpected spike, see how visible that is against the timeline. The algorithm is pretty simple, but we need to setup a bunch of variables first. We start off by calculating an initial trend value by looking at the difference in the average values over the first two 'seasons' (the length being a configurable parameter of the function).

    <?php


    // Calculate an initial trend level
    $trend1 = 0;
    for($i = 0; $i < $season_length; $i++) {
        $trend1 += $data[$i];
    }
    $trend1 /= $season_length;
       
    $trend2 = 0;
    for($i = $season_length; $i < 2*$season_length; $i++) {
        $trend2 += $data[$i];
    }
    $trend2 /= $season_length;
       
    $initial_trend = ($trend2 - $trend1) / $season_length;
    ?>

    Next we create an initial value for the 'level' part, the direct data smoothing parameter, map the data for the season index, and calculate the seasonal changes for the first period.

    <?php


    // Take the first value as the initial level
    $initial_level = $data[0];
           
    // Build index
    $index

    Truncated by Planet PHP, read more at the original (another 24725 bytes)

  • Permalink for 'building a nice image gallery like pinterest/friendsheet using facebook graph api and LightBulb'

    building a nice image gallery like pinterest/friendsheet using facebook graph api and LightBulb

    Posted: March 9th, 2012, 8:30pm MST by Hasin Hayder
  • Permalink for 'PHP Constructor Best Practices And The Prototype Pattern'

    PHP Constructor Best Practices And The Prototype Pattern

    Posted: March 9th, 2012, 1:16pm MST by Ralph Schindler

    If your knowledge of constructors ends with “the place where I put my object initialization code,” read on. While this is mostly what a constructor is, the way a developer crafts their class constructor greatly impacts the initial API of a particular class/object; which ultimately affects usability and extensibility. After all, the constructor is the first impression a particular class can make.

    Constructors, in their current form, have been in PHP since 5.0.0. Previous to 5.0, PHP loosely followed the style similar to that of C++ where the name of the method matching the name of the class would act as the class constructor. PHP 5 brought us the __construct() “magic method” which greatly formalized the new object initialization routine.

    Before jumping into some of the topics covered in this post, there are a few things you might want to be familiar with. First, be familiar with the SOLID principles, particularly the S (single responsibility principle), the L (Liskov substitution principle, commonly referred to as the LSP), and the D (dependency inversion principle). More to the point of the latter, review a previous post on Dependency Injection in PHP for background dependency injection specific to PHP.

    The Constructor Signature

    In PHP, you create a constructor by adding a method called __construct() to your class. The __construct() method is an instance method and as such, is not marked static. For all intents and purposes, consider the __construct() magic method as a special type of static object factory, one which will always return the type of the object requested via the new keyword.

    class Foo {
        public function __construct() {
        }
    }
    
    $object = new Foo();
    

    In the above code, PHP will, upon executing new Foo(), internally create a new object from scratch, execute __construct() in the Foo class, and assign this object to the variable $object. Pretty standard stuff. What’s important to know here is that before new Foo(), the object did not exist. It is this fact alone that makes this completely different from any other kind of instance method. That said, without getting into the gritty details, it is this fact alone that excuses the __construct() method from the same rules of the LSP that might apply to other instance methods.

    This means that all of the following are legal:

    class Foo {
        public function __construct() {
        }
    }
    
    class Bar extends Foo {
        public function __construct(ArrayObject $arrayObj, $number = 0) {
            /* do stuff with $arrayObj and $number */
        }
    }
    
    class Baz extends Bar {
        public function __construct(Bar $bar) {
            // yes, this is the proxy pattern
        }
    }
    

    The above, with E_STRICT enabled, will not produce a warning. Yet, if you renamed all of the __construct methods to anything else, they will produce a E_STRICT warning like:

    Strict standards: Declaration of Bar::somemethod() should be compatible with that of Foo::somemethod()
    

    Why is this the case? Simply put, the LSP referrers to sub-types of a particular object, and since before the __construct() method, no type exists (yet). This rules simply cannot apply to something that does not exist. For a more detailed response, go here.

    What you should take away from this is that the best-practice is that each concrete object has a constructor with a signature that best represents how a consumer should fully instantiate that particular object. In some cases where inheritance is involved, “borrowing” the parents constructor is acceptable and useful. Furthermore, it is encouraged that when you subclass a particular type, that your new type should, when appropriate, have its own constructor that makes the most sense to the new subtype.

    At this point, it should be noted that most other languages do not allow constructors to be marked final, be abstract, or be marked as statics (see above on the static n

    Truncated by Planet PHP, read more at the original (another 14920 bytes)

  • Permalink for 'PHP Constructor Best Practices And The Prototype Pattern'

    PHP Constructor Best Practices And The Prototype Pattern

    Posted: March 9th, 2012, 1:16pm MST by Ralph Schindler

    If your knowledge of constructors ends with “the place where I put my object initialization code,” read on. While this is mostly what a constructor is, the way a developer crafts their class constructor greatly impacts the initial API of a particular class/object; which ultimately affects usability and extensibility. After all, the constructor is the first impression a particular class can make.

    Constructors, in their current form, have been in PHP since 5.0.0. Previous to 5.0, PHP loosely followed the style similar to that of C++ where the name of the method matching the name of the class would act as the class constructor. PHP 5 brought us the __construct() “magic method” which greatly formalized the new object initialization routine.

    Before jumping into some of the topics covered in this post, there are a few things you might want to be familiar with. First, be familiar with the SOLID principles, particularly the S (single responsibility principle), the L (Liskov substitution principle, commonly referred to as the LSP), and the D (dependency inversion principle). More to the point of the latter, review a previous post on Dependency Injection in PHP for background dependency injection specific to PHP.

    The Constructor Signature

    In PHP, you create a constructor by adding a method called __construct() to your class. The __construct() method is an instance method and as such, is not marked static. For all intents and purposes, consider the __construct() magic method as a special type of static object factory, one which will always return the type of the object requested via the new keyword.

    class Foo {
        public function __construct() {
        }
    }
    
    $object = new Foo();
    

    In the above code, PHP will, upon executing new Foo(), internally create a new object from scratch, execute __construct() in the Foo class, and assign this object to the variable $object. Pretty standard stuff. What’s important to know here is that before new Foo(), the object did not exist. It is this fact alone that makes this completely different from any other kind of instance method. That said, without getting into the gritty details, it is this fact alone that excuses the __construct() method from the same rules of the LSP that might apply to other instance methods.

    This means that all of the following are legal:

    class Foo {
        public function __construct() {
        }
    }
    
    class Bar extends Foo {
        public function __construct(ArrayObject $arrayObj, $number = 0) {
            /* do stuff with $arrayObj and $number */
        }
    }
    
    class Baz extends Bar {
        public function __construct(Bar $bar) {
            // yes, this is the proxy pattern
        }
    }
    

    The above, with E_STRICT enabled, will not produce a warning. Yet, if you renamed all of the __construct methods to anything else, they will produce a E_STRICT warning like:

    Strict standards: Declaration of Bar::somemethod() should be compatible with that of Foo::somemethod()
    

    Why is this the case? Simply put, the LSP referrers to sub-types of a particular object, and since before the __construct() method, no type exists (yet). This rules simply cannot apply to something that does not exist. For a more detailed response, go here.

    What you should take away from this is that the best-practice is that each concrete object has a constructor with a signature that best represents how a consumer should fully instantiate that particular object. In some cases where inheritance is involved, “borrowing” the parents constructor is acceptable and useful. Furthermore, it is encouraged that when you subclass a particular type, that your new type should, when appropriate, have its own constructor that makes the most sense to the new subtype.

    At this point, it should be noted that most other languages do not allow constructors to be marked final, be abstract, or be marked as statics (see above on the static n

    Truncated by Planet PHP, read more at the original (another 14920 bytes)

Nettuts+

  • Permalink for 'Sass vs. LESS vs. Stylus — a Preprocessor Shootout'

    Sass vs. LESS vs. Stylus — a Preprocessor Shootout

    Posted: March 9th, 2012, 10:00am MST by Jeffrey Way

    Wielding the true power of a CSS preprocessor is an adventure. There are countless languages, syntaxes, and features, all ready for use right now.

    In this article, we will be covering the various features and benefits of using three different preprocessors—Sass, LESS, and Stylus.

    Introduction

    Preprocessors produce CSS that works in all browsers.

    CSS3 preprocessors are languages written for the sole purpose of adding cool, inventive features to CSS without breaking browser compatibility. They do this by compiling the code we write into regular CSS that can be used in any browser all the way back to the stone ages. There are thousands of features that preprocessors bring to the table, and in this article we will cover some of the publicized ones, and some of the not-so-publicized ones. Let’s get started.

    Syntax

    The most important part of writing code in a CSS preprocessor is understanding the syntax. Luckily for us, the syntax is (or can be) identical to regular CSS for all three preprocessors.

    Sass & LESS

    Sass and LESS both use the standard CSS syntax. This makes it extremely easy to convert an existing CSS file to either preprocessor. Sass uses the .scss file extension and LESS uses the .less extension. The basic Sass or LESS file can be setup like below:

    /* style.scss or style.less */
    h1 {
      color: #0982C1;
    }
    

    As you may have noticed, this is just regular CSS, which compiles perfectly in both Sass and LESS.

    It’s important to note that Sass also has an older syntax, which omits semicolons and curly brackets. Although this is still around, it is old and we won’t be using it past this example. The syntax uses the .sass file extension and looks like this:

    /* style.sass */
    h1
      color: #0982c1
    
    Stylus

    The syntax for Stylus is much more verbose. Using the .styl file extension, Stylus accepts the standard CSS syntax, but it also accepts some other variations where brackets, colons, and semi-colons are all optional. For example:

    /* style.styl */
    h1 {
      color: #0982C1;
    }
    
    /* omit brackets */
    h1
      color: #0982C1;
    
    /* omit colons and semi-colons */
    h1
      color #0982C1
    

    Using different variations in the same stylesheet is also valid, so the following will compile without errors.

    h1 {
      color #0982c1
    }
    h2
      font-size: 1.2em
    
    Variables

    Variables can be declared and used throughout the stylesheet. They can have any value that is a CSS value (e.g. colors, numbers [units included], or text.), and can be referenced anywhere throughout our stylesheet.

    Sass

    Sass variables are prepended with the $ symbol and the value and name are separated with a semicolon, just like a CSS property.

    $mainColor: #0982c1;
    $siteWidth: 1024px;
    $borderStyle: dotted;
    
    body {
      color: $mainColor;
      border: 1px $borderStyle $mainColor;
      max-width: $siteWidth;
    }
    
    LESS

    LESS variables are exactly the same as Sass variables, except the variable names are prepended with the @ symbol.

    @mainColor: #0982c1;
    @siteWidth: 1024px;
    @borderStyle: dotted;
    
    body {
      color: @mainColor;
      border: 1px @borderStyle @mainColor;
      max-width: @siteWidth;
    }
    
    Stylus

    Stylus variables don’t require anything to be prepended to them, although it allows the $ symbol. As always, the ending semicolon is not required, but an equal sign in between the value and variable is. One thing to note is that Stylus (0.22.4) compiles if we prepend the @ symbol to a variable name, but will not apply the value when referenced. In other words, don’t do that.

    mainColor = #0982c1
    siteWidth = 1024px
    $borderStyle = dotted
    
    body
      color mainColor
      border 1px $borderStyle mainColor
      max-width siteWidth
    
    Compiled CSS

    Each of the above files will compile to the same CSS. You can use your imagination to see how useful variables can be. We will no longer need to change one color and have to retype it twenty times, or want to change our site width and have to dig around to find it. Here’s the CSS after compilation:

    body {
      color: #0982c1;
      border: 1px dotted #0982c1;
      max-width: 1024px;
    }
    
    Nesting

    If we need to reference multiple elements with the same parent in our CSS, it can be tedious to keep writing the parent over and over.

    section {
      margin: 10px;
    }
    section nav {
      height: 25px;
    }
    section nav a {
      color: #0982C1;
    }
    section nav a:hover {
      text-decoration: underline;
    }
    

    Instead, using a preprocessor, we can write the children selectors inside the parent’s brackets. Also, the & symbol references the parent selector.

    Sass, LESS, & Stylus

    All three preprocessors have the same syntax for nesting selectors.

    section {
      margin: 10px;
    
      nav {
        height: 25px;
    
        a {
          color: #0982C1;
    
          &amp;:hover {
            text-decoration: underline;
          }
        }
      }
    }
    
    Compiled CSS

    This is the compiled CSS from the code above. It is exactly the same as when we started—how convenient!

    section {
      margin: 10px;
    }
    section nav {
      height: 25px;
    }
    section nav a {
      color: #0982C1;
    }
    section nav a:hover {
      text-decoration: underline;
    }
    
    Mixins

    Mixins are functions that allow the reuse of properties throughout our stylesheet. Rather than having to go throughout our stylesheet and change a property multiple times, we can now just change it inside our mixin. This can be really useful for specific styling of elements and vendor prefixes. When mixins are called from within a CSS selector, the mixin arguments are recognized and the styles inside the mixin are applied to the selector.

    Sass
    /* Sass mixin error with (optional) argument $borderWidth which defaults to 2px if not specified */
    @mixin error($borderWidth: 2px) {
      border: $borderWidth solid #F00;
      color: #F00;
    }
    
    .generic-error {
      padding: 20px;
      margin: 4px;
      @include error(); /* Applies styles from mixin error */
    }
    .login-error {
      left: 12px;
      position: absolute;
      top: 20px;
      @include error(5px); /* Applies styles from mixin error with argument $borderWidth equal to 5px*/
    }
    
    LESS
    /* LESS mixin error with (optional) argument @borderWidth which defaults to 2px if not specified */
    .error(@borderWidth: 2px) {
      border: @borderWidth solid #F00;
      color: #F00;
    }
    
    .generic-error {
      padding: 20px;
      margin: 4px;
      .error(); /* Applies styles from mixin error */
    }
    .login-error {
      left: 12px;
      position: absolute;
      top: 20px;
      .error(5px); /* Applies styles from mixin error with argument @borderWidth equal to 5px */
    }
    
    Stylus
    /* Stylus mixin error with (optional) argument borderWidth which defaults to 2px if not specified */
    error(borderWidth= 2px) {
      border: borderWidth solid #F00;
      color: #F00;
    }
    
    .generic-error {
      padding: 20px;
      margin: 4px;
      error(); /* Applies styles from mixin error */
    }
    .login-error {
      left: 12px;
      position: absolute;
      top: 20px;
      error(5px); /* Applies styles from mixin error with argument borderWidth equal to 5px */
    }
    
    Compiled CSS

    All the preprocessors compile to the same code below:

    .generic-error {
      padding: 20px;
      margin: 4px;
      border: 2px solid #f00;
      color: #f00;
    }
    .login-error {
      left: 12px;
      position: absolute;
      top: 20px;
      border: 5px solid #f00;
      color: #f00;
    }
    
    Inheritance

    When writing CSS the old-fashioned way, we could use the following code to apply the same styles to multiple elements at once:

    p,
    ul,
    ol {
      /* styles here */
    }
    

    That works great, but if we need to further style the elements individually, another selector has to be created for each and it can quickly get messier and harder to maintain. To counter this, inheritance can be used. Inheritance is the ability for other CSS selectors to inherit the properties of another selector.

    Sass & Stylus
    .block {
      margin: 10px 5px;
      padding: 2px;
    }
    
    p {
      @extend .block; /* Inherit styles from '.block' */
      border: 1px solid #EEE;
    }
    ul, ol {
      @extend .block; /* Inherit styles from '.block' */
      color: #333;
      text-transform: uppercase;
    }
    
    Compiled CSS (Sass & Stylus)
    .block, p, ul, ol {
      margin: 10px 5px;
      padding: 2px;
    }
    p {
      border: 1px solid #EEE;
    }
    ul, ol {
      color: #333;
      text-transform: uppercase;
    }
    
    LESS

    LESS doesn’t truly support inheriting styles like Sass and Stylus. Instead of adding multiple selectors to one set of properties, it treats inheritance like a mixin without arguments and imports the styles into their own selectors. The downside to this is that the properties are repeated in your compiled stylesheet. Here’s how you would set it up:

    .block {
      margin: 10px 5px;
      padding: 2px;
    }
    
    p {
      .block; /* Inherit styles from '.block' */
      border: 1px solid #EEE;
    }
    ul, ol {
      .block; /* Inherit styles from '.block' */
      color: #333;
      text-transform: uppercase;
    }
    
    Compiled CSS (LESS)
    .block {
      margin: 10px 5px;
      padding: 2px;
    }
    p {
      margin: 10px 5px;
      padding: 2px;
      border: 1px solid #EEE;
    }
    ul,
    ol {
      margin: 10px 5px;
      padding: 2px;
      color: #333;
      text-transform: uppercase;
    }
    

    As you can see, the styles from .block were inserted into the selectors that we wanted to give the inheritance to. It’s important to note that priority can become an issue here, so be cautious.

    Importing

    In the CSS community, importing CSS is frowned upon because it requires multiple HTTP requests. Importing with a preprocessor works differently, however. If you import a file from any of the three preprocessors, it will literally include the import during the compile, creating only one file. Keep in mind though that importing regular .css files compiles with the default @import "file.css"; code. Also, mixins and variables can be imported and used in your main stylesheet. Importation makes creating separate files for organization very worthwhile.

    Sass, LESS, & Stylus
    /* file.{type} */
    body {
      background: #EEE;
    }
    
    @import "reset.css";
    @import "file.{type}";
    
    p {
      background: #0982C1;
    }
    
    Compiled CSS
    @import "reset.css";
    body {
      background: #EEE;
    }
    p {
      background: #0982C1;
    }
    
    Color Functions

    Color functions are built in functions that will transform a color upon compilation. This can be extremely useful for creating gradients, darker hover colors, and much more.

    Sass
    lighten($color, 10%); /* returns a color 10% lighter than $color */
    darken($color, 10%);  /* returns a color 10% darker than $color */
    
    saturate($color, 10%);   /* returns a color 10% more saturated than $color */
    desaturate($color, 10%); /* returns a color 10% less saturated than $color */
    
    grayscale($color);  /* returns grayscale of $color */
    complement($color); /* returns complement color of $color */
    invert($color);     /* returns inverted color of $color */
    
    mix($color1, $color2, 50%); /* mix $color1 with $color2 with a weight of 50% */
    

    This is only a short list of the available color functions in Sass, a full list of available Sass color functions can be found by reading the Sass Documentation.

    Color functions can be used anywhere that a color is valid CSS. Here’s an example:

    $color: #0982C1;
    
    h1 {
      background: $color;
      border: 3px solid darken($color, 50%);
    }
    
    LESS
    lighten(@color, 10%); /* returns a color 10% lighter than @color */
    darken(@color, 10%);  /* returns a color 10% darker than @color */
    
    saturate(@color, 10%);   /* returns a color 10% more saturated than @color */
    desaturate(@color, 10%); /* returns a color 10% less saturated than @color */
    
    spin(@color, 10);  /* returns a color with a 10 degree larger in hue than @color */
    spin(@color, -10); /* returns a color with a 10 degree smaller hue than @color */
    
    mix(@color1, @color2); /* return a mix of @color1 and @color2 */
    

    A list of all the LESS functions can be found by reading the LESS Documentation.

    Here’s an example of how to use a color function in LESS:

    @color: #0982C1;
    
    h1 {
      background: @color;
      border: 3px solid darken(@color, 50%);
    }
    
    Stylus
    lighten(color, 10%); /* returns a color 10% lighter than 'color' */
    darken(color, 10%);  /* returns a color 10% darker than 'color' */
    
    saturate(color, 10%);   /* returns a color 10% more saturated than 'color' */
    desaturate(color, 10%); /* returns a color 10% less saturated than 'color' */
    

    A full list of all the Stylus color functions can be found by reading the Stylus Documentation.

    Here’s an example using Stylus color functions:

    color = #0982C1
    
    h1
      background color
      border 3px solid darken(color, 50%)
    
    Operations

    Doing math in CSS is quite useful, and now fully possible. It’s simple and this is how to do it:

    Sass, LESS, & Stylus
    body {
      margin: (14px/2);
      top: 50px + 100px;
      right: 100px - 50px;
      left: 10 * 10;
    }
    
    Practical Applications

    We have covered a lot of the features and new things that preprocessors can do, but we haven’t covered anything hands-on or practical. Here’s a short list of real-world applications where using a preprocessor is a life-saver.

    Vendor Prefixes

    This is one of the hyped up reasons to use a preprocessor and for a very good reason—it saves loads of time and tears. Creating a mixin to handle vendor prefixes is easy and saves a lot of repetition and painful editing. Here’s how to do it:

    Sass
    @mixin border-radius($values) {
      -webkit-border-radius: $values;
         -moz-border-radius: $values;
              border-radius: $values;
    }
    
    div {
      @include border-radius(10px);
    }
    
    LESS
    .border-radius(@values) {
      -webkit-border-radius: @values;
         -moz-border-radius: @values;
              border-radius: @values;
    }
    
    div {
      .border-radius(10px);
    }
    
    Stylus
    border-radius(values) {
      -webkit-border-radius: values;
         -moz-border-radius: values;
              border-radius: values;
    }
    
    div {
      border-radius(10px);
    }
    
    Compiled CSS
    div {
      -webkit-border-radius: 10px;
         -moz-border-radius: 10px;
              border-radius: 10px;
    }
    
    3D Text

    Faking 3D text using multiple text-shadows is a clever idea. The only problem is that changing the color after the fact is difficult and cumbersome. Using mixins and color functions, we can create 3D text and change the color on the fly!

    Sass
    @mixin text3d($color) {
      color: $color;
      text-shadow: 1px 1px 0px darken($color, 5%),
                   2px 2px 0px darken($color, 10%),
                   3px 3px 0px darken($color, 15%),
                   4px 4px 0px darken($color, 20%),
                   4px 4px 2px #000;
    }
    
    h1 {
      font-size: 32pt;
      @include text3d(#0982c1);
    }
    
    LESS
    .text3d(@color) {
      color: @color;
      text-shadow: 1px 1px 0px darken(@color, 5%),
                   2px 2px 0px darken(@color, 10%),
                   3px 3px 0px darken(@color, 15%),
                   4px 4px 0px darken(@color, 20%),
                   4px 4px 2px #000;
    }
    
    span {
      font-size: 32pt;
      .text3d(#0982c1);
    }
    
    Stylus
    text3d(color)
      color: color
      text-shadow: 1px 1px 0px darken(color, 5%), 2px 2px 0px darken(color, 10%), 3px 3px 0px darken(color, 15%), 4px 4px 0px darken(color, 20%), 4px 4px 2px #000
    span
      font-size: 32pt
      text3d(#0982c1)
    

    I chose to write the Stylus text-shadows on one line because I omitted the curly brackets.

    Compiled CSS
    span {
      font-size: 32pt;
      color: #0982c1;
      text-shadow: 1px 1px 0px #097bb7,
                   2px 2px 0px #0875ae,
                   3px 3px 0px #086fa4,
                   4px 4px 0px #07689a,
                   4px 4px 2px #000;
    }
    
    End Result Columns

    Using number operations and variables for columns is an idea I came up with when I was first playing with CSS preprocessors. By declaring a desired width in a variable, we can easily change it down the road without any mental-math. Here’s how it’s done:

    Sass
    $siteWidth: 1024px;
    $gutterWidth: 20px;
    $sidebarWidth: 300px;
    
    body {
      margin: 0 auto;
      width: $siteWidth;
    }
    .content {
      float: left;
      width: $siteWidth - ($sidebarWidth+$gutterWidth);
    }
    .sidebar {
      float: left;
      margin-left: $gutterWidth;
      width: $sidebarWidth;
    }
    
    LESS
    @siteWidth: 1024px;
    @gutterWidth: 20px;
    @sidebarWidth: 300px;
    
    body {
      margin: 0 auto;
      width: @siteWidth;
    }
    .content {
      float: left;
      width: @siteWidth - (@sidebarWidth+@gutterWidth);
    }
    .sidebar {
      float: left;
      margin-left: @gutterWidth;
      width: @sidebarWidth;
    }
    
    Stylus
    siteWidth = 1024px;
    gutterWidth = 20px;
    sidebarWidth = 300px;
    
    body {
      margin: 0 auto;
      width: siteWidth;
    }
    .content {
      float: left;
      width: siteWidth - (sidebarWidth+gutterWidth);
    }
    .sidebar {
      float: left;
      margin-left: gutterWidth;
      width: sidebarWidth;
    }
    
    Compiled CSS
    body {
      margin: 0 auto;
      width: 1024px;
    }
    .content {
      float: left;
      width: 704px;
    }
    .sidebar {
      float: left;
      margin-left: 20px;
      width: 300px;
    }
    
    Notable Quirks

    There are quite a few quirks to using a CSS preprocessor. I’m going to go over a few of the fun ones, but if you’re really interested in finding them all I recommend you scour the documentation or, better yet, just start using a preprocessor in your daily coding.

    Error Reporting

    If you’ve written CSS for any decent amount of time, I am sure you have reached a point where you had an error somewhere and simply could not find it. If you’re anything like me you probably spent the afternoon pulling your hair out and commenting out various things to hunt the error down.

    CSS preprocessors report errors. It’s just that simple. If there’s something wrong with your code it tells you where, and if you’re lucky: why. You can check out this blog post if you’re interested in seeing how errors are reported in the different preprocessors.

    Comments

    When compiling with a CSS preprocessor, any double-slash comment gets removed (e.g. //comment) and any slash-asterisk comment stays (e.g. /* comment */). That being said, use double-slash for comments you want on the non-compiled side and slash-asterisk for comments you want visible after the compilation.

    Just a note: if you compile minified, all comments are removed.

    Conclusion

    Each CSS preprocessor we covered (Sass, LESS, and Stylus) has its own unique way of accomplishing the same task— giving developers the ability to use useful, unsupported features while keeping browser compatibility and code cleanliness.

    While not a requirement for development, preprocessors can save a lot of time and have some very useful features.

    I encourage you all to try as many of the preprocessors as possible so that you can effectively choose a favorite and know why it is favored over the numerous others. If you haven’t yet tried using a preprocessor to write your CSS, I highly recommend you give it a try.

    Do you have a favorite CSS preprocessor feature I didn’t mention? Is there something one can do that another cannot? Let us know in the comments below!

    A special thanks to Karissa Smith, a super-talented friend of mine that created the preview thumbnail for this article.


Planet PHP

  • Permalink for 'Handling Plugins In PHP'

    Handling Plugins In PHP

    Posted: March 9th, 2012, 8:00am MST by Anthony Ferrara
    Handling Plugins In PHP
  • Permalink for 'Handling Plugins In PHP'

    Handling Plugins In PHP

    Posted: March 9th, 2012, 8:00am MST by Anthony Ferrara
    A common problem that developers face when building applications is how to allow the application to be "plug-able" at runtime.  Meaning, to allow non-core code to modify the way an application is processed at runtime.  There are a lot of different ways that this can be done, and lots of examples of it in real life.  Over a year ago, I wrote a StackOverflow Answer on this topic.  However, I think it deserves another look.  So let's look at some patterns and common implementations.
    Read more »

Nettuts+

  • Permalink for 'Build a Contacts Manager Using Backbone.js: Part 2'

    Build a Contacts Manager Using Backbone.js: Part 2

    Posted: March 8th, 2012, 10:00am MST by Dan Wellman

    Welcome back to part two of this tutorial; in part one we looked at some of the model, collection and view basics for when working with Backbone and saw how to render individual contact views using a master view bound to a collection.

    In this part of the tutorial, we’re going to look at how we can filter our view based on user input, and how we can add a router to give our basic application some URL functionality.
    We’ll need the source files from part one as we’ll be building on the existing code for this part. I’d strongly recommend reading part one if you haven’t already.

    Reacting to User Input

    You may have noticed in part one that each of our individual models has an attributed called type which categorises each model based on whether it relates to a friend, family member of colleague. Let’s add a select element to our master view that will let the user filter the contacts based on these types.

    Now, we can hardcode a select menu into our underlying HTML and manually add options for each of the different types. But, this wouldn’t be very forward thinking; what if we add a new type later on, or delete all of the contacts of a certain type? Our application doesn’t yet have the capability to add or remove contacts (part three spoiler alert!), but it’s still best to take these kinds of things into consideration, even at this early stage of our application.

    As such, we can easily build a select element dynamically based on the existing types. We will add a tiny bit of HTML to the underlying page first; add the following new elements to the contacts container:

    <header>
        <div id="filter"><label>Show me:</label></div>
    </header>

    That’s it, we’ve an outer <header> element to act as a general container, within which is another container with an id attribute, and a <label> with some explanatory text.

    Now let’s build the <select> element. First we’ll add two new methods to our DirectoryView mater view; the first one will extract each unique type and the second will actually build the drop-down. Both methods should be added to the end of the view:

    getTypes: function () {
        return _.uniq(this.collection.pluck("type"), false, function (type) {
            return type.toLowerCase();
        });
    },
    
    createSelect: function () {
        var filter = this.el.find("#filter"),
            select = $("<select/>", {
                html: "<option>All</option>"
            });
    
        _.each(this.getTypes(), function (item) {
            var option = $("<option/>", {
                value: item.toLowerCase(),
                text: item.toLowerCase()
            }).appendTo(select);
        });
        return select;
    }

    The first of our methods, getTypes() returns an array created using Underscore’s uniq() method. This method accepts an array as an argument and returns a new array containing only unique items. The array we pass into the uniq() method is generated using Backbone’s pluck() method, which is a simple way to pull all values of a single attribute out of a collection of models. The attribute we are interested in here is the type attribute.

    In order to prevent case issues later on, we should also normalise the types to lowercase. We can use an iterator function, supplied as the third argument to uniq(), to transform each value before it is put through the comparator. The function receives the current item as an argument so we just return the item in lowercase format. The second argument passed to uniq(), which we set to false here, is a flag used to indicate whether the array that is being compared has been sorted.

    The second method, createSelect() is slightly larger, but not much more complex. Its only purpose is to create and return a new <select> element, so we can call this method from somewhere else in our code and receive a shiny new drop-down box with an option for each of our types. We start by giving the new <select element a default <option> with the text All.

    We then use Underscore’s each() method to iterate over each value in the array returned by our getTypes() method. For each item in the array we create a new <option> element, set its text to the value of the current item (in lowercase) and then append it to the <select>.

    To actually render the <select> element to the page, we can add some code to our master view’s initialize() method:

    this.$el.find("#filter").append(this.createSelect());

    The container for our master view is cached in the $el property that Backbone automatically adds to our view class, so we use this to find the filter container and append the <select element to it.

    If we run the page now, we should see our new <select> element, with an option for each of the different types of contact:

    Filtering the View

    So now we have our <select menu, we can add the functionality to filter the view when an option is selected. To do this, we can make use of the master view’s events attribute to add a UI event handler. Add the following code directly after our renderSelect() method:

    events: {
        "change #filter select": "setFilter"
    },

    The events attribute accepts an object of key:value pairs where each key specifies the type of event and a selector to bind the event handler to. In this case we are interested in the change event that will be fired by the <select element within the #filter container. Each value in the object is the event handler which should be bound; in this case we specify setFilter as the handler.

    Next we can add the new handler:

    setFilter: function (e) {
        this.filterType = e.currentTarget.value;
        this.trigger("change:filterType");
    },

    All we need to do in the setFilter() function is set a property on the master view called filterType, which we set to the value of the option that was selected, which is available via the currentTarget property of the event object that is automatically passed to our handler.

    Once the property has been added or updated we can also trigger a custom change event for it using the property name as a namespace. We’ll look at how we can use this custom event in just a moment, but before we do, we can add the function that will actually perform the filter; after the setFilter() method add the following code:

    filterByType: function () {
        if (this.filterType === "all") {
            this.collection.reset(contacts);
        } else {
            this.collection.reset(contacts, { silent: true });
    
            var filterType = this.filterType,
                filtered = _.filter(this.collection.models, function (item) {
                return item.get("type").toLowerCase() === filterType;
            });
    
            this.collection.reset(filtered);
        }
    }

    We first check whether the master view’s filterType property is set to all; if it is, we simply repopulate the collection with the complete set of models, the data for which is stored locally on our contacts array.

    If the property does not equal all, we still reset the collection to get all the contacts back in the collection, which is required in order to switch between the different types of contact, but this time we set the silent option to true (you’ll see why this is necessary in a moment) so that the reset event is not fired.

    We then store a local version of the view’s filterType property so that we can reference it within a callback function. We use Underscore’s filter() method to filter the collection of models. The filter() method accepts the array to filter and a callback function to execute for each item in the array being filtered. The callback function is passed the current item as an argument.

    The callback function will return true for each item that has a type attribute equal to the value that we just stored in the variable. The types are converted to lowercase again, for the same reason as before. Any items that the callback function returns false for are removed from the array.

    Once the array has been filtered, we call the reset() method once more, passing in the filtered array. Now we’re ready to add the code that will wire up the setType() method, the filterType property and filterByType() method.

    Binding Events to the Collection

    As well as binding UI events to our interface using the events attribute, we can also bind event handlers to collections. In our setFilter() method we fired a custom event, we now need to add the code that will bind the filterByType() method to this event; add the following code to the initialize() method of our master view:

    this.on("change:filterType", this.filterByType, this);

    We use Backbone’s on() method in order to listen for our custom event. We specify the filterByType() method as the handler function for this event using the second argument of on(), and can also set the context for the callback function by setting this as the third argument. The this object here refers to our master view.

    In our filterByType function, we reset the collection in order to repopulate it with either all of the models, or the filtered models. We can also bind to the reset event in order to repopulate the collection with model instances. We can specify a handler function for this event as well, and the great thing is, we’ve already got the function. Add the following line of code directly after the change event binding:

    this.collection.on("reset", this.render, this);

    In this case we’re listening for the reset event and the function we wish to invoke is the collection’s render() method. We also specify that the callback should use this (as in the instance of the master view) as its context when it is executed. If we don’t supply this as the third argument, we will not be able to access the collection inside the render() method when it handles the reset event.

    At this point, we should now find that we can use the select box to display subsets of our contacts. The reason why we set the silent option to true in our filterByType() method is so that the view is not re-rendered unnecessarily when we reset the collection at the start of the second branch of the conditional. We need to do this so that we can filter by one type, and then filter by another type without losing any models.

    Routing

    So, what we’ve got so far is alright, we can filter our models using the select box. But wouldn’t it be awesome if we could filter the collection using a URL as well? Backbone’s router module gives us this ability, let’s see how, and because of the nicely decoupled way that we’ve structured our filtering so far, it’s actually really easy to add this functionality. First we need to extend the Router module; add the following code after the master view:

    var ContactsRouter = Backbone.Router.extend({
        routes: {
            "filter/:type": "urlFilter"
        },
    
        urlFilter: function (type) {
            directory.filterType = type;
            directory.trigger("change:filterType");
        }
    });

    The first property we define in the object passed to the Router’s extend() method is routes, which should be an object literal where each key is a URL to match and each value is a callback function when the URL is matched. In this case we are looking for URLs that start with #filter and end with anything else. The part of the URL after the filter/ part is passed to the function we specify as the callback function.

    Within this function we set or update the filterType property of the master view and then trigger our custom change event once again. This is all we need to do in order to add filtering functionality using the URL. We still need to create an instance of our router however, which we can do by adding the following line of code directly after the DirectoryView instantiation:

    var contactsRouter = new ContactsRouter();

    We should now be able to enter a URL such as #filter/family and the view will re-render itself to show just the contacts with the type family:

    So that’s pretty cool right? But there’s still one part missing – how will users know to use our nice URLs? We need to update the function that handles UI events on the <select element so that the URL is updated when the select box is used.

    To do this requires two steps; first of all we should enable Backbone’s history support by starting the history service after our app is initialised; add the following line of code right at the end of our script file (directly after we initialise our router):

    Backbone.history.start();

    From this point onwards, Backbone will monitor the URL for hash changes. Now, when we want to update the URL after something happens, we just call the navigate() method of our router. Change the filterByType() method so that it appears like this:

    filterByType: function () {
        if (this.filterType === "all") {
            this.collection.reset(contacts);
    
            <b>contactsRouter.navigate("filter/all");</b>
    
        } else {
            this.collection.reset(contacts, { silent: true });
    
            var filterType = this.filterType,
                filtered = _.filter(this.collection.models, function (item) {
                    return item.get("type") === filterType;
            });
    
            this.collection.reset(filtered);
    
            <b>contactsRouter.navigate("filter/" + filterType);</b>
        }
    }

    Now when the select box is used to filter the collection, the URL will be updated and the user can then bookmark or share the URL, and the back and forward buttons of the browser will navigate between states. Since version 0.5 Backbone has also supported the pushState API, however, in order for this to work correctly the server must be able to render the pages that are requested, which we have not configured for this example, hence using the standard history module.

    Summary

    In this part of the tutorial, we looked at a couple more Backbone modules, specifically the Router, History and Events modules. We’ve now looked at all of the different modules that come with Backbone.

    We also looked at some more Underscore methods, including filter(), which we used to filter down our collection to only those models containing a specific type.

    Lastly, we looked at Backbone’s Router module, which allowed us to set routes that can be matched by our application in order to trigger methods, and the History module which we can use to remember state and keep the URL updated with hash fragments.

    One point to take away is the loosely coupled nature of our filtering functionality; when we added filtering via the select menu, it was done in such a way that it was very quick and easy to come along afterwards and add a completely new method of filtering without having to change our filter() method. This is one of the keys to successfully building non-trivial, maintainable and scalable JavaScript applications. If we wanted, it would be very easy to add another, completely new method of filtering, which having to change our filtering method.

    In the next part of this series, we’ll go back to working with models and see how we can remove models from, and add new ones to the collection.


  • Permalink for 'Decoding HTML5: My New Book'

    Decoding HTML5: My New Book

    Posted: March 8th, 2012, 8:54am MST by Jeffrey Way

    Hey guys! I have a few fun things to announce. After months of work, my new book, Decoding HTML5, is finally available. Even better, though, I’ve managed to work out a special arrangement with Rockable Press to offer much, much more.

    The Book - $19 Decoding HTML5

    Toying with new JavaScript APIs is like Christmas for me!

    Toying with new JavaScript APIs is like Christmas for me! So when I set out to write this book, I had one goal in mind: decipher that incredibly confusing spec into something that any John Q. designer or developer can understand. It’s what I wish I had in the beginning.

    Have you ever found yourself thinking, “I wish there was somebody who could sit next to me and make me understand this code…because I don’t!” I’ve been in that position countless times.

    Well, if you can relate, I think this book just might do the trick. Rather than using high level jargon that no beginner could possibly understand, I’ve done my best to break these complicated concepts into chunks that everyone can grasp.

    I cover everything from the new semantic elements, to form enhancements, to a variety of the new JavaScript APIs, such as web workers, web storage, and geolocation.

    Now Available: $19 HTML5 Fundamentals

    In addition to the book, I’ve also released my latest Tuts+ Premium course, called “HTML5 Fundamentals.

    HTML5 Fundamentals Screencast Course

    Split into two chunks, this first course – geared specifically for those of you who prefer visual training – will get you up and running with HTML5 in no time. It’s the perfect companion to Decoding HTML5. The follow-up, “Advanced HTML5,” is scheduled for May-June.

    A Special Arrangement

    I’m very excited to announce that I was able to work out a special arrangement with Rockable Press.

    Beginning today, Decoding HTML5 has already been added to the Tuts+ Premium library.

    For those unfamiliar, Tuts+ Premium provides top-notch education in the creative fields. You might be familiar with the massively popular (and free) “30 Days To Learn jQuery“? That was part of Tuts+ Premium, and there are countless more courses and ebooks on the site just like it. A monthly membership to the site is $19.

    So what this means is that you have two choices, if you’d like to pick this book up:

    Overall, I really hope you enjoy the book!


Planet PHP

  • Permalink for 'Migrating PHP applications to DB2'

    Migrating PHP applications to DB2

    Posted: March 8th, 2012, 7:51am MST by Daniel Krook
    IBM developerWorks has just published the final part in our series on migrating a PHP application from MySQL to DB2. Learn why to move a PHP application to DB2, how to plan the migration, how to execute it, how to support it, and how to handle potential risks based on the experience of an IBM [...]
  • Permalink for 'CSS: Love Hate'

    CSS: Love Hate

    Posted: March 8th, 2012, 5:46am MST by The odd bit

    The slightly odd title is there for a reason. This post exists for a reason. I’ll explain both…

    I’ve always struggled to remember the order in which hyperlink styles should be defined in a stylesheet. Hyperlink styles? Order? I’m talking about these (in alphabetical order):

    • :active
    • :hover
    • :link
    • :visited

    They should be specified in the right order or things won’t work the way you’d expect them to. Here they are again but this time in the correct order:

    • :link
    • :visited
    • :hover
    • :active

    I could go into details why this is the right order but I won’t -) That’s not the purpose of this post.

    The good news is that there’s a mnemonic to remember the order: LoVe HAte. For those not paying attention: mind the casing of the mnemonic!

    So that’s the title of this post. But why? To keep me from googling each time I forget the order P

  • Permalink for 'An XSS Vulerability In The Making'

    An XSS Vulerability In The Making

    Posted: March 7th, 2012, 5:00am MST by Brandon Savage
    Back in September, Socorro received a security bug relating to the method we were using for processing inputs for the duration of certain reports. The vulnerability included a proof of concept, with an alert box popping up on production when the link was followed. The Vulnerability I was quite surprised at the root cause of [...]
  • Permalink for 'An XSS Vulnerability In The Making'

    An XSS Vulnerability In The Making

    Posted: March 7th, 2012, 5:00am MST by Brandon Savage
    Back in September, Socorro received a security bug relating to the method we were using for processing inputs for the duration of certain reports. The vulnerability included a proof of concept, with an alert box popping up on production when the link was followed. The Vulnerability I was quite surprised at the root cause of [...]
  • Permalink for 'Living in the Prove It Culture'

    Living in the Prove It Culture

    Posted: March 6th, 2012, 9:45pm MST by Brian Moon
    Engineering cultures differ from shop to shop. I have been in the same culture for 13 years so I am not an expert on what all the different types are. Before that I was living in Dilbert world. The culture there was really weird. The ideas were never yours. It was always some need some way off person had. A DBA, a UI "expert" and some product manager would dictate what code you wrote. Creativity was stifled and met with resistance.

    I then moved to the early (1998) days of the web. It was a start up environment. In the beginning there were just two of us writing code. So, we thought everything we did was awesome. Then we added some more guys. Lucky for us we mostly hired well. The good hires where type A personalities that had skills we didn't have. They challenged us and we challenged them. On top of that, we had a CEO who had been a computer hacker in his teens. So, he had just enough knowledge to challenge us as well. Over the years we kept hiring more and more people. We always asked in the interview if the person could take criticism and if they felt comfortable defending their ideas. We decided to always have a white board session. We would ask them questions and have them work it out on a white board or talk it out with us in a group setting. The point of this was not to see if they always knew the answer. The point was to see how they worked in that setting. Looking back, the hires that did not work out also did not excel in that phase of the interview. The ones that have worked out always questioned our methods in the interview. They did not belittle our methods or dismiss them. They just asked questions. They would ask if we had tried this or that. Even if we could quickly explain why our method was right for us, they still questioned it. They challenged us.

    When dealing with people outside the engineering team, we subconsciously applied these same tactics. The philosophy came to be that if you came to us with an idea, you had to throw it up on the proverbial wall. We would then try to knock it down. If it stuck, it was probably a good idea. Some people could handle this and some could not. The ones that could not handle that did not always get their ideas pushed through. It may not mean they were bad ideas. And that is maybe the down side of this culture. But, it has worked pretty well for us.

    We apply this to technology too. My first experience on Linux was with RedHat. The mail agent I cut my teeth on was qmail. I used djbdns. When Daniel Beckham, our now director of operations, came on, he had used sendmail and bind. He immediately challenged qmail. I went through some of the reasons I prefered it. He took more shots. In the end, he agreed that qmail was better than sendmail. However, his first DNS setup for us was bind. It took a few more years of bind hell for him to come around to djbdns.

    When RedHat splintered into RedHat Enterprise and Fedora, we tried out Fedora on one server. We found it to be horribly unstable. It got the axe. We looked around for other distros. We found a not very well known distro that was known as the ricer distro of the Linux world called Gentoo. We installed it on one server to see what it was all about. I don't remember now whose idea it was. Probably not mine. We eventually found it to be the perfect distro for us. It let us compile our core tools like Apache, PHP and MySQL while at the same time using a package system. We never trusted RPMs for those things on RedHat. Sure, bringing a server online took longer but it was so worth it. Eventually we bought in and it is now the only distro in use here.

    We have done this over and over and over. From the fact that we all use Macs now thanks to Daniel and his willingness to try it out at our CEO's prodding to things like memcached, Gearman, etc. We even keep evaluating the tools we already have. When we decided to write our own proxy we discounted everything we knew and evaluated all the options. In the end, Apache was known and good at handling web requests and PHP could do all we needed in a timely, sane manner. But, we looked at and tested everything we could think of. Apache/PHP had to prove itself again.

    Now, you might think that a culture of skepticism like this would lead to new employees having a hard time getting any traction. Quite the opposite. Because we hire people that fit the culture, they can have a near immediate impact. We have a problem I want solved and a developer that has been here less than a year suggested that Hadoop may be a solution, but was not sure we would use it. I recently sent this in an email to the whole team in response to that.
    The only thing that is *never* on the table is using a Windows server. If you can get me unique visitors for an arbitrary date range in milliseconds and it require Hadoop, go for it.
    You see, we don't currently use Hadoop here. But, if that is what it takes to solve my problem a

    Truncated by Planet PHP, read more at the original (another 4959 bytes)

  • Permalink for 'connecting to flickr using PHP and PECL oAuth extension'

    connecting to flickr using PHP and PECL oAuth extension

    Posted: March 6th, 2012, 9:22pm MST by Hasin Hayder

Nettuts+

Planet PHP

  • Permalink for 'PECL/mysqlnd_ms:  MySQL 5.6.4-m8+ global transaction identifier feature supported'

    PECL/mysqlnd_ms: MySQL 5.6.4-m8+ global transaction identifier feature supported

    Posted: March 6th, 2012, 6:05am MST by Internet Super Hero
    MySQL Replication is sometimes critizied for being asynchronous and having slaves that lag behind. True! However, sometimes slaves can be used safely and reliably for read-your-writes. Its easy for PHP MySQL users. All the magic is in the driver. As of yesterday, the development version of PECL/mysqlnd_ms 1.3.0-alpha supports not ...
  • Permalink for 'Scalar type hinting is harder than you think'

    Scalar type hinting is harder than you think

    Posted: March 6th, 2012, 1:00am MST by Nikita Popov

    One of the features originally planned for PHP 5.4 was scalar type hinting. But as you know, they weren’t included in the release.

    Recently the topic has come up again on the mailing list and there has been a hell lot of discussion about it. Yesterday ircmaxell published a blog post about his particular proposals.

    The reactions on reddit were mixed. On one hand it is clear that people do really want scalar type hints, on the other hand they didn’t seem to like that particular proposal.

    One comment particularly caught my interest:

    Why can’t the PHP dev’s just get this thing right? Why must they always choose the worst, more useless, most convoluted way to implement every new feature! It’s disheartening. Especially when there aren’t good backwards-compatibility reasons for doing it wrong.

    In a way, this is a pretty important comment: It shows what people think about how PHP is being developed. They think that it’s a bunch of people that somehow, magically, manage to always do the wrong decisions.

    That’s not how it works. Really. You see, most people, when confronted with scalar type hinting, think “Hey, this is so simple, just do XYZ”, and then wonder why PHP is having such a hard time implementing this most trivial of all features.

    The thing is: It’s just not that simple. Most proposals seem so easy and straightforward on first sight, but when it comes to the details they are not.

    In the following I want to introduce you to some of the various proposals that were made in the past and the problems associated with them. I hope this way people will get a little bit more insight into why this is so hard.

    Strict type hinting

    I’ll start with the proposal that I personally dislike most: Strict type hinting, i.e. allowing only the hinted type to be passed and not any of the types that PHP would normally consider equivalent. See this example:

    <?php
    function foo(int $i) { /* ... */ }
    
    foo(1);   // works
    foo(1.0); // fatal error: int expected, float given
    foo("1"); // fatal error: int expected, string given
    

    I think it is evident that this is not an option. One of PHP’s greatest strengths is being a weakly typed language and this proposal would turn it into a strictly typed one. This goes against the PHP philosophy and also differs from how pretty much everything else works in PHP.

    Unenforced type hinting

    Another proposal that was made, is type hinting that isn’t enforced by the engine. WTF? What would this be good for? Basically, it would work just like doc comments (which aren’t enforced either ^^), but with nicer syntax.

    <?php
    function foo(int $i) { /* ... */ }
    
    foo(1);          // works
    foo(1.0);        // works
    foo("1");        // works
    foo(array(123);  // works
    foo($iAmObject); // works
    // everything works...
    

    I dislike this proposal, too, for

    Truncated by Planet PHP, read more at the original (another 14578 bytes)

  • Permalink for 'How To Find The Right Job'

    How To Find The Right Job

    Posted: March 5th, 2012, 3:14pm MST by Brandon Savage
    In my career as a software developer I’ve been lucky. I’ve been lucky that finding work has never been terribly difficult. The longest I’ve ever been out of work is a month and a half. Six weeks might seem like a long time, especially in software; in my case I was unfortunate enough to experience [...]
  • Permalink for 'How To Find The Right Job'

    How To Find The Right Job

    Posted: March 5th, 2012, 3:14pm MST by Brandon Savage
    In my career as a software developer I’ve been lucky. I’ve been lucky that finding work has never been terribly difficult. The longest I’ve ever been out of work is a month and a half. Six weeks might seem like a long time, especially in software; in my case I was unfortunate enough to experience [...]
  • Permalink for 'Build PHP 5.4 on CentOS 6.2'

    Build PHP 5.4 on CentOS 6.2

    Posted: March 5th, 2012, 12:30pm MST by Ben Ramsey

    In case you haven’t heard the news, the PHP project released version 5.4.0 last Thursday. Naturally, I decided it was time to install and give it a try. I chose to install to a clean and bare-bones CentOS 6.2 virtual machine using VirtualBox. I did this for two reasons: 1) I wanted a clean environment for the build, and 2) I wanted to play with CentOS. At the time of this writing, there are not yet any official CentOS RPMs for PHP 5.4, so I had to build PHP from source. What follows are the notes I took during the installation and build process. I hope you find them helpful.

    Set up a CentOS virtual machine

    First of all, go grab the CentOS 6.2 netinstall ISO. Depending on the mirror, it will likely be located somewhere like centos/6.2/isos/x86_64/CentOS-6.2-x86_64-netinstall.iso (note that I’m using the 64-bit version). Following that, create a new basic VirtualBox VM (512 MB RAM, 8 GB HDD, 12 MB video RAM) for your CentOS installation (use “Red Hat (64 bit)” as the Version) and follow these instructions for a CentOS 6.2 netinstall. I chose the 64-bit version, using the netinstall URL of http://mirror.centos.org/centos/6.2/os/x86_64/.

    Since the VirtualBox video RAM selected is only 12 MB, it won’t boot into the graphical mode shown in the netinstall installation guide. Don’t worry about this. Also, it will make some assumptions (e.g. it won’t install Gnome or KDE), since you aren’t in graphical mode. What you’ll have at the end is a very bare-bones server installation.

    After installation, I like to power down the VM and adjust my settings to set up port forwarding so that I can shell into my VM from my Mac terminal. Feel free to configure things as you like. See the screenshot for an example of forwarding ports in Virtual Box. Once set up, you can boot the VM and then use your favorite local terminal to SSH to the instance:

    1
    
    ssh -p 2222 root@localhost
    

    You’ll probably want to create a user for yourself, so that you’re not using root all the time, but since this is a VM on your local machine, it’s not a huge deal. If this was a box out in the open, I’d recommend locking it down and creating a user with much more restricted permissions.

    Install packages needed for PHP

    Once logged in to the VM, you’ll need to install some basic build stuff, like gcc, etc.

    1
    2
    
    yum install man wget
    yum groupinstall "Development Tools"
    

    Next, update iptables to allow connections to the VM over ports 80 and 8000.

    1
    2
    3
    
    sed -i '/22/ i -A INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT' /etc/sysconfig/iptables
    sed -i '/22/ i -A INPUT -m state --state NEW -m tcp -p tcp --dport 8000 -j ACCEPT' /etc/sysconfig/iptables
    /etc/init.d/iptables restart
    

    For the PHP configuration that I’m using, install the following packages. There will be a bunch of dependencies it will ask you to install. Just say yes to them all.

    1
    2
    3
    4
    5
    

    Truncated by Planet PHP, read more at the original (another 13513 bytes)

  • Permalink for 'Hacking Rails (and GitHub)'

    Hacking Rails (and GitHub)

    Posted: March 5th, 2012, 9:26am MST by Chris Shiflett

    Hacker News exploded yesterday with news of GitHub being hacked. Wanting to know what all the fuss was about, I began with GitHub's side of the story:

    A GitHub user exploited a security vulnerability in the public key update form in order to add his public key to the rails organization. He was then able to push a new file to the project as a demonstration of this vulnerability.

    As soon as we detected the attack we expunged the unauthorized key and suspended the user.

    My confidence in the clarity of GitHub's side of the story dissipated when I read one of the comments:

    You didn't really "detect" anything. You were informed. It also wasn't an attack.

    Not only did the "attacker" not do any actual damage, but he was continually ignored.

    The author of this comment, Chris Acky, also made a more comprehensive blog post about the incident.

    The "attacker" in question is Egor Homakov (his account has been reinstated), and he did in fact disclose the vulnerability a few days before he demonstrated it. There are a few facts worth noting up front:

    • This was not a public key security vulnerability as the title of GitHub's post suggests.
    • Egor is not a native English speaker, which might have made the potential impact of his discovery difficult to appreciate.
    • He was not actually ignored, but he was pretty firmly dismissed (citing a prior discussion).

    Telling someone they're wrong only fuels their desire to prove they're right. It's not a huge surprise that Egor's next step was to demonstrate the vulnerability.

    I'd like to explain the vulnerability, but rather than show you any code, I want you to understand the nuts and bolts, because it's extraordinarily simple. If you have a GitHub account, you can manage your SSH keys. The form to add a new key looks something like this (edited for clarity):

    <form method="post" action="/account/public_keys">
      <input type="hidden" value="412e11d5317627e48a4b0615c84b9a8f" name="authenticity_token" />
      <dl>
        <dt>Title</dt>
        <dd><input type="text" name="public_key[title]" /></dd>
        <dt>Key</dt>
        <dd><textarea name="public_key[key]" /></dd>
      </dl>
      <input type="submit">Add key</input>
    </form>
    

    The authenticity_token is almost certainly an anti-CSRF token, so it doesn't complicate this exploit at all.

    All Egor did was modify his own form to add the following:

    <input type="hidden" name="public_key[user_id]" value="4223" />
    

    The user_id of the Rails project is 4223, so that's why he chose it. (He believes this is a Rails issue, and it's hard to argue that.) By sending along this user_id, his public key was added to another account. Yikes!

    For those of you more familiar with PHP, imagine a feature like register_globals, but instead of injecting arbitrary form data into the global namespace, it injects arbitrary form data into the database. It might as well be called opt-in SQL injection, but even that's being too generous, because this is much easier to exploit than an SQL injection vulnerability.

    Egor points out that this vulnerability is unique to Rails:

    Only Rails app have this kind of bug.

    Wanting to better understand why Rails refuses to fix this, I looked into mass assignment, the feature in question, and found a post from last year:

    If you're using Rails and you want to be secure, you shou

    Truncated by Planet PHP, read more at the original (another 3027 bytes)

Nettuts+

  • Permalink for 'PHP 5.4 is Here! What You Must Know'

    PHP 5.4 is Here! What You Must Know

    Posted: March 5th, 2012, 9:05am MST by Dejan Marjanovic

    PHP 5.4 is here; the next major step forward since version 5.3 – keeping PHP 6 (full Unicode support) on hold for now. The latest enhancements significantly improve its elegance, while removing deprecated functionality, resulting in a dramatic optimization of the runtime (up to 20% more speed and memory usage reduction).

    brace yourself New Features and Improvements

    Some of the key new features include traits, a shortened array syntax, a built-in webserver for testing purposes, use of $this in closures, class member access on instantiation, <?= is always available, and more!

    PHP 5.4.0 significantly improves performance, memory footprint and fixes over 100 bugs. Notable deprecated/removed features include register_globals, magic_quotes (about time) and safe_mode. Also worth mentioning is the fact that multibyte support is enabled by default and default_charset has been changed from ISO-8859-1 to UTF-8.

    Content-Type: text/html; charset=utf-8 is always sent; so there’s no need to set that HTML meta tag, or send additional headers for UTF-8 compatibility.

    Traits

    The best demonstration of traits is when multiple classes share the same functionality.

    Traits (horizontal reuse/multiple inheritance) are a set of methods, which are structurally similar to a class (but can’t be instantiated), that can enable developers to reuse sets of methods freely in several independent classes. Because PHP is a single inheritance language, a subclass can inherit from only one superclass; that’s where traits come to play.

    The best use of traits is demonstrated when multiple classes share the same functionality. For instance, imagine that we are building some website, and need to use both the Facebook and Twitter APIs. We build two classes which, in common, have a cURL wrapper function/method. Instead of performing the classic copy & paste of that method – to be used in two classes – we use Traits (copy & paste, compiler style). This way, we make reusable code, and follow the DRY (Don’t Repeat Yourself) principle.

    Here’s an example:

    /** cURL wrapper trait */
    trait cURL
    {
        public function curl($url)
        {
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, $url);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
            $output = curl_exec($ch);
            curl_close($ch);
            return $output;
        }
    }
    
    /** Twitter API Class */
    class Twitter_API
    {
        use cURL; // use trait here
        public function get($url)
        {
            return json_decode($this->curl('http://api.twitter.com/'.$url));
        }
    }
    
    /** Facebook API Class */
    class Facebook_API
    {
        use cURL; // and here
        public function get($url)
        {
            return json_decode($this->curl('http://graph.facebook.com/'.$url));
        }
    }
    
    $facebook = new Facebook_API();
    echo $facebook->get('500058753')->name; // Rasmus Lerdorf
    
    /** Now demonstrating the awesomeness of PHP 5.4 syntax */
    echo (new Facebook_API)->get('500058753')->name; // Rasmus Lerdorf
    $foo = 'get';
    echo (new Facebook_API)->$foo('500058753')->name; // and again, Rasmus Lerdorf
    echo (new Twitter_API)->get('1/users/show.json?screen_name=rasmus')->name; // and yet again, Rasmus Lerdorf
    // P.S. I'm not obsessed with Rasmus :)
    

    Got it? No? Here is the simplest example!

    trait Net
    {
        public function net()
        {
            return 'Net';
        }
    }
    
    trait Tuts
    {
        public function tuts()
        {
            return 'Tuts';
        }
    }
    
    class NetTuts
    {
        use Net, Tuts;
        public function plus()
        {
            return '+';
        }
    }
    
    $o = new NetTuts;
    echo $o->net(), $o->tuts(), $o->plus();
    echo (new NetTuts)->net(), (new NetTuts)->tuts(), (new NetTuts)->plus();
    

    If you have any question about traits, please post a note in the comments section below.

    Important Tip: The magic constant for traits is __TRAIT__.

    Built-in CLI Web-Server

    In web development, PHP’s best friend is Apache [HTTPD] Server. Sometimes, though, it can be overkill to set up [httpd.conf] just to use it within a development environment, when you really need tiny web server that can be launched with a simple command line. Thankfully, PHP 5,4 comes with a built-in CLI web server.

    The PHP CLI web server is designed for developmental purposes only, and should not be used in production.

    Note: The instructions below are for a Windows environment.

    Step 1 – Create Document Root Directory, Router File and Index File

    Go to your hard drive root (assuming C:\). Create a directory/folder, called public_html. Create a new file within this folder, and name it router.php. Copy the contents below, and paste it into this newly created file.

    <?php
    // router.php
    if (preg_match('#\.php$#', $_SERVER['REQUEST_URI']))
    {
        require basename($_SERVER['REQUEST_URI']); // serve php file
    }
    else if (strpos($_SERVER['REQUEST_URI'], '.') !== false)
    {
        return false; // serve file as-is
    }
    ?>
    

    Now, create another file, called index.php. Copy the contents below and save the file.

    <?php
    // index.php
    echo 'Hello Nettuts+ Readers!';
    ?>
    

    Open your php.ini file (it is located in the PHP install directory – e.g. C:\php).

    Find the include_path settings (it is located at ~708th line). Add C:\public_html to the end of the string between quotes, separate by a semicolon. The final result should look like:

    include_path = ".;C:\php\PEAR;C:\public_html"
    

    Save and close the file. On to next step.

    Step 2 – Run Web-Server

    Open the command prompt (Windows + R, type in cmd, hit Enter); you should see something like this, depending on your Windows version.

    Microsoft Windows XP [Version 5.1.2600]
    (C) Copyright 1985-2001 Microsoft Corp.
    C:\Documents and Settings\nettuts>
    

    Change your current directory to the PHP installation by following the example below:

    C:\Documents and Settings\nettuts>cd C:\php
    C:\php>
    

    Here comes the most important part – running the web-server. Copy…

    php -S 0.0.0.0:8080 -t C:\public_html router.php
    

    … and paste it in the command prompt (right mouse button, click Paste to paste). Hit Enter. If all goes well, you should see something similar to what’s shown below. Do not close the command prompt; if you do, you will exit the web-server as well.

    C:\php>php -S 0.0.0.0:8080 -t C:\public_html router.php
    PHP 5.4.0 Development Server started at Fri Mar 02 09:36:40 2012
    Listening on 0.0.0.0:8080
    Document root is C:\public_html
    Press Ctrl-C to quit.
    

    Open up http://localhost:8080/index.php in your browser and you should see:

    Hello Nettuts+ Readers!
    

    Voila! That’s it, happy coding!

    Tip 1: Make a php-server.bat file with the following contents: C:\php\php -S 0.0.0.0:8080 -t C:\public_html router.php. Double click it, and, now, the server is up and running!

    Tip 2: Use 0.0.0.0 instead of localhost if you anticipate that your server will be accessed from the internet.

    Shorter Array Syntax

    PHP 5.4 offers a new shorter array syntax:

    $fruits = array('apples', 'oranges', 'bananas'); // "old" way
    
    // The same as Javascript's literal array notation
    $fruits = ['apples', 'oranges', 'bananas'];
    
    // associative array
    $array = [
        'foo' => 'bar',
        'bar' => 'foo'
    ];
    

    Please note that “old” method is still in use and always will be. This is simply an alternative.

    Array Dereferencing

    No more temporary variables when dealing with arrays!

    Let’s imagine that we want to retrieve the middle name of Alan Mathison Turing:

    echo explode(' ', 'Alan Mathison Turing')[1]; // Mathison
    

    Sweet; but it wasn’t always this easy. Before 5.4, we had to do:

    $tmp = explode(' ', 'Alan Mathison Turing');
    echo $tmp[1]; // Mathison
    

    Now, what if we want to get the last name (last element in array):

    echo end(explode(' ', 'Alan Mathison Turing')); // Turing
    

    This works fine, however, it will throw a E_STRICT (Strict Standards: Only variables should be passed by reference) error, since it became part of E_ALL in error_reporting.

    Here’s a slightly more advanced example:

    function foobar()
    {
        return ['foo' => ['bar' => 'Hello']];
    }
    echo foobar()['foo']['bar']; // Hello
    
    $this In Anonymous Functions
    this is anonymous functions

    You can now refer to the object instance from anonymous functions (also known as closures) by using $this.

    class Foo
    {
        function hello() {
            echo 'Hello Nettuts!';
        }
    
        function anonymous()
        {
            return function() {
                $this->hello(); // $this wasn't possible before
            };
        }
    }
    
    class Bar
    {
        function __construct(Foo $o) // object of class Foo typehint
        {
            $x = $o->anonymous(); // get Foo::hello()
            $x(); // execute Foo::hello()
        }
    }
    new Bar(new Foo); // Hello Nettuts!
    

    Note that this could be achieved prior to 5.4, but it was overkill.

        function anonymous()
        {
            $that = $this; // $that is now $this
            return function() use ($that) {
                $that->hello();
            };
        }
    
    <?= is Always On

    Regardless of the php.ini setting, short_open_tag, <?= (open PHP tag and echo) will always be available. This means that you can now safely use:

    <?=$title?>
    

    …in your templates instead of…

    <?php echo $title ?>
    
    Binary Number Representation
    binary php

    There are only 0b10 kinds of people;
    those who understand binary and those who don’t.

    From now on, integers can be specified in decimal (base 10), hexadecimal (base 16), octal (base 8) or binary (base 2) notation, optionally preceded by a sign (- or +). To use octal notation, precede the number with a 0 (zero). To use hexadecimal notation, precede the number with 0x. To use binary notation, precede the number with 0b.

    Example: representation of number 31 (decimal).

    echo 0b11111; // binary, introduced in PHP 5.4
    echo 31; // duh
    echo 0x1f; // hexadecimal
    echo 037; // octal
    
    Callable Typehint
    wuts dat

    Typehinting is for those who desire to make PHP a stronger typed language. Type Hints can only be of the object and array type since PHP 5.1, and callable since PHP 5.4. Traditional type hinting with int and string isn’t yet supported.

    function my_function(callable $x)
    {
        return $x();
    }
    
    function my_callback_function(){return 'Hello Nettuts!';}
    
    class Hello{static function hi(){return 'Hello Nettuts!';}}
    class Hi{function hello(){return 'Hello Nettuts!';}}
    
    echo my_function(function(){return 'Hello Nettuts!';}); // anonymous function
    echo my_function('my_callback_function'); // callback function
    echo my_function(['Hello', 'hi']); // class name, static method
    echo my_function([(new Hi), 'hello']); // class object, method name
    
    Initialized High Precision Timer

    $_SERVER['REQUEST_TIME_FLOAT'] has been added, with microsecond precision (float). This is useful when you need to calculate the execution time for a script.

    echo 'Executed in ', round(microtime(true) - $_SERVER['REQUEST_TIME_FLOAT'], 2), 's';
    
    __destruct() (or Summary)

    Overall, PHP 5.4 offers numerous improvements. Now, it’s up to you to grab a fresh copy from php.net, and make quality Object-Oriented PHP code!

    What do you think PHP 5.5 will bring us, and what do you expect?


Planet PHP

  • Permalink for 'Parameter Type Casting in PHP'

    Parameter Type Casting in PHP

    Posted: March 5th, 2012, 8:30am MST by Anthony Ferrara
    As any of you who follow the PHP internals list know, scalar type hinting has been a hot topic as of late.  You'll also know that I've submitted two new RFC (Request For Comment) proposals for inclusion of two new major features in the PHP language.  I figured it was worth going into both RFCs and patches a little deeper, explain my rationale and (hopefully) garner some more visibility of the proposals.
    RFC1: Parameter Type Casting Hints
    The RFC can be found
    here.  Basically, this patch and RFC adds support for type-hinting scalar variables in functions and methods.  But to keep PHP's dynamic typing paradigm, the hints are designed to cast whatever is supplied to the requested type.  For example, with the RFC and patch, this becomes valid:
    function foo((int) $int)

    It's worth noting that this is fundamentally different behavior from prior attempts to add scalar hinting to PHP on two fronts.  First off, it is intentionally casting the parameters to the destination type without throwing errors (so it's not strict type hinting).  Secondly, it uses the exact same casting rules that the engine uses for variable casting.  The RFC takes a leap from the prior RFCs on scalar type hinting by trying to not only work with PHP's dynamic typing behavior, but to fully embrace it.

    Example:
    function test1((int) $foo) {
    var_dump($foo);
    }
    function test2((float) $foo = null) {
    var_dump($foo);
    }
    test1(1); // int(1)
    test1("2"); // int(2)
    test1(array()); // int(0)
    test1(1.5); // int(1)

    test2(); // null
    test2(null); // null
    test2(1); // float(1)
    test2(1.5); // float(1.5)
    test2("2.5"); // float(2.5)

    RFC2: Object Scalar Casting Magic Methods
    The RFC can be found here.  In short, the RFC adds a number of new magic methods to classes to allow for finer control over how objects are casted to primitive types.  These magic methods are:
    public function __toInt();
    public function __toFloat();
    public function __toArray();
    public function __toScalar();

    With the new magic methods, explicit casts (using (int) $obj syntax) will now be fully controlled by the class.  The one odd method out is the __toScalar() method.  This is called when the object is used in a scalar context, but without an explicit cast.  So it allows for 1 + $obj to be meaningful...  The return type is up to the class, so it can return the type that best describes how the object should be represented in that context.
    Additionally, the RFC adds support to internal PHP functions to support casting to the destination type.  So that means that an object implementing __toInt() can be passed to an internal function that expects an integer parameter directly.  
    It's worth noting that references are not supported and will cause an error if attempted to be passed into an internal function.  So that means an object implementing __toArray() cannot be directly passed to sort().  This is to prevent really odd side-effects where passing an object to a function changes the type of the variable holding the object.  However, the object can still be manually cast using (array) prior to calling the function...

    Example:
    class Test1 {
    public function __toInt() {
    return 2;
    }
    public function __toFloat() {
    return 3.5;
    }
    public function __toArray() {
    return array(1, 2);
    }
    public function __toScalar() {
    return 5;
    }
    }
    $t1 = new Test1;
    var_dump((int) $t1); // int(2)
    var_dump((float) $t1); // float(3.5)
    var_dump(array_keys($t1)); // array(0, 1)
    var_dump(1 + $t1); // int(6)
    var_dump(round($i)); // float(3)

    Two Sides of the Same Coin
    It should be pretty easy to see the connection between the two RFCs.  They are both very complimentary and are intended to work together.  If both are implemented, it will greatly reduce a lot of boile

    Truncated by Planet PHP, read more at the original (another 4380 bytes)

  • Permalink for '5.4 is out!'

    5.4 is out!

    Posted: March 5th, 2012, 2:49am MST by Stas Malyshev

    Since May 2011 we have worked on releasing PHP 5.4, and now it happened. Thanks everybody who helped with it!

    PHP 5.4 has some new and exciting features – for some of them, like traits, I have no idea right now how they will work out and what people would do with them. It’d be very interesting to see.
    For some of them, I feel they are basic common sense and long overdue in PHP (of course, not everybody may share my opinion ;) – like ['short','array','syntax'] or detaching <?= from INI settings. Some were just missing features that we didn’t catch up with before – more fluent syntax, linking objects to closures, etc.
    Some things in PHP, as we have come to realize, were clearly mistakes – like register_globals, some were driven by real needs but proved to do more harm than good at the end – like magic quotes and “safe” mode – so we had to lay them to rest.

    One of the best things that happened in 5.4 though is not immediately apparent. The engine behind 5.4 is significantly faster and consumes less memory than before. How much faster and how much less? Depends on your application, of course, but from some benchmarks 10-20% speed improvement and 20-30% memory improvement can be expected. Do your own benchmarks and blog about the results! Also would be a good time to ensure your application runs fine on 5.4 – since 5.4 is now the stable version and you have to start using it! )

    Another great things that happened – and is continuing to happen – is that we are finally moving towards more streamlined release process, towards having more regular releases (expect 5.4.1 release cycle to start in late March-early April and 5.4.1 be out in about a month after that) and more organized feature/change proposal process. There’s a wiki where people can post their RFC proposals, we have a voting process and while we may be still working out some fine details of the procedure, I feel we definitely have improved in this regard. It is time to get some organization into the process – we don’t need to create a bureaucracy, but some process is definitely needed and we’re establishing it.

    Yet another thing that is happening – PHP project is slowly but surely moving from SVN to Git. This will be a great improvement. Having used Git for the last couple of years, I can clearly see that it can make many things we’re doing in PHP everyday so much easier. Can’t wait for it ) Also makes easy for people to do pull requests and for core devs to merge them, among other things – should make bug resolutions, etc. work faster.

    And after catching our breaths a bit and relaxing soon there will be time to think what we do in 5.5 – remember the thing about more regular releases? ) I’ll try to post some thoughts about what I’d want in 5.5 soon.


    Tagged: performance, PHP, php54
  • Permalink for 'URL Encoding and Hashbang Hell'

    URL Encoding and Hashbang Hell

    Posted: March 4th, 2012, 11:49am MST by Chris Shiflett

    Thanks to reader Steve Gricci, I have learned that BackTweets no longer exists, presumably because BackType was acquired by Twitter. (Regardless, why let the domain expire?) Until today, I have been using BackTweets for the "tweets" link at the top of each post, so anyone who clicked it recently was greeted by a parked Go Daddy page instead of seeing all tweets related to a particular post. Yikes!

    My quick fix is to use Twitter instead, but their hashbang URLs make it difficult to link directly to anything. Thankfully, if you want to search for tweets that mention something simple like brooklynbeta, you can use an ordinary URL like this:

    [twitter.com]

    No hashbang. It just works. Nice! Maybe this will be easy after all. Let's try a search for a URL:

    [twitter.com]

    Account suspended? That's weird. While this error message isn't very helpful (maybe @search is the account that was suspended), the fault in this case is ours. We're using a query that has special characters, but we didn't bother to URL encode it. Our bad. Let's try that again:

    [twitter.com]

    The page doesn't exist? But, we're doing the right thing now! Okay, fine, maybe we have to use the hashbang URL after all:

    [twitter.com]

    Hooray! Well, almost. If this works for you, I recommend going to your Twitter settings and checking the box to always use [HTTPS.] Once you've done this, you'll be told the page doesn't exist. It seems that Twitter is decoding the query when it redirects. Maybe we can just URL encode it twice to compensate for Twitter's decoding?

    [twitter.com]

    Hooray! But wait, what if we don't check the box to always use [HTTPS?] We won't get redirected, so Twitter won't decode our query. We'll actually be searching for http%3A%2F%2Ftwitter.com%2F instead of http://twitter.com/. What can we do? We can do this:

    [https:]]

    Because Twitter doesn't redirect [HTTPS] to [HTTP,] this avoids the redirect, regardless of the user's settings. Hooray?

    There is a lesson here. URLs are underrated. Making it extremely easy and obvious for users to link to your content should be a priority. Let's try our best to remember this, even when it seems difficult to push the Web forward without abandoning its past.

    Luckily, it sounds like Twitter hashbang URLs will soon be a thing of the past. That's very good news.

  • Permalink for 'Logging best practices'

    Logging best practices

    Posted: March 4th, 2012, 4:38am MST by Mark van der Velden
    Introduction

    This document explains some best practices for application error/debug logging. Application logging is an important "tool" to help identifying problems. If done correctly, and if an infrastructure is in place that allows events to be put into context, it's easier to debug situations and thus makes it easier to solve problems sooner.

    While out of scope for this document, I'd like to point out the following tools that can make that possible:

     

    Different logging meanings

    Logging can mean different things and logging can have different purposes. The logging this document refers to is application and semantic logging.

    Application logging (also called "debug" or "error" logging) is intended to keep track of the "low level" application behaviour. Application logging is used to log events, that allows for debugging a problem within an application or to monitor application health. In contrast, a different form of logging could for example be Google Analytics. Tracking (or "logging" actions of) visitors of a website, this type of logging is very different and not something this document refers too.

    Why do we log

    In order to understand how to log, it must first be clear what we try to accomplish with application logging.


    Continue reading "Logging best practices"
  • Permalink for 'Performance Analysis of isset() vs array_key_exists() '

    Performance Analysis of isset() vs array_key_exists()

    Posted: March 3rd, 2012, 7:23am MST by Ilia Alshanetsky

    At Confoo I had an interesting conversation with Guilherme Blanco regarding the fact that in Doctrine 2 they had a performance issue due to usage of array_key_exists() and how it was significantly slower than isset(). His anecdotal example was that doing isset() took 0.5 seconds, while array_key_exists() for the same operation took 5 seconds!

    That seemed wrong, given that array_key_exists() simply does a hash table look-up, to determine if the array key exists and the only speed difference would be due to the fact that isset() is a language construct and does not have the overhead of function & parameter processing. So, I've decided to do a quick benchmark using a 5,000 element array.

    PHP: <?php $arr = array(); $fp = fopen("/usr/share/dict/words", "r"); while ($i < 5000 && ($w = fgets($fp))) {     $arr[trim($w)] = ++$i; } $s = microtime(1); for ($i = 0; $i < 100000; $i++) {     isset($arr['abracadabra']); } $e = microtime(1); echo "Isset: ".($e - $s)."\n"; $s = microtime(1); for ($i = 0; $i < 100000; $i++) {     array_key_exists('abracadabra', $arr); } $e = microtime(1); echo "array_key_exists: ".($e - $s"/>

    Truncated by Planet PHP, read more at the original (another 1162 bytes)