card 1.101.3 → 1.101.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/VERSION +1 -1
- data/config/initializers/02_patches/active_record.rb +1 -1
- data/config/locales/en.yml +155 -378
- data/db/migrate_core_cards/20150202143810_import_bootstrap_layout.rb +1 -1
- data/lib/card.rb +15 -2
- data/lib/card/auth.rb +5 -2
- data/lib/card/auth/current.rb +39 -100
- data/lib/card/auth/proxy.rb +36 -16
- data/lib/card/auth/token.rb +6 -0
- data/lib/card/cache/all.rb +83 -0
- data/lib/card/cache/card_class.rb +41 -0
- data/lib/card/cache/persistent.rb +3 -34
- data/lib/card/cache/persistent_class.rb +28 -0
- data/lib/card/codename.rb +1 -1
- data/lib/card/content.rb +16 -2
- data/lib/card/content/all.rb +59 -0
- data/lib/card/director/act_direction.rb +4 -0
- data/lib/card/director/all.rb +61 -0
- data/lib/card/director/card_class.rb +18 -0
- data/lib/card/director/phases.rb +0 -1
- data/lib/card/dirty.rb +13 -3
- data/lib/card/env/success.rb +14 -14
- data/lib/card/env/success/target.rb +9 -11
- data/lib/card/error.rb +1 -1
- data/lib/card/fetch/all.rb +32 -0
- data/lib/card/fetch/card_class.rb +147 -0
- data/lib/card/format.rb +1 -1
- data/lib/card/format/error.rb +3 -3
- data/lib/card/format/nest.rb +1 -1
- data/lib/card/format/nest/fetch.rb +1 -1
- data/lib/card/lexicon.rb +2 -2
- data/lib/card/name/all.rb +8 -0
- data/lib/card/name/all/descendants.rb +6 -3
- data/lib/card/name/card_class.rb +26 -0
- data/lib/card/reference/all.rb +131 -0
- data/lib/card/rule/all.rb +75 -0
- data/lib/card/set/event/all.rb +95 -0
- data/lib/card/set/event/skip_and_trigger.rb +89 -0
- data/lib/card/set/pattern/all.rb +63 -0
- data/lib/card/subcards/all.rb +103 -0
- data/lib/cardio/migration/import.rb +1 -1
- data/lib/cardio/utils.rb +5 -3
- data/mod/admin/set/self/admin_info.rb +3 -5
- data/mod/admin/set/self/trash.rb +2 -2
- data/mod/core/set/all/autoname.rb +17 -0
- data/mod/core/set/all/codename.rb +2 -2
- data/mod/core/set/all/content.rb +52 -97
- data/mod/core/set/all/name_events.rb +69 -58
- data/mod/core/set/all/reference_events.rb +67 -0
- data/mod/core/set/all/states.rb +2 -2
- data/mod/core/set/all/subcards.rb +0 -100
- data/mod/core/set/all/trash.rb +11 -13
- data/mod/core/set/all/type.rb +7 -9
- data/mod/core/set/all/utils.rb +3 -0
- data/mod/core/set/type/cardtype.rb +3 -3
- data/mod/core/set_pattern/06_rule.rb +1 -1
- data/mod/core/spec/set/all/{rules2_spec.rb → clean_me_spec.rb} +0 -0
- data/mod/core/spec/set/all/name_events_spec.rb +204 -0
- metadata +30 -37
- data/lib/card/mod_inflector.rb +0 -16
- data/lib/card/name/all/class_methods.rb +0 -28
- data/mod/core/set/all/actify.rb +0 -68
- data/mod/core/set/all/cache.rb +0 -109
- data/mod/core/set/all/event_conditions.rb +0 -172
- data/mod/core/set/all/fetch.rb +0 -122
- data/mod/core/set/all/fetch_helper.rb +0 -35
- data/mod/core/set/all/i18n.rb +0 -9
- data/mod/core/set/all/pattern.rb +0 -54
- data/mod/core/set/all/references.rb +0 -191
- data/mod/core/set/all/rename.rb +0 -33
- data/mod/core/set/all/rules.rb +0 -81
- data/mod/core/spec/set/all/actify_spec.rb +0 -58
- data/mod/core/spec/set/all/content_spec.rb +0 -15
- data/mod/core/spec/set/all/event_conditions_spec.rb +0 -217
- data/mod/core/spec/set/all/fetch_helper_spec.rb +0 -65
- data/mod/core/spec/set/all/fetch_spec.rb +0 -338
- data/mod/core/spec/set/all/i18n_spec.rb +0 -17
- data/mod/core/spec/set/all/pattern_spec.rb +0 -101
- data/mod/core/spec/set/all/permissions/reader_rules_spec.rb +0 -166
- data/mod/core/spec/set/all/references_spec.rb +0 -62
- data/mod/core/spec/set/all/rename_spec.rb +0 -189
- data/mod/core/spec/set/all/rules_spec.rb +0 -100
- data/mod/core/spec/set/all/subcards_spec.rb +0 -102
@@ -0,0 +1,95 @@
|
|
1
|
+
class Card
|
2
|
+
module Set
|
3
|
+
class Event
|
4
|
+
# card methods for testing event applicability
|
5
|
+
module All
|
6
|
+
include SkipAndTrigger
|
7
|
+
|
8
|
+
def event_applies? event
|
9
|
+
return unless set_condition_applies? event.set_module, event.opts[:changing]
|
10
|
+
|
11
|
+
CONDITIONS.all? { |c| send "#{c}_condition_applies?", event, event.opts[c] }
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def set_condition_applies? set_module, old_sets
|
17
|
+
return true if set_module == Card
|
18
|
+
|
19
|
+
set_condition_card(old_sets).singleton_class.include? set_module
|
20
|
+
end
|
21
|
+
|
22
|
+
def on_condition_applies? _event, actions
|
23
|
+
actions = Array(actions).compact
|
24
|
+
actions.empty? ? true : actions.include?(action)
|
25
|
+
end
|
26
|
+
|
27
|
+
# if changing name/type, the old card has no-longer-applicable set modules,
|
28
|
+
# so we create a new card to determine whether events apply.
|
29
|
+
# (note: cached condition card would ideally be cleared after all
|
30
|
+
# conditions are reviewed)
|
31
|
+
# @param old_sets [True/False] whether to use the old_sets
|
32
|
+
def set_condition_card old_sets
|
33
|
+
return self if old_sets || no_current_action?
|
34
|
+
@set_condition_card ||=
|
35
|
+
updating_sets? ? set_condition_card_with_new_set_modules : self
|
36
|
+
end
|
37
|
+
|
38
|
+
# existing card is being changed in a way that alters its sets
|
39
|
+
def updating_sets?
|
40
|
+
action == :update && real? && (type_id_is_changing? || name_is_changing?)
|
41
|
+
end
|
42
|
+
|
43
|
+
# prevents locking in set_condition_card
|
44
|
+
def no_current_action?
|
45
|
+
return false if @current_action
|
46
|
+
|
47
|
+
@set_condition_card = nil
|
48
|
+
true
|
49
|
+
end
|
50
|
+
|
51
|
+
def set_condition_card_with_new_set_modules
|
52
|
+
cc = Card.find id
|
53
|
+
cc.name = name
|
54
|
+
cc.type_id = type_id
|
55
|
+
cc.include_set_modules
|
56
|
+
end
|
57
|
+
|
58
|
+
def changed_condition_applies? _event, db_columns
|
59
|
+
return true unless action == :update
|
60
|
+
db_columns = Array(db_columns).compact
|
61
|
+
return true if db_columns.empty?
|
62
|
+
db_columns.any? { |col| single_changed_condition_applies? col }
|
63
|
+
end
|
64
|
+
alias_method :changing_condition_applies?, :changed_condition_applies?
|
65
|
+
|
66
|
+
def when_condition_applies? _event, block
|
67
|
+
case block
|
68
|
+
when Proc then block.call(self)
|
69
|
+
when Symbol then send block
|
70
|
+
else true
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def single_changed_condition_applies? db_column
|
75
|
+
return true unless db_column
|
76
|
+
send "#{db_column}_is_changing?"
|
77
|
+
end
|
78
|
+
|
79
|
+
def wrong_stage opts
|
80
|
+
return false if director.stage_ok? opts
|
81
|
+
if !stage
|
82
|
+
"phase method #{method} called outside of event phases"
|
83
|
+
else
|
84
|
+
"#{opts.inspect} method #{method} called in stage #{stage}"
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def wrong_action actn
|
89
|
+
return false if on_condition_applies?(nil, actn)
|
90
|
+
"on: #{actn} method #{method} called on #{action}"
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
class Card
|
2
|
+
module Set
|
3
|
+
class Event
|
4
|
+
# opt into (trigger) or out of (skip) events
|
5
|
+
module SkipAndTrigger
|
6
|
+
# force skipping this event for all cards in act
|
7
|
+
def skip_event! *events
|
8
|
+
@full_skip_hash = nil
|
9
|
+
force_events events, act_skip_hash
|
10
|
+
end
|
11
|
+
|
12
|
+
# force skipping this event for this card only
|
13
|
+
def skip_event_in_action! *events
|
14
|
+
force_events events, full_skip_hash
|
15
|
+
end
|
16
|
+
|
17
|
+
# force triggering this event (when it comes up) for all cards in act
|
18
|
+
def trigger_event! *events
|
19
|
+
@full_trigger_hash = nil
|
20
|
+
force_events events, act_trigger_hash
|
21
|
+
end
|
22
|
+
|
23
|
+
# force triggering this event (when it comes up) for this card only
|
24
|
+
def trigger_event_in_action! *events
|
25
|
+
force_events events, full_trigger_hash
|
26
|
+
end
|
27
|
+
|
28
|
+
# hash form of raw skip setting, eg { "my_event" => true }
|
29
|
+
def skip_hash
|
30
|
+
@skip_hash ||= hash_with_value skip, true
|
31
|
+
end
|
32
|
+
|
33
|
+
def trigger_hash
|
34
|
+
@trigger_hash ||= hash_with_value trigger, true
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
# "applies always means event can run
|
40
|
+
# so if skip_condition_applies?, we do NOT skip
|
41
|
+
def skip_condition_applies? event, allowed
|
42
|
+
return true unless (val = full_skip_hash[event.name.to_s])
|
43
|
+
|
44
|
+
allowed ? val.blank? : (val != :force)
|
45
|
+
end
|
46
|
+
|
47
|
+
def trigger_condition_applies? event, required
|
48
|
+
return true unless required
|
49
|
+
|
50
|
+
full_trigger_hash[event.name.to_s].present?
|
51
|
+
end
|
52
|
+
|
53
|
+
def full_skip_hash
|
54
|
+
@full_skip_hash ||= act_skip_hash.merge skip_in_action_hash
|
55
|
+
end
|
56
|
+
|
57
|
+
def act_skip_hash
|
58
|
+
(act_card || self).skip_hash
|
59
|
+
end
|
60
|
+
|
61
|
+
def skip_in_action_hash
|
62
|
+
hash_with_value skip_in_action, true
|
63
|
+
end
|
64
|
+
|
65
|
+
def full_trigger_hash
|
66
|
+
@full_trigger_hash ||= act_trigger_hash.merge trigger_in_action_hash
|
67
|
+
end
|
68
|
+
|
69
|
+
def trigger_in_action_hash
|
70
|
+
hash_with_value trigger_in_action, true
|
71
|
+
end
|
72
|
+
|
73
|
+
def act_trigger_hash
|
74
|
+
(act_card || self).trigger_hash
|
75
|
+
end
|
76
|
+
|
77
|
+
def hash_with_value array, value
|
78
|
+
Array.wrap(array).each_with_object({}) do |event, hash|
|
79
|
+
hash[event.to_s] = value
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def force_events events, hash
|
84
|
+
events.each { |e| hash[e.to_s] = :force }
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
class Card
|
2
|
+
module Set
|
3
|
+
class Pattern
|
4
|
+
# pattern-related Card instance methods
|
5
|
+
module All
|
6
|
+
def patterns?
|
7
|
+
defined? @patterns
|
8
|
+
end
|
9
|
+
|
10
|
+
def all_patterns
|
11
|
+
@all_patterns ||= set_patterns.map { |sub| sub.new self }.compact
|
12
|
+
end
|
13
|
+
|
14
|
+
# new cards do not
|
15
|
+
def patterns
|
16
|
+
@patterns ||= (new_card? ? all_patterns[1..-1] : all_patterns)
|
17
|
+
end
|
18
|
+
|
19
|
+
def reset_patterns
|
20
|
+
# Rails.logger.info "resetting patterns: #{name}"
|
21
|
+
@patterns = @all_patterns = nil
|
22
|
+
@template = @virtual = nil
|
23
|
+
@set_mods_loaded = @set_modules = @set_names = @rule_set_keys = nil
|
24
|
+
@junction_only = nil # only applies to set cards
|
25
|
+
true
|
26
|
+
end
|
27
|
+
|
28
|
+
def safe_set_keys
|
29
|
+
patterns.map(&:safe_key).reverse * " "
|
30
|
+
end
|
31
|
+
|
32
|
+
def set_modules
|
33
|
+
@set_modules ||= all_patterns[0..-2].reverse.map(&:module_list).flatten.compact
|
34
|
+
end
|
35
|
+
|
36
|
+
def set_format_modules klass
|
37
|
+
@set_format_modules ||= {}
|
38
|
+
@set_format_modules[klass] =
|
39
|
+
all_patterns[0..-2].reverse.map do |pattern|
|
40
|
+
pattern.format_module_list klass
|
41
|
+
end.flatten.compact
|
42
|
+
end
|
43
|
+
|
44
|
+
def set_names
|
45
|
+
@set_names = patterns.map(&:to_s) if @set_names.nil?
|
46
|
+
@set_names
|
47
|
+
end
|
48
|
+
|
49
|
+
def in_set? set_module
|
50
|
+
patterns.map(&:module_key).include? set_module.shortname
|
51
|
+
end
|
52
|
+
|
53
|
+
def rule_set_keys
|
54
|
+
@rule_set_keys ||= patterns.map(&:rule_set_key).compact
|
55
|
+
end
|
56
|
+
|
57
|
+
def include_module? set
|
58
|
+
singleton_class&.include? set
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,103 @@
|
|
1
|
+
class Card
|
2
|
+
class Subcards
|
3
|
+
# subcard-related Card instance methods
|
4
|
+
module All
|
5
|
+
def subcard card_name
|
6
|
+
subcards.card card_name
|
7
|
+
end
|
8
|
+
|
9
|
+
def subfield field_name
|
10
|
+
subcards.field field_name
|
11
|
+
end
|
12
|
+
|
13
|
+
def field? tag
|
14
|
+
field(tag) || subfield(tag)
|
15
|
+
end
|
16
|
+
|
17
|
+
def subcards
|
18
|
+
@subcards ||= Card::Subcards.new self
|
19
|
+
end
|
20
|
+
|
21
|
+
def subcards?
|
22
|
+
subcards.present?
|
23
|
+
end
|
24
|
+
|
25
|
+
def expire_subcards
|
26
|
+
subcards.clear
|
27
|
+
end
|
28
|
+
|
29
|
+
# phase_method :attach_subcard, before: :store do |name_or_card, args=nil|
|
30
|
+
# TODO: handle differently in different stages
|
31
|
+
def add_subcard name_or_card, args={}
|
32
|
+
subcards.add name_or_card, args
|
33
|
+
end
|
34
|
+
alias_method :attach_subcard, :add_subcard
|
35
|
+
|
36
|
+
def add_subcard! name_or_card, args={}
|
37
|
+
subcard = subcards.add name_or_card, args
|
38
|
+
subcard.director.reset_stage
|
39
|
+
subcard
|
40
|
+
end
|
41
|
+
alias_method :attach_subcard!, :add_subcard!
|
42
|
+
|
43
|
+
# phase_method :attach_subfield, before: :approve do |name_or_card, args=nil|
|
44
|
+
def attach_subfield name_or_card, args={}
|
45
|
+
subcards.add_field name_or_card, args
|
46
|
+
end
|
47
|
+
alias_method :add_subfield, :attach_subfield
|
48
|
+
|
49
|
+
def attach_subfield! name_or_card, args={}
|
50
|
+
subcard = subcards.add_field name_or_card, args
|
51
|
+
subcard.director.reset_stage
|
52
|
+
subcard
|
53
|
+
end
|
54
|
+
|
55
|
+
def detach_subcard name_or_card
|
56
|
+
subcards.remove name_or_card
|
57
|
+
end
|
58
|
+
alias_method :remove_subcard, :detach_subcard
|
59
|
+
|
60
|
+
def detach_subfield name_or_card
|
61
|
+
subcards.remove_field name_or_card
|
62
|
+
end
|
63
|
+
alias_method :remove_subfield, :detach_subfield
|
64
|
+
|
65
|
+
def clear_subcards
|
66
|
+
subcards.clear
|
67
|
+
end
|
68
|
+
|
69
|
+
# ensures subfield is present
|
70
|
+
# does NOT override subfield content if already present
|
71
|
+
def ensure_subfield field_name, args={}
|
72
|
+
if subfield_present? field_name
|
73
|
+
subfield field_name
|
74
|
+
else
|
75
|
+
add_subfield field_name, args
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def subfield_present? field_name
|
80
|
+
subfield(field_name)&.content&.present?
|
81
|
+
end
|
82
|
+
|
83
|
+
def deep_clear_subcards
|
84
|
+
subcards.deep_clear
|
85
|
+
end
|
86
|
+
|
87
|
+
def handle_subcard_errors
|
88
|
+
subcards.each do |subcard|
|
89
|
+
subcard.errors.each do |error|
|
90
|
+
subcard_error subcard, error
|
91
|
+
end
|
92
|
+
subcard.errors.clear
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def subcard_error subcard, error
|
97
|
+
msg = error.message
|
98
|
+
msg = "#{error.attribute} #{msg}" unless %i[content abort].member? error.attribute
|
99
|
+
errors.add subcard.name.from(name), msg
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
data/lib/cardio/utils.rb
CHANGED
@@ -1,9 +1,7 @@
|
|
1
1
|
module Cardio
|
2
2
|
# Utilities that may need to be run even when mods are not loaded.
|
3
3
|
module Utils
|
4
|
-
def
|
5
|
-
kaller = args.delete(:caller) || caller
|
6
|
-
args[:scope] ||= Card::Set.scope kaller
|
4
|
+
def t key, args={}
|
7
5
|
::I18n.t key, args
|
8
6
|
end
|
9
7
|
|
@@ -11,6 +9,10 @@ module Cardio
|
|
11
9
|
system "env RAILS_ENV=test bundle exec rake db:fixtures:load"
|
12
10
|
end
|
13
11
|
|
12
|
+
def database_name
|
13
|
+
@database_name ||= config.database_configuration.dig Rails.env, "database"
|
14
|
+
end
|
15
|
+
|
14
16
|
# deletes tmp directory within files directory
|
15
17
|
# It's here because it gets called as part of cache clearing, which sometimes gets
|
16
18
|
# called in a context where card mods are not loaded.
|
@@ -27,19 +27,17 @@ format :html do
|
|
27
27
|
def warning_alert warnings
|
28
28
|
# 'ADMINISTRATOR WARNING'
|
29
29
|
alert :warning, true do
|
30
|
-
"<h5>#{
|
30
|
+
"<h5>#{t :admin_warn}</h5>" + list_tag(warnings)
|
31
31
|
end
|
32
32
|
end
|
33
33
|
|
34
34
|
def no_email_delivery_message
|
35
35
|
# "Email delivery is turned off."
|
36
36
|
# "Change settings in config/application.rb to send sign up notifications."
|
37
|
-
|
37
|
+
t :admin_email_off, path: "config/application.rb"
|
38
38
|
end
|
39
39
|
|
40
40
|
def warning_list_with_auto_scope warnings
|
41
|
-
|
42
|
-
admin_warn = tr(:admin_warn)
|
43
|
-
"<h5>#{admin_warn}</h5>" + warnings.join("\n")
|
41
|
+
"<h5>#{t :admin_warn}</h5>" + warnings.join("\n")
|
44
42
|
end
|
45
43
|
end
|
data/mod/admin/set/self/trash.rb
CHANGED
@@ -35,7 +35,7 @@ format :html do
|
|
35
35
|
button_link("empty trash",
|
36
36
|
btn_type: :default,
|
37
37
|
path: { mark: :admin, action: :update, task: :empty_trash,
|
38
|
-
success: {
|
38
|
+
success: { mark: "~#{card.id}" } },
|
39
39
|
"data-confirm" => "Are you sure you want to delete "\
|
40
40
|
"all cards in the trash?")
|
41
41
|
)
|
@@ -58,6 +58,6 @@ format :html do
|
|
58
58
|
action: :update,
|
59
59
|
restore: trashed_card.id,
|
60
60
|
action_ids: [before_delete],
|
61
|
-
success: {
|
61
|
+
success: { mark: "~#{card.id}" } }
|
62
62
|
end
|
63
63
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
event :set_autoname, :prepare_to_store, on: :create, when: :autoname? do
|
2
|
+
self.name = autoname rule(:autoname)
|
3
|
+
autoname_card = rule_card :autoname
|
4
|
+
autoname_card.update_column :db_content, name
|
5
|
+
autoname_card.expire
|
6
|
+
pull_from_trash!
|
7
|
+
Card.write_to_soft_cache self
|
8
|
+
end
|
9
|
+
|
10
|
+
def no_autoname?
|
11
|
+
!autoname?
|
12
|
+
end
|
13
|
+
|
14
|
+
def autoname?
|
15
|
+
name.blank? &&
|
16
|
+
(@autoname_rule.nil? ? (@autoname_rule = rule(:autoname).present?) : @autoname_rule)
|
17
|
+
end
|