Paul M. Jones

Don't listen to the crowd, they say "jump."

Solar 1.0.0beta3 Released

Yesterday, I released Solar 1.0.0beta3. You can see the very short change log here. Special thanks to “kalkin” for committing a series of fixes and improvements.

These days I’m concentrating more on documentation. Previously, we had only the ubiquitous quick-start blog demo. This release includes a new chapter on Solar’s dynamic dispatch cycle; i.e., the bootstrap, front controller, page controller, action method, and view. (I’m starting a chapter on the DataMapper-style model system today.)

Incidentally, I’ve been writing the docs in DocBook 5 and building them with xsltproc. You can see the whole build system in the Solar docs repository. I tried using the new PhD build system, but it required more effort and energy than I could spare. PhD is screamingly fast, but it’s not doing everything that xsltproc does just yet, and I barely have enough time to work on my own projects as it is.

(This announcement is cross-posted from the Solar framework blog).


Barney Frank Doesn't Know What To Do

Here’s an idea. Why not let people of who want to borrow money to buy a house convince the people who lend the money that there’s a good chance that the money will get paid back. Creative, no? It’s called voluntary exchange. Or a market. Or normal. Fannie and Freddie were abnormal. We don’t need a “new system.” The old system didn’t work because you, Barney Frank, and others, tried to steer it. Let’s have NO SYSTEM that you figure out and control and steer. Let’s let the housing market emerge that has the built-in feedback loops of profit and loss.

via Frank on Fannie and Freddie.


Mr. Right has left the building....

So our society has created a mess where men are vilified in the classroom, fed PC rhetoric, told their life's goal is to make women happy and do anything that assists her with her goals, while simultaneously told that he is a dope, idiot and unable to care properly for children, and now people are questioning where Mr. Right went?

via Dr. Helen: Mr. Right has left the building.....


Supreme Court Vindicates Political Speech, Pulverizes McCain-Feingold

In a landmark 5-to-4 ruling, the Supreme Court today in Citizens United v. FEC struck down major portions of the McCain-Feingold campaign-finance law. The Court left in place the disclosure requirement for corporations and the disclaimer requirement that identifies whether an ad is not paid for by the campaign. But little else remains. The Court overruled the highly controversial 1990 decision in Austin v. Michigan Chamber of Commerce, which upheld restrictions on corporate spending to support or oppose political candidates.

...

This is a vindication of the First Amendment and a victory for the protection of political speech, which is at the heart of our political system. It will certainly increase the amount of speech. Even the New York Times recognizes this (well, sort of) ...

Thank goodness. McCain-Feingold was horrifying. Via Commentary » Blog Archive » Supreme Court Vindicates Political Speech, Pulverizes McCain-Feingold.


Solar Models vs. Zend Framework Models

Today, Michelangelo van Dam posted this narrative relating his experience with Zend Framework models:

http://www.dragonbe.com/2010/01/zend-framework-data-models.html

