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
@@ -19,11 +19,11 @@ private
19
19
  def validate_codename_permission
20
20
  return if Auth.always_ok? || Auth.as_id == creator_id
21
21
 
22
- errors.add :codename, tr(:only_admins_codename)
22
+ errors.add :codename, t(:core_only_admins_codename)
23
23
  end
24
24
 
25
25
  def validate_codename_uniqueness
26
26
  return (self.codename = nil) if codename.blank?
27
27
  return if errors.present? || !Card.find_by_codename(codename)
28
- errors.add :codename, tr(:error_code_in_use, codename: codename)
28
+ errors.add :codename, t(:core_error_code_in_use, codename: codename)
29
29
  end
@@ -1,30 +1,67 @@
1
- def content= value
2
- self.db_content = standardize_content(value)
1
+ event :set_content, :store, on: :save do
2
+ self.db_content = prepare_db_content
3
+ @selected_action_id = @selected_content = nil
4
+ clear_drafts
5
+ end
6
+
7
+ event :save_draft, :store, on: :update, when: :draft? do
8
+ save_content_draft content
9
+ abort :success
10
+ end
11
+
12
+ event :set_default_content,
13
+ :prepare_to_validate,
14
+ on: :create, when: :use_default_content? do
15
+ self.db_content = template.db_content
16
+ end
17
+
18
+ def draft?
19
+ Env.params["draft"] == "true"
20
+ end
21
+
22
+ def clean_html?
23
+ true
24
+ end
25
+
26
+ def use_default_content?
27
+ !db_content_changed? && template && template.db_content.present?
28
+ end
29
+
30
+ def unfilled?
31
+ blank_content? && blank_comment? && !subcards?
3
32
  end
4
33
 
5
- def content
6
- structured_content || standard_content
34
+ def blank_comment?
35
+ comment.blank? || comment.strip.blank?
7
36
  end
8
- alias raw_content content #DEPRECATED!
9
37
 
10
- def content?
11
- content.present?
38
+ def prepare_db_content
39
+ cont = standard_db_content || "" # necessary?
40
+ clean_html? ? Card::Content.clean!(cont) : cont
12
41
  end
13
42
 
14
- def standard_content
15
- db_content || (new_card? && template.db_content)
43
+ def standard_db_content
44
+ if structure
45
+ # do not override db_content with content from structure
46
+ db_content
47
+ else
48
+ standard_content
49
+ end
16
50
  end
17
51
 
18
- def standardize_content value
19
- value.is_a?(Array) ? value.join("\n") : value
52
+ # seems like this should be moved to format so we can fall back on title
53
+ # rather than name. (In fact, name, title, AND label is a bit much.
54
+ # Trim to 2?)
55
+ def label
56
+ name
20
57
  end
21
58
 
22
- def structured_content
23
- structure && template.db_content
59
+ def creator
60
+ Card[creator_id]
24
61
  end
25
62
 
26
- def refresh_content
27
- self.content = Card.find(id)&.db_content
63
+ def updater
64
+ Card[updater_id]
28
65
  end
29
66
 
30
67
  format do
@@ -94,85 +131,3 @@ format :html do
94
131
  hidden_field :content, class: "d0-card-content"
95
132
  end
96
133
  end
