card 1.101.3 → 1.101.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (84) hide show
  1. checksums.yaml +4 -4
  2. data/VERSION +1 -1
  3. data/config/initializers/02_patches/active_record.rb +1 -1
  4. data/config/locales/en.yml +155 -378
  5. data/db/migrate_core_cards/20150202143810_import_bootstrap_layout.rb +1 -1
  6. data/lib/card.rb +15 -2
  7. data/lib/card/auth.rb +5 -2
  8. data/lib/card/auth/current.rb +39 -100
  9. data/lib/card/auth/proxy.rb +36 -16
  10. data/lib/card/auth/token.rb +6 -0
  11. data/lib/card/cache/all.rb +83 -0
  12. data/lib/card/cache/card_class.rb +41 -0
  13. data/lib/card/cache/persistent.rb +3 -34
  14. data/lib/card/cache/persistent_class.rb +28 -0
  15. data/lib/card/codename.rb +1 -1
  16. data/lib/card/content.rb +16 -2
  17. data/lib/card/content/all.rb +59 -0
  18. data/lib/card/director/act_direction.rb +4 -0
  19. data/lib/card/director/all.rb +61 -0
  20. data/lib/card/director/card_class.rb +18 -0
  21. data/lib/card/director/phases.rb +0 -1
  22. data/lib/card/dirty.rb +13 -3
  23. data/lib/card/env/success.rb +14 -14
  24. data/lib/card/env/success/target.rb +9 -11
  25. data/lib/card/error.rb +1 -1
  26. data/lib/card/fetch/all.rb +32 -0
  27. data/lib/card/fetch/card_class.rb +147 -0
  28. data/lib/card/format.rb +1 -1
  29. data/lib/card/format/error.rb +3 -3
  30. data/lib/card/format/nest.rb +1 -1
  31. data/lib/card/format/nest/fetch.rb +1 -1
  32. data/lib/card/lexicon.rb +2 -2
  33. data/lib/card/name/all.rb +8 -0
  34. data/lib/card/name/all/descendants.rb +6 -3
  35. data/lib/card/name/card_class.rb +26 -0
  36. data/lib/card/reference/all.rb +131 -0
  37. data/lib/card/rule/all.rb +75 -0
  38. data/lib/card/set/event/all.rb +95 -0
  39. data/lib/card/set/event/skip_and_trigger.rb +89 -0
  40. data/lib/card/set/pattern/all.rb +63 -0
  41. data/lib/card/subcards/all.rb +103 -0
  42. data/lib/cardio/migration/import.rb +1 -1
  43. data/lib/cardio/utils.rb +5 -3
  44. data/mod/admin/set/self/admin_info.rb +3 -5
  45. data/mod/admin/set/self/trash.rb +2 -2
  46. data/mod/core/set/all/autoname.rb +17 -0
  47. data/mod/core/set/all/codename.rb +2 -2
  48. data/mod/core/set/all/content.rb +52 -97
  49. data/mod/core/set/all/name_events.rb +69 -58
  50. data/mod/core/set/all/reference_events.rb +67 -0
  51. data/mod/core/set/all/states.rb +2 -2
  52. data/mod/core/set/all/subcards.rb +0 -100
  53. data/mod/core/set/all/trash.rb +11 -13
  54. data/mod/core/set/all/type.rb +7 -9
  55. data/mod/core/set/all/utils.rb +3 -0
  56. data/mod/core/set/type/cardtype.rb +3 -3
  57. data/mod/core/set_pattern/06_rule.rb +1 -1
  58. data/mod/core/spec/set/all/{rules2_spec.rb → clean_me_spec.rb} +0 -0
  59. data/mod/core/spec/set/all/name_events_spec.rb +204 -0
  60. metadata +30 -37
  61. data/lib/card/mod_inflector.rb +0 -16
  62. data/lib/card/name/all/class_methods.rb +0 -28
  63. data/mod/core/set/all/actify.rb +0 -68
  64. data/mod/core/set/all/cache.rb +0 -109
  65. data/mod/core/set/all/event_conditions.rb +0 -172
  66. data/mod/core/set/all/fetch.rb +0 -122
  67. data/mod/core/set/all/fetch_helper.rb +0 -35
  68. data/mod/core/set/all/i18n.rb +0 -9
  69. data/mod/core/set/all/pattern.rb +0 -54
  70. data/mod/core/set/all/references.rb +0 -191
  71. data/mod/core/set/all/rename.rb +0 -33
  72. data/mod/core/set/all/rules.rb +0 -81
  73. data/mod/core/spec/set/all/actify_spec.rb +0 -58
  74. data/mod/core/spec/set/all/content_spec.rb +0 -15
  75. data/mod/core/spec/set/all/event_conditions_spec.rb +0 -217
  76. data/mod/core/spec/set/all/fetch_helper_spec.rb +0 -65
  77. data/mod/core/spec/set/all/fetch_spec.rb +0 -338
  78. data/mod/core/spec/set/all/i18n_spec.rb +0 -17
  79. data/mod/core/spec/set/all/pattern_spec.rb +0 -101
  80. data/mod/core/spec/set/all/permissions/reader_rules_spec.rb +0 -166
  81. data/mod/core/spec/set/all/references_spec.rb +0 -62
  82. data/mod/core/spec/set/all/rename_spec.rb +0 -189
  83. data/mod/core/spec/set/all/rules_spec.rb +0 -100
  84. 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
@@ -99,7 +99,7 @@ module Cardio
99
99
  def fetch_remote_data name, view, url
100
100
  json_url = "#{url}/#{name}.json"
101
101
  json_url += "?view=#{view}" if view
102
- json = ::File.open(json_url).read
102
+ json = open(json_url).read
103
103
  parse_and_symbolize json
104
104
  end
105
105
 
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 tr key, args={}
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>#{tr :admin_warn}</h5>" + list_tag(warnings)
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
- tr :email_off, path: "config/application.rb"
37
+ t :admin_email_off, path: "config/application.rb"
38
38
  end
39
39
 
40
40
  def warning_list_with_auto_scope warnings
41
- # 'ADMINISTRATOR WARNING'
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
@@ -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: { id: "~#{card.id}" } },
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: { id: "~#{card.id}" } }
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