card 1.16.14 → 1.16.15

Sign up to get free protection for your applications and to get access to all the features.
Files changed (69) hide show
  1. checksums.yaml +4 -4
  2. data/VERSION +1 -1
  3. data/db/migrate_core_cards/20150903130006_attachment_upload_cards.rb +4 -2
  4. data/lib/card/auth.rb +15 -10
  5. data/lib/card/codename.rb +25 -21
  6. data/lib/card/content.rb +100 -68
  7. data/lib/card/format.rb +158 -129
  8. data/lib/card/query.rb +15 -9
  9. data/lib/card/query/attributes.rb +41 -49
  10. data/lib/card/set.rb +15 -12
  11. data/lib/card/set_pattern.rb +4 -5
  12. data/lib/card/spec_helper.rb +54 -16
  13. data/lib/cardio.rb +43 -25
  14. data/mod/01_core/chunk/include.rb +1 -1
  15. data/mod/01_core/set/all/collection.rb +76 -73
  16. data/mod/01_core/set/all/content.rb +0 -4
  17. data/mod/01_core/set/all/fetch.rb +35 -42
  18. data/mod/01_core/set/all/name.rb +17 -7
  19. data/mod/01_core/set/all/pattern.rb +12 -11
  20. data/mod/01_core/set/all/permissions.rb +51 -42
  21. data/mod/01_core/set/all/phases.rb +2 -1
  22. data/mod/01_core/set/all/references.rb +2 -2
  23. data/mod/01_core/set/all/rules.rb +28 -35
  24. data/mod/01_core/set/all/subcards.rb +12 -12
  25. data/mod/01_core/set/all/tracked_attributes.rb +1 -1
  26. data/mod/01_core/set/all/type.rb +11 -11
  27. data/mod/01_core/set/all/utils.rb +6 -1
  28. data/mod/01_core/spec/set/all/fetch_spec.rb +6 -6
  29. data/mod/01_core/spec/set/all/permissions_spec.rb +11 -11
  30. data/mod/01_core/spec/set/all/tracked_attributes_spec.rb +1 -1
  31. data/mod/01_history/lib/card/action.rb +52 -47
  32. data/mod/01_history/set/all/actions.rb +20 -16
  33. data/mod/01_history/set/all/history.rb +18 -13
  34. data/mod/02_basic_types/set/all/base.rb +23 -2
  35. data/mod/02_basic_types/set/type/pointer.rb +45 -36
  36. data/mod/02_basic_types/spec/set/all/base_spec.rb +40 -24
  37. data/mod/02_basic_types/spec/set/type/pointer_spec.rb +87 -0
  38. data/mod/03_machines/set/right/machine_output.rb +10 -6
  39. data/mod/04_settings/set/abstract/permission.rb +10 -5
  40. data/mod/04_settings/set/type/setting.rb +4 -1
  41. data/mod/05_email/set/all/follow.rb +39 -44
  42. data/mod/05_email/set/all/notify.rb +4 -1
  43. data/mod/05_email/set/right/followers.rb +16 -14
  44. data/mod/05_email/set/self/follow_defaults.rb +22 -19
  45. data/mod/05_standard/lib/carrier_wave/cardmount.rb +1 -0
  46. data/mod/05_standard/set/abstract/attachment.rb +85 -58
  47. data/mod/05_standard/set/all/comment.rb +35 -19
  48. data/mod/05_standard/set/all/error.rb +124 -98
  49. data/mod/05_standard/set/all/list_changes.rb +27 -22
  50. data/mod/05_standard/set/all/rich_html/editing.rb +96 -70
  51. data/mod/05_standard/set/all/rich_html/form.rb +123 -81
  52. data/mod/05_standard/set/all/rich_html/modal.rb +15 -58
  53. data/mod/05_standard/set/right/account.rb +2 -2
  54. data/mod/05_standard/set/right/email.rb +3 -2
  55. data/mod/05_standard/set/rstar/rules.rb +3 -3
  56. data/mod/05_standard/set/self/search.rb +45 -22
  57. data/mod/05_standard/set/type/cardtype.rb +13 -11
  58. data/mod/05_standard/set/type/listed_by.rb +3 -2
  59. data/mod/05_standard/set/type/set.rb +17 -13
  60. data/mod/05_standard/set/type/signup.rb +1 -2
  61. data/mod/05_standard/set/type/user.rb +1 -1
  62. data/mod/05_standard/spec/set/all/account_spec.rb +1 -1
  63. data/mod/05_standard/spec/set/all/history_spec.rb +1 -1
  64. data/mod/05_standard/spec/set/type/email_template_spec.rb +140 -134
  65. data/mod/05_standard/spec/set/type/image_spec.rb +2 -1
  66. data/mod/05_standard/spec/set/type/signup_spec.rb +2 -2
  67. data/spec/models/card/trash_spec.rb +1 -1
  68. data/spec/spec_helper.rb +0 -1
  69. metadata +2 -2