97
-
98
- # seems like this should be moved to format so we can fall back on title
99
- # rather than name. (In fact, name, title, AND label is a bit much.
100
- # Trim to 2?)
101
- def label
102
- name
103
- end
104
-
105
- def creator
106
- Card[creator_id]
107
- end
108
-
109
- def updater
110
- Card[updater_id]
111
- end
112
-
113
- def save_content_draft _content
114
- clear_drafts
115
- end
116
-
117
- def clear_drafts
118
- drafts.created_by(Card::Auth.current_id).each(&:delete)
119
- end
120
-
121
- def last_draft_content
122
- drafts.last.card_changes.last.value
123
- end
124
-
125
- event :set_content, :store, on: :save do
126
- self.db_content = prepare_db_content
127
- @selected_action_id = @selected_content = nil
128
- clear_drafts
129
- end
130
-
131
- event :save_draft, :store, on: :update, when: :draft? do
132
- save_content_draft content
133
- abort :success
134
- end
135
-
136
- event :set_default_content,
137
- :prepare_to_validate,
138
- on: :create, when: :use_default_content? do
139
- self.db_content = template.db_content
140
- end
141
-
142
- def draft?
143
- Env.params["draft"] == "true"
144
- end
145
-
146
- def prepare_db_content
147
- cont = standard_db_content || "" # necessary?
148
- clean_html? ? Card::Content.clean!(cont) : cont
149
- end
150
-
151
- def standard_db_content
152
- if structure
153
- # do not override db_content with content from structure
154
- db_content
155
- else
156
- standard_content
157
- end
158
- end
159
-
160
- def clean_html?
161
- true
162
- end
163
-
164
- def use_default_content?
165
- !db_content_changed? && template && template.db_content.present?
166
- end
167
-
168
- def unfilled?
169
- blank_content? && blank_comment? && !subcards?
170
- end
171
-
172
- def blank_content?
173
- content.blank? || content.strip.blank?
174
- end
175
-
176
- def blank_comment?
177
- comment.blank? || comment.strip.blank?
178
- end
@@ -7,73 +7,58 @@ event :validate_name, :validate, on: :save, changed: :name, when: :no_autoname?
7
7
  validate_uniqueness_of_name
8
8
  end
9
9
 
10
+ # called by validate_name
10
11
  event :validate_uniqueness_of_name, skip: :allowed do
11
- # validate uniqueness of name
12
-
13
12
  return unless (existing_id = Card::Lexicon.id key) && existing_id != id
14
13
  # The above is a fast check but cannot detect if card is in trash
15
14
 
16
15
  # TODO: perform the following as a remote-only fetch (not yet supported)
17
16
  return unless (existing_card = Card.where(id: existing_id, trash: false).take)
18
17
 
19
- errors.add :name, tr(:error_name_exists, name: existing_card.name)
18
+ errors.add :name, t(:core_error_name_exists, name: existing_card.name)
20
19
  end
21
20
 
21
+ # called by validate_name
22
22
  event :validate_legality_of_name do
23
23
  if name.length > 255
24
- errors.add :name, tr(:error_too_long, length: name.length)
24
+ errors.add :name, t(:core_error_too_long, length: name.length)
25
25
  elsif name.blank?
26
- errors.add :name, tr(:error_blank_name)
26
+ errors.add :name, t(:core_error_blank_name)
27
27
  elsif name_incomplete?
28
- errors.add :name, tr(:is_incomplete)
28
+ errors.add :name, t(:core_is_incomplete)
29
29
  elsif !name.valid?
30
- errors.add :name, tr(:error_banned_characters, banned: Card::Name.banned_array * " ")
30
+ errors.add :name, t(:core_error_banned_characters,
31
+ banned: Card::Name.banned_array * " ")
31
32
  elsif changing_existing_tag_to_junction?
32
- errors.add :name, tr(:error_name_tag, name: name)
33
+ errors.add :name, t(:core_error_name_tag, name: name)
33
34
  end
34
35
  end
35
36
 
36
37
  event :validate_key, after: :validate_name, on: :save, when: :no_autoname? do
37
38
  if key.empty?
38
- errors.add :key, tr(:error_blank_key) if errors.empty?
39
+ errors.add :key, t(:core_error_blank_key) if errors.empty?
39
40
  elsif key != name.key
40
- errors.add :key, tr(:error_wrong_key, key: key, name: name)
41
+ errors.add :key, t(:core_error_wrong_key, key: key, name: name)
41
42
  end
42
43
  end
43
44
 
44
- # STAGE: store
45
-
46
- event :set_autoname, :prepare_to_store, on: :create, when: :autoname? do
47
- self.name = autoname rule(:autoname)
48
- autoname_card = rule_card :autoname
49
- autoname_card.update_column :db_content, name
50
- autoname_card.expire
51
- pull_from_trash!
52
- Card.write_to_soft_cache self
45
+ event :validate_renaming, :validate, on: :update, changed: :name, skip: :allowed do
46
+ return if name_before_act&.to_name == name # just changing to new variant
47
+ errors.add :content, t(:core_cannot_change_content) if content_is_changing?
48
+ errors.add :type, t(:core_cannot_change_type) if type_is_changing?
49
+ detect_illegal_compound_names
53
50
  end
