card 1.101.3 → 1.101.4
Sign up to get free protection for your applications and to get access to all the features.
- 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
@@ -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,
|
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,
|
28
|
+
errors.add :codename, t(:core_error_code_in_use, codename: codename)
|
29
29
|
end
|
data/mod/core/set/all/content.rb
CHANGED
@@ -1,30 +1,67 @@
|
|
1
|
-
|
2
|
-
self.db_content =
|
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
|
6
|
-
|
34
|
+
def blank_comment?
|
35
|
+
comment.blank? || comment.strip.blank?
|
7
36
|
end
|
8
|
-
alias raw_content content #DEPRECATED!
|
9
37
|
|
10
|
-
def
|
11
|
-
|
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
|
15
|
-
|
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
|
-
|
19
|
-
|
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
|
23
|
-
|
59
|
+
def creator
|
60
|
+
Card[creator_id]
|
24
61
|
end
|
25
62
|
|
26
|
-
def
|
27
|
-
|
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,
|
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,
|
24
|
+
errors.add :name, t(:core_error_too_long, length: name.length)
|
25
25
|
elsif name.blank?
|
26
|
-
errors.add :name,
|
26
|
+
errors.add :name, t(:core_error_blank_name)
|
27
27
|
elsif name_incomplete?
|
28
|
-
errors.add :name,
|
28
|
+
errors.add :name, t(:core_is_incomplete)
|
29
29
|
elsif !name.valid?
|
30
|
-
errors.add :name,
|
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,
|
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,
|
39
|
+
errors.add :key, t(:core_error_blank_key) if errors.empty?
|
39
40
|
elsif key != name.key
|
40
|
-
errors.add :key,
|
41
|
+
errors.add :key, t(:core_error_wrong_key, key: key, name: name)
|
41
42
|
end
|
42
43
|
end
|
43
44
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
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 :
|
60
|
-
Card
|
61
|
-
|
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
|
-
|
86
|
-
|
87
|
-
|
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
|
-
|
93
|
-
|
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
|
-
|
96
|
-
|
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
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
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
|
111
|
-
|
102
|
+
def changed_from_simple_to_compound?
|
103
|
+
name.compound? && name_before_act.to_name.simple?
|
112
104
|
end
|
113
105
|
|
114
|
-
def
|
115
|
-
|
116
|
-
|
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
|
data/mod/core/set/all/states.rb
CHANGED
@@ -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
|
-
|
75
|
-
|
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?
|