3

I've added some functionality to some of my instance classes in my symfony project that I want ALL of my instance classes to have. If I didn't have any qualms about editing the core symfony installation, I would just add my methods directly to the sfDoctrineRecord class. But I don't want to do that, of course, because my changes would break on upgrade, plus my changes wouldn't port well to other projects.

If I want to add certain functionality to all my instance classes in symfony, what's the "right" way to do that?

(P.S. When I say "instance class", I mean something like lib/model/doctrine/Customer.class.php.)

Jason Swett
  • 43,526
  • 67
  • 220
  • 351

2 Answers2

6

Steps:

  1. Create myDoctrineRecord

    abstract class myDoctrineRecord extends sfDoctrineRecord
    {
      public function commonRecordMethod() { }
    }
    

    I place this file in lib/record, but you can put it anywhere that the autoloader will see it.

  2. Set Symfony to use this class in the configureDoctrine callback of your ProjectConfiguration:

     public function configureDoctrine(Doctrine_Manager $manager)
     {
       sfConfig::set('doctrine_model_builder_options', array('baseClassName' => 'myDoctrineRecord'));
     }
    

That's it! Isn't Symfony great? :)

Jeremy Kauffman
  • 10,293
  • 5
  • 42
  • 52
  • 2
    Awesome. That's exactly what I was looking for. For some reason, it won't work for me, but that's another issue for another question. For anyone who's curious, the official docs about this are here: http://www.symfony-project.org/doctrine/1_2/en/03-Configuration – Jason Swett Dec 08 '10 at 21:40
  • ahhhh i thought i had seen that somewhere but when i didnt see a `Doctrine_Core::ATTR_*` attribute constant i though i was worng... I had no idea it was in the builder options. +1. – prodigitalson Dec 08 '10 at 21:41
  • 1
    Here's my question about why it's not working: http://stackoverflow.com/questions/4392713/cant-change-model-builder-options – Jason Swett Dec 08 '10 at 21:48
2

I suppose the proper way would probably be to add a Doctrine_Template to the models in question, however you would need to define it as a behavior for every model in your schema.yml

class MyMethodsTemplate extends Doctrine_Template
{
   public function customMethod1(){
      $model = $this->getInvoker();
      //do stuff with model
   }

   public function customMethod2(){
      $model = $this->getInvoker();
      //do stuff with model
   }
}

And then in your schema.yml:

ModelName:
  actAs:
   MyMethodTemplate: ~
  # the rest of your definition

After you rebuild you should be able to call:

$model = new ModelName();
$model->customMethod1();
$model->customMethod2(); 

Of course Doctrine templates and listeners are much more powerful than that. You should take a look at the documentation for decent overview

prodigitalson
  • 60,050
  • 10
  • 100
  • 114