Class: CmseditController
- Inherits:
-
DcApplicationController
- Object
- ActionController::Base
- DcApplicationController
- CmseditController
- Defined in:
- app/controllers/cmsedit_controller.rb
Overview
This is main controller for processing actions by DRG forms. It provides CRUD actions for editing MongoDB documents. DRG CMS does not require controller to be made for every document model but centers all actions into single controller. Logic required to control data entry is provided within DRG forms which are loaded dynamically for every action.
Most of data entry controls must therefore be done in document models definitions. And there are controls that cannot be done in document models. Like controls which include url parameters or accessing session variables. This is hard to be done in model therefore cmsedit_controls had to be invented. cmsedit_controls are modules with methods that are injected into cmsedit_controller and act in runtime like they are part of cmsedit_controller.
Since Ruby and Rails provide some automagic loading of modules DRG CMS controls must be saved into app/controllers/drgcms_controls folder. Every model can have its own controls file. dc_page model’s controls live in dc_page_controls.rb file. If model has embedded document its control’s would be found in model_embedded_controls.rb. By convention module names are declared in camel case, so our dc_page_controls.rb declares DrgcmsControls::DcPageControls module.
Controls (among other) may contain 7 callback methods. These methods are:
-
dc_new_record
-
dc_dup_record
-
dc_before_edit
-
dc_before_save
-
dc_after_save
-
dc_before_delete
-
dc_after_delete
Methods dc_before_edit, before_save or before_delete may also effect flow of the application. If method return false (not nil but FalseClass) normal flow of the program is interrupted and last operation is canceled.
Second control methods that can be declared in DRG CMS controls are filters for viewing and sorting documents. It is often required that dynamic filters are applied to result_set documents.
result_set:
filter: current_users_documents
Example implemented controls method:
def current_users_documents
if dc_user_can(DcPermission::CAN_READ)
dc_page.where(created_by: session[:user_id])
else
flash[:error] = 'User can not perform this operation!'
nil
end
end
If filter method returns false user will be presented with flash error.
Instance Method Summary collapse
-
#_filter ⇒ Object
Filter action.
-
#create ⇒ Object
Create (or duplicate) action.
-
#destroy ⇒ Object
Destroy action.
-
#duplicate_document(source) ⇒ Object
Will create duplicate document of source document.
-
#duplicate_embedded(source) ⇒ Object
Duplicate embedded document.
-
#edit ⇒ Object
Edit action.
-
#index ⇒ Object
Index action.
-
#login ⇒ Object
Login action.
-
#logout ⇒ Object
Logout action.
-
#new ⇒ Object
New action.
-
#run ⇒ Object
Run action.
-
#set_test_site ⇒ Object
Shortcut for setting currently selected site in development.
-
#show ⇒ Object
Show displays record in readonly mode.
-
#update ⇒ Object
Update action.
Methods inherited from DcApplicationController
#dc_dump, #dc_edit_mode?, #dc_get_site, #dc_log_visit, #dc_render_404, #dc_user_has_role, #set_page_title
Instance Method Details
#_filter ⇒ Object
Filter action.
102 103 104 |
# File 'app/controllers/cmsedit_controller.rb', line 102 def _filter index end |
#create ⇒ Object
Create (or duplicate) action.
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 |
# File 'app/controllers/cmsedit_controller.rb', line 263 def create # not authorized unless dc_user_can(DcPermission::CAN_CREATE) flash[:error] = t('drgcms.not_authorized') return index end # create document if params['id'].nil? # Prevent double form submit params[:form_time_stamp] = params[:form_time_stamp].to_i session[:form_time_stamp] ||= 0 return index if params[:form_time_stamp] <= session[:form_time_stamp] && !Rails.env.test? session[:form_time_stamp] = params[:form_time_stamp] create_new_empty_record if save_data flash[:info] = t('drgcms.doc_saved') params[:return_to] = 'index' if params[:commit] == t('drgcms.save&back') # save & back return process_return_to(params[:return_to]) if params[:return_to] @form_params['id'] = @record.id # must be set, for proper update link params[:id] = @record.id # must be set, for find_record edit else # error return process_return_to(params[:return_to]) if params[:return_to] render action: :new end else # duplicate record find_record new_doc = duplicate_document(@record) create_new_empty_record(new_doc) if (m = callback_method('dup_record')) then call_callback_method(m) end update_standards @record.save! index end end |
#destroy ⇒ Object
Destroy action. Used also for enabling and disabling record.
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 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 |
# File 'app/controllers/cmsedit_controller.rb', line 352 def destroy find_record # check permission required to delete = if params['operation'].nil? if @record.respond_to?('created_by') # needs can_delete_all if created_by is present and not owner (@record.created_by == session[:user_id]) ? DcPermission::CAN_DELETE : DcPermission::CAN_DELETE_ALL else DcPermission::CAN_DELETE # by default end else # enable or disable record if @record.respond_to?('created_by') (@record.created_by == session[:user_id]) ? DcPermission::CAN_EDIT : DcPermission::CAN_EDIT_ALL else DcPermission::CAN_EDIT # by default end end ok2delete = dc_user_can() case # not authorized when !ok2delete then flash[:error] = t('drgcms.not_authorized') return index # delete document when params['operation'].nil? then # before_delete callback if (m = callback_method('before_delete') ) ret = call_callback_method(m) # don't do anything if return is false return index if ret.class == FalseClass end if @record.destroy save_journal(:delete) flash[:info] = t('drgcms.record_deleted') # after_delete callback if (m = callback_method('after_delete') ) call_callback_method(m) elsif params['after-delete'].to_s.match('return_to') params[:return_to] = params['after-delete'] end # Process return_to link return process_return_to(params[:return_to]) if params[:return_to] else flash[:error] = (@record) end return index # deactivate document when params['operation'] == 'disable' then if @record.respond_to?('active') @record.active = false save_journal(:update, @record.changes) update_standards() @record.save flash[:info] = t('drgcms.doc_disabled') end # reactivate document when params['operation'] == 'enable' then if @record.respond_to?('active') @record.active = true update_standards() save_journal(:update, @record.changes) @record.save flash[:info] = t('drgcms.doc_enabled') end #TODO reorder documents when params['operation'] == 'reorder' then end @form_params['action'] = 'update' render action: :edit end |
#duplicate_document(source) ⇒ Object
Will create duplicate document of source document. This method is used for duplicating document and is subroutine of create action.
235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 |
# File 'app/controllers/cmsedit_controller.rb', line 235 def duplicate_document(source) params['dup_fields'] += ',' if params['dup_fields'] # for easier field matching dest = {} source.attribute_names.each do |attribute_name| next if attribute_name == '_id' # don't duplicate _id # if duplicate, string dup is added. For unique fields add_duplicate = params['dup_fields'].to_s.match(attribute_name + ',') dest[attribute_name] = source[attribute_name] dest[attribute_name] << ' dup' if add_duplicate end # embedded documents source..keys.each do || next if source[].nil? # it happens dest[] = [] source[].each do || dest[] << () end end dest['created_at'] = Time.now if dest['created_at'] dest['updated_at'] = Time.now if dest['updated_at'] dest end |
#duplicate_embedded(source) ⇒ Object
Duplicate embedded document. Since embedded documents are returned differently then top level document. Subroutine of duplicate_socument.
TODO Works for two embedded levels. Dies with third and more levels.
209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 |
# File 'app/controllers/cmsedit_controller.rb', line 209 def (source) #:nodoc: dest = {} source.each do |attribute_name, value| next if attribute_name == '_id' # don't duplicate _id if value.class == Array dest[attribute_name] = [] value.each do |ar| dest[attribute_name] << (ar) end else # if duplicate, string dup is added. For unique fields add_duplicate = params['dup_fields'].to_s.match(attribute_name + ',') dest[attribute_name] = value dest[attribute_name] << ' dup' if add_duplicate end end dest['created_at'] = Time.now if dest['created_at'] dest['updated_at'] = Time.now if dest['updated_at'] dest end |
#edit ⇒ Object
Edit action.
306 307 308 309 310 311 312 313 314 315 |
# File 'app/controllers/cmsedit_controller.rb', line 306 def edit find_record if (m = callback_method('before_edit') ) ret = call_callback_method(m) # don't do anything if return is false return index if ret.class == FalseClass end @form_params['action'] = 'update' render action: :edit end |
#index ⇒ Object
Index action
87 88 89 90 91 92 93 94 95 96 97 |
# File 'app/controllers/cmsedit_controller.rb', line 87 def index @form['result_set'] ||= {} redirected = (@form['table'] == 'dc_memory' ? process_in_memory : process_collections) return if redirected call_callback_method(@form['result_set']['footer'] || 'dc_footer') respond_to do |format| format.html { render action: :index } format.js { render partial: :result } end end |
#login ⇒ Object
Login action. Used to login direct to CMS. It is mostly used when first time creating site and when something goes so wrong, that traditional login procedure is not available.
Login can be called directly with url site.com/cmsedit/login
131 132 133 134 135 136 |
# File 'app/controllers/cmsedit_controller.rb', line 131 def login return set_test_site if params[:id] == 'test' session[:edit_mode] = 0 if !params[:ok] render action: 'login', layout: 'cms' end |
#logout ⇒ Object
Logout action. Used to logout direct from CMS.
Logout can be called directly with url site.com/cmsedit/logout
143 144 145 146 147 |
# File 'app/controllers/cmsedit_controller.rb', line 143 def logout session[:edit_mode] = 0 session[:user_id] = nil render action: 'login', layout: 'cms' end |
#new ⇒ Object
New action.
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 |
# File 'app/controllers/cmsedit_controller.rb', line 171 def new # clear flash messages. flash[:error] = flash[:warning] = flash[:info] = nil create_new_empty_record # before_new callback if (m = callback_method('before_new') ) ret = call_callback_method(m) return index if ret.class == FalseClass end table = @tables.last[1] + '.' # initial values set on page if [:record] && [:record].size > 0 Marshal.load([:record]).each do |k,v| k = k.to_s if k.match(table) field = k.split('.').last @record.send("#{field}=", v) if @record.respond_to?(field) end end end # initial values set in url (params) params.each do |k,v| if k.match(table) field = k.split('.').last @record.send("#{field}=", v) if @record.respond_to?(field) end end # new_record callback. Set default values for new record if (m = callback_method('new_record') ) then call_callback_method(m) end @form_params['action'] = 'create' end |
#run ⇒ Object
Run action
433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 |
# File 'app/controllers/cmsedit_controller.rb', line 433 def run # determine control file name and method control_name, method_name = params[:control].split('.') if method_name.nil? method_name = control_name control_name = CmsHelper.table_param(params) end # extend with control methods extend_with_control_module(control_name) if respond_to?(method_name) # can it be called return return_run_error t('drgcms.not_authorized') unless can_process_run # call method respond_to do |format| format.json { send method_name } format.html { send method_name } end else # Error message return_run_error "Method #{method_name} not defined in #{control_name}_control" end end |
#set_test_site ⇒ Object
Shortcut for setting currently selected site in development. Will search for dc_site document with site name ‘test’ and set alias_for to site url parameter.
154 155 156 157 158 159 160 161 162 163 164 165 166 |
# File 'app/controllers/cmsedit_controller.rb', line 154 def set_test_site # only in development return dc_render_404 unless Rails.env.development? alias_site = DcSite.find_by(:name => params[:site]) return dc_render_404 unless alias_site # update alias for site = DcSite.find_by(:name => 'test') site.alias_for = params[:site] site.save redirect_to '/' end |
#show ⇒ Object
Show displays record in readonly mode.
109 110 111 112 113 114 115 116 117 118 119 120 121 122 |
# File 'app/controllers/cmsedit_controller.rb', line 109 def show find_record # before_show callback if (m = callback_method('before_show') ) ret = call_callback_method(m) if ret.class == FalseClass @form['readonly'] = nil # must be flash[:error] ||= t('drgcms.not_authorized') return index end end render action: 'edit', layout: 'cms' end |
#update ⇒ Object
Update action.
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 |
# File 'app/controllers/cmsedit_controller.rb', line 320 def update find_record # check if record was not updated in mean time if @record.respond_to?(:updated_at) if params[:last_updated_at].to_i != @record.updated_at.to_i flash[:error] = t('drgcms.updated_by_other') return render(action: :edit) end end if dc_user_can(DcPermission::CAN_EDIT_ALL) || (@record.respond_to?('created_by') && @record.created_by == session[:user_id] && dc_user_can(DcPermission::CAN_EDIT)) if save_data params[:return_to] = 'index' if params[:commit] == t('drgcms.save&back') # save & back @form_params['action'] = 'update' # Process return_to return process_return_to(params[:return_to]) if params[:return_to] else # do not forget before_edit callback if m = callback_method('before_edit') then call_callback_method(m) end return render action: :edit end else flash[:error] = t('drgcms.not_authorized') end edit end |