Paul M. Jones

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

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.


The truth about airplane security measures. - By Christopher Hitchens - Slate Magazine

What nobody in authority thinks us grown-up enough to be told is this: We had better get used to being the civilians who are under a relentless and planned assault from the pledged supporters of a wicked theocratic ideology. These people will kill themselves to attack hotels, weddings, buses, subways, cinemas, and trains. They consider Jews, Christians, Hindus, women, homosexuals, and dissident Muslims (to give only the main instances) to be divinely mandated slaughter victims. Our civil aviation is only the most psychologically frightening symbol of a plethora of potential targets. The future murderers will generally not be from refugee camps or slums (though they are being indoctrinated every day in our prisons); they will frequently be from educated backgrounds, and they will often not be from overseas at all. They are already in our suburbs and even in our military. We can expect to take casualties. The battle will go on for the rest of our lives. Those who plan our destruction know what they want, and they are prepared to kill and die for it. Those who don't get the point prefer to whine about "endless war," accidentally speaking the truth about something of which the attempted Christmas bombing over Michigan was only a foretaste. While we fumble with bureaucracy and euphemism, they are flying high.

via The truth about airplane security measures. - By Christopher Hitchens - Slate Magazine.


Logical Fallacy vs Bayesian Reasoning

Most fallacies aren’t really fallacies when you reinterpret them as Bayesian reasons to give an idea more credence rather than iron-clad syllogisms. Without the “argument from authority” and the “ad hominem fallacy”, you would either never get lunch or you’d give all your money to Nigerian spammers.

via Climate Change and Argumentative Fallacies.


Married (Happily) With Issues

In psychiatry, the term “good-enough mother” describes the parent who loves her child well enough for him to grow into an emotionally healthy adult. The goal is mental health, defined as the fortitude and flexibility to live one’s own life -- not happiness. This is a crucial distinction. Similarly the “good-enough marriage” is characterized by its capacity to allow spouses to keep growing, to afford them the strength and bravery required to face the world.

via Married (Happily) With Issues - NYTimes.com.