Question

I have some custom logic I need to insert into CDbCommand, CDbTransaction & CActiveRecord classes that comes with the Yii framework. I can't replace them because I am using the same framework files for other projects.

Most of my models are already generated and is extended from CActiveRecord. I know I can easily switch them to my own custom class extended from CActiveRecord. However, the methods that I want to override in CDbCommand would not be filtered into CActiveRecord if I extend the CDbCommand class, and in addition CDbCommand is used by many other Framework classes. I need all other framework classes to use my overrides of CDbCommand methods.

Any ideas?

Was it helpful?

Solution 3

== Correct Answer Added below ==

ORIGINAL ANSWER

As far as Yii 1.1.* is concerned the best way seems to be to place the overriding versions of the files into a folder such as

/protected/component/overridden/ folder

and then to bind the application to the custom classes by adding them to import configuration in

/protected/config/main.php.

    'import'=>array(
        'application.components.CDbConnection',
        'application.components.CDbTransaction',
        'application.components.CDbConnection',
        ...
    ),

This would then call the custom class files even when called by the Framework files.

CORRECT ANSWER - RESOLVED

What I needed was the following at the end of index.php (in the root of project)

Yii::$classMap= [
    'CActiveRecord' => dirname(__FILE__) . 
        '/protected/components/auditAndOps/CActiveRecord.php',
    'CDbCommand' => dirname(__FILE__) . 
        '/protected/components/auditAndOps/CDbCommand.php',
    'CDbTransaction' => dirname(__FILE__) . 
        '/protected/components/auditAndOps/CDbTransaction.php',
];

Yii::createWebApplication($config)->run();

What this essentially does is to remap the original classMap locations of the respective Framework files, to my custom files in /protected/components/auditAndOps/

OTHER TIPS

There has been a similar question in the yii forums, concerning classes like CHtml, which are caled statically all over the framework and in generated Code.

There seems to be no pretty way, the kind-of-consensus in the discussion was to do the following (example CHtml):

Move CHtml.php to Html.php and rename the class to Html. Create a new, empty CHtml class, that extends Html. Add your overwrites to the new CHtml class.

It's not pretty but it works and is reasonably maintanable on Yii updates.

Override

To override CDbCommand and CDbTransaction, you should override CDbConnection. Most of my Yii Projects have many Yii classes overridden including classes that are mentioned in your question. It is a lot of work, but you have few choices.

For me, it is good practice to begin projects with overriding all classes you use. Once you write your project template with custom ActiveRecord, DbConnection, DbCommand and DbTransaction, Html and widget classes, there will be no need to solve problem of extending Yii classes again.

Fork

Of course, you always can fork and add custom logic directly to Yii classes or adjust something to allow extend classes easily. Sometimes, it is the simplest solution.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top