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.
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
@@ -1,35 +0,0 @@
1
- module ClassMethods
2
- # a fetch method to support the needs of the card controller.
3
- # should be in Decko?
4
- def controller_fetch args
5
- card_opts = controller_fetch_opts args
6
- if args[:action] == "create"
7
- # FIXME: we currently need a "new" card to catch duplicates
8
- # (otherwise save will just act like a normal update)
9
- # We may need a "#create" instance method to handle this checking?
10
- Card.new card_opts
11
- else
12
- standard_controller_fetch args, card_opts
13
- end
14
- end
15
-
16
- private
17
-
18
- def standard_controller_fetch args, card_opts
19
- mark = args[:mark] || card_opts[:name]
20
- card = Card.fetch mark, skip_modules: true,
21
- look_in_trash: args[:look_in_trash],
22
- new: card_opts
23
- card.assign_attributes card_opts if args[:assign] && card&.real?
24
- card&.include_set_modules
25
- card
26
- end
27
-
28
- def controller_fetch_opts args
29
- opts = Env.hash args[:card]
30
- opts[:type] ||= args[:type] if args[:type]
31
- # for /new/:type shortcut. we should handle in routing and deprecate this
32
- opts[:name] ||= Card::Name.url_key_to_standard args[:mark]
33
- opts
34
- end
35
- end
@@ -1,9 +0,0 @@
1
- def tr key, args={}
2
- Cardio.tr key, args.merge(caller: caller)
3
- end
4
-
5
- format do
6
- def tr key, args={}
7
- Cardio.tr key, args.merge(caller: caller)
8
- end
9
- end
@@ -1,54 +0,0 @@
1
- def patterns?
2
- defined? @patterns
3
- end
4
-
5
- def all_patterns
6
- @all_patterns ||= set_patterns.map { |sub| sub.new self }.compact
7
- end
8
-
9
- # new cards do not
10
- def patterns
11
- @patterns ||= (new_card? ? all_patterns[1..-1] : all_patterns)
12
- end
13
-
14
- def reset_patterns
15
- # Rails.logger.info "resetting patterns: #{name}"
16
- @patterns = @all_patterns = nil
17
- @template = @virtual = nil
18
- @set_mods_loaded = @set_modules = @set_names = @rule_set_keys = nil
19
- @junction_only = nil # only applies to set cards
20
- true
21
- end
22
-
23
- def safe_set_keys
24
- patterns.map(&:safe_key).reverse * " "
25
- end
26
-
27
- def set_modules
28
- @set_modules ||= all_patterns[0..-2].reverse.map(&:module_list).flatten.compact
29
- end
30
-
31
- def set_format_modules klass
32
- @set_format_modules ||= {}
33
- @set_format_modules[klass] =
34
- all_patterns[0..-2].reverse.map do |pattern|
35
- pattern.format_module_list klass
36
- end.flatten.compact
37
- end
38
-
39
- def set_names
40
- @set_names = patterns.map(&:to_s) if @set_names.nil?
41
- @set_names
42
- end
43
-
44
- def in_set? set_module
45
- patterns.map(&:module_key).include? set_module.shortname
46
- end
47
-
48
- def rule_set_keys
49
- @rule_set_keys ||= patterns.map(&:rule_set_key).compact
50
- end
51
-
52
- def include_module? set
53
- singleton_class&.include? set
54
- end
@@ -1,191 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # Cards can refer to other cards in their content, eg via links and nests.
4
- # The card that refers is the "referer", the card that is referred to is
5
- # the "referee". The reference itself has its own class (Card::Reference),
6
- # which handles id-based reference tracking.
7
-
8
- PARTIAL_REF_CODE = "P".freeze
9
-
10
- # cards that refer to self
11
- def referers
12
- referer_cards_from_references references_in
13
- end
14
-
15
- # cards that include self
16
- def nesters
17
- referer_cards_from_references references_in.where(ref_type: "I")
18
- end
19
-
20
- def referer_cards_from_references references
21
- references.map(&:referer_id).uniq.map(&Card.method(:fetch)).compact
22
- end
23
-
24
- # cards that self refers to
25
- def referees
26
- referees_from_references references_out
27
- end
28
-
29
- # cards that self includes
30
- def nestees
31
- referees_from_references references_out.where(ref_type: "I")
32
- end
33
-
34
- def referees_from_references references
35
- references.map(&:referee_key).uniq.map { |key| Card.fetch key, new: {} }
36
- end
37
-
38
- # cards that refer to self by name
39
- # (finds cards not yet linked by id)
40
- def name_referers
41
- Card.joins(:references_out).where card_references: { referee_key: key }
42
- end
43
-
44
- # replace references in card content
45
- def replace_reference_syntax old_name, new_name
46
- obj_content = Card::Content.new content, self
47
- obj_content.find_chunks(Card::Content::Chunk::Reference).select do |chunk|
48
- next unless (old_ref_name = chunk.referee_name)
49
- next unless (new_ref_name = old_ref_name.swap old_name, new_name)
50
- chunk.referee_name = chunk.replace_reference old_name, new_name
51
- refs = Card::Reference.where referee_key: old_ref_name.key
52
- refs.update_all referee_key: new_ref_name.key
53
- end
54
-
55
- obj_content.to_s
56
- end
57
-
58
- # delete old references from this card's content, create new ones
59
- def update_references_out
60
- delete_references_out
61
- create_references_out
62
- end
63
-
64
- # interpret references from this card's content and
65
- # insert entries in reference table
66
- def create_references_out
67
- ref_hash = {}
68
- each_reference_out do |referee_name, ref_type|
69
- interpret_reference ref_hash, referee_name, ref_type
70
- end
71
- return if ref_hash.empty?
72
- Card::Reference.mass_insert reference_values_array(ref_hash)
73
- end
74
-
75
- # delete references from this card
76
- def delete_references_out
77
- raise "id required to delete references" if id.nil?
78
- Card::Reference.where(referer_id: id).delete_all
79
- end
80
-
81
- # interpretation phase helps to prevent duplicate references
82
- # results in hash like:
83
- # { referee1_key: [referee1_id, referee1_type2],
84
- # referee2_key...
85
- # }
86
- def interpret_reference ref_hash, raw_referee_name, ref_type
87
- with_normalized_referee raw_referee_name do |referee_name, referee_key, referee_id|
88
- ref_hash[referee_key] ||= [referee_id]
89
- ref_hash[referee_key] << ref_type
90
- interpret_partial_references ref_hash, referee_name unless referee_id
91
- end
92
- end
93
-
94
- # Partial references are needed to track references to virtual cards.
95
- # For example a link to virual card [[A+*self]] won't have a referee_id,
96
- # but when A's name is changed we have to find and update that link.
97
- def interpret_partial_references ref_hash, referee_name
98
- return if referee_name.simple?
99
- [referee_name.left, referee_name.right].each do |sidename|
100
- interpret_reference ref_hash, sidename, PARTIAL_REF_CODE
101
- end
102
- end
103
-
104
- # translate interpreted reference hash into values array,
105
- # removing duplicate and unnecessary ref_types
106
- def reference_values_array ref_hash
107
- values = []
108
- ref_hash.each do |referee_key, hash_val|
109
- referee_id = hash_val.shift || "null"
110
- ref_types = hash_val.uniq
111
- ref_types.delete PARTIAL_REF_CODE if ref_types.size > 1
112
- # partial references are not necessary if there are explicit references
113
- ref_types.each do |ref_type|
114
- values << [id, referee_id, "'#{referee_key}'", "'#{ref_type}'"]
115
- end
116
- end
117
- values
118
- end
119
-
120
- # invokes the given block for each reference in content with
121
- # the reference name and reference type
122
- def each_reference_out
123
- content_object.find_chunks(Card::Content::Chunk::Reference).each do |chunk|
124
- yield chunk.referee_name, chunk.reference_code
125
- end
126
- end
127
-
128
- def has_nests?
129
- content_object.has_chunk? Card::Content::Chunk::Nest
130
- end
131
-
132
- def content_object
133
- Card::Content.new content, self
134
- end
135
-
136
- protected
137
-
138
- # test for updating referer content
139
- event :prepare_referer_update, :validate, on: :update, changed: :name do
140
- self.update_referers = ![nil, false, "false"].member?(update_referers)
141
- end
142
-
143
- # on rename, update names in cards that refer to self by name (as directed)
144
- event :update_referer_content, :finalize, on: :update, when: :update_referers do
145
- referers.each do |card|
146
- next if card.structure
147
- card.skip_event! :validate_renaming, :check_permissions
148
- card.content = card.replace_reference_syntax name_before_act, name
149
- attach_subcard card
150
- end
151
- end
152
-
153
- # on rename, when NOT updating referer content, update references to ensure
154
- # that partial references are correctly tracked
155
- # eg. A links to X+Y. if X+Y is renamed and we're not updating the link in A,
156
- # then we need to be sure that A has a partial reference
157
- event :update_referer_references_out, :finalize,
158
- changed: :name, on: :update, when: :not_update_referers do
159
- referers.map(&:update_references_out)
160
- end
161
-
162
- # when name changes, update references to card
163
- event :refresh_references_in, :finalize, changed: :name, on: :save do
164
- Card::Reference.unmap_referees id if action == :update && !update_referers
165
- Card::Reference.map_referees key, id
166
- end
167
-
168
- # when content changes, update references to other cards
169
- event :refresh_references_out, :finalize, on: :save, changed: :content do
170
- update_references_out
171
- end
172
-
173
- # clean up reference table when card is deleted
174
- event :clear_references, :finalize, on: :delete do
175
- delete_references_out
176
- Card::Reference.unmap_referees id
177
- end
178
-
179
- def not_update_referers
180
- !update_referers
181
- end
182
-
183
- private
184
-
185
- def with_normalized_referee referee_name
186
- return unless referee_name # eg commented nest has no referee_name
187
- referee_name = referee_name.to_name
188
- referee_key = referee_name.key
189
- return if referee_key == key # don't create self reference
190
- yield referee_name, referee_key, Card::Lexicon.id(referee_name)
191
- end
@@ -1,33 +0,0 @@
1
- event :rename_in_trash, after: :expire_old_name, on: :update do
2
- existing_card = Card.find_by_key_and_trash name.key, true
3
- return if !existing_card || existing_card == self
4
- existing_card.name = existing_card.name + "*trash"
5
- existing_card.rename_in_trash_without_callbacks
6
- existing_card.save!
7
- end
8
-
9
- event :validate_renaming, :validate, on: :update, changed: :name, skip: :allowed do
10
- return if name_before_act&.to_name == name # just changing to new variant
11
- errors.add :content, tr(:cannot_change_content) if content_is_changing?
12
- errors.add :type, tr(:cannot_change_type) if type_is_changing?
13
- detect_illegal_compound_names
14
- end
15
-
16
- event :cascade_name_changes, :finalize, on: :update, changed: :name do
17
- each_descendant do |d|
18
- d.action = :update
19
- update_referers ? d.update_referers : d.update_referer_references_out
20
- d.refresh_references_in
21
- d.refresh_references_out
22
- d.expire
23
- end
24
- end
25
-
26
- def changed_from_simple_to_compound?
27
- name.compound? && name_before_act.to_name.simple?
28
- end
29
-
30
- def detect_illegal_compound_names
31
- return unless changed_from_simple_to_compound? && child_ids(:right).present?
32
- errors.add :name, "illegal name change; existing names end in +#{name_before_act}"
33
- end
@@ -1,81 +0,0 @@
1
- def rule setting_code
2
- rule_card(setting_code, skip_modules: true)&.db_content
3
- end
4
-
5
- def rule_card setting_code, options={}
6
- Card.fetch rule_card_id(setting_code), options
7
- end
8
-
9
- def rule_card_id setting_code
10
- rule_id_lookup Card::Rule.rule_cache, setting_code
11
- end
12
-
13
- def preference setting_code, user=nil
14
- preference_card(setting_code, user, skip_modules: true)&.db_content
15
- end
16
-
17
- def preference_card setting_code, user=nil, options={}
18
- Card.fetch preference_card_id(setting_code, user), options
19
- end
20
-
21
- def preference_card_id setting_code, user=nil
22
- return unless (user_id = preference_user_id user)
23
- rule_id_lookup Card::Rule.preference_cache,
24
- "#{setting_code}+#{user_id}",
25
- "#{setting_code}+#{AllID}"
26
- end
27
-
28
- def is_rule?
29
- is_standard_rule? || is_preference?
30
- end
31
-
32
- def is_standard_rule?
33
- (r = right(skip_modules: true)) &&
34
- r.type_id == SettingID &&
35
- (l = left(skip_modules: true)) &&
36
- l.type_id == SetID
37
- end
38
-
39
- def is_preference?
40
- name.parts.length > 2 &&
41
- (r = right(skip_modules: true)) &&
42
- r.type_id == SettingID &&
43
- (set = self[0..-3, skip_modules: true]) &&
44
- set.type_id == SetID &&
45
- (user = self[-2, skip_modules: true]) &&
46
- (user.type_id == UserID || user.codename == :all)
47
- end
48
-
49
- # FIXME: move to a better place (if still needed) and use codenames
50
- def related_sets with_self=false
51
- # refers to sets that users may configure from the current card -
52
- # NOT to sets to which the current card belongs
53
-
54
- sets = []
55
- sets << ["#{name}+*self", Card::Set::Self.label(name)] if with_self
56
- if known? && name.simple?
57
- sets << ["#{name}+*right", Card::Set::Right.label(name)]
58
- end
59
- sets
60
- end
61
-
62
- private
63
-
64
- def preference_user_id user
65
- case user
66
- when Integer then user;
67
- when Card then user
68
- when nil then Auth.current_id
69
- else
70
- raise Card::ServerError, "invalid preference user"
71
- end
72
- end
73
-
74
- def rule_id_lookup lookup_hash, cache_suffix, fallback_suffix=nil
75
- rule_set_keys.each do |rule_set_key|
76
- rule_id = lookup_hash["#{rule_set_key}+#{cache_suffix}"]
77
- rule_id ||= fallback_suffix && lookup_hash["#{rule_set_key}+#{fallback_suffix}"]
78
- return rule_id if rule_id
79
- end
80
- nil
81
- end
@@ -1,58 +0,0 @@
1
- # -*- encoding : utf-8 -*-
2
-
3
- RSpec.describe Card::Set::All::Actify do
4
- describe "#act" do
5
- let(:card) { Card["A"] }
6
-
7
- before do
8
- allow(card).to receive(:act).and_return nil
9
- end
10
-
11
- it "is called by valid?" do
12
- card.valid?
13
- expect(card).to have_received :act
14
- end
15
-
16
- it "is called by #save!" do
17
- card.save!
18
- expect(card).to have_received :act
19
- end
20
-
21
- it "is called by #save" do
22
- card.save
23
- expect(card).to have_received :act
24
- end
25
-
26
- it "is called by #update" do
27
- card.update content: "A"
28
- expect(card).to have_received :act
29
- end
30
-
31
- it "is called by #update!" do
32
- card.update! content: "A"
33
- expect(card).to have_received :act
34
- end
35
-
36
- it "is called by #update_attributes" do
37
- card.update_attributes content: "A"
38
- expect(card).to have_received :act
39
- end
40
-
41
- it "is called by #update_attributes!" do
42
- card.update_attributes! content: "A"
43
- expect(card).to have_received :act
44
- end
45
- end
46
-
47
- describe "Card.create!" do
48
- it "does not prevent validations when run as subcard" do
49
- with_test_events do
50
- test_event :finalize do
51
- expect { Card.create! name: "A" }.to raise_error(/unique/)
52
- raise Card::Error, "woot"
53
- end
54
- expect { Card["B"].update! content: "what" }.to raise_error(/woot/)
55
- end
56
- end
57
- end
58
- end