Skip to content

Commit

Permalink
CONTENTBOX-646 #resolve
Browse files Browse the repository at this point in the history
Ability to store global site settings in CacheBox with admin panel cusomizations
  • Loading branch information
lmajano committed Jan 21, 2016
1 parent fa2a4c0 commit 55f3676
Show file tree
Hide file tree
Showing 6 changed files with 100 additions and 37 deletions.
16 changes: 11 additions & 5 deletions modules/contentbox-admin/handlers/settings.cfc
Expand Up @@ -233,12 +233,18 @@ component extends="baseHandler"{
setNextEvent(event=prc.xehRawSettings,queryString="##wirebox" );
}

// View cached Keys
/**
* View settings cached data
* @return html
*/
function viewCached( event, rc, prc ){
var key = settingsService.getSettingsCacheKey();
rc.settings = getColdBoxOCM().get( key );
rc.metadata = getColdBoxOCM().getCachedObjectMetadata( key );
event.setView(view="settings/viewCached",layout="ajax" );
var cache = settingsService.getSettingsCacheProvider();
var cacheKey = settingsService.getSettingsCacheKey();
// get Cached Settings
prc.settings = cache.get( cacheKey );
prc.metadata = cache.getCachedObjectMetadata( cacheKey );

event.setView( view="settings/viewCached", layout="ajax" );
}

// Show full Auth Logs
Expand Down
14 changes: 14 additions & 0 deletions modules/contentbox-admin/views/settings/sections/siteOptions.cfm
Expand Up @@ -85,6 +85,20 @@
</div>
</div>

<!--- Caching of Settings --->
<div class="form-group">
<label class="control-label" for="cb_site_settings_cache">Settings Cache Provider:</label>
<div class="controls">
<small>Choose the CacheBox provider to cache global site settings into.</small><br/>
#html.select(
name = "cb_site_settings_cache",
options = prc.cacheNames,
selectedValue = prc.cbSettings.cb_site_settings_cache,
class = "input-sm"
)#
</div>
</div>

</fieldset>
<!---Blog Entries --->
<fieldset>
Expand Down
22 changes: 11 additions & 11 deletions modules/contentbox-admin/views/settings/viewCached.cfm
Expand Up @@ -4,7 +4,7 @@
<h3>Cached Settings</h3>
</div>
<div class="modal-body">
<h4>Cached Metadata</h4>
<h2>Cached Metadata</h2>
<!--- settings --->
<table class="table table-hover table-condensed table-striped" width="98%">
<thead>
Expand All @@ -19,17 +19,17 @@
</thead>
<tbody>
<tr>
<td class="text-center">#rc.metadata.hits#</td>
<td class="text-center">#rc.metadata.isExpired#</td>
<td class="text-center">#rc.metadata.created#</td>
<td class="text-center">#rc.metadata.lastAccessed#</td>
<td class="text-center">#rc.metadata.timeout#</td>
<td class="text-center">#rc.metadata.lastAccessTimeout#</td>
<td class="text-center">#prc.metadata.hits#</td>
<td class="text-center">#prc.metadata.isExpired#</td>
<td class="text-center">#prc.metadata.created#</td>
<td class="text-center">#prc.metadata.lastAccessed#</td>
<td class="text-center">#prc.metadata.timeout#</td>
<td class="text-center">#prc.metadata.lastAccessTimeout#</td>
</tr>
</tbody>
</table>

