jwage

Follow me on the net

    11/19/2008

  • Twitter jwage: @boxee I love you, and I love twitter. Instant reply. Doesn't get any better. Thank you so much! [link]

  • Twitter jwage: @boxee I got an invite for boxee and want to run it on apple tv. When I go to download I don't see any option for AppleTV, thoughts? [link]

  • Facebook Jonathan is ugh? [link]

  • Twitter jwage: @stevenc1015 jigga what? I never blocked you!!! [link]

  • Facebook Jonathan is sleep time. [link]

  • Twitter jwage: @morganlevy thanks tho ;) [link]

  • Twitter jwage: @morganlevy @travib actually just sent me an invite... [link]

  • Twitter jwage: @travib ya I do!! [link]

  • 11/18/2008

  • Twitter jwage: @jwd2a Use Doctrine/PDO and you don't have to worry about it. [link]

  • Twitter jwage: @jwd2a of course!! [link]

  • Twitter jwage: And now the wait for my Boxee invitation begins!! [link]

  • Twitter jwage: READ IT - http://tinyurl.com/6zqjcq [link]

  • Twitter jwage: @AshleyBriggs sweet. I haven't been to Climb Nashville or some place like it in over 10 years. I think I remember it being awesome fun tho.. [link]

  • Twitter jwage: Watching old UFC fights. GSP is the most amazing fighter ever!!!!!!!!!!!!!!!!!!!! [link]

  • Twitter jwage: @briggsa I wanna go with you guys to climb Nashville sometime. Do u have to be a member or can I pay each time? [link]

  • Twitter jwage: Back at home after hard core workout. My abs are saying "wtf mate" [link]

  • Twitter jwage: Finally back online @ home...wooooooooooooooooooooooo... [link]

  • Twitter jwage: @jaxn don't lie. Your recent business endeavors are actually in the porn industry!!! Ok I know that joke is old but I had to do it!! [link]

  • Facebook Jonathan is waiting for comcrap to show up. They didn't show up last appt. And called a few hours after. [link]

  • Twitter jwage: Waiting for comcast to show up [link]

  • Twitter jwage: @stevenc1015 wtf!?!?! You are just now following me. I am hurt... [link]

  • Twitter jwage: @jasonRmoore You know I have no idea. That is what loopt sends to twitter. [link]

  • Facebook Jonathan is can't sleep but I am exhausted. [link]

  • Twitter jwage: Argh I can't sleeep! [link]

  • 11/17/2008

  • Facebook Jonathan is tired. [link]

  • Facebook Jonathan is getting oil changed in the whip. [link]

  • 11/16/2008

  • Facebook Jonathan is I shaved the beard. Could not stand it any longer. [link]

  • Facebook Jonathan is I am excited for tonight! Cannot wait!!!!! [link]

  • 11/15/2008

  • Facebook Jonathan is ufc tonight wooo. Good fights!!!!! [link]

  • Facebook Jonathan is planning new biz this weekend. Project plans, llc, lawyers, development, design, oh my. [link]

  • Facebook Jonathan can't sleep. I should be tired but my mind is racing. [link]

  • 11/14/2008

  • Facebook Jonathan is awake. [link]

  • 11/13/2008

  • Facebook Jonathan is ready to shave the beard. [link]

  • Facebook Jonathan is twerking. [link]

  • Google Starting with Doctrine ORM [link]

    Preparing myself to switch from Symfony 1.0 to Symfony 1.2 as my default framework, I started to rea[...]

  • Facebook Jonathan is sore. [link]

  • 11/12/2008

  • Google Call the expert: Customizing sfDoctrineGuardPlugin [link]

    Getting Started

    If you are just now getting started with Doctrine, check this previous blog post for how to get started with a new symfony + Doctrine project.

    Installing sfDoctrineGuardPlugin

    The sfDoctrineGuardPlugin has not been packaged for symfony 1.2 yet so you will need to install via svn like the following:

    $ cd /path/to/symfony1.2project
    $ svn co http://svn.symfony-project.com/plugins/sfDoctrineGuardPlugin/trunk plugins/sfDoctrineGuardPlugin
    

    Now that the plugin is in your plugins folder you need to tell symfony to enable it. Edit config/ProjectConfiguration.class.php and enable the sfDoctrineGuardPlugin.

    public function setup()
    {
      $this->enableAllPluginsExcept(array('sfPropelPlugin', 'sfCompat10Plugin'));
    }
     

    Be sure to clear your cache after doing the previous steps.

    $ ./symfony cc
    

    Enable Modules

    sfDoctrineGuardPlugin comes with three modules by default, so in order to use these we will need to enable them in our apps/backend/config/settings.yml. Open it up and modify the enabled_modules setting like the following:

    all:
      .settings:
        enabled_modules:        [default, sfGuardUser, sfGuardGroup, sfGuardPermission]
    

    Schema and Data Fixtures

    First we need to add some new models to our schema that have relationships defined to the sfGuardUser model included in the sfDoctrineGuardPlugin. So, create a config/doctrine/schema.yml and place the below YAML inside.

    In this example we're going to add a Profile model and relate it to sfGuardUser to include some additional information. By default the sfGuardUser schema only includes the information required for the authentication process, nothing more and nothing less. So, in order to capture additional information it is common practice to create a Profile model and relate it to sfGuardUser.

    Profile:
      columns:
        sf_guard_user_id: integer(4)
        first_name: string(255)
        middle_name: string(255)
        last_name: string(255)
        email_address: string(255)
      relations:
        User:
          class: sfGuardUser
          foreignType: one
     

    Now you will see we defined a one-to-one relationship between Profile and sfGuardUser. By adding that schema, the following is now possible.

    $user = new sfGuardUser();
    $user->Profile->first_name = 'Jonathan';
     

    And you can also access the relationship from the opposite end as Doctrine automatically makes relationships bi-directional.

    $profile = Doctrine_Query::create()
      ->from('Profile p')
      ->innerJoin('p.User u')
      ->where('p.id = ?', 1)
      ->fetchOne();
    $user = $profile->User;
     

    Now that we have our schema defined, we need to define some simple data fixtures to test against. Edit data/fixtures/data.yml and place the following YAML inside.

    sfGuardUser:
      jwage:
        username:       jwage
        password:       changeme
        is_super_admin: true
        Profile:
          first_name: Jonathan
          middle_name: Hurley
          last_name: Wage
          email_address: jonwage@gmail.com
     

    Now that we have our schema and data fixtures defined, we need to build everything. You can do so by running the following command:

    $ ./symfony doctrine:build-all-reload
    

    Well that was pretty easy! Now lets just do a little inspecting and make sure that all is well and the data is loaded properly. Run the following DQL query to inspect the data.

    $ ./symfony doctrine:dql "FROM sfGuardUser u, u.Profile p"
    >> doctrine  executing dql query
    DQL: FROM sfGuardUser u, u.Profile p
    found 1 results
    -
      id: '1'
      username: jwage
      algorithm: sha1
      salt: 9509acc86d1201e5d8314c2421339896
      password: a9119b7ca39bbb842fed640ed93c121990a37dbf
      is_active: true
      is_super_admin: true
      last_login: null
      created_at: '2008-11-12 13:40:42'
      updated_at: '2008-11-12 13:40:42'
      Profile:
        id: '1'
        sf_guard_user_id: '1'
        first_name: Jonathan
        middle_name: Hurley
        last_name: Wage
        email_address: jonwage@gmail.com
    

    You can even do the opposite to get the Profile objects with the User record joined.

    $ ./symfony doctrine:dql "FROM Profile p, p.User u"
    >> doctrine  executing dql query
    DQL: FROM Profile p, p.User u
    found 1 results
    -
      id: '1'
      sf_guard_user_id: '1'
      first_name: Jonathan
      middle_name: Hurley
      last_name: Wage
      email_address: jonwage@gmail.com
      User:
        id: '1'
        username: jwage
        algorithm: sha1
        salt: 9509acc86d1201e5d8314c2421339896
        password: a9119b7ca39bbb842fed640ed93c121990a37dbf
        is_active: true
        is_super_admin: true
        last_login: null
        created_at: '2008-11-12 13:40:42'
        updated_at: '2008-11-12 13:40:42'
    

    Now we are ready to take a look at the enabled modules and check out the functionality they provide. Open http://yourhost/backend_dev.php/sf_guard_user and you should see the sfGuardUser module in action like the following:

    sfDoctrineGuardPlugin Users

    The Customizing

    Now we finally get to the fun part. We added a Profile model and related it to sfGuardUser but how do we make that editable when editing sfGuardUser records via the admin generator? This is pretty simple. We need to tweak a few pieces of code to make this possible.

    First, lets update our sfGuardUserAdminForm to embed the ProfileForm. To do this we need to copy a file from the plugin to our project so we can customize the form.

    $ cp plugins/sfDoctrineGuardPlugin/lib/form/doctrine/sfGuardUserAdminForm.class.php lib/form/doctrine/
    

    Now open lib/form/doctrine/sfGuardUserAdminForm.class.php and override the configure() method to customize it and embed the ProfileForm.

    public function configure()
    {
      parent::configure();
     
      $profileForm = new ProfileForm($this->object->Profile);
      unset($profileForm['id'], $profileForm['sf_guard_user_id']);
      $this->embedForm('Profile', $profileForm);
    }
     

    The last thing we need to make this all work is to customize the generator.yml that comes with the plugin. To do this we need to override some of the plugin.

    $ mkdir apps/backend/modules/sfGuardUser
    $ mkdir apps/backend/modules/sfGuardUser/config
    $ touch apps/backend/modules/sfGuardUser/config/generator.yml
    

    Now we need to open apps/backend/modules/config/generator.yml in our editor and tweak it a bit to include the embedded form we named Profile in the previous step.

    generator:
      class: sfDoctrineGenerator
      param:
        config:
          form:
            class: sfGuardUserAdminForm
            display:
              "NONE":                   [username, password, password_again, Profile]
              "Permissions and groups": [is_active, is_super_admin, groups_list, permissions_list]
     

    Notice all we added was the Profile to the list of things to display in the form.

    Final Product

    sfDoctrineGuardPlugin Edit User

    Now when you add and edit users you have the ability to enter the Profile information directly inside of the user form.


    Be trained by symfony experts - Dec 10 Paris - Dec 10 Atlanta - Dec 17 Montreal - Jan 21 Paris - Feb 18 Paris

  • 11/11/2008

  • Google Interactive embedded forms [link]

    This tutorial describes how to create one sfForm which edits an object, edits related objects and allows you to add or remove related objects:

  • Google PHP Tutorial - PHP Doctrine - adding automatic, simple CRUD [link]

    Example of how a simple system for creating a CRUD interface from the information in the model class[...]

  • Facebook Jonathan is sleep time. [link]

  • 11/10/2008

  • Google symfony 1.2 beta2 - The Doctrine Admin Generator is here [link]

    We are very happy to announce the symfony 1.2 beta 2 release, which now supports the admin generators for both Doctrine and Propel. No need to use Propel for sexy admin generator anymore. Hooray!

    Thanks to Jonathan for his great work on this. But of course we other folks were not lazy, and killed a lot of bugs. The main man to praise here is Fabien, who did work really a lot the last week.

    Many enhancements have been made based on community feedback or tickets to the admin generator and forms system, and even better, quite some of them have been backported to symfony 1.1.

    What's in here?

    Main Highlights

    • To provide an easier upgrade path form 1.1, all plugins are now enabled by default when upgrading (except for the Doctrine plugin and the Compat10 one) r12639
    • Admin Generation creation can now also creates the required route for you r12758
    • Forms save now embedded forms automatically. Read more in this tutorial
    • Session storage now also can work with propel connections where it could not before r12763
    • Propel Tasks using plugins with behaviours now work correctly r12809
    • Time logging in the Web Debug toolbar is back to the old mechanism, because the new one was faulty r12698
    • The CLI is now much faster thanks to caching the autoloading settings r12864
    • A lot of small bugs in the new admin generator have been fixed
    • Web assets now get relative symlinks r12847
    • Improved PHP 5.3 and PHP 5.1 compatibility r12625 and r12676

    In Total

    Tracking all the changes is not always very easy, especially when they affect multiple versions. For the 1.2 milestone, we have now a "Closed Tickets" count of 104, and Beta 2 milestone adds up another 29.

    Give it a try

    We encourage you to try this new beta version. Please be reminded to follow the UPGRADE procedure. Even if you are upgrading from beta 1, you need to follow these steps:

    $ php symfony project:upgrade1.2
    $ php symfony propel:build-model
    $ php symfony propel:build-forms
    $ php symfony propel:build-filters
    $ php symfony cc
    

    This is due to changes in code that will be generated by these tasks for you.

    What's up next?

    As we are pretty pleased with the quality and also feature wise everything for 1.2 is in now, this will be the last beta. The next release on the path to a 1.2 final will be the symfony 1.2 RC1, coming very soon.

    We are also ramping up the documentation efforts to make sure that symfony will remain the best documented framework available.

    So if you think "hey this is really missing in 1.2" it is time to speak up (and create a ticket with patch, tests and documentation, you get it).

    You own a plugin? You have not started porting it to symfony 1.2 yet? You should get started. Kris made the sfTaskExtraPlugin which can help you out.

    Contribute

    Do you want to see the new admin generators in your language? Then:

    Thanks a lot to all the folks out there who already translated the admin generator. 28 translations are a pretty impressive number already.

    Also I would like thank you to everybody who already tried symfony 1.2. I appreciate your feedback in mailinglist, IRC and especially in tickets. Thank you!


    Be trained by symfony experts - Dec 10 Paris - Dec 10 Atlanta - Dec 17 Montreal - Jan 21 Paris - Feb 18 Paris

  • Google Call the expert: Nested forms - A real implementation [link]

    As announced in a previous post, symfony 1.2 is able to automatically save objects from deep nested forms. I gave a simple example in the announcement post, but some people asked me for a real project example. So here it is.

    The project

    Let's take a classified website. The website is composed of ads. Each ad is described with some generic information (like a title, a description, ...) and some more specific ones based on the ad type (like the number of beds or the year of construction for a house, or the make, the model, or the color for a car).

    So, the model schema is composed of a main demo_ad table and some type tables (demo_ad_type_house and demo_ad_type_car) to host the detailed information for the ad:

    # config/schema.yml
    propel:
      demo_ad:
        id:              ~
        title:           { type: varchar(255), required: true }
        description:     { type: longvarchar, required: true }
        price:           float
        type:            { type: varchar(255), required: true }
     
      demo_ad_type_house:
        id:              ~
        demo_ad_id:      { type: integer, foreignTable: demo_ad, foreignReference: id, required: true }
        square_footage:  { type: integer, required: true }
        nb_beds:         { type: integer, required: true }
        nb_baths:        { type: integer, required: true }
        year:            { type: varchar(255), required: true }
     
      demo_ad_type_car:
        id:              ~
        demo_ad_id:      { type: integer, foreignTable: demo_ad, foreignReference: id, required: true }
        make:            { type: varchar(255), required: true }
        model:           { type: varchar(255), required: true }
        year:            { type: varchar(255), required: true }
        color:           { type: varchar(255), required: true }
     

    To make it more real, let's add some initial data:

    # data/fixtures/ads.yml
    DemoAd:
      house_1:
        title: Farm
        description: |
          250 acres with irrigation, several shares of water rights, creek, spring and a well.
        price: 2225000
        type: house
      car_1:
        title: Honda Accor
        description: |
          Honda accord fully loaded, power windows, sun roof, new timing belt, new brakes, a/c , cd player.
        price: 6900
        type: car
     
    DemoAdTypeHouse:
      house_1_desc:
        demo_ad_id: house_1
        square_footage: 4500
        nb_beds:  4
        nb_baths: 3
        year:     1910
     
    DemoAdTypeCar:
      car_1_desc:
        demo_ad_id: car_1
        make:  honda
        model: accor
        year:  2002
        color: green
     

    Project Initialization

    If you want to follow along, create a new symfony project the usual way:

    $ mkdir classifieds
    $ cd classifieds
    $ symfony generate:project classifieds
    

    Then create the two files we have described above (config/schema.yml and data/fixtures/ads.yml), configure the database, build the model, and feed the database with the initial data:

    $ ./symfony configure:database "mysql:host=localhost;dbname=classifieds" root mYsEcret
    $ mysqladmin -uroot -pmYsEcret create classifieds
    $ ./symfony propel:build-all-load
    

    In this post, we will create the backend of the application to demonstrate all the power of the new admin generator bundled with symfony 1.2.

    $ ./symfony generate:app --escaping-strategy=on --csrf-secret=Unique$ecret1 backend
    

    Then create the backend module to list, create, edit, and delete the ads:

    $ ./symfony propel:generate-admin backend DemoAd
    

    The propel:generate-admin automatically adds a route to the routing.yml configuration file.

    The ad module is now ready to be used as shown on these screenshots:

    Ads list action

    Ads edit action

    Project Customization

    As you can see for yourself on the screenshots, it is not quite finished yet.

    The type column, which is stored as a string in the database, need to be changed from an input text box to a select box in the form.

    Instead of hardcoding the possible types in the form, declare them as a simple property of the DemoAdPeer class, so it can be reused later on in the project:

    // lib/model/DemoAdPeer.php
    class DemoAdPeer extends BaseDemoAdPeer
    {
      static public $types = array('house' => 'house', 'car' => 'car');
    }
     

    It is now easy to change the type widget of DemoAdForm from a text input to a choice:

    // lib/form/DemoAdForm.class.php
    class DemoAdForm extends BaseDemoAdForm
    {
      public function configure()
      {
        $this->widgetSchema['type'] = new sfWidgetFormChoice(array('choices' => DemoAdPeer::$types));
        $this->validatorSchema['type'] = new sfValidatorChoice(array('choices' => array_keys(DemoAdPeer::$types)));
      }
    }
     

    Ads edit action with type

    When editing an ad, we want to edit the main information but also the detailed ones. So, we need to embed the specific description form in the main form.

    As there is no database relation between the ad and the type, we need to create a custom method in the DemoAd model to get the DemoAdType* object:

    // lib/model/DemoAd.php
    class DemoAd extends BaseDemoAd
    {
      public function getTypeObject()
      {
        // if no type has been defined yet, there is no type object
        if (!$this->getType())
        {
          return null;
        }
     
        // the type class depends on the ad type
        $class = sprintf('DemoAdType%s', ucfirst($this->getType()));
        $peer = constant($class.'::PEER');
     
        // get the type object related to the current ad
        $criteria = new Criteria();
        $criteria->add(constant($peer.'::DEMO_AD_ID'), $this->getId());
     
        // if there is none, create a new one associated with this ad
        if (is_null($type = call_user_func(array($peer, 'doSelectOne'), $criteria)))
        {
          $type = new $class();
          $type->setDemoAd($this);
        }
     
        return $type;
      }
    }
     

    Now for the fun part. Embed the type form into the main ad form if there is one:

    // lib/form/DemoAdForm.class.php
    class DemoAdForm extends BaseDemoAdForm
    {
      public function configure()
      {
        $this->widgetSchema['type'] = new sfWidgetFormChoice(array('choices' => DemoAdPeer::$types));
        $this->validatorSchema['type'] = new sfValidatorChoice(array('choices' => array_keys(DemoAdPeer::$types)));
     
        // only embed if there is a type object (edit vs create)
        if ($this->getObject()->getType())
        {
          $this->embedForm('desc', $this->getTypeForm());
        }
      }
     
      public function getTypeForm()
      {
        $class = sprintf('DemoAdType%sForm', ucfirst($this->object->getType()));
     
        return new $class($this->object->getTypeObject());
      }
    }
     

    If you refresh your browser now, you will have an exception because the embedded form has a select box to choose the ad to which it is linked to. To render this select box, symfony needs a text representation of an Ad:

    class DemoAd extends BaseDemoAd
    {
      public function __toString()
      {
        return $this->getTitle();
      }
     
      // ...
    }
     

    Ads edit action with the embed form

    As we don't want people to be able to change the link between the ad and the type, we need to disable the corresponding widget in the type form classes:

    // lib/form/DemoAdTypeCarForm.class.php
    class DemoAdTypeCarForm extends BaseDemoAdTypeCarForm
    {
      public function configure()
      {
        unset($this['demo_ad_id']);
      }
    }
     
    // lib/form/DemoAdTypeHouseForm.class.php
    class DemoAdTypeHouseForm extends BaseDemoAdTypeHouseForm
    {
      public function configure()
      {
        unset($this['demo_ad_id']);
      }
    }
     

    Final ads edit action with the embed form

    That's all there is to it. You can now change the main ad columns or the specific ones and when saving the form, symfony will save everything back to the database. And this has been possible with the admin generator without customizing anything. It just works!

    Final ads edit action with the embed save

    Final ads edit action with the embed form errors

    Of course, you will find some edge cases that need to be worked on, but hopefully you are now able to customize it further.


    Be trained by symfony experts - Dec 10 Paris - Dec 10 Atlanta - Dec 17 Montreal - Jan 21 Paris - Feb 18 Paris

  • 11/09/2008

  • Google File Uploads with PHP Doctrine Tutorial - Tutorials-Expert.com [link]

    An example of how to integrate uploads into the Doctrine validation process.

  • Facebook Jonathan is titans are still no joke. [link]

  • Facebook Jonathan is almost back to Nashville. [link]

  • Google The Geek Shall Inherit the Earth [link]

    I was having a conversation with my two oldest sons today about the word “geek”. They were trying to convince me that I am not a “geek”.

    It led to a conversation about what a geek is. We ended up that a geek is someone who likes math and computers (a seriously narrow definition that ignores science, but they don’t really have science in 1st grade). This then led us to computer programming which is a pretty geeky hobby no matter who is defining “geek”.

    It got me thinking about my BASIC programming in grade school. I asked them if they wanted to learn how to program computers; they are interested as long as they can create games.

    Then, a few hours later I was reading some feeds when I saw a few references to this:

    smallbasiclogooct_2008.jpg“After a year in the making, and with very little fanfare, Microsoft last month launched Small Basic, a free programming language aimed at kids. Unlike Scratch and Alice, tools designed for kids to learn programming in a ‘codeless’ environment, Small Basic is essentially a small version of the BASIC language.”

    Sweet. We may have to give this a try. Anyone want to make a rocket ship scroll across the screen?



  • 11/08/2008

  • Google river [link]

    cwage posted a photo:

  • Facebook Jonathan is uh huh. [link]

  • Google Additional tasks to streamline your workflow [link]

    The sfTaskExtraPlugin is a plugin maintained by the symfony core team. It adds a number of useful tasks to your symfony command line to help streamline your workflow. This plugin is relatively young, so I will just be discussing those tasks that we'll be using for today's Plugin Developers Day. I should also note this plugin requires symfony 1.2.

    Plugin Tasks

    We now turn our focus to easing the process of creating, developing and releasing plugins. The following tasks are included in sfTaskExtraPlugin:

    • generate:plugin
    • generate:plugin-module
    • plugin:package

    New Task: generate:plugin

    Very much like generate:app task, the generate:plugin task creates a basic plugin directory structure:

    $ ./symfony generate:plugin myFirstPlugin
    

    After running this command you should see the following plugin structure in your project's plugins directory:

    myFirstPlugin/
      config/
        myFirstPluginConfiguration.class.php
      lib/
      test/
        bin/
          prove.php
        bootstrap/
          functional.php
          unit.php
        fixtures/
          project/
        functional/
        unit/
      LICENSE
      README
      package.xml.tmpl
    

    As you can see, part of what this task does is setup a proper testing environment for your plugin, including an isolated symfony project to run your plugin's functional tests through. Once you've created your test scripts, you can easily execute them all by running the prove.php script before committing your code:

    $ php plugins/myFirstPlugin/test/bin/prove.php
    

    Building a robust unit and functional testing suite is a strongly recommended best practice, but if you would rather not bother you can simply include the --skip-test-dir option when generating your plugin.

    New Task: generate:plugin-module

    Often times a plugin will require one or more modules to support its functionality in the project, such as an administrative backend interface. In order for your module to be easily customizable for its housing project you will need to provide a "stub" actions class that can be replicated and customized in an application's modules directory.

    Previously this would have involved either creating the module directory structure by hand, or running generate:module in your application and then copying, modifying and creating new files in your plugin. This process is now much more streamlined thanks to the generate:plugin-module task.

    $ ./symfony generate:plugin-module myFirstPlugin myFirstModule
    

    Executing this command will add the following to your plugin's directory structure:

    modules/
      myFirstModule/
        actions/
          actions.class.php
        lib/
          BasemyFirstModuleActions.class.php
        templates/
    
    test/
      functional/
        myFirstModuleActionsTest.php
    

    As you develop this module, write all your action code in the /lib/BasemyFirstModuleActions.class.php file. Leaving the actions.class.php file empty makes it possible to replicate that file in the project and not lose or have to duplicate code from the plugin; this will be taken care of by the symfony autoloader and the magic of OOP inheritance.

    This task also creates a functional test script for the new module and updates the embedded test project's config/settings.yml to enable the module.

    New Task: plugin:package

    Anyone who has released a symfony plugin in the past is familiar with the tedious task of filling out the necessary values in the requisite package.xml file. We have added the plugin:package task in order to speed up this process.

    $ ./symfony plugin:package myFirstPlugin
    

    This task will look for either a package.xml or package.xml.tmpl file in the plugin directory. If neither are found, the task will package the plugin using a default package.xml template. In any case, if any field values are not known the task will take advantage of one of the new symfony 1.2 task features and ask you for that information.

    Interactive task

    Once the task knows what it needs to package the plugin, a myFirstPlugin-0.0.1.tgz file will be created in the plugin directory. Once you upload this file to the symfony plugins application, your work will become immediately available to the entire symfony community.

    What's Next?

    The sfTaskExtraPlugin is young, but we have big plans for it. If you have any tasks you'd like to see incorporated, please let us know.


    Be trained by symfony experts - Dec 10 Paris - Dec 10 Atlanta - Dec 17 Montreal - Jan 21 Paris - Feb 18 Paris

  • 11/07/2008

  • Google Jonathan Wage - New in symfony 1.2: Doctrine goodies [link]

    Jonathan Wage has written an excellent post on the symfony-project blog showing how easy it is to get a new symfony project up and running with symfony 1.2 and Doctrine ORM.



  • Google Symfony 1.2 Bondades de Doctrine [link]

    Un Gran Agradecimiento Una gran cantidad de cosas impresionantes, se han a??adido recientemente a la[...]

  • Facebook Jonathan is LA. [link]

  • Google Another Symfony 1.2 and Doctrine Tutorial [link]

    Yes, just last week I linked to a tutorial on Symfony 1.2 and Doctrine, but here’s another good on[...]

  • 11/06/2008

  • Flickr montroyal [link]

    jonwage posted a photo:

    montroyal

  • Flickr montreal [link]

    jonwage posted a photo:

    montreal

  • Flickr IMG_0160 [link]

    jonwage posted a photo:

    IMG_0160

  • Flickr IMG_0159 [link]

    jonwage posted a photo:

    IMG_0159

  • Flickr IMG_0158 [link]

    jonwage posted a photo:

    IMG_0158

  • Flickr IMG_0157 [link]

    jonwage posted a photo:

    IMG_0157

  • Flickr IMG_0155 [link]

    jonwage posted a photo:

    IMG_0155

  • Flickr IMG_0154 [link]

    jonwage posted a photo:

    IMG_0154

  • Flickr IMG_0153 [link]

    jonwage posted a photo:

    IMG_0153

  • Flickr IMG_0145 [link]

    jonwage posted a photo:

    IMG_0145

  • Flickr IMG_0144 [link]

    jonwage posted a photo:

    IMG_0144

  • Flickr IMG_0143 [link]

    jonwage posted a photo:

    IMG_0143

  • Flickr IMG_0142 [link]

    jonwage posted a photo:

    IMG_0142

  • Flickr IMG_0141 [link]

    jonwage posted a photo:

    IMG_0141

  • Flickr IMG_0140 [link]

    jonwage posted a photo:

    IMG_0140

  • Flickr IMG_0139 [link]

    jonwage posted a photo:

    IMG_0139

  • Flickr IMG_0138 [link]

    jonwage posted a photo:

    IMG_0138

  • Flickr IMG_0137 [link]

    jonwage posted a photo:

    IMG_0137

  • Flickr IMG_0136 [link]

    jonwage posted a photo:

    IMG_0136

  • Flickr IMG_0135 [link]

    jonwage posted a photo:

    IMG_0135

  • 10/31/2008

  • Google Piotr Gabryjeluk: Doctrine PHP [link]

    Now, I'm converting my nuclear project — opiwo.com (bet a beer in Polish) to Doctrine ORM (from Ze[...]

  • 10/29/2008

  • Google PHP Doctrine DQL recipes - Develop The Web Forums [link]

    PHP Doctrine DQL recipes Pixel2Life RSS - Tutorials.

  • 10/24/2008

  • Google File Uploads with PHP Doctrine - Tutorialized [link]

    File Uploads with PHP Doctrine. ... An example of how to integrate uploads into the Doctrine validat[...]

  • 10/23/2008

  • Google PHP Doctrine - adding automatic, simple CRUD | ProDevTips - dev ... [link]

    I just found myself wishing for automatic CRUD, for quick and simple administrative tasks, as it tur[...]

  • 09/25/2008

  • Google Extending PHP Doctrine Record - Tutorialized [link]

    Extending PHP Doctrine Record. ... Here we extend PHP Doctrine records fromArray function to allow f[...]

  • 09/03/2008

  • Google Search and Pagination with PHP Doctrine [link]

    PHP Doctrine introduction for dummies; Smarty and Doctrine combination; Extending PHP Doctrine Recor[...]

  • 08/08/2008

  • Wordpress Testing posting from my iphone [link]

    Testing 123

  • 08/05/2008

  • Google Doctrine for dummies [link]

    It was long overdue but finally I’ve taken a look at Doctrine. And I’m blown away, bye bye Zend [...]