54
51
 
52
+ # STAGE: store
53
+
55
54
  event :expire_old_name, :store, changed: :name, on: :update do
56
55
  Director.expirees << name_before_act
57
56
  end
58
57
 
59
- event :update_lexicon_on_create, :finalize, changed: :name, on: :create do
60
- Card::Lexicon.add self
61
- end
62
-
63
- event :update_lexicon_on_rename, :finalize, changed: :name, on: :update do
64
- Card::Lexicon.update self
65
- end
66
-
67
- def lex
68
- simple? ? name : [left_id, right_id]
69
- end
70
-
71
- def old_lex
72
- if (old_left_id = left_id_before_act)
73
- [old_left_id, right_id_before_act]
74
- else
75
- name_before_act
76
- end
58
+ event :rename_in_trash, after: :expire_old_name, on: :update do
59
+ existing_card = Card.find_by_key_and_trash name.key, true
60
+ return if !existing_card || existing_card == self
61
+ existing_card.rename_as_trash_obstacle
77
62
  end
78
63
 
79
64
  event :prepare_left_and_right, :store, changed: :name, on: :save do
@@ -82,42 +67,47 @@ event :prepare_left_and_right, :store, changed: :name, on: :save do
82
67
  prepare_side :right
83
68
  end
84
69
 
85
- def prepare_side side
86
- side_id = send "#{side}_id"
87
- sidename = name.send "#{side}_name"
88
- prepare_obstructed_side(side, side_id, sidename) ||
89
- prepare_new_side(side, side_id, sidename)
70
+ event :update_lexicon, :finalize, changed: :name, on: :save do
71
+ lexicon_action = @action == :create ? :add : :update
72
+ Card::Lexicon.send lexicon_action, self
90
73
  end
91
74
 
92
- def prepare_new_side side, side_id, sidename
93
- return unless side_id == -1 || !Card[side_id]&.real?
75
+ event :cascade_name_changes, :finalize, on: :update, changed: :name do
76
+ each_descendant { |d| d.rename_as_descendant update_referers }
77
+ end
94
78
 
95
- sidecard = Director.card(sidename) || add_subcard(sidename)
96
- send "#{side}_id=", sidecard
79
+ protected
80
+
81
+ def rename_as_trash_obstacle
82
+ self.name = name + "*trash"
83
+ rename_in_trash_without_callbacks
84
+ save!
97
85
  end
98
86
 
99
- def prepare_obstructed_side side, side_id, sidename
100
- return unless side_id && side_id == id
101
- clear_name sidename
102
- send "#{side}_id=", add_subcard(sidename)
103
- true
87
+ def rename_as_descendant referers=true
88
+ self.action = :update
89
+ referers ? update_referers : update_referer_references_out
90
+ refresh_references_in
91
+ refresh_references_out
92
+ expire
93
+ Card::Lexicon.update self
104
94
  end
105
95
 
96
+ private
97
+
106
98
  def name_incomplete?
107
99
  name.parts.include?("") && !superleft&.autoname?
108
100
  end
109
101
 
110
- def no_autoname?
111
- !autoname?
102
+ def changed_from_simple_to_compound?
103
+ name.compound? && name_before_act.to_name.simple?
112
104
  end
113
105
 
114
- def autoname?
115
- name.blank? &&
116
- (@autoname_rule.nil? ? (@autoname_rule = rule(:autoname).present?) : @autoname_rule)
106
+ def detect_illegal_compound_names
107
+ return unless changed_from_simple_to_compound? && child_ids(:right).present?
108
+ errors.add :name, "illegal name change; existing names end in +#{name_before_act}"
117
109
  end
118
110
 
119
- private
120
-
121
111
  def changing_existing_tag_to_junction?
122
112
  return false unless changing_name_to_junction?
