When to use CApplicationComponent, and alternative?

Okay, I created a CApplicationComponent. Another one, actually. But in this one, the array passed by the main config file points to classes within modules that apparently do not exist at the time Yii components are being loaded. So that idea is pretty much scrapped.

But that’s okay, because as far as I can tell, those classes are always loaded, with every single access to the site. And I really don’t think it needs to have information on parsing user profiles on-hand when someone’s posting to the forum, for example. Am I right on that, that CApplicationComponents should only be used for things that nearly every page load will utilize?

But aside from that, what should I be using? The same methods are to be shared between two different modules, acting primarily as a parser and parameter-checker of sorts. In theory, they should only need to be called a single time during any given page load, but they’re also used pretty rarely - pretty much only when viewing or modifying a user or character profile.

Anyone? With all these helpers and extensions and components and whatever else, it’s rather difficult to figure out what to use for a class that can be accessed from anywhere, but isn’t automatically initialized on every run. I imagine a BBCode parser would have similar requirements.

CComponent and CApplicationComponent does not load on every page

When you access it by calling


Yii::app()->getComponent('myComponent');

//or

Yii::app()->myComponent;



it checks if it exists and if does returns it , if not it will create a new one and register for later use

the __construct function will handle the options given in the config and set your variable with the values for example:


//config 

'MyComponent'=>array('class'=>'ext.MyComponent','option1'=>'value1','option2'=>'value');

//it will set in your component

class MyComponent extends CComponent{

//the __construct function will overwrite the following values with the one provided

   public $option1='defaultValue';

   public $option2='defaultValue2';

}



Hope it clarify things a bit for you

Aha! That is fascinating, and incredibly helpful, thank you.

Now, is there any way I can allow those components to access constants that I set within module models? According to what you say, the component should not be loaded until it is called, which is well after the model has been used, but I still get an error page;


Fatal error: Class 'Character' not found in /var/www/anthroempire/protected/config/charfields.php on line 18

It should work just fine, put a trace on the ‘init’ method of your component and another one once that you load the class ‘Character’ and see the timeline

I checked it, and I found the problem. I’m assuming that the first thing loaded is the main config file, and the main config file gathers the data it will need to pass to the ProfileManager component… with include(‘charfields.php’). Naturally, it attempts to execute that the moment it finds it, triggering that file to return the array contained within, which fails when some of the values are constants from a class it doesn’t know about yet.

If it held off on trying to evaluate those constants until the ProfileManager component were actually called - definitely after the Character module and model are ready - then it would work perfectly fine.

you should add a method to your component that gets the ProfileManager component

something like :




class MyComponent extends CComponent{

  public $profileManager='ProfileManager';

  public $charfields='charfileds.php';

  function getProfileManager(){

  	$profile=$this->profileManager;

  	if(is_string($profile)){

         	$profile=$this->profileManager=new $profile(include $this->charfields);

  	}

 	return $profile;

  }

}



and then instead of using $this->profileManager use $this->getProfileManager();

something like that, i can only be more specific if i take a look at your code

Thankfully I didn’t have to get quite that complex. Now that I know components aren’t initialized until called for, all I needed was this:




public function init()

{

	$this->fields = array(

		'char'=>include('protected/config/charfields.php'),

		'user'=>include('protected/config/userfields.php')

		);

}



… instead of setting the class variables in the config file. I might mess with it so that it only loads the field array for the type of profile being processed, but for now, it works :)