@@ -121,22 +121,31 @@ def left_or_new args={}
121
121
  left(args) || Card.new(args.merge(name: cardname.left))
122
122
  end
123
123
 
124
+ def fields
125
+ field_names.map { |name| Card[name] }
126
+ end
127
+
128
+ def field_names parent_name=nil
129
+ child_names parent_name, :left
130
+ end
131
+
124
132
  def children
125
- children_names.map { |name| Card[name] }
133
+ child_names.map { |name| Card[name] }
126
134
  end
127
135
 
128
- def children_names parent_name=nil
136
+ def child_names parent_name=nil, side=nil
129
137
  # eg, A+B is a child of A and B
130
138
  parent_name ||= name
131
- field = parent_name.to_name.simple? ? :part : :left
132
- Card.search field => parent_name, return: :name
139
+ side ||= parent_name.to_name.simple? ? :part : :left
140
+ Card.search({ side => parent_name, return: :name },
141
+ "(#{side}) children of #{parent_name}")
133
142
  end
134
143
 
135
144
  def descendant_names parent_name=nil
136
145
  return [] if new_card?
137
146
  parent_name ||= name
138
147
  Auth.as_bot do
139
- deps = children_names parent_name
148
+ deps = child_names parent_name
140
149
  deps.inject(deps) do |array, childname|
141
150
  array + descendant_names(childname)
142
151
  end
@@ -223,8 +232,9 @@ end
223
232
  event :set_autoname, before: :validate_name, on: :create do
224
233
  if name.blank? && (autoname_card = rule_card(:autoname))
225
234
  self.name = autoname autoname_card.content
226
- # FIXME: should give placeholder on new, do next and save on create
227
- Auth.as_bot { autoname_card.refresh.update_attributes! content: name }
235
+ # FIXME: should give placeholder in approve phase
236
+ # and finalize/commit change in store phase
237
+ autoname_card.refresh.update_column :db_content, name
228
238
  end
229
239
  end
230
240
 
@@ -19,26 +19,28 @@ def reset_patterns_if_rule saving=false
19
19
  set.reset_patterns
20
20
  set.include_set_modules
21
21
 
22
- #this is really messy.
23
- if saving
24
- self.add_to_read_rule_update_queue( set.item_cards limit: 0 ) if right.id == Card::ReadID
22
+ # FIXME: should be in right/read.rb
23
+ if saving && right.id == Card::ReadID
24
+ self.add_to_read_rule_update_queue(set.item_cards limit: 0)
25
25
  end
26
26
  end
27
27
  end
28
28
 
29
29
  def safe_set_keys
30
- patterns.map( &:safe_key ).reverse * " "
30
+ patterns.map(&:safe_key).reverse * " "
31
31
  end
32
32
 
33
33
  def set_modules
34
- @set_modules ||= patterns_without_new[0..-2].reverse.map(&:module_list).flatten.compact
34
+ @set_modules ||=
35
+ patterns_without_new[0..-2].reverse.map(&:module_list).flatten.compact
35
36
  end