I read the article, and wondered how hard it would be to replicate his narrative using the Solar Framework model system. Turns out it's pretty easy: there's a lot of work that Solar does for you.

  1. Download a Solar system, move it to your localhost directory and make sure that the tmp and sqlite directories are accessible to the web server.

    $ wget http://svn.solarphp.com/system/download/solar-system-1.0.0beta2.tgz
    $ tar -zxf solar-system-1.0.0beta2.tgz
    $ cp -r solar/* /var/www/htdocs # or your localhost directory
    $ cd /var/www/htdocs         # or your localhost directory
    $ chmod -R 777 tmp sqlite
    
  2. Create tables and data in sqlite/example.sq3. There are two changes from Michelangelo's code: the table names are plural, and rename the column type_id to address_type_id. (These are easy enough to change in the model class definitions, but I'd like to minimize the amount of customization for this example.)

    CREATE TABLE "users" (
        "id" integer primary key autoincrement,
        "username" varchar(255) not null,
        "password" varchar(255) not null
    );
    
    
    CREATE TABLE "contacts" (
        "id" integer primary key autoincrement,
        "user_id" integer not null,
        "email" varchar(255) not null,
        "phone" varchar(255) null,
        "fax" varchar(255) null
    );
    
    
    CREATE TABLE "addresses" (
        "id" integer primary key autoincrement,
        "address_type_id" integer not null default 1,
        "user_id" integer not null,
        "address1" varchar(255) not null,
        "address2" varchar(255) null,
        "city" varchar(255) not null,
        "state" varchar(255) null,
        "zip" varchar(255) not null,
        "country" varchar(255) not null
    );
    
    
    CREATE TABLE "address_types" (
        "id" integer primary key autoincrement,
        "type" varchar(255) not null
    );
    
    
    -- Data for users table --
    INSERT INTO "users"
        VALUES (1, 'testuser1', 'test123');
    INSERT INTO "users"
        VALUES (2, 'testuser2', 'test234');
    
    
    -- Data for contacts table --
    INSERT INTO "contacts"
        VALUES (1, 1, 'test1@example.com', '1-800-555-1234', '1-800-555-1230');
    INSERT INTO "contacts"
        VALUES (2, 2, 'test2@example.com', '1-800-555-2234', '1-800-555-2230');
    
    
    -- Data for addresses table --
    INSERT INTO "addresses"
        VALUES (1, 1, 1, '1 Test Home', '', 'Testtown', 'ZF', '1234', 'PHP');
    INSERT INTO "addresses"
        VALUES (2, 1, 2, '2 Test Home', '', 'Testtown', 'ZF', '1234', 'PHP');
    INSERT INTO "addresses"
        VALUES (3, 2, 2, 'Test Corp, LTD', '4 Test Ave', 'Testtown', 'ZF', '1234', 'PHP');
    
    
    -- Data for address_types table --
    INSERT INTO "address_types"
        VALUES (1, 'Home address');
    INSERT INTO "address_types"
        VALUES (2, 'Billing address');
    
  3. Make sure the SQLite database is accessible to the web server.

    $ chmod 777 sqlite/example.sq3
    
  4. Make a vendor space for the controllers, models, suppory libraries, etc. For this example the vendor will be named Example.

    $ ./script/solar make-vendor Example
    
  5. Edit the system configuration in config.php. Change the front-controller class prefixes and model catalog class prefixes, and tell the SQLite adapter which file name to use.

    // front controller
    $config['Solar_Controller_Front'] = array(
        'classes' = array('Example_App'),
        // ... the rest of the front-controller array ...
    );
    
    
    // model catalog
    $config['Solar_Sql_Model_Catalog']['classes'] = 'Example_Model';
    
    
    // add sqlite config
    $config['Solar_Sql_Adapter_Sqlite'] = array(
        'name' => "$system/sqlite/example.sq3",
    );
    
  6. Make the model classes. Note that this avoids a ton of effort that Zend Framework requires: Michelangelo had to hand-create table, model, and mapper classes for each of the following single-line commands.

    $ ./script/solar make-model Example_Model_Users
    $ ./script/solar make-model Example_Model_Contacts
    $ ./script/solar make-model Example_Model_Addresses
    $ ./script/solar make-model Example_Model_AddressTypes
    
  7. Edit the model classes to express what the related models are:

    /** source/example/Example/Model/Users.php */
    protected function _setup()
    {
        // chain to parent
        parent::_setup();
    
    
        // relateds
        $this->_hasOne('contact');
        $this->_hasMany('addresses');
    }
    
    
    /** source/example/Example/Model/Contacts.php */
    protected function _setup()
    {
        // chain to parent
        parent::_setup();
    
    
        // relateds
        $this->_belongsTo('user');
    }
    
    
    /** source/example/Example/Model/AddressTypes.php */
    protected function _setup()
    {
        // chain to parent
        parent::_setup();
    
    
        // relateds
        $this->_hasMany('addresses');
    }
    
    
    /** source/example/Example/Model/Addresses.php */
    protected function _setup()
    {
        // chain to parent
        parent::_setup();
    
    
        // relateds
        $this->_belongsTo('address_type');
        $this->_belongsTo('user');
    }
    
    
  8. Make a skeleton app (i.e., a controller with its associated actions and views):

    $ ./script/solar make-app Example_App_Accounts
    
  9. Edit the controller action to fetch user account data:

    /** source/example/Example/App/Accounts.php */
    public $list;
    public function actionIndex()
    {
        // get a model catalog
        $model = Solar_Registry::get('model_catalog');
    
    
        // populate $this->list with all users.
        // eager-fetch the contact record and addresses collection.
        $this->list = $model->users->fetchAll(array(
            'eager' => array(
                'contact',
                'addresses',
            ),
        ));
    }
    
  10. Edit the view for the index action. This could be a view and a partial, but let's keep it straightforward for now.

    /** source/example/Example/App/Accounts/View/index.php */
    <table>
        <tr>
            <th>Username</th>
            <th>E-Mail</th>
            <th>Phone</th>
            <th>Fax</th>
            <th># addresses</th>
        </tr>
    
    
        <?php foreach ($this->list as $user): ?>
    
    
        <tr>
            <td><?php echo $this->escape($user->username); ?></td>
            <td><?php echo $this->escape($user->contact->email); ?></td>
            <td><?php echo $this->escape($user->contact->phone); ?></td>
            <td><?php echo $this->escape($user->contact->fax); ?></td>
            <td><?php echo count($user->addresses); ?></td>
        </tr>
    
    
        <?php endforeach; ?>
    
    
    </table>
    
    