123
113
  name_in_use_as_tag?
@@ -143,3 +133,24 @@ def clear_name name
143
133
  Card::Lexicon.cache.reset # probably overkill, but this for an edge case...
144
134
  # Card::Lexicon.delete id, key
145
135
  end
136
+
137
+ def prepare_side side
138
+ side_id = send "#{side}_id"
139
+ sidename = name.send "#{side}_name"
140
+ prepare_obstructed_side(side, side_id, sidename) ||
141
+ prepare_new_side(side, side_id, sidename)
142
+ end
143
+
144
+ def prepare_new_side side, side_id, sidename
145
+ return unless side_id == -1 || !Card[side_id]&.real?
146
+
147
+ sidecard = Director.card(sidename) || add_subcard(sidename)
148
+ send "#{side}_id=", sidecard
149
+ end
150
+
151
+ def prepare_obstructed_side side, side_id, sidename
152
+ return unless side_id && side_id == id
153
+ clear_name sidename
154
+ send "#{side}_id=", add_subcard(sidename)
155
+ true
156
+ end
@@ -0,0 +1,67 @@
1
+ # test for updating referer content
2
+ event :prepare_referer_update, :validate, on: :update, changed: :name do
3
+ self.update_referers = ![nil, false, "false"].member?(update_referers)
4
+ end
5
+
6
+ # on rename, update names in cards that refer to self by name (as directed)
7
+ event :update_referer_content, :finalize, on: :update, when: :update_referers do
8
+ referers.each do |card|
9
+ next if card.structure
10
+ card.skip_event! :validate_renaming, :check_permissions
11
+ card.content = card.replace_references name_before_act, name
12
+ attach_subcard card
13
+ end
14
+ end
15
+
16
+ # on rename, when NOT updating referer content, update references to ensure
17
+ # that partial references are correctly tracked
18
+ # eg. A links to X+Y. if X+Y is renamed and we're not updating the link in A,
19
+ # then we need to be sure that A has a partial reference
20
+ event :update_referer_references_out, :finalize,
21
+ changed: :name, on: :update, when: :not_update_referers do
22
+ referers.map(&:update_references_out)
23
+ end
24
+
25
+ # when name changes, update references to card
26
+ event :refresh_references_in, :finalize, changed: :name, on: :save do
27
+ Reference.unmap_referees id if action == :update && !update_referers
28
+ Reference.map_referees key, id
29
+ end
30
+
31
+ # when content changes, update references to other cards
32
+ event :refresh_references_out, :finalize, on: :save, changed: :content do
33
+ update_references_out
34
+ end
35
+
36
+ # clean up reference table when card is deleted
37
+ event :clear_references, :finalize, on: :delete do
38
+ delete_references_out
39
+ Reference.unmap_referees id
40
+ end
41
+
42
+ # replace references in card content
43
+ def replace_references old_name, new_name
44
+ cont = content_object
45
+ cont.find_chunks(:Reference).each do |chunk|
46
+ next unless replace_reference chunk, old_name, new_name
47
+ end
48
+ cont.to_s
49
+ end
50
+
51
+ protected
52
+
53
+ def not_update_referers
54
+ !update_referers
55
+ end
56
+
57
+ private
58
+
59
+ def replace_reference chunk, old_name, new_name
60
+ return unless (old = chunk.referee_name) && (new = old.swap old_name, new_name)
61
+ chunk.referee_name = chunk.replace_reference old_name, new_name
62
+ update_reference old.key, new.key
63
+ end
64
+
65
+ def update_reference old_key, new_key
66
+ Reference.where(referee_key: old_key).update_all referee_key: new_key
67
+ end
@@ -71,8 +71,8 @@ def new?
71
71
  new_record? || # not yet in db (from ActiveRecord)
72
72
  !@from_trash.nil? # in process of restoration from trash
73
73
  end
74
- alias new_card? new?
75
- alias unreal? new?
74
+ alias_method :new_card?, :new?
75
+ alias_method :unreal?, :new?
76
76
 
77
77
  # has not been edited directly by human users. bleep blorp.
78
78
  def pristine?