36
37
 
37
38
  def set_format_modules klass
38
39
  @set_format_modules ||= {}
39
- @set_format_modules[klass] = patterns_without_new[0..-2].reverse.map do |pattern|
40
- pattern.format_module_list klass
41
- end.flatten.compact
40
+ @set_format_modules[klass] =
41
+ patterns_without_new[0..-2].reverse.map do |pattern|
42
+ pattern.format_module_list klass
43
+ end.flatten.compact
42
44
  end
43
45
 
44
46
  def set_names
@@ -50,7 +52,6 @@ def set_names
50
52
  end
51
53
 
52
54
  def rule_set_keys
53
- set_names #this triggers set_members cache. need better solution!
54
- @rule_set_keys ||= patterns.map( &:rule_set_key ).compact
55
+ set_names # this triggers set_members cache. need better solution!
56
+ @rule_set_keys ||= patterns.map(&:rule_set_key).compact
55
57
  end
56
-
@@ -32,32 +32,39 @@ end
32
32
  def who_can action
33
33
  # warn "who_can[#{name}] #{(prc=permission_rule_card(action)).inspect},
34
34
  # #{prc.first.item_cards.map(&:id)}" if action == :update
35
- permission_rule_card(action).first.item_cards.map &:id
35
+ permission_rule_card(action).item_cards.map &:id
36
+ end
37
+
38
+ def permission_rule_id_and_class action
39
+ direct_rule_id = rule_card_id action
40
+ require_permission_rule! direct_rule_id, action
41
+ direct_rule = Card.fetch direct_rule_id, skip_modules: true
42
+ [applicable_permission_rule_id(direct_rule, action),
43
+ direct_rule.rule_class_name]
44
+ end
45
+
46
+ def applicable_permission_rule_id direct_rule, action
47
+ if junction? && direct_rule.db_content =~ /^\[?\[?_left\]?\]?$/
48
+ lcard = left_or_new(skip_virtual: true, skip_modules: true)
49
+ if action == :create && lcard.real? && !lcard.action == :create
50
+ action = :update
51
+ end
52
+ lcard.permission_rule_id_and_class(action).first
53
+ else
54
+ direct_rule.id
55
+ end
36
56
  end
37
57
 
38
58
  def permission_rule_card action
39
- opcard = rule_card action
59
+ Card.fetch permission_rule_id_and_class(action).first
60
+ end
40
61
 
62
+ def require_permission_rule! rule_id, action
63
+ return if rule_id
41
64
  # RULE missing. should not be possible.
42
65
  # generalize this to handling of all required rules
43
- unless opcard
44
- errors.add :permission_denied, "No #{action} rule for #{name}"
45
- raise Card::PermissionDenied.new(self)
46
- end
47
-
48
- rcard = Auth.as_bot do
49
- # compound cards can inherit permissions from left parent
50
- if ['_left', '[[_left]]'].member?(opcard.db_content) && self.junction?
51
- lcard = left_or_new(skip_virtual: true, skip_modules: true)
52
- if action == :create && lcard.real? && !lcard.action == :create
53
- action = :update
54
- end
55
- lcard.permission_rule_card(action).first
56
- else
57
- opcard
58
- end
59
- end
60
- return rcard, opcard.rule_class_name
66
+ errors.add :permission_denied, "No #{action} rule for #{name}"
67
+ raise Card::PermissionDenied.new(self)
61
68
  end
62
69
 
63
70
  def rule_class_name
@@ -114,7 +121,7 @@ end
114
121
 
115
122
  def ok_to_read
116
123
  return if Auth.always_ok?
117
- @read_rule_id ||= permission_rule_card(:read).first.id.to_i
124
+ @read_rule_id ||= permission_rule_id_and_class(:read).first
118
125
  return if Auth.as_card.read_rules.member? @read_rule_id