You're done. Browse to http://localhost/index.php/accounts/index to see the results of your handiwork.

Total elapsed time from when I read Michelangelo's article to come up with the Solar conversion and write this article: under two hours.

Solar makes model creation and interaction very easy and very powerful. Maybe your next project should use Solar instead of Zend Framework?


PHP Is Like A Handgun?

PHP is like a handgun. On its own, it is simply an inanimate tool that has no moral leaning. In the hands of a responsible citizen, it can be used to the benefit of society. But in the hands of someone who is untrained or mentally unstable, it can be used to commit horrible atrocities.

Whenever there's such a tragedy, other developers are quick to blame PHP. If PHP were illegal, then Yahoo! would never have happened. If we regulated PHP tightly, then there would be no Digg.

via Microsoft arms half-wit developers with PHP handgun [printer-friendly] • The Register.


Avatar and America

But the more blatant lesson of Avatar is not that American imperialism is bad, but that in fact it’s necessary. Sure there are some bad Americans--the ones with tanks ready to mercilessly kill the Na’vi population, but Jake is set up as the real embodiment of the American spirit. He learns Na’vi fighting tactics better than the Na’vi themselves, he takes the King’s daughter for his own, he becomes the only Na’vi warrior in centuries to tame this wild dragon bird thing. Even in someone else’s society the American is the chosen one. He’s going to come in, lead your army, f**k your princesses, and just generally save the day for you. Got it? This is how we do it.

via In Which We Teach James Cameron A Thing Or Two - Home - This Recording.


Solar Beta 1 and 2, With A Blog Demo

The Solar Framework for PHP went to “beta” status on 18 Dec 2009 with its first beta release. I just now released beta2, along with an official blog demo tutorial.

http://solarphp.com/manual

The blog demo tutorial covers how to:

  • Download and install a new Solar system;
  • Make a vendor-space for working in the system;
  • Configure the system;
  • Make a model from a database table;
  • Make a basic application;
  • Add application actions and views to:
    • Browse all public articles,
    • Read one article,
    • Browse all draft articles,
    • Edit one article,
    • Add a new article,
    • Delete an article;
  • And finally, set locale strings for the application.

The beta release notes are here:

Download the latest system release and try it out!

http://svn.solarphp.com/system/download/solar-system-1.0.0beta2.tgz


Keith Casey on "Joining a Startup"

Keith Casey has a great series of points about joining a startup here, especially the part about founders who "believe in themselves".

To this, I must also add a recommendation to read Gerber's The E-Myth for entrepreneurial-minded programmers thinking about starting a business of their own.


Jihadi Hates Holiday Travel

When the flight to Detroit started boarding, the concierge told me to keep quiet and he would take care of the check-in. The US State Department agent asked to see my passport, and the concierge explained that I was a Somali refugee. So she looks at her computer screen and says, "um, I'm afraid there's a problem, this passenger's name is on a watch list." Oh, great. Looks like my dad is playing Mr. Buzzkill again, just because I took that semester off from Oxford to go backpacking in Yemen. So I showed her my official State Department visa.

So I'm like, "honey, do I look like I'm a US military veteran?"

"No."

"Do I look like I'm some sort of right wing anti-tax teabagger?"

"No."

"Do I look like anybody else on the DHS terrorism danger list?"

"No, but..."

"Then I suggest that unless you want a nasty anti-discrimination lawsuit on your hands, you'd best give me an aisle seat. With extended legroom."

That shut her up.

via iowahawk: Man, Do I Hate Holiday Travel. Read the whoel thing; hilarious and insightful.