This extension is an alternative to my "myconfig" extension from here: http://www.yiiframework.com/extension/myconfig/ but it uses only the database+caching.
As explained in this comment http://www.yiiframework.com/extension/myconfig/#c3727 using this extension has some advantages and some extra requirements.
1) Yii 1.1.x
2) A Cache component activated (CFileCache will do it just fine)
Add the component to the main.php config file:
[...] 'cache'=>array( 'class'=>'system.caching.CFileCache', ), 'settings'=>array( 'class' => 'CmsSettings', 'cacheComponentId' => 'cache', 'cacheId' => 'global_website_settings', 'cacheTime' => 84000, 'tableName' => '{{settings}}', 'dbComponentId' => 'db', 'createTable' => true, 'dbEngine' => 'InnoDB', ), [...]
/* * Set a database item: * $itemName can be an associative array() in key=>value pairs ($itemValue="" in this case) */ Yii::app()->settings->set($categoryName, $itemName, $itemValue, $toDatabase=true); // Get a database item: Yii::app()->settings->get($categoryName, $itemName); // Get all items from a category: Yii::app()->settings->get($categoryName); // Delete a database item: Yii::app()->settings->delete($categoryName, $itemName); // Delete all items from a category: Yii::app()->settings->delete($categoryName); //Import items from a file: $items=include('path/to/file.php');//returns an array() in key=>value pairs Yii::app()->settings->set($categoryName, $items);
The component uses something like "lazy loading" for loading items within a category, meaning that the items from a category will be loaded when you request them first time. Beside this, at the end of the request, the items from that requested category are written to cache, so next time when you request them, they will be served from cache.
Note, the component is smart enough to know itself when a new item/category has been added and refresh the cache accordingly so you don't have to keep track of the items you add to database.
Basically, in most of the cases, the database will be hit only once, then all items will be served from cache, which means you will get a nice way to manage the project configuration without performance penalties.
Version 1.1.c
Various improvements
Version 1.1.d
-> Contains small performance improvements.
-> You can now use the get() method like
$retrieve_custom_settings=Yii::app()->settings->get('system',array('admin_email','contact_email','my_email'=>'some default value'));
In the above example, $retrieve_custom_settings becomes an array having the 'admin_email' and 'contact_email' keys. If these values are empty or they don't exists in database then they will be set to null otherwise you will retrieve their values. It is set this way so that you can safely use $retrieve_custom_settings['admin_email'] even if it doesn't exists.
Version 1.1.e
->Added setters/getters for all the public properties.
->The component supports the automatic creation of the database table (optionally, you can specify which storage engine to use in case you use MYSQL)
->Added the option to specify the name of the Cache/Database components via the $cacheComponentId and $dbComponentId properties.
->removed the __call() magic function.
->commented the class methods.
Special thanks goes to Gustavo who helped me allot with this version.
Upgrading to this version will not break the backward compatibility in any way(hope you didn't make use of the __call() method) and it is recommended to do so.
In case you use the autocreate database table option, don't forget to turn it off after the table has been created.
Version 1.2
-> added the deleteCache() public method to allow to delete cached categories
-> implemented a cache registry that will hold all the cached categories and it will be updated
each time a new category is loaded/deleted
Usage:
-> various changes that won't break BC.
Yii::app()->settings->deleteCache('categoryName'); //delete a single category Yii::app()->settings->deleteCache(array('c1', 'c2','c3')); // delete multiple categories Yii::app()->settings->deleteCache(); // delete all cached categories.
Please let me know in case you find any error.
Total 20 comments
Hi all, i read all your comments but for now i don't really have enough time to implement everything as i am very busy at work. Hope i'll have some spare time to improve the extension in the near future(the version used in my projects already is better, so i'll post all at once).
Thanks for your pacience:)
Hi to all,
This extension is very useful and I use it in several projects. From my experience, when application has a lot of different parameters, it may become not handy to manage them.
With following approach I'm trying to solve such hassles:
1) a lot of editions when you need to add new parameters to your application
2) obtrusive (not handy) code in model, controller and view files (which I first met on a large project where this extension was used)
3) instead of writing long requests, to use small helper function to call parameters
What can be improved:
1) add proper validation method (which isn't difficult to add, I just didn't need it for now)
2) get rid of literals usage as categories and parameters names - I think it would be more handy to have kinda of constants.
Your suggestions are welcome :)
controller
model
views to set params
main view shows tabs, content for which is stored in partial views
index.php
example partial view
catch parameter
Helper function is stored in globals.php, which may be included to code in application bootstrap file.
usage
P.S. I would put this message to extension forum topic but couldn't find the link to it here.
Hi, after using your settings for a long time, I see some minor fix should be made:
protected function createTable() { $schema = Yii::app()->getDb()->getSchema(); $table = $schema->quoteTableName($this->getTableName()); $create = $schema->createTable( $table, array( 'category' => 'string', 'key' => 'string', 'value' => 'text', ) ); $index = $schema->createIndex('category_key', $table, 'category,key', TRUE); Yii::app()->getDb()->createCommand($create)->execute(); Yii::app()->getDb()->createCommand($index)->execute(); return TRUE; }This will use Yii createTable instead of raw SQL one.
I think this is more convenient, in case switching db engine.
Also, remove the dbEngine variable, and table prefix. No need for that, right?
@fad
okay, this will be implemented in the next version (along with a few bug fixes) which will be available somewhere this week.
Back to comment #4225 Nothing new, just new options. Question to author: Where to send the updated code, if possibly?
Or maybe I do fork on github?
Ok, i don't use prefix.
I suggest writing it to the extension description text, because i hav'nt read all the comments (but maybe i'm the only one not reading all comments).
Sorry.
(Feel free to delete that comment and the previous one (if you can))
it was written somewhere here that your database settings should also include a database table prefix even if it is just an empty string .
I'm not a db expert, but it looks like the database table field 'id' is not used for insert/update/delete operation, so the primary key (id) of that table is not used. It could be better to have a composite primary key ('category','key').
I had to remove the {{ }} around the table name param (in config file or in the default param value. To get it to work.
Otherwise it raise an exception :
Then it seems to work ok (not tested a lot).
2012-06-01 17:24:39 Apache/2.2.21 (FreeBSD) mod_ssl/2.2.21 OpenSSL/0.9.8q PHP/5.3.8 with Suhosin-Patch Yii Framework/1.1.10
The component has been updated to version 1.2 with some new goodies (see changelog) Please test it and report any bug you find. Thanks.
This would require to have some kind of registry to store permanently all the defined categories that are cached, and it might be a good thing to have something like:
So i'll take it into consideration and implement it :)
Can we have a method where clear the cache for all groups? (I have a migration that inserts some values into the settings table, and I would like to call a method after that to clear the cache.)
I opened a new topic here: http://www.yiiframework.com/forum/index.php?/topic/23075-extensionsettings/ , please add the file as an attachment there and i'll check it and in the end implement your changes.
please create a post to discuss about the extension.
I've made a modified version of the extension that I would like to share.
Basically what I've changed is that I added a public property named 'tableName' with default value '{{settings}}' so you can easiely change the name of the table to use and this change also removes the need to add tablePrefix if you don't use it.
I've also added a connectionId property that defaults to 'db' and a getDbConnection method, replacing all Yii::app()->db to $this->getDbConnection so you can use a different db connection.
And a couple more things
Btw, great extension.
Thanks
Just now i saw the comments, don't know why but the yii website doesn't send notifications anymore for comments on my extensions.
@Wiseon3 - the values shouldn't be manipulated directly from database. And i prefer to use the serialize/unserialize functions to store all kind of data in the database.
Anyway, glad to hear this isn't another bug:)
@yiqing95 - sorry, right now i don't have too much available time, but i will take it into consideration.
@twisted1919 It seems the problem I had was due to the fact that I inserted the values by hand in the db (using phpmyadmin) instead of using the functions provided by the extension, which serialize the values before saving them to the db. Sorry about that.
@twisted1919 I encountered the same bug as ryurhrt After looking trough the code, I found what the problem is: In the load() function you unserialize every corresponding key value from the database. If the value is a string then the function returns false as it is unserializeable. To fix it, simply replace:
with
@twisted1919 : I am here again :)
now my situation is this: the table your provided is different from mine. but the
table fields have same semantics , only i need is tableName and table fields mapping.
so i need something like this:
then in your code reference above values: {$this->tableName} , {$this->xxAttibute} , thus these extension can apply to the tables existing early ,
surely i can do it myself ,but if you can add it will be better :). best regards !
Good to hear, but don't worry, thanks to you the extension has been improved and some bugs were fixed, so you did a great job reporting all of these.
Hi,
Sorry for the false bugs report, as I actually code to read the configuration with a class of my own, and i forgot the switch the reading class to read from the settings, and it read back to the yii's settings, so even i reset the value, it still reading the wrong place.
sorry for that, but now the module work correctly without any problem, thanks.
Leave a comment
Please login to leave your comment.