119
126
  deny_because you_cant 'read this'
120
127
  end
@@ -138,24 +145,26 @@ def ok_to_comment
138
145
  deny_because 'No comments allowed on structured content' if structure
139
146
  end
140
147
 
141
- event :set_read_rule, before: :store do
142
- if trash == true
143
- self.read_rule_id = self.read_rule_class = nil
144
- else
145
- # avoid doing this on simple content saves?
146
- rcard, rclass = permission_rule_card(:read)
147
- self.read_rule_id = rcard.id
148
- self.read_rule_class = rclass
149
- # find all cards with me as trunk and update their read_rule
150
- # (because of *type plus right)
151
- # skip if name is updated because will already be resaved
152
-
153
- if !new_card? && type_id_changed?
154
- Auth.as_bot do
155
- Card.search(left: self.name).each do |plus_card|
156
- plus_card = plus_card.refresh.update_read_rule
157
- end
158
- end
148
+ event :clear_read_rule, before: :store, on: :delete do
149
+ self.read_rule_id = self.read_rule_class = nil
150
+ end
151
+
152
+ event :set_read_rule, before: :store, on: :save do
153
+ # avoid doing this on simple content saves?
154
+ read_rule_id, read_rule_class = permission_rule_id_and_class(:read)
155
+ self.read_rule_id = read_rule_id
156
+ self.read_rule_class = read_rule_class
157
+ end
158
+
159
+ event :set_field_read_rules,
160
+ after: :set_read_rule, on: :update, changed: :type_id do
161
+ # find all cards with me as trunk and update their read_rule
162
+ # (because of *type plus right)
163
+ # skip if name is updated because will already be resaved
164
+
165
+ Auth.as_bot do
166
+ fields.each do |field|
167
+ field.refresh.update_read_rule
159
168
  end
160
169
  end
161
170
  end
@@ -176,9 +185,9 @@ def update_read_rule
176
185
  # currently doing a brute force search for every card that may be impacted.
177
186
  # may want to optimize(?)
178
187
  Auth.as_bot do
179
- Card.search(left: name).each do |plus_card|
180
- if plus_card.rule(:read) == '_left'
181
- plus_card.update_read_rule
188
+ fields.each do |field|
189
+ if field.rule(:read) == '_left'
190
+ field.update_read_rule
182
191
  end
183
192
  end
184
193
  end
@@ -143,7 +143,8 @@ def phase_ok? opts
143
143
  phase && (
144
144
  (opts[:during] && in?(opts[:during])) ||
145
145
  (opts[:before] && before?(opts[:before])) ||
146
- (opts[:after] && after?(opts[:after]))
146
+ (opts[:after] && after?(opts[:after])) ||
147
+ true # no phase restriction in opts
147
148
  )
148
149
  end
149
150
 
@@ -68,7 +68,7 @@ def update_references rendered_content = nil, refresh = false
68
68
  end
