card 1.19.1 → 1.19.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.yardopts +3 -3
- data/VERSION +1 -1
- data/db/migrate_core_cards/20160908154210_add_trash_card.rb +7 -0
- data/lib/card.rb +2 -2
- data/lib/card/act_manager.rb +143 -0
- data/lib/card/act_manager/stage.rb +56 -0
- data/lib/card/act_manager/stage_director.rb +313 -0
- data/lib/card/act_manager/subdirector_array.rb +43 -0
- data/lib/card/set.rb +1 -0
- data/lib/card/set/i18n_scope.rb +52 -0
- data/lib/card/subcards.rb +2 -3
- data/lib/cardio.rb +4 -4
- data/mod/admin/set/self/admin.rb +1 -2
- data/mod/admin/set/self/trash.rb +29 -0
- data/mod/core/set/abstract/code_file.rb +5 -25
- data/mod/core/set/all/actify.rb +35 -0
- data/mod/core/set/all/fetch.rb +12 -15
- data/mod/core/set/all/i18n.rb +9 -0
- data/mod/core/set/all/phases.rb +1 -1
- data/mod/core/set/all/stages.rb +2 -2
- data/mod/developer/set/all/event_viz.rb +2 -1
- data/mod/email/set/all/notify.rb +1 -1
- data/mod/history/lib/card/act.rb +1 -1
- data/mod/history/lib/card/action.rb +1 -1
- data/mod/history/set/all/history.rb +1 -1
- data/mod/machines/set/abstract/machine.rb +1 -1
- data/mod/machines/spec/set/type/coffeescript_spec.rb +1 -1
- data/mod/machines/spec/set/type/css_spec.rb +1 -1
- data/mod/machines/spec/set/type/javascript_spec.rb +1 -1
- data/mod/machines/spec/set/type/scss_spec.rb +1 -1
- data/mod/machines/spec/set/type/skin_spec.rb +1 -1
- data/mod/machines/spec/{lib/shared_machine_examples.rb → shared_examples/machine.rb} +15 -24
- data/mod/machines/spec/{lib/shared_machine_input_examples.rb → shared_examples/machine_input.rb} +0 -0
- data/mod/settings/spec/set/right/script_spec.rb +1 -1
- data/mod/settings/spec/set/right/style_spec.rb +1 -4
- data/mod/solid_cache/set/abstract/solid_cache.rb +1 -1
- data/spec/lib/card/content_spec.rb +118 -132
- data/spec/lib/card/i18n_spec.rb +6 -7
- data/spec/lib/card/query_spec.rb +5 -4
- data/spec/lib/card/stage_director_spec.rb +1 -1
- data/spec/spec_helper.rb +3 -4
- data/tmpsets/set/{mod002-core → mod001-core}/abstract/code_file.rb +0 -0
- data/tmpsets/set/{mod002-core → mod001-core}/all/actify.rb +0 -0
- data/tmpsets/set/{mod002-core → mod001-core}/all/active_card.rb +0 -0
- data/tmpsets/set/{mod002-core → mod001-core}/all/collection.rb +0 -0
- data/tmpsets/set/{mod002-core → mod001-core}/all/content.rb +0 -0
- data/tmpsets/set/{mod002-core → mod001-core}/all/erb.rb +0 -0
- data/tmpsets/set/{mod002-core → mod001-core}/all/event.rb +0 -0
- data/tmpsets/set/{mod002-core → mod001-core}/all/export.rb +0 -0
- data/tmpsets/set/{mod002-core → mod001-core}/all/fetch.rb +12 -14
- data/tmpsets/set/{mod002-core → mod001-core}/all/haml.rb +0 -0
- data/tmpsets/set/{mod002-core → mod001-core}/all/initialize.rb +0 -0
- data/tmpsets/set/{mod002-core → mod001-core}/all/location_history.rb +0 -0
- data/tmpsets/set/{mod002-core → mod001-core}/all/name.rb +0 -0
- data/tmpsets/set/{mod002-core → mod001-core}/all/name_validations.rb +0 -0
- data/tmpsets/set/{mod002-core → mod001-core}/all/pattern.rb +0 -0
- data/tmpsets/set/{mod002-core → mod001-core}/all/permissions.rb +0 -0
- data/tmpsets/set/{mod002-core → mod001-core}/all/phases.rb +0 -0
- data/tmpsets/set/{mod002-core → mod001-core}/all/references.rb +0 -0
- data/tmpsets/set/{mod002-core → mod001-core}/all/rules.rb +0 -0
- data/tmpsets/set/{mod002-core → mod001-core}/all/stages.rb +0 -0
- data/tmpsets/set/{mod002-core → mod001-core}/all/states.rb +0 -0
- data/tmpsets/set/{mod002-core → mod001-core}/all/subcards.rb +0 -0
- data/tmpsets/set/{mod002-core → mod001-core}/all/templating.rb +0 -0
- data/tmpsets/set/{mod002-core → mod001-core}/all/tracked_attributes.rb +0 -0
- data/tmpsets/set/{mod002-core → mod001-core}/all/trash.rb +0 -50
- data/tmpsets/set/{mod002-core → mod001-core}/all/type.rb +0 -0
- data/tmpsets/set/{mod002-core → mod001-core}/all/utils.rb +33 -0
- data/tmpsets/set/{mod002-core → mod001-core}/all/view_cache.rb +0 -0
- data/tmpsets/set/{mod003-history → mod002-history}/all/actions.rb +0 -0
- data/tmpsets/set/{mod003-history → mod002-history}/all/content_history.rb +0 -0
- data/tmpsets/set/{mod003-history → mod002-history}/all/history.rb +0 -0
- data/tmpsets/set/{mod004-basic_formats → mod003-basic_formats}/all/all_css.rb +0 -0
- data/tmpsets/set/{mod004-basic_formats → mod003-basic_formats}/all/all_csv.rb +0 -0
- data/tmpsets/set/{mod004-basic_formats → mod003-basic_formats}/all/all_js.rb +0 -0
- data/tmpsets/set/{mod004-basic_formats → mod003-basic_formats}/all/base.rb +0 -0
- data/tmpsets/set/{mod004-basic_formats → mod003-basic_formats}/all/file.rb +0 -0
- data/tmpsets/set/{mod004-basic_formats → mod003-basic_formats}/all/json.rb +0 -0
- data/tmpsets/set/{mod004-basic_formats → mod003-basic_formats}/all/rss.rb +0 -0
- data/tmpsets/set/{mod004-basic_formats → mod003-basic_formats}/all/text.rb +0 -0
- data/tmpsets/set/{mod004-basic_formats → mod003-basic_formats}/self/01_head/javascript.rb +0 -0
- data/tmpsets/set/{mod004-basic_formats → mod003-basic_formats}/self/head.rb +1 -1
- data/tmpsets/set/{mod005-pointer → mod004-pointer}/abstract/01_pointer.rb +0 -0
- data/tmpsets/set/{mod005-pointer → mod004-pointer}/abstract/01_pointer/edit.rb +0 -0
- data/tmpsets/set/{mod005-pointer → mod004-pointer}/abstract/code_pointer.rb +0 -0
- data/tmpsets/set/{mod005-pointer → mod004-pointer}/self/script_editors.rb +0 -0
- data/tmpsets/set/{mod005-pointer → mod004-pointer}/self/script_mods.rb +0 -0
- data/tmpsets/set/{mod005-pointer → mod004-pointer}/self/script_pointer_config.rb +0 -0
- data/tmpsets/set/{mod005-pointer → mod004-pointer}/type/pointer.rb +0 -0
- data/tmpsets/set/{mod006-ace_editor → mod005-ace_editor}/abstract/ace_editor.rb +0 -0
- data/tmpsets/set/{mod006-ace_editor → mod005-ace_editor}/self/script_ace.rb +0 -0
- data/tmpsets/set/{mod006-ace_editor → mod005-ace_editor}/self/script_ace_config.rb +0 -0
- data/tmpsets/set/{mod007-prosemirror_editor → mod006-prosemirror_editor}/abstract/prosemirror_editor.rb +0 -0
- data/tmpsets/set/{mod007-prosemirror_editor → mod006-prosemirror_editor}/self/script_prosemirror.rb +0 -0
- data/tmpsets/set/{mod007-prosemirror_editor → mod006-prosemirror_editor}/self/script_prosemirror_config.rb +0 -0
- data/tmpsets/set/{mod009-solid_cache → mod008-solid_cache}/abstract/solid_cache.rb +1 -1
- data/tmpsets/set/{mod009-solid_cache → mod008-solid_cache}/all/solid_cache.rb +0 -0
- data/tmpsets/set/{mod009-solid_cache → mod008-solid_cache}/right/solid_cache.rb +0 -0
- data/tmpsets/set/{mod010-basic_types → mod009-basic_types}/type/html.rb +0 -0
- data/tmpsets/set/{mod010-basic_types → mod009-basic_types}/type/plain_text.rb +0 -0
- data/tmpsets/set/{mod011-machines → mod010-machines}/abstract/script.rb +0 -0
- data/tmpsets/set/{mod011-machines → mod010-machines}/all/reset_machines.rb +0 -0
- data/tmpsets/set/{mod011-machines → mod010-machines}/right/machine_cache.rb +0 -0
- data/tmpsets/set/{mod011-machines → mod010-machines}/right/machine_input.rb +0 -0
- data/tmpsets/set/{mod011-machines → mod010-machines}/right/machine_output.rb +1 -9
- data/tmpsets/set/{mod011-machines → mod010-machines}/self/script_card_menu.rb +0 -0
- data/tmpsets/set/{mod011-machines → mod010-machines}/self/script_html5shiv_printshiv.rb +0 -0
- data/tmpsets/set/{mod011-machines → mod010-machines}/self/script_jquery.rb +0 -0
- data/tmpsets/set/{mod011-machines → mod010-machines}/self/script_jquery_helper.rb +0 -0
- data/tmpsets/set/{mod011-machines → mod010-machines}/self/script_slot.rb +0 -0
- data/tmpsets/set/{mod011-machines → mod010-machines}/self/style_bootstrap_compatible.rb +0 -0
- data/tmpsets/set/{mod011-machines → mod010-machines}/self/style_cards.rb +0 -0
- data/tmpsets/set/{mod011-machines → mod010-machines}/self/style_jquery_ui_smoothness.rb +0 -0
- data/tmpsets/set/{mod011-machines → mod010-machines}/type/coffee_script.rb +6 -2
- data/tmpsets/set/{mod011-machines → mod010-machines}/type/css.rb +2 -2
- data/tmpsets/set/{mod011-machines → mod010-machines}/type/java_script.rb +2 -2
- data/tmpsets/set/{mod011-machines → mod010-machines}/type/scss.rb +0 -0
- data/tmpsets/set/{mod011-machines → mod010-machines}/type/skin.rb +2 -2
- data/tmpsets/set/{mod012-settings → mod011-settings}/abstract/permission.rb +0 -0
- data/tmpsets/set/{mod012-settings → mod011-settings}/right/add_help.rb +0 -0
- data/tmpsets/set/{mod012-settings → mod011-settings}/right/comment.rb +0 -0
- data/tmpsets/set/{mod012-settings → mod011-settings}/right/create.rb +0 -0
- data/tmpsets/set/{mod012-settings → mod011-settings}/right/default.rb +0 -0
- data/tmpsets/set/{mod012-settings → mod011-settings}/right/delete.rb +0 -0
- data/tmpsets/set/{mod012-settings → mod011-settings}/right/help.rb +0 -0
- data/tmpsets/set/{mod012-settings → mod011-settings}/right/read.rb +0 -0
- data/tmpsets/set/{mod012-settings → mod011-settings}/right/script.rb +1 -1
- data/tmpsets/set/{mod012-settings → mod011-settings}/right/structure.rb +0 -0
- data/tmpsets/set/{mod012-settings → mod011-settings}/right/style.rb +1 -1
- data/tmpsets/set/{mod012-settings → mod011-settings}/right/update.rb +0 -0
- data/tmpsets/set/{mod012-settings → mod011-settings}/self/accountable.rb +0 -0
- data/tmpsets/set/{mod012-settings → mod011-settings}/self/add_help.rb +0 -0
- data/tmpsets/set/{mod012-settings → mod011-settings}/self/autoname.rb +0 -0
- data/tmpsets/set/{mod012-settings → mod011-settings}/self/captcha.rb +0 -0
- data/tmpsets/set/{mod012-settings → mod011-settings}/self/create.rb +0 -0
- data/tmpsets/set/{mod012-settings → mod011-settings}/self/default.rb +0 -0
- data/tmpsets/set/{mod012-settings → mod011-settings}/self/default_html_view.rb +0 -0
- data/tmpsets/set/{mod012-settings → mod011-settings}/self/delete.rb +0 -0
- data/tmpsets/set/{mod012-settings → mod011-settings}/self/follow_fields.rb +0 -0
- data/tmpsets/set/{mod012-settings → mod011-settings}/self/help.rb +0 -0
- data/tmpsets/set/{mod012-settings → mod011-settings}/self/input.rb +0 -0
- data/tmpsets/set/{mod012-settings → mod011-settings}/self/layout.rb +0 -0
- data/tmpsets/set/{mod012-settings → mod011-settings}/self/on_create.rb +0 -0
- data/tmpsets/set/{mod012-settings → mod011-settings}/self/on_delete.rb +0 -0
- data/tmpsets/set/{mod012-settings → mod011-settings}/self/on_update.rb +0 -0
- data/tmpsets/set/{mod012-settings → mod011-settings}/self/options.rb +0 -0
- data/tmpsets/set/{mod012-settings → mod011-settings}/self/options_label.rb +0 -0
- data/tmpsets/set/{mod012-settings → mod011-settings}/self/read.rb +0 -0
- data/tmpsets/set/{mod012-settings → mod011-settings}/self/recent_settings.rb +0 -0
- data/tmpsets/set/{mod012-settings → mod011-settings}/self/script.rb +0 -0
- data/tmpsets/set/{mod012-settings → mod011-settings}/self/structure.rb +0 -0
- data/tmpsets/set/{mod012-settings → mod011-settings}/self/style.rb +0 -0
- data/tmpsets/set/{mod012-settings → mod011-settings}/self/table_of_contents.rb +0 -0
- data/tmpsets/set/{mod012-settings → mod011-settings}/self/thanks.rb +0 -0
- data/tmpsets/set/{mod012-settings → mod011-settings}/self/update.rb +0 -0
- data/tmpsets/set/{mod012-settings → mod011-settings}/type/setting.rb +0 -0
- data/tmpsets/set/{mod013-email → mod012-email}/all/email_html.rb +0 -0
- data/tmpsets/set/{mod013-email → mod012-email}/all/email_text.rb +0 -0
- data/tmpsets/set/{mod013-email → mod012-email}/all/follow.rb +0 -0
- data/tmpsets/set/{mod013-email → mod012-email}/all/notify.rb +0 -0
- data/tmpsets/set/{mod013-email → mod012-email}/all/observer.rb +0 -0
- data/tmpsets/set/{mod013-email → mod012-email}/right/bcc.rb +0 -0
- data/tmpsets/set/{mod013-email → mod012-email}/right/cc.rb +0 -0
- data/tmpsets/set/{mod013-email → mod012-email}/right/follow.rb +0 -0
- data/tmpsets/set/{mod013-email → mod012-email}/right/follow_fields.rb +0 -0
- data/tmpsets/set/{mod013-email → mod012-email}/right/followers.rb +0 -0
- data/tmpsets/set/{mod013-email → mod012-email}/right/following.rb +0 -0
- data/tmpsets/set/{mod013-email → mod012-email}/right/from.rb +0 -0
- data/tmpsets/set/{mod013-email → mod012-email}/right/html_message.rb +0 -0
- data/tmpsets/set/{mod013-email → mod012-email}/right/to.rb +0 -0
- data/tmpsets/set/{mod013-email → mod012-email}/self/always.rb +0 -0
- data/tmpsets/set/{mod013-email → mod012-email}/self/created.rb +0 -0
- data/tmpsets/set/{mod013-email → mod012-email}/self/edited.rb +0 -0
- data/tmpsets/set/{mod013-email → mod012-email}/self/follow.rb +0 -0
- data/tmpsets/set/{mod013-email → mod012-email}/self/follow_defaults.rb +0 -0
- data/tmpsets/set/{mod013-email → mod012-email}/self/never.rb +0 -0
- data/tmpsets/set/{mod013-email → mod012-email}/type/email_template.rb +0 -0
- data/tmpsets/set/{mod013-email → mod012-email}/type_plus_right/user/follow.rb +8 -4
- data/tmpsets/set/mod016-standard/all/links.rb +2 -2
- data/tmpsets/set/mod018-bootstrap/all/bootstrap/table.rb +1 -1
- data/tmpsets/set/mod018-bootstrap/self/bootswatch_shared.rb +1 -1
- metadata +149 -163
- data/lib/card/director_register.rb +0 -101
- data/lib/card/stage.rb +0 -106
- data/lib/card/stage_director.rb +0 -310
- data/lib/card/subdirector_array.rb +0 -43
- data/tmpsets/set/mod001-admin/self/admin.rb +0 -130
- data/tmpsets/set/mod001-admin/self/admin_info.rb +0 -110
- data/tmpsets/set/mod001-admin/self/version.rb +0 -15
- data/tmpsets/set/mod002-core/all/debug.rb +0 -30
- data/tmpsets/set/mod002-core/all/update_read_rules.rb +0 -91
- data/tmpsets/set/mod011-machines/abstract/machine.rb +0 -277
- data/tmpsets/set/mod011-machines/abstract/machine_input.rb +0 -83
- data/tmpsets/set/mod014-developer/all/event_viz.rb +0 -59
- data/tmpsets/set/mod014-developer/all/view_viz.rb +0 -30
- data/tmpsets/set/mod014-developer/right/debug.rb +0 -96
- data/tmpsets/set/mod015-carrierwave/abstract/attachment.rb +0 -118
- data/tmpsets/set/mod015-carrierwave/abstract/attachment/paths.rb +0 -57
- data/tmpsets/set/mod015-carrierwave/abstract/attachment/storage_type.rb +0 -326
- data/tmpsets/set/mod015-carrierwave/abstract/attachment/upload_cache.rb +0 -84
- data/tmpsets/set/mod015-carrierwave/all/file_utils.rb +0 -35
- data/tmpsets/set/mod015-carrierwave/self/admin.rb +0 -30
- data/tmpsets/set/mod015-carrierwave/type/file.rb +0 -158
- data/tmpsets/set/mod015-carrierwave/type/image.rb +0 -97
@@ -1,101 +0,0 @@
|
|
1
|
-
class Card
|
2
|
-
def act opts={}
|
3
|
-
if DirectorRegister.act_card
|
4
|
-
if DirectorRegister.act_card != self && !only_storage_phase
|
5
|
-
director.reset_stage
|
6
|
-
if opts && opts[:trash]
|
7
|
-
@action = :delete
|
8
|
-
else
|
9
|
-
identify_action
|
10
|
-
end
|
11
|
-
director.update_card self
|
12
|
-
self.only_storage_phase = true
|
13
|
-
end
|
14
|
-
main_act_block = false
|
15
|
-
else
|
16
|
-
DirectorRegister.clear
|
17
|
-
self.director = nil
|
18
|
-
DirectorRegister.act_card = self
|
19
|
-
main_act_block = true
|
20
|
-
if opts && opts[:success]
|
21
|
-
Env[:success] = Env::Success.new(cardname, Env.params[:success])
|
22
|
-
end
|
23
|
-
end
|
24
|
-
yield
|
25
|
-
ensure
|
26
|
-
DirectorRegister.clear if main_act_block
|
27
|
-
end
|
28
|
-
|
29
|
-
def self.new_director card, opts={}
|
30
|
-
if opts[:parent]
|
31
|
-
StageSubdirector.new card, opts
|
32
|
-
elsif DirectorRegister.act_card &&
|
33
|
-
DirectorRegister.act_card != card &&
|
34
|
-
DirectorRegister.act_card.director.running?
|
35
|
-
DirectorRegister.act_card.director.subdirectors.add(card)
|
36
|
-
else
|
37
|
-
StageDirector.new card
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
class DirectorRegister
|
42
|
-
cattr_accessor :act_card
|
43
|
-
|
44
|
-
class << self
|
45
|
-
def act_director
|
46
|
-
return unless DirectorRegister.act_card
|
47
|
-
DirectorRegister.act_card.director
|
48
|
-
end
|
49
|
-
|
50
|
-
def directors
|
51
|
-
@directors ||= {}
|
52
|
-
end
|
53
|
-
|
54
|
-
def clear
|
55
|
-
DirectorRegister.act_card = nil
|
56
|
-
directors.each_pair do |card, _dir|
|
57
|
-
card.director = nil
|
58
|
-
end
|
59
|
-
@directors = nil
|
60
|
-
end
|
61
|
-
|
62
|
-
def fetch card, opts={}
|
63
|
-
return directors[card] if directors[card]
|
64
|
-
directors.each_key do |dir_card|
|
65
|
-
return dir_card.director if dir_card.name == card.name
|
66
|
-
end
|
67
|
-
directors[card] = Card.new_director card, opts
|
68
|
-
end
|
69
|
-
|
70
|
-
def add director
|
71
|
-
directors[director.card] = director
|
72
|
-
end
|
73
|
-
|
74
|
-
def card_changed old_card
|
75
|
-
return unless (director = @directors.delete old_card)
|
76
|
-
add director
|
77
|
-
end
|
78
|
-
|
79
|
-
def delete director
|
80
|
-
return unless @directors
|
81
|
-
@directors.delete director.card
|
82
|
-
director.delete
|
83
|
-
end
|
84
|
-
|
85
|
-
def deep_delete director
|
86
|
-
director.subdirectors.each do |subdir|
|
87
|
-
deep_delete subdir
|
88
|
-
end
|
89
|
-
delete director
|
90
|
-
end
|
91
|
-
|
92
|
-
def running_act?
|
93
|
-
(dir = DirectorRegister.act_director) && dir.running?
|
94
|
-
end
|
95
|
-
|
96
|
-
def to_s
|
97
|
-
directors.values.map(&:to_s).join "\n"
|
98
|
-
end
|
99
|
-
end
|
100
|
-
end
|
101
|
-
end
|
data/lib/card/stage.rb
DELETED
@@ -1,106 +0,0 @@
|
|
1
|
-
class Card
|
2
|
-
# The process of writing a card change to the database is divided into
|
3
|
-
# 8 stages that are grouped in 3 phases.
|
4
|
-
#
|
5
|
-
# 'validation phase'
|
6
|
-
# * initialize stage (I)
|
7
|
-
# * prepare_to_validate stage (P2V)
|
8
|
-
# * validate stage (V)
|
9
|
-
#
|
10
|
-
# 'storage phase'
|
11
|
-
# * prepare_to_store stage (P2S)
|
12
|
-
# * store stage (S)
|
13
|
-
# * finalize stage (F)
|
14
|
-
#
|
15
|
-
# 'integration phase'
|
16
|
-
# * integrate stage (IG)
|
17
|
-
# * integrate_with_delay stage (IGwD)
|
18
|
-
#
|
19
|
-
#
|
20
|
-
# Explanation:
|
21
|
-
# yes! the recommended stage to do that
|
22
|
-
# yes ok to do it here if necessary
|
23
|
-
# no not recommended; chance to mess things up
|
24
|
-
# but if something forces you to do it here you can try
|
25
|
-
# no! never do it here. it won't work or will break things
|
26
|
-
#
|
27
|
-
# if there is only a single entry in a phase column it counts for all stages
|
28
|
-
# of that phase
|
29
|
-
#
|
30
|
-
# validation | storage | integrate
|
31
|
-
# I P2V V | P2S S F | IG IGwD
|
32
|
-
#-------------------------------------------------------------------------
|
33
|
-
# 1 attach subcard yes! yes! yes | yes yes yes | yes
|
34
|
-
# 2 detach subcard yes! yes! yes | yes no no! | no!
|
35
|
-
# 3 validate yes yes yes! | no | no
|
36
|
-
# 4 insecure change yes yes! no | no! | no!
|
37
|
-
# 5 secure change yes | yes! no! no! | no!
|
38
|
-
# 6 abort yes! | yes | yes?
|
39
|
-
# 7 fail
|
40
|
-
# 8 create other cards
|
41
|
-
# 9 has id no | no no? yes | yes
|
42
|
-
# 10 within transaction yes | yes | no
|
43
|
-
# 11 within web request yes | yes | yes no
|
44
|
-
|
45
|
-
# available values:
|
46
|
-
# dirty attributes yes | yes | yes
|
47
|
-
# success yes | yes | yes no
|
48
|
-
# session yes | yes | yes no
|
49
|
-
# params yes | yes | yes
|
50
|
-
#
|
51
|
-
# 4) 'insecure' means a change of a card attribute that can possibly make
|
52
|
-
# the card invalid to save
|
53
|
-
# 5) 'secure' means you are sure that the change doesn't affect the validation
|
54
|
-
module Stage
|
55
|
-
STAGES = [:initialize, :prepare_to_validate, :validate, :prepare_to_store,
|
56
|
-
:store, :finalize, :integrate, :integrate_with_delay].freeze
|
57
|
-
STAGE_INDEX = {}
|
58
|
-
STAGES.each_with_index do |stage, i|
|
59
|
-
STAGE_INDEX[stage] = i
|
60
|
-
end
|
61
|
-
STAGE_INDEX.freeze
|
62
|
-
|
63
|
-
def stage_symbol index
|
64
|
-
case index
|
65
|
-
when Symbol
|
66
|
-
return index if STAGE_INDEX[index]
|
67
|
-
when Integer
|
68
|
-
return STAGES[index] if index < STAGES.size
|
69
|
-
end
|
70
|
-
raise Card::Error, "not a valid stage index: #{index}"
|
71
|
-
end
|
72
|
-
|
73
|
-
def stage_index stage
|
74
|
-
case stage
|
75
|
-
when Symbol then
|
76
|
-
return STAGE_INDEX[stage]
|
77
|
-
when Integer then
|
78
|
-
return stage
|
79
|
-
else
|
80
|
-
raise Card::Error, "not a valid stage: #{stage}"
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
|
-
def stage_ok? opts
|
85
|
-
stage && (
|
86
|
-
(opts[:during] && in?(opts[:during])) ||
|
87
|
-
(opts[:before] && before?(opts[:before])) ||
|
88
|
-
(opts[:after] && after?(opts[:after])) ||
|
89
|
-
true # no phase restriction in opts
|
90
|
-
)
|
91
|
-
end
|
92
|
-
|
93
|
-
def before? allowed_phase
|
94
|
-
STAGE_INDEX[allowed_phase] > STAGE_INDEX[stage]
|
95
|
-
end
|
96
|
-
|
97
|
-
def after? allowed_phase
|
98
|
-
STAGE_INDEX[allowed_phase] < STAGE_INDEX[stage]
|
99
|
-
end
|
100
|
-
|
101
|
-
def in? allowed_phase
|
102
|
-
(allowed_phase.is_a?(Array) && allowed_phase.include?(stage)) ||
|
103
|
-
allowed_phase == stage
|
104
|
-
end
|
105
|
-
end
|
106
|
-
end
|
data/lib/card/stage_director.rb
DELETED
@@ -1,310 +0,0 @@
|
|
1
|
-
|
2
|
-
class Card
|
3
|
-
def restore_changes_information
|
4
|
-
return unless @previously_changed
|
5
|
-
@changed_attributes = ActiveSupport::HashWithIndifferentAccess.new
|
6
|
-
@previously_changed.each do |k, (old, _new)|
|
7
|
-
@changed_attributes[k] = old
|
8
|
-
end
|
9
|
-
end
|
10
|
-
|
11
|
-
def clean_after_stage_fail
|
12
|
-
@action = nil
|
13
|
-
expire_pieces
|
14
|
-
subcards.each(&:expire_pieces)
|
15
|
-
end
|
16
|
-
# A 'StageDirector' executes the stages of a card when the card gets created,
|
17
|
-
# updated or deleted.
|
18
|
-
# For subcards, i.e. other cards that are changed in the same act, a
|
19
|
-
# StageDirector has StageSubdirectors that take care of the stages for
|
20
|
-
# those cards
|
21
|
-
#
|
22
|
-
# In general a stage is executed for all involved cards before the
|
23
|
-
# StageDirector proceeds with the next stage.
|
24
|
-
# Only exception is the finalize stage.
|
25
|
-
# The finalize stage of a subcard is executed immediately after its store
|
26
|
-
# stage. When all subcards are finalized the supercard's finalize stage is
|
27
|
-
# executed.
|
28
|
-
#
|
29
|
-
# If a subcard is added in a stage then it catches up at the end of the stage
|
30
|
-
# to the current stage.
|
31
|
-
# For example if you add a subcard in a card's :prepare_to_store stage then
|
32
|
-
# after that stage the stages :initialize, :prepare_to_validate,
|
33
|
-
# :validate and :prepare_to_store are executed for the subcard.
|
34
|
-
#
|
35
|
-
# Stages are executed with pre-order depth-first search.
|
36
|
-
# That means if A has subcards AA and AB; AAA is subcard of AA and ABA
|
37
|
-
# subcard of AB then the order of execution is
|
38
|
-
# A -> AA -> AAA -> AB -> ABA
|
39
|
-
#
|
40
|
-
# A special case can happen in the store phase.
|
41
|
-
# If the id of a subcard is needed for a supercard
|
42
|
-
# (for example as left_id or as type_id) and the subcard doesn't
|
43
|
-
# have an id yet (because it gets created in the same act)
|
44
|
-
# then the subcard's store stage is executed before the supercard's store
|
45
|
-
# stage
|
46
|
-
class StageDirector
|
47
|
-
include Stage
|
48
|
-
|
49
|
-
attr_accessor :prior_store, :act, :card, :stage, :parent, :main,
|
50
|
-
:subdirectors, :transact_in_stage
|
51
|
-
attr_reader :running
|
52
|
-
alias_method :running?, :running
|
53
|
-
alias_method :main?, :main
|
54
|
-
|
55
|
-
def initialize card, opts={}, main=true
|
56
|
-
@card = card
|
57
|
-
@card.director = self
|
58
|
-
# for read actions there is no validation phase
|
59
|
-
# so we have to set the action here
|
60
|
-
@card.identify_action
|
61
|
-
|
62
|
-
@stage = nil
|
63
|
-
@running = false
|
64
|
-
@prepared = false
|
65
|
-
@parent = opts[:parent]
|
66
|
-
# has card to be stored before the supercard?
|
67
|
-
@prior_store = opts[:priority]
|
68
|
-
@call_after_store = []
|
69
|
-
@main = main
|
70
|
-
@subdirectors = SubdirectorArray.initialize_with_subcards(self)
|
71
|
-
register
|
72
|
-
end
|
73
|
-
|
74
|
-
def register
|
75
|
-
Card::DirectorRegister.add self
|
76
|
-
end
|
77
|
-
|
78
|
-
def unregister
|
79
|
-
Card::DirectorRegister.delete self
|
80
|
-
end
|
81
|
-
|
82
|
-
def delete
|
83
|
-
@card.director = nil
|
84
|
-
@subdirectors.clear
|
85
|
-
@stage = nil
|
86
|
-
@action = nil
|
87
|
-
end
|
88
|
-
|
89
|
-
def prepare_for_phases
|
90
|
-
@card.prepare_for_phases unless @prepared
|
91
|
-
@prepared = true
|
92
|
-
@subdirectors.each(&:prepare_for_phases)
|
93
|
-
end
|
94
|
-
|
95
|
-
def validation_phase
|
96
|
-
run_single_stage :initialize
|
97
|
-
run_single_stage :prepare_to_validate
|
98
|
-
run_single_stage :validate
|
99
|
-
@card.expire_pieces if @card.errors.any?
|
100
|
-
@card.errors.empty?
|
101
|
-
end
|
102
|
-
|
103
|
-
def storage_phase &block
|
104
|
-
catch_up_to_stage :prepare_to_store
|
105
|
-
run_single_stage :store, &block
|
106
|
-
run_single_stage :finalize
|
107
|
-
ensure
|
108
|
-
@from_trash = nil
|
109
|
-
end
|
110
|
-
|
111
|
-
def integration_phase
|
112
|
-
return if @abort
|
113
|
-
@card.restore_changes_information
|
114
|
-
run_single_stage :integrate
|
115
|
-
run_single_stage :integrate_with_delay
|
116
|
-
rescue => e # don't rollback
|
117
|
-
Card::Error.current = e
|
118
|
-
@card.notable_exception_raised
|
119
|
-
return false
|
120
|
-
ensure
|
121
|
-
@card.changes_applied unless @abort
|
122
|
-
DirectorRegister.clear if main? && !@card.only_storage_phase
|
123
|
-
end
|
124
|
-
|
125
|
-
def catch_up_to_stage next_stage
|
126
|
-
if @transact_in_stage
|
127
|
-
return if @transact_in_stage != next_stage
|
128
|
-
next_stage = :integrate_with_delay
|
129
|
-
end
|
130
|
-
upto_stage(next_stage) do |stage|
|
131
|
-
run_single_stage stage
|
132
|
-
end
|
133
|
-
end
|
134
|
-
|
135
|
-
def reset_stage
|
136
|
-
@stage = -1
|
137
|
-
end
|
138
|
-
|
139
|
-
def abort
|
140
|
-
@abort = true
|
141
|
-
end
|
142
|
-
|
143
|
-
def call_after_store &block
|
144
|
-
@call_after_store << block
|
145
|
-
end
|
146
|
-
|
147
|
-
def need_act
|
148
|
-
act_director = main_director
|
149
|
-
unless act_director
|
150
|
-
raise Card::Error, "act requested without a main stage director"
|
151
|
-
end
|
152
|
-
act_director.act ||= Card::Act.create(ip_address: Env.ip)
|
153
|
-
@card.current_act = @act = act_director.act
|
154
|
-
end
|
155
|
-
|
156
|
-
def main_director
|
157
|
-
if main?
|
158
|
-
self
|
159
|
-
else
|
160
|
-
DirectorRegister.act_director || (@parent && @parent.main_director)
|
161
|
-
end
|
162
|
-
end
|
163
|
-
|
164
|
-
def to_s
|
165
|
-
str = @card.name.to_s.clone
|
166
|
-
if @subdirectors
|
167
|
-
subs = subdirectors.map(&:card)
|
168
|
-
.map { |card| " #{card.name}" }.join "\n"
|
169
|
-
str << "\n#{subs}"
|
170
|
-
end
|
171
|
-
str
|
172
|
-
end
|
173
|
-
|
174
|
-
def update_card card
|
175
|
-
old_card = @card
|
176
|
-
@card = card
|
177
|
-
DirectorRegister.card_changed old_card
|
178
|
-
end
|
179
|
-
|
180
|
-
private
|
181
|
-
|
182
|
-
def upto_stage stage
|
183
|
-
@stage ||= -1
|
184
|
-
(@stage + 1).upto(stage_index(stage)) do |i|
|
185
|
-
yield stage_symbol(i)
|
186
|
-
end
|
187
|
-
end
|
188
|
-
|
189
|
-
def valid_next_stage? stage
|
190
|
-
new_stage = stage_index(stage)
|
191
|
-
@stage ||= -1
|
192
|
-
return if @stage >= new_stage
|
193
|
-
if @stage < new_stage - 1
|
194
|
-
raise Card::Error, "stage #{stage_symbol(new_stage - 1)} was skipped " \
|
195
|
-
"for card #{@card}"
|
196
|
-
end
|
197
|
-
@card.errors.empty? || new_stage > stage_index(:validate)
|
198
|
-
end
|
199
|
-
|
200
|
-
def run_single_stage stage, &block
|
201
|
-
return true unless valid_next_stage? stage
|
202
|
-
# puts "#{@card.name}: #{stage} stage".red
|
203
|
-
|
204
|
-
@stage = stage_index stage
|
205
|
-
if stage == :initialize
|
206
|
-
@running ||= true
|
207
|
-
prepare_for_phases
|
208
|
-
end
|
209
|
-
# in the store stage it can be necessary that
|
210
|
-
# other subcards must be saved before we save this card
|
211
|
-
if stage == :store
|
212
|
-
store(&block)
|
213
|
-
else
|
214
|
-
run_stage_callbacks stage
|
215
|
-
run_subdirector_stages stage
|
216
|
-
end
|
217
|
-
rescue => e
|
218
|
-
@card.clean_after_stage_fail
|
219
|
-
raise e
|
220
|
-
end
|
221
|
-
|
222
|
-
def run_stage_callbacks stage
|
223
|
-
Rails.logger.debug "#{stage}: #{@card.name}"
|
224
|
-
# we use abort :success in the :store stage for :save_draft
|
225
|
-
if stage_index(stage) <= stage_index(:store) && !main?
|
226
|
-
@card.abortable do
|
227
|
-
@card.run_callbacks :"#{stage}_stage"
|
228
|
-
end
|
229
|
-
else
|
230
|
-
@card.run_callbacks :"#{stage}_stage"
|
231
|
-
end
|
232
|
-
end
|
233
|
-
|
234
|
-
def run_subdirector_stages stage
|
235
|
-
@subdirectors.each do |subdir|
|
236
|
-
subdir.catch_up_to_stage stage
|
237
|
-
end
|
238
|
-
ensure
|
239
|
-
@card.handle_subcard_errors
|
240
|
-
end
|
241
|
-
|
242
|
-
# handle the store stage
|
243
|
-
# The tricky part here is to preserve the dirty marks on the subcards'
|
244
|
-
# attributes for the finalize stage.
|
245
|
-
# To achieve this we can't just call the :store and :finalize callbacks on
|
246
|
-
# the subcards as we do in the other phases.
|
247
|
-
# Instead we have to call `save` on the subcards
|
248
|
-
# and use the ActiveRecord :around_save callback to run the :store and
|
249
|
-
# :finalize stages
|
250
|
-
def store &save_block
|
251
|
-
if main? && !block_given?
|
252
|
-
raise Card::Error, "need block to store main card"
|
253
|
-
end
|
254
|
-
# the block is the ActiveRecord block from the around save callback that
|
255
|
-
# saves the card
|
256
|
-
if block_given?
|
257
|
-
run_stage_callbacks :store
|
258
|
-
store_with_subcards(&save_block)
|
259
|
-
else
|
260
|
-
trigger_storage_phase_callback
|
261
|
-
end
|
262
|
-
end
|
263
|
-
|
264
|
-
def store_with_subcards
|
265
|
-
store_pre_subcards
|
266
|
-
yield
|
267
|
-
@call_after_store.each { |handle_id| handle_id.call(@card.id) }
|
268
|
-
store_post_subcards
|
269
|
-
true.tap { @virtual = false } # TODO: find a better place for this
|
270
|
-
ensure
|
271
|
-
@card.handle_subcard_errors
|
272
|
-
end
|
273
|
-
|
274
|
-
# store subcards whose ids we need for this card
|
275
|
-
def store_pre_subcards
|
276
|
-
@subdirectors.each do |subdir|
|
277
|
-
next unless subdir.prior_store
|
278
|
-
subdir.catch_up_to_stage :store
|
279
|
-
end
|
280
|
-
end
|
281
|
-
|
282
|
-
def store_post_subcards
|
283
|
-
@subdirectors.each do |subdir|
|
284
|
-
next if subdir.prior_store
|
285
|
-
subdir.catch_up_to_stage :store
|
286
|
-
end
|
287
|
-
end
|
288
|
-
|
289
|
-
# trigger the storage_phase, skip the other phases
|
290
|
-
# At this point the :prepare_to_store stage was already executed
|
291
|
-
# by the parent director. So the storage phase will only run
|
292
|
-
# the :store stage and the :finalize stage
|
293
|
-
def trigger_storage_phase_callback
|
294
|
-
@stage = stage_index :prepare_to_store
|
295
|
-
@card.only_storage_phase = true
|
296
|
-
@card.save! validate: false
|
297
|
-
end
|
298
|
-
end
|
299
|
-
|
300
|
-
class StageSubdirector < StageDirector
|
301
|
-
def initialize card, opts={}
|
302
|
-
super card, opts, false
|
303
|
-
end
|
304
|
-
|
305
|
-
def delete
|
306
|
-
@parent.subdirectors.delete self if @parent
|
307
|
-
super
|
308
|
-
end
|
309
|
-
end
|
310
|
-
end
|