forked from pixl8/Preside-CMS
-
Notifications
You must be signed in to change notification settings - Fork 0
/
SystemConfigurationService.cfc
381 lines (325 loc) · 11.1 KB
/
SystemConfigurationService.cfc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
/**
* The system configuration service provides the API layer
* for interacting with PresideCMS' [[editablesystemsettings]].
*
* @singleton
* @autodoc
*/
component displayName="System configuration service" {
// CONSTRUCTOR
/**
* @autoDiscoverDirectories.inject presidecms:directories
* @dao.inject presidecms:object:system_config
* @injectedConfig.inject coldbox:setting:injectedConfig
* @formsService.inject delayedInjector:formsService
* @siteService.inject delayedInjector:siteService
*/
public any function init(
required array autoDiscoverDirectories
, required any dao
, required struct injectedConfig
, required any formsService
, required any siteService
) {
_setAutoDiscoverDirectories( arguments.autoDiscoverDirectories );
_setDao( arguments.dao );
_setInjectedConfig( arguments.injectedConfig );
_setFormsService( arguments.formsService );
_setSiteService( arguments.siteService );
_setLoaded( false );
return this;
}
// PUBLIC API METHODS
/**
* Returns a setting that has been saved.
* See [[editablesystemsettings]] for a full guide.
*
* @autodoc
* @category.hint Category name of the setting to get
* @setting.hint Name of the setting to get
* @default.hint A default value to return should no value be saved for the setting
*
*/
public string function getSetting( required string category, required string setting, string default="" ) {
_reloadCheck();
var injected = _getInjectedConfig();
var activeSite = _getSiteService().getActiveSiteId();
var result = _getDao().selectData(
selectFields = [ "value" ]
, filter = { category = arguments.category, setting = arguments.setting, site=activeSite }
);
if ( result.recordCount ) {
return result.value;
}
result = _getDao().selectData(
selectFields = [ "value" ]
, filter = "category = :category and setting = :setting and site is null"
, filterParams = { category = arguments.category, setting = arguments.setting }
);
if ( result.recordCount ) {
return result.value;
}
return injected[ "#arguments.category#.#arguments.setting#" ] ?: arguments.default;
}
/**
* Returns all the saved settings for a given category.
* See [[editablesystemsettings]] for a full guide.
*
* @autodoc
* @category.hint The name of the category whose settings you wish to get
* @includeDefaults.hint Whether to include default global and injected settings or whether to just return the settings for the current site
* @globalDefaultsOnly.hint Whether to only include default global and injected settings or whether to include all amalgamated settings
*
*/
public struct function getCategorySettings(
required string category
, boolean includeDefaults = true
, boolean globalDefaultsOnly = false
, boolean fromVersionTable = false
, numeric maxVersionNumber = 0
, string orderBy = ""
, string siteId = _getSiteService().getActiveSiteId()
) {
_reloadCheck();
var result = {};
if ( !arguments.globalDefaultsOnly ) {
var rawSiteResult = _getDao().selectData(
selectFields = [ "setting", "value" ]
, filter = { category = arguments.category, site=arguments.siteId }
, fromVersionTable = arguments.fromVersionTable
, maxVersionNumber = arguments.maxVersionNumber
, orderBy = arguments.orderBy
);
for( var record in rawSiteResult ){
result[ record.setting ] = record.value;
}
}
if ( arguments.includeDefaults ) {
var injectedStartsWith = "#arguments.category#.";
var rawGlobalResult = _getDao().selectData(
selectFields = [ "setting", "value" ]
, filter = "category = :category and site is null"
, filterParams = { category = arguments.category }
, fromVersionTable = arguments.fromVersionTable
, maxVersionNumber = arguments.maxVersionNumber
, orderBy = arguments.orderBy
);
for( var record in rawGlobalResult ){
if ( !result.keyExists( record.setting ) ) {
result[ record.setting ] = record.value;
}
}
var injected = _getInjectedConfig().filter( function( key ){ return key.startsWith( injectedStartsWith ) } );
for( var key in injected ) {
var setting = ListRest( key, "." );
if ( !result.keyExists( setting ) ) {
result[ setting ] = injected[ key ];
}
}
}
return result;
}
/**
* Saves the value of a setting.
* See [[editablesystemsettings]] for a full guide.
*
* @autodoc
* @category.hint Category name of the setting to save
* @setting.hint Name of the setting to save
* @value.hint Value to save
* @siteId.hint ID of site to which the setting applies (optional, if empty setting is treated as system wide default)
*
*/
public any function saveSetting(
required string category
, required string setting
, required string value
, string siteId = ""
) {
_reloadCheck();
var dao = _getDao();
transaction {
var filter = "category = :category and setting = :setting and site ";
var params = { category = arguments.category, setting = arguments.setting };
if ( Len( Trim( arguments.siteId ) ) ) {
filter &= "= :site";
params.site = arguments.siteId;
} else {
filter &= "is null";
}
var currentRecord = dao.selectData(
selectFields = [ "id" ]
, filter = filter
, filterParams = params
);
if ( currentRecord.recordCount ) {
return dao.updateData(
data = { value = arguments.value }
, id = currentRecord.id
);
} else {
return dao.insertData(
data = {
category = arguments.category
, setting = arguments.setting
, value = arguments.value
, site = arguments.siteId
}
);
}
}
}
public any function deleteSetting(
required string category
, required string setting
, string siteId = ""
) {
_reloadCheck();
var dao = _getDao();
var filter = "category = :category and setting = :setting and site ";
var params = { category = arguments.category, setting = arguments.setting };
if ( Len( Trim( arguments.siteId ) ) ) {
filter &= "= :site";
params.site = arguments.siteId;
}
return dao.deleteData(
filter = filter
, filterParams = params
);
}
public array function listConfigCategories() {
_reloadCheck();
var categories = _getConfigCategories();
var result = [];
for( var id in categories ){
ArrayAppend( result, categories[ id ] );
}
return result;
}
public ConfigCategory function getConfigCategory( required string id ) {
_reloadCheck();
var categories = _getConfigCategories();
if ( categories.keyExists( arguments.id ) ) {
return categories[ arguments.id ];
}
categories = categories.keyArray();
categories.sort( "textnocase" );
categories = SerializeJson( categories );
throw(
type = "SystemConfigurationService.category.notFound"
, message = "The configuration category [#arguments.id#] could not be found. Configured categories are: #categories#"
);
}
public void function reload() {
_setConfigCategories({});
_autoDiscoverCategories();
}
// PRIVATE HELPERS
private void function _autoDiscoverCategories() {
var objectsPath = "/forms/system-config";
var ids = {};
var autoDiscoverDirectories = _getAutoDiscoverDirectories();
for( var dir in autoDiscoverDirectories ) {
dir = ReReplace( dir, "/$", "" );
var objects = DirectoryList( dir & objectsPath, false, "query", "*.xml" );
for ( var obj in objects ) {
if ( obj.type eq "File" ) {
ids[ ReReplace( obj.name, "\.xml$", "" ) ] = true;
}
}
}
for( var id in ids ) {
if ( _getFormsService().formExists( formName="system-config." & id, checkSiteTemplates=false ) ) {
_registerCategory( id = LCase( id ) );
}
}
}
private void function _registerCategory( required string id ) {
var categories = _getConfigCategories();
categories[ arguments.id ] = new ConfigCategory(
id = arguments.id
, name = _getConventionsBaseCategoryName( arguments.id )
, description = _getConventionsBaseCategoryDescription( arguments.id )
, icon = _getConventionsBaseCategoryIcon( arguments.id )
, form = _getConventionsBaseCategoryForm( arguments.id )
, siteForm = _getConventionsBaseSiteCategoryForm( arguments.id )
);
}
private string function _getConventionsBaseCategoryName( required string id ) {
return "system-config.#arguments.id#:name";
}
private string function _getConventionsBaseCategoryDescription( required string id ) {
return "system-config.#arguments.id#:description";
}
private string function _getConventionsBaseCategoryIcon( required string id ) {
return "system-config.#arguments.id#:iconClass";
}
private string function _getConventionsBaseCategoryForm( required string id ) {
return "system-config.#arguments.id#";
}
private string function _getConventionsBaseSiteCategoryForm( required string id ) {
var fullFormName = _getConventionsBaseCategoryForm( arguments.id );
return _getFormsService().createForm( basedOn=fullFormName, generator=function( definition ){
var rawForm = definition.getRawDefinition();
var tabs = rawForm.tabs ?: [];
for( var tab in tabs ) {
var fieldsets = tab.fieldsets ?: [];
for ( var fieldset in tab.fieldsets ) {
var fields = fieldset.fields ?: [];
for( var field in fields ) {
definition.modifyField( name=field.name ?: "", fieldset=fieldset.id ?: "", tab=tab.id ?: "", required=false );
}
}
}
} );
}
private void function _reloadCheck() {
if ( !_isLoaded() ) {
reload();
_setLoaded( true );
}
}
// GETTERS AND SETTERS
private array function _getAutoDiscoverDirectories() {
return _autoDiscoverDirectories;
}
private void function _setAutoDiscoverDirectories( required array autoDiscoverDirectories ) {
_autoDiscoverDirectories = arguments.autoDiscoverDirectories;
}
private any function _getDao() {
return _dao;
}
private void function _setDao( required any dao ) {
_dao = arguments.dao;
}
private struct function _getConfigCategories() {
return _configCategories;
}
private void function _setConfigCategories( required struct configCategories ) {
_configCategories = arguments.configCategories;
}
private struct function _getInjectedConfig() {
return _injectedConfig;
}
private void function _setInjectedConfig( required struct injectedConfig ) {
_injectedConfig = arguments.injectedConfig;
}
private struct function _getFormsService() {
return _formsService;
}
private void function _setFormsService( required struct formsService ) {
_formsService = arguments.formsService;
}
private boolean function _isLoaded() {
return _loaded;
}
private void function _setLoaded( required boolean loaded ) {
_loaded = arguments.loaded;
}
private any function _getSiteService() {
return _siteService;
}
private void function _setSiteService( required any siteService ) {
_siteService = arguments.siteService;
}
}