<h4>Cached Data</h4>
<h2>Cached Data</h2>
<!--- settings --->
<table name="settings" id="settings" class="table table-hover table-condensed table-striped" width="98%">
<thead>
Expand All @@ -39,10 +39,10 @@
</tr>
</thead>
<tbody>
<cfloop query="rc.settings">
<cfloop query="prc.settings">
<tr>
<td>#rc.settings.name#</td>
<td>#HTMLEditFormat( rc.settings.value )#</td>
<td>#HTMLEditFormat( prc.settings.name#</td>
<td>#HTMLEditFormat( prc.settings.value )#</td>
</tr>
</cfloop>
</tbody>
Expand Down
1 change: 1 addition & 0 deletions modules/contentbox-installer/models/InstallerService.cfc
Expand Up @@ -274,6 +274,7 @@ component accessors="true"{
"cb_site_blog_entrypoint" = "blog",
"cb_site_ssl" = "false",
"cb_site_poweredby" = "true",
"cb_site_settings_cache" = "Template",

// Security Settings
"cb_security_login_blocker" = "true",
Expand Down
81 changes: 60 additions & 21 deletions modules/contentbox/models/system/SettingService.cfc
Expand Up @@ -8,24 +8,32 @@
component extends="cborm.models.VirtualEntityService" accessors="true" threadsafe singleton{

// DI properties
property name="cache" inject="cachebox:default";
property name="cachebox" inject="cachebox";
property name="moduleSettings" inject="coldbox:setting:modules";
property name="appMapping" inject="coldbox:setting:appMapping";
property name="requestService" inject="coldbox:requestService";

// Properties
property name="settingsCacheKey" type="string";
/**
* The cache provider name. This is lazy-loaded upon request
*/
property name="cacheProviderName";

/**
* Constructor
*/
SettingService function init(){
// init it
super.init( entityName="cbSetting" );
// settings cache key
setSettingsCacheKey( "cb-settings-#cgi.http_host#" );
variables.cacheProviderName = "";
return this;
}

/**
* Retrieve a multi-tenant settings cache key
*/
string function getSettingsCacheKey(){
return "cb-settings-#cgi.http_host#";
}

/**
* Check if the installer and dsn creator modules are present
Expand Down Expand Up @@ -111,17 +119,22 @@ component extends="cborm.models.VirtualEntityService" accessors="true" threadsaf

/**
* Get all settings
* @asStruct Indicator if we should return structs or array of objects
*
* @return struct or array of objects
*/
function getAllSettings(asStruct=false){
// retrieve from cache
var settings = cache.get( settingsCacheKey );
function getAllSettings( boolean asStruct=false ){
var cache = getSettingsCacheProvider();
var cacheKey = getSettingsCacheKey();
// retrieve all settings from cache
var settings = cache.get( getSettingsCacheKey() );

// found in cache?
if( isNull( settings ) ){
// not found, so query db
var settings = list( sortOrder="name" );
// cache them for an hour
cache.set( settingsCacheKey, settings, 60 );
// cache them for 2 hours
cache.set( cacheKey, settings, 90 );
}

// convert to struct
Expand All @@ -137,26 +150,27 @@ component extends="cborm.models.VirtualEntityService" accessors="true" threadsaf
}

/**
* flush settings cache
* flush settings cache for current multi-tenant host
*/
function flushSettingsCache(){
cache.clear( settingsCacheKey );
SettingService function flushSettingsCache(){
getSettingsCacheProvider().clear( getSettingsCacheKey() );
return this;
}

/**
* Bulk saving of options using a memento structure of options
*/
any function bulkSave(struct memento){
var settings = getAllSettings(asStruct=true);
any function bulkSave( struct memento ){
var settings = getAllSettings( asStruct=true );
var oOption = "";
var newOptions = [];

// iterate over settings
for(var key in settings){
// save only sent in setting keys
if( structKeyExists(memento, key) ){
oOption = findWhere( {name=key} );
oOption.setValue( memento[key] );
if( structKeyExists( memento, key ) ){
oOption = findWhere( { name=key } );
oOption.setValue( memento[ key ] );
arrayAppend( newOptions, oOption );
}
}
Expand Down Expand Up @@ -208,7 +222,7 @@ component extends="cborm.models.VirtualEntityService" accessors="true" threadsaf
/**
* setting search returns struct with keys [settings,count]
*/
struct function search(search="", max=0, offset=0, sortOrder="name asc" ){
struct function search( search="", max=0, offset=0, sortOrder="name asc" ){
var results = {};
// criteria queries
var c = newCriteria();
Expand All @@ -229,9 +243,9 @@ component extends="cborm.models.VirtualEntityService" accessors="true" threadsaf
array function getAllForExport(){
var c = newCriteria();

return c.withProjections(property="settingID,name,value" )
return c.withProjections( property="settingID,name,value" )
.resultTransformer( c.ALIAS_TO_ENTITY_MAP )
.list(sortOrder="name" );
.list( sortOrder="name" );

}

Expand Down Expand Up @@ -291,4 +305,29 @@ component extends="cborm.models.VirtualEntityService" accessors="true" threadsaf
return importLog.toString();
}

/**
* Get the cache provider object to be used for settings
* @return coldbox.system.cache.ICacheProvider
*/
function getSettingsCacheProvider(){
if( !len( variables.cacheProviderName ) ){
lock name="settingsCacheProviderName" timeout="10" throwOnTimeout="true"{
if( !len( variables.cacheProviderName ) ){
// query db for cache name
var cacheProvider = newCriteria()
.isEq( "name", "cb_site_settings_cache" )
.get();
// lazy load it.
variables.cacheProviderName = cacheprovider.getValue();
}
}
}
// Return the cache to use.
return cacheBox.getCache( variables.cacheProviderName );
}

/******************************** PRIVATE ************************************************/



}
3 changes: 3 additions & 0 deletions workbench/patches/3.0.0-beta/Update.cfc
Expand Up @@ -217,6 +217,9 @@ component implements="contentbox.models.updates.IUpdate"{
var oSearchSetting = settingService.findWhere( { name="cb_search_adapter" } );
oSearchSetting.setValue( "contentbox.models.search.DBSearch" );
settingService.save( entity=oSearchSetting, transactional=false );

// Add new settings
addSetting( "cb_site_settings_cache", "Template" );
}

/************************************** DB MIGRATION OPERATIONS *********************************************/
Expand Down

1 comment on commit 55f3676

@Tropicalista
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi luis,

I think this commit breaks installer.

After dsn verify when the script redirect to installer, the ratelimiter checks for existence of setting

if( !settingService.getSetting( "cb_security_rate_limiter", false ) ){ return false; }

and try to access cacheprovider variable.

The problem is cacheprovider that does not exists.

Event: contentbox-ui:blog.index
Routed URL: /
Layout: N/A (Module: )
View: N/A
Timestamp: 01/24/2016 02:18:29 AM
Type: expression
Messages: variable [cacheprovider] doesn't exist
Tag Context:

Template: E:\ColdfusionBuilder\Network\cc\modules\contentbox\models\system\SettingService.cfc
LINE: 325: }
326: // lazy load it.
327: variables.cacheProviderName = cacheprovider.getValue();
328: }
329: }
Template: E:\ColdfusionBuilder\Network\cc\modules\contentbox\models\system\SettingService.cfc
LINE: 125: */
126: function getAllSettings( boolean asStruct=false ){
127: var cache = getSettingsCacheProvider();
128: var cacheKey = getSettingsCacheKey();
129: // retrieve all settings from cache
Template: E:\ColdfusionBuilder\Network\cc\modules\contentbox\models\system\SettingService.cfc
LINE: 104: */
105: function getSetting( required name, defaultValue ){
106: var s = getAllSettings( asStruct=true );
107: if( structKeyExists( s, arguments.name ) ){
108: return s[ arguments.name ];
Template: E:\ColdfusionBuilder\Network\cc\modules\contentbox\models\security\RateLimiter.cfc
LINE: 42: function onRequestCapture( event, interceptData, buffer ){
43: // If turned off, just exist
44: if( !settingService.getSetting( "cb_security_rate_limiter", false ) ){ return false; }
45: // do we limit bot OR normal requests as well?
46: if( !len( cgi.http_cookie ) OR !settingService.getSetting( "cb_security_rate_limiter_bots_only" ) ) {
Template: E:\ColdfusionBuilder\Network\cc\coldbox\system\web\context\InterceptorState.cfc
LINE: 368:
369:
370:
371:
372: <!--- Log It --->

Please sign in to comment.