69
69
  Card::Reference.create!(
70
70
  referer_id: id,
71
- referee_id: Card.where(key: name.key).pluck(:id).first,
71
+ referee_id: Card.fetch_id(name),
72
72
  referee_key: name.key,
73
73
  ref_type: ref_type,
74
74
  present: 1
@@ -108,7 +108,7 @@ end
108
108
  protected
109
109
 
110
110
 
111
- event :refresh_references, after: :store, on: :save do
111
+ event :refresh_references, after: :store, on: :save, changed: :content do
112
112
  self.update_references
113
113
  expire_structuree_references
114
114
  end
@@ -48,7 +48,7 @@ def rule setting_code, options={}
48
48
  end
49
49
 
50
50
  def rule_card setting_code, options={}
51
- Card.fetch rule_card_id( setting_code, options ), options
51
+ Card.fetch rule_card_id(setting_code, options), options
52
52
  end
53
53
 
54
54
  def rule_card_id setting_code, options={}
@@ -71,21 +71,24 @@ def rule_card_id setting_code, options={}
71
71
  end
72
72
 
73
73
  def related_sets with_self = false
74
- # refers to sets that users may configure from the current card - NOT to sets to which the current card belongs
74
+ # refers to sets that users may configure from the current card -
75
+ # NOT to sets to which the current card belongs
75
76
 
76
- sets = []
77
- sets << ["#{name}+*type", Card::TypeSet.label( name) ] if known? && type_id==Card::CardtypeID
78
- sets << ["#{name}+*self", Card::SelfSet.label( name) ] if with_self
79
- sets << ["#{name}+*right", Card::RightSet.label(name) ] if known? && cardname.simple?
77
+ # FIXME: change to use codenames!!
80
78
 
81
- # Card.search(type: 'Set',left: {right: name},right: '*type plus right',return: 'name').each do |set_name|
82
- # sets<< set_name
83
- # end
79
+ sets = []
80
+ if known? && type_id == Card::CardtypeID # FIXME: belongs in type/cardtype
81
+ sets << ["#{name}+*type", Card::TypeSet.label(name)]
82
+ end
83
+ if with_self
84
+ sets << ["#{name}+*self", Card::SelfSet.label(name)]
85
+ end
86
+ if known? && cardname.simple?
87
+ sets << ["#{name}+*right", Card::RightSet.label(name)]
88
+ end
84
89
  sets
85
90
  end
86
91
 
87
-
88
-
89
92
  module ClassMethods
90
93
 
91
94
  # User-specific rule use the pattern
@@ -174,11 +177,12 @@ module ClassMethods
174
177
  end
175
178
 
176
179
  def all_user_ids_with_rule_for set_card, setting_code
177
- key = if (l=set_card.left) and (r=set_card.right)
178
- set_class_code = Codename[ r.id ]
180
+ key =
181
+ if (l = set_card.left) && (r = set_card.right)
182
+ set_class_code = Codename[r.id]
179
183
  "#{l.id}+#{set_class_code}+#{setting_code}"
180
184
  else
181
- set_class_code = Codename[ set_card.id ]
185
+ set_class_code = Codename[set_card.id]
182
186
  "#{set_class_code}+#{setting_code}"
183
187
  end
184
188
  user_ids = user_ids_cache[key] || []
@@ -187,11 +191,14 @@ module ClassMethods
187
191
  else
188
192
  user_ids
189
193
  end
190
-
191
194
  end
192
195
 
193
196
  def user_rule_cards user_name, setting_code
194
- Card.search right: {codename: setting_code}, left: {left: {type_id: SetID}, right: user_name}
197
+ Card.search(
198
+ { right: { codename: setting_code },
199
+ left: { left: { type_id: SetID }, right: user_name }
200
+ }, "rule cards for user: #{user_name}"
201
+ )
195
202
  end
196
203
 
197
204
  def rule_cache
@@ -282,15 +289,15 @@ module ClassMethods
282
289
  Card.cache.write 'RULE_KEYS', hash
283
290
  end
284
291
 
285
-
286
-
287
292
  def read_rule_cache
288
293
  Card.cache.read('READRULES') || begin
289
294
  hash = {}
290
- ActiveRecord::Base.connection.select_all( Card::Set::All::Rules::ReadRuleSQL ).each do |row|
291
- party_id, read_rule_id = row['party_id'].to_i, row['read_rule_id'].to_i
295
+ ActiveRecord::Base.connection.select_all(
296
+ Card::Set::All::Rules::ReadRuleSQL
297
+ ).each do |row|
298
+ party_id = row['party_id'].to_i
292
299
  hash[party_id] ||= []
293
- hash[party_id] << read_rule_id
300
+ hash[party_id] << row['read_rule_id'].to_i
294
301
  end
295
302
  Card.cache.write 'READRULES', hash
296
303
  end
@@ -299,18 +306,4 @@ module ClassMethods
299
306
  def clear_read_rule_cache
300
307
  Card.cache.write 'READRULES', nil
301
308
  end
302
- =begin
303
- def default_rule setting_code, fallback=nil
304
- card = default_rule_card setting_code, fallback
305
- return card && card.content
306
- end
307
-
308
- def default_rule_card setting_code, fallback=nil
309
- rule_id = rule_cache["all+#{setting_code}"]
310
- rule_id ||= fallback && rule_cache["all+#{fallback}"]
311
- Card[rule_id] if rule_id
312
- end
313
- =end
314
309
  end
315
-
316
-
@@ -36,7 +36,18 @@ def unfilled?
36
36
  !subcards.present?
37
37
  end
38
38
 
39
- event :reject_empty_subcards, after: :approve, on: :save do
39
+ event :approve_subcards, after: :approve, on: :save do
40
+ subcards.each do |subcard|
41
+ if !subcard.valid_subcard?
42
+ subcard.errors.each do |field, err|
43
+ err = "#{field} #{err}" unless [:content, :abort].member? field
44
+ errors.add subcard.relative_name.s, err
45
+ end
46
+ end
47
+ end
48
+ end
49
+
50
+ event :reject_empty_subcards, before: :approve_subcards do
40
51
  subcards.each_with_key do |subcard, key|
41
52
  if subcard.new? && subcard.unfilled?
42
53
  remove_subcard key
@@ -49,17 +60,6 @@ end
49
60
  event :process_subcards, after: :reject_empty_subcards, on: :save do
50
61
  end
51
62
 
52
- event :approve_subcards, after: :process_subcards do
53
- subcards.each do |subcard|
54
- if !subcard.valid_subcard?
55
- subcard.errors.each do |field, err|
56
- err = "#{field} #{err}" unless [:content, :abort].member? field
57
- errors.add subcard.relative_name.s, err
58
- end
59
- end
60
- end
61
- end
62
-
63
63
  event :store_subcards, after: :store do
64
64
  subcards.each do |subcard|
65
65
  subcard.save! validate: false if subcard != self # unless @draft
@@ -21,7 +21,7 @@ def assign_attributes args={}
21
21
  end
22
22
 
23
23
  def assign_set_specific_attributes
24
- return unless @set_specific && @set_specific.present?
24
+ return unless @set_specific.present?
25
25
  @set_specific.each_pair do |name, value|
26
26
  send "#{name}=", value
27
27
  end
@@ -7,7 +7,7 @@ end
7
7
 
8
8
  def type_card
9
9
  return if type_id.nil?
10
- Card.fetch type_id.to_i, skip_modules: true
10
+ Card.quick_fetch type_id.to_i
11
11
  end
12
12
 
13
13
  def type_code
@@ -18,6 +18,10 @@ def type_name
18
18
  type_card.try :name
19
19
  end
20
20
 
21
+ def type_name_or_default
22
+ type_card.try(:name) || Card.quick_fetch(Card.default_type_id).name
23
+ end
24
+
21
25
  def type_cardname
22
26
  type_card.try :cardname
23
27
  end
@@ -51,16 +55,12 @@ event :validate_type, before: :approve, changed: :type_id do
51
55
  end
52
56
 
53
57
  event :reset_type_specific_fields, after: :store do
58
+ wql = { left: { left_id: type_id },
59
+ right: { codename: 'type_plus_right' }
60
+ }
61
+ wql_comment = "sets with a type_plus_right rule for #{name}"
62
+
54
63
  Auth.as_bot do
55
- Card.search left: { left_id: type_id },
56
- right: { codename: 'type_plus_right' } do |set_card|
57
- set_card.reset_set_patterns
58
- end
64
+ Card.search(wql, wql_comment).each &:reset_set_patterns
59
65
  end
60
66
  end
61
-
62
- # Card.search left_plus: [ type_name, right_plus: {codename:
63
- # 'type_plus_right'}] do |right_anchor|
64
- # Card["#{lef}"]
65
- # set_card.reset_set_patterns
66
- # end