0

How can I set an application component property to be an array of objects from within the main.cpp config file?

in the components section of main.php config file we have a section:

   'components' => array(
       ....
       'company' => array(
           'class' => 'application.components.Company',
           'employees' => array(
               'class' => 'application.components.Employee'
           )
       )
   );

but the $company->employees property is just being set to 'application.components.Employee' .. I would have expected it to be equal to array( new Employee) (ie an Employee object within an array) .

Any knowledge on this matter?

Mike Graf
  • 5,077
  • 4
  • 45
  • 58

2 Answers2

0

You'd need to use standard PHP notation here, not Yii's class specifier, since you're simply assigning a value to the component member var employees:

'company' => array(
    'class' => 'application.components.Company',
    'employees' => array(new Employee())
)

That said, why do this? Just initialize employee in the Company class's constructor or init method.

Madbreaks
  • 19,094
  • 7
  • 58
  • 72
  • re: why? We would like it to be configurable instead of having to change the code (the constructor). – Mike Graf Apr 25 '13 at 23:01
  • Are you familiar with how `include` works? You'll need to provide the fully-qualified path to `Employee.php`, otherwise you'll get the error you mention. As for your "why?" - I see, thanks for clarifying. – Madbreaks Apr 25 '13 at 23:05
  • The include is pretty ugly because I'll have to include everything it depends on (including CComponent etc.. ) – Mike Graf Apr 25 '13 at 23:21
  • 1
    You've got me curious now - I'll do some looking around as well, it seems useful – Madbreaks Apr 25 '13 at 23:25
0

So it seems you want to use Yii's object initialization logic for your custom objects, right? Something like this could help:

class Company extends CApplicatinoComponent
{
    private $_employees = array();
    public function setEmployees($value)
    {
        foreach($value as $config)
            $this->_employees[] = Yii::createComponent($config);
    }
    public function getEmployees()
    {
        return $this->_employees;
    }
}

Of course you should add some error checking. But now you can configure your employees like:

'company' => array(
    'class' => 'Company',
    'employees' => array(
        array(
            'class' => 'Employee',
            'somePropertyOfEmployee' => 'bla',
        ),
        array(
            'class' => 'OtherEmployee',
            'otherProperty' => 'bla',
        ),
    ),
),
Michael Härtl
  • 8,428
  • 5
  • 35
  • 62
  • I think this may be on the right track.. Is there a way we could put the get/set in a behavior so that the code change is only in main.php (+ a new behavior) ? – Mike Graf Apr 26 '13 at 17:06
  • Not sure what you try to achieve. But putting the above in a behavior will not work. If i get you right, you want to put the above code in a behavior so that you can mix in the `employees` property to any component. So you would have to configure the behavior in `main.php`'s component section. At the same time you already try to set `employees` there. But by that time the component was not yet initialized. Thus the configured behaviors are not attached yet. And thus a call to `setEmployees()` would fail. – Michael Härtl Apr 26 '13 at 21:14
  • I've ended up putting the default employees code in the getEmployees() fn . (If !$this->employees) { /* generate employees */ } return $this->employees; . – Mike Graf Apr 29 '13 at 16:08