sakai-info 0.2.1 → 0.3.0
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.
- data/CHANGELOG.md +8 -0
- data/README.md +2 -18
- data/ROADMAP.md +24 -3
- data/bin/sakai-info +32 -9
- data/lib/sakai-info.rb +5 -2
- data/lib/sakai-info/cli.rb +15 -1
- data/lib/sakai-info/cli/help.rb +93 -5
- data/lib/sakai-info/database.rb +30 -3
- data/lib/sakai-info/mod_props.rb +73 -0
- data/lib/sakai-info/question_pool.rb +109 -0
- data/lib/sakai-info/quiz.rb +535 -0
- data/lib/sakai-info/sakai_object.rb +13 -6
- data/lib/sakai-info/site.rb +3 -3
- data/lib/sakai-info/user.rb +2 -6
- data/lib/sakai-info/version.rb +1 -1
- metadata +8 -6
- data/lib/sakai-info/samigo.rb +0 -196
@@ -0,0 +1,109 @@
|
|
1
|
+
# sakai-info/question_pool.rb
|
2
|
+
# SakaiInfo::QuestionPool library
|
3
|
+
#
|
4
|
+
# Created 2012-02-26 daveadams@gmail.com
|
5
|
+
# Last updated 2012-02-26 daveadams@gmail.com
|
6
|
+
#
|
7
|
+
# https://github.com/daveadams/sakai-info
|
8
|
+
#
|
9
|
+
# This software is public domain.
|
10
|
+
#
|
11
|
+
|
12
|
+
module SakaiInfo
|
13
|
+
class QuestionPool < SakaiObject
|
14
|
+
attr_reader :title, :owner, :description, :parent_pool_id, :dbrow
|
15
|
+
|
16
|
+
include ModProps
|
17
|
+
created_at_key :datecreated
|
18
|
+
created_by_key :ownerid
|
19
|
+
modified_at_key :lastmodifieddate
|
20
|
+
modified_by_key :lastmodifiedby
|
21
|
+
|
22
|
+
def initialize(dbrow)
|
23
|
+
@dbrow = dbrow
|
24
|
+
|
25
|
+
@id = dbrow[:questionpoolid]
|
26
|
+
@title = dbrow[:title]
|
27
|
+
@description = dbrow[:description]
|
28
|
+
@owner = User.find(dbrow[:ownerid])
|
29
|
+
@parent_pool_id = dbrow[:parentpoolid]
|
30
|
+
@parent_pool_id = nil if @parent_pool_id == 0
|
31
|
+
end
|
32
|
+
|
33
|
+
@@cache = {}
|
34
|
+
def self.find(id)
|
35
|
+
if @@cache[id].nil?
|
36
|
+
row = DB.connect[:sam_questionpool_t].filter(:questionpoolid => id).first
|
37
|
+
if row.nil?
|
38
|
+
raise ObjectNotFoundException.new(QuestionPool, id)
|
39
|
+
end
|
40
|
+
@@cache[id] = QuestionPool.new(row)
|
41
|
+
end
|
42
|
+
@@cache[id]
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.find_by_user_id(user_id)
|
46
|
+
results = []
|
47
|
+
DB.connect[:sam_questionpool_t].filter(:ownerid => user_id).all.each do |row|
|
48
|
+
id = row[:questionpoolid]
|
49
|
+
@@cache[id] = QuestionPool.new(row)
|
50
|
+
results << @@cache[id]
|
51
|
+
end
|
52
|
+
results
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.count_by_user_id(user_id)
|
56
|
+
DB.connect[:sam_questionpool_t].filter(:ownerid => user_id).count
|
57
|
+
end
|
58
|
+
|
59
|
+
def item_count
|
60
|
+
@item_count ||=
|
61
|
+
DB.connect[:sam_questionpoolitem_t].filter(:questionpoolid => @id).count
|
62
|
+
end
|
63
|
+
|
64
|
+
def parent
|
65
|
+
if not @parent_pool_id.nil?
|
66
|
+
@parent ||= QuestionPool.find(@parent_pool_id)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
# serialization
|
71
|
+
def default_serialization
|
72
|
+
result = {
|
73
|
+
"id" => self.id,
|
74
|
+
"title" => self.title,
|
75
|
+
"owner" => self.owner.serialize(:summary),
|
76
|
+
"parent" => nil,
|
77
|
+
"item_count" => self.item_count
|
78
|
+
}
|
79
|
+
if not self.parent.nil?
|
80
|
+
result["parent"] = self.parent.serialize(:summary)
|
81
|
+
else
|
82
|
+
result.delete("parent")
|
83
|
+
end
|
84
|
+
result
|
85
|
+
end
|
86
|
+
|
87
|
+
def summary_serialization
|
88
|
+
result = {
|
89
|
+
"id" => self.id,
|
90
|
+
"title" => self.title,
|
91
|
+
"owner_eid" => self.owner.eid,
|
92
|
+
"parent_pool_id" => self.parent_pool_id,
|
93
|
+
"item_count" => self.item_count
|
94
|
+
}
|
95
|
+
if result["parent_pool_id"].nil?
|
96
|
+
result.delete("parent_pool_id")
|
97
|
+
end
|
98
|
+
result
|
99
|
+
end
|
100
|
+
|
101
|
+
def user_summary_serialization
|
102
|
+
{
|
103
|
+
"id" => self.id,
|
104
|
+
"title" => self.title,
|
105
|
+
"item_count" => self.item_count
|
106
|
+
}
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
@@ -0,0 +1,535 @@
|
|
1
|
+
# sakai-info/quiz.rb
|
2
|
+
# SakaiInfo::Quiz library
|
3
|
+
#
|
4
|
+
# Created 2012-02-17 daveadams@gmail.com
|
5
|
+
# Last updated 2012-02-26 daveadams@gmail.com
|
6
|
+
#
|
7
|
+
# https://github.com/daveadams/sakai-info
|
8
|
+
#
|
9
|
+
# This software is public domain.
|
10
|
+
#
|
11
|
+
|
12
|
+
module SakaiInfo
|
13
|
+
class Quiz < SakaiObject
|
14
|
+
attr_reader :title, :site, :dbrow
|
15
|
+
|
16
|
+
include ModProps
|
17
|
+
created_by_key :createdby
|
18
|
+
created_at_key :createddate
|
19
|
+
modified_by_key :lastmodifiedby
|
20
|
+
modified_at_key :lastmodifieddate
|
21
|
+
|
22
|
+
# a note about quizzes:
|
23
|
+
# they do not link directly back to sites
|
24
|
+
# instead, they link back only via the sam_authzdata_t table
|
25
|
+
def initialize(dbrow, site = nil)
|
26
|
+
@site = nil
|
27
|
+
if site.is_a? String
|
28
|
+
begin
|
29
|
+
@site = Site.find(site)
|
30
|
+
rescue ObjectNotFoundException
|
31
|
+
@site = nil
|
32
|
+
end
|
33
|
+
elsif site.is_a? Site
|
34
|
+
@site = site
|
35
|
+
end
|
36
|
+
|
37
|
+
@id = dbrow[:id]
|
38
|
+
@title = dbrow[:title]
|
39
|
+
@dbrow = dbrow
|
40
|
+
|
41
|
+
if @site.nil?
|
42
|
+
# published quizzes map to site_id via the OWN_PUBLISHED_ASSESSMENT function
|
43
|
+
# pending quizzes map to site_id via the EDIT_ASSESSMENT function
|
44
|
+
DB.connect[:sam_authzdata_t].select(:distinct.sql_function(:agentid)).
|
45
|
+
where(:qualifierid => @id).
|
46
|
+
where(:functionid => ["OWN_PUBLISHED_ASSESSMENT","EDIT_ASSESSMENT"]).
|
47
|
+
all.each do |row|
|
48
|
+
begin
|
49
|
+
site = Site.find(row[:agentid])
|
50
|
+
@site = site
|
51
|
+
rescue ObjectNotFoundException
|
52
|
+
@site = nil
|
53
|
+
end
|
54
|
+
break if not @site.nil?
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
@@cache = {}
|
60
|
+
def self.find(id)
|
61
|
+
id = id.to_s
|
62
|
+
if @@cache[id].nil?
|
63
|
+
quiz = nil
|
64
|
+
begin
|
65
|
+
quiz = PendingQuiz.find(id)
|
66
|
+
rescue ObjectNotFoundException
|
67
|
+
begin
|
68
|
+
quiz = PublishedQuiz.find(id)
|
69
|
+
rescue ObjectNotFoundException
|
70
|
+
raise ObjectNotFoundException.new(Quiz, id)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
@@cache[id] = quiz
|
74
|
+
end
|
75
|
+
@@cache[id]
|
76
|
+
end
|
77
|
+
|
78
|
+
def self.find_by_site_id(site_id)
|
79
|
+
{
|
80
|
+
"pending" => PendingQuiz.find_by_site_id(site_id),
|
81
|
+
"published" => PublishedQuiz.find_by_site_id(site_id)
|
82
|
+
}
|
83
|
+
end
|
84
|
+
|
85
|
+
def self.count_by_site_id(site_id)
|
86
|
+
{
|
87
|
+
"pending_count" => PendingQuiz.count_by_site_id(site_id),
|
88
|
+
"published_count" => PublishedQuiz.count_by_site_id(site_id)
|
89
|
+
}
|
90
|
+
end
|
91
|
+
|
92
|
+
def quiz_type
|
93
|
+
nil
|
94
|
+
end
|
95
|
+
|
96
|
+
def section_count
|
97
|
+
@section_count ||= QuizSection.count_by_quiz_id(@id)
|
98
|
+
end
|
99
|
+
|
100
|
+
def sections
|
101
|
+
@sections ||= QuizSection.find_by_quiz_id(@id)
|
102
|
+
end
|
103
|
+
|
104
|
+
def default_serialization
|
105
|
+
result = {
|
106
|
+
"id" => self.id,
|
107
|
+
"title" => self.title,
|
108
|
+
"site" => nil,
|
109
|
+
"type" => self.quiz_type,
|
110
|
+
"section_count" => self.section_count
|
111
|
+
}
|
112
|
+
if not self.site.nil?
|
113
|
+
result["site"] = self.site.serialize(:summary)
|
114
|
+
end
|
115
|
+
result
|
116
|
+
end
|
117
|
+
|
118
|
+
def summary_serialization
|
119
|
+
result = {
|
120
|
+
"id" => self.id,
|
121
|
+
"title" => self.title,
|
122
|
+
"site_id" => nil,
|
123
|
+
"type" => self.quiz_type
|
124
|
+
}
|
125
|
+
if not self.site.nil?
|
126
|
+
result["site_id"] = self.site.id
|
127
|
+
end
|
128
|
+
result
|
129
|
+
end
|
130
|
+
|
131
|
+
def site_summary_serialization
|
132
|
+
{
|
133
|
+
"id" => self.id,
|
134
|
+
"title" => self.title
|
135
|
+
}
|
136
|
+
end
|
137
|
+
|
138
|
+
def sections_serialization
|
139
|
+
{
|
140
|
+
"sections" => self.sections.collect{|s|s.serialize(:quiz_summary)}
|
141
|
+
}
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
class PendingQuiz < Quiz
|
146
|
+
@@cache = {}
|
147
|
+
def self.find(id)
|
148
|
+
id = id.to_s
|
149
|
+
if @@cache[id].nil?
|
150
|
+
row = DB.connect[:sam_assessmentbase_t].filter(:id => id.to_i).first
|
151
|
+
if row.nil?
|
152
|
+
raise ObjectNotFoundException.new(PendingQuiz, id)
|
153
|
+
end
|
154
|
+
@@cache[id] = PendingQuiz.new(row)
|
155
|
+
end
|
156
|
+
@@cache[id]
|
157
|
+
end
|
158
|
+
|
159
|
+
def self.query_by_site_id(site_id)
|
160
|
+
db = DB.connect
|
161
|
+
db[:sam_assessmentbase_t].
|
162
|
+
where(:id =>
|
163
|
+
db[:sam_authzdata_t].select(:qualifierid).
|
164
|
+
where(:agentid => site_id,
|
165
|
+
:functionid => "EDIT_ASSESSMENT"))
|
166
|
+
end
|
167
|
+
|
168
|
+
def self.find_by_site_id(site_id)
|
169
|
+
results = []
|
170
|
+
PendingQuiz.query_by_site_id(site_id).all.each do |row|
|
171
|
+
@@cache[row[:id]] = PendingQuiz.new(row, site_id)
|
172
|
+
results << @@cache[row[:id]]
|
173
|
+
end
|
174
|
+
results
|
175
|
+
end
|
176
|
+
|
177
|
+
def self.count_by_site_id(site_id)
|
178
|
+
PendingQuiz.query_by_site_id(site_id).count
|
179
|
+
end
|
180
|
+
|
181
|
+
def quiz_type
|
182
|
+
"pending"
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
class PublishedQuiz < Quiz
|
187
|
+
@@cache = {}
|
188
|
+
def self.find(id)
|
189
|
+
id = id.to_s
|
190
|
+
if @@cache[id].nil?
|
191
|
+
row = DB.connect[:sam_publishedassessment_t].filter(:id => id.to_i).first
|
192
|
+
if row.nil?
|
193
|
+
raise ObjectNotFoundException.new(PublishedQuiz, id)
|
194
|
+
end
|
195
|
+
|
196
|
+
@@cache[id] = PublishedQuiz.new(row)
|
197
|
+
end
|
198
|
+
@@cache[id]
|
199
|
+
end
|
200
|
+
|
201
|
+
def self.query_by_site_id(site_id)
|
202
|
+
db = DB.connect
|
203
|
+
db[:sam_publishedassessment_t].
|
204
|
+
where(:id =>
|
205
|
+
db[:sam_authzdata_t].select(:qualifierid).
|
206
|
+
where(:agentid => site_id,
|
207
|
+
:functionid => "OWN_PUBLISHED_ASSESSMENT"))
|
208
|
+
end
|
209
|
+
|
210
|
+
def self.find_by_site_id(site_id)
|
211
|
+
results = []
|
212
|
+
PublishedQuiz.query_by_site_id(site_id).all.each do |row|
|
213
|
+
@@cache[row[:id]] = PublishedQuiz.new(row, site_id)
|
214
|
+
results << @@cache[row[:id]]
|
215
|
+
end
|
216
|
+
results
|
217
|
+
end
|
218
|
+
|
219
|
+
def self.count_by_site_id(site_id)
|
220
|
+
PublishedQuiz.query_by_site_id(site_id).count
|
221
|
+
end
|
222
|
+
|
223
|
+
def quiz_type
|
224
|
+
"published"
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
228
|
+
class QuizSection < SakaiObject
|
229
|
+
attr_reader :dbrow, :quiz, :sequence, :title, :description, :typeid, :status
|
230
|
+
|
231
|
+
include ModProps
|
232
|
+
created_by_key :createdby
|
233
|
+
created_at_key :createddate
|
234
|
+
modified_by_key :lastmodifiedby
|
235
|
+
modified_at_key :lastmodifieddate
|
236
|
+
|
237
|
+
def initialize(dbrow)
|
238
|
+
@dbrow = dbrow
|
239
|
+
|
240
|
+
@id = dbrow[:sectionid]
|
241
|
+
@quiz = Quiz.find(dbrow[:assessmentid])
|
242
|
+
@sequence = dbrow[:sequence]
|
243
|
+
@title = dbrow[:title]
|
244
|
+
@description = dbrow[:description]
|
245
|
+
@typeid = dbrow[:typeid]
|
246
|
+
@status = dbrow[:status]
|
247
|
+
end
|
248
|
+
|
249
|
+
@@cache = {}
|
250
|
+
def self.find(id)
|
251
|
+
id = id.to_s
|
252
|
+
if @@cache[id].nil?
|
253
|
+
begin
|
254
|
+
@@cache[id] = PendingQuizSection.find(id)
|
255
|
+
rescue ObjectNotFoundException
|
256
|
+
begin
|
257
|
+
@@cache[id] = PublishedQuizSection.find(id)
|
258
|
+
rescue ObjectNotFoundException
|
259
|
+
raise ObjectNotFoundException(QuizSection, id)
|
260
|
+
end
|
261
|
+
end
|
262
|
+
end
|
263
|
+
@@cache[id]
|
264
|
+
end
|
265
|
+
|
266
|
+
def self.query_by_quiz_id(quiz_id)
|
267
|
+
table = if Quiz.find(quiz_id).quiz_type == "pending"
|
268
|
+
:sam_section_t
|
269
|
+
else
|
270
|
+
:sam_publishedsection_t
|
271
|
+
end
|
272
|
+
DB.connect[table].where(:assessmentid => quiz_id).order(:sequence)
|
273
|
+
end
|
274
|
+
|
275
|
+
def self.find_by_quiz_id(quiz_id)
|
276
|
+
section_class = if Quiz.find(quiz_id).quiz_type == "pending"
|
277
|
+
PendingQuizSection
|
278
|
+
else
|
279
|
+
PublishedQuizSection
|
280
|
+
end
|
281
|
+
|
282
|
+
QuizSection.query_by_quiz_id(quiz_id).all.collect do |row|
|
283
|
+
section_class.new(row)
|
284
|
+
end
|
285
|
+
end
|
286
|
+
|
287
|
+
def self.count_by_quiz_id(quiz_id)
|
288
|
+
QuizSection.query_by_quiz_id(quiz_id).count
|
289
|
+
end
|
290
|
+
|
291
|
+
def section_type
|
292
|
+
nil
|
293
|
+
end
|
294
|
+
|
295
|
+
def item_count
|
296
|
+
@item_count ||= QuizItem.count_by_section_id(@id)
|
297
|
+
end
|
298
|
+
|
299
|
+
def items
|
300
|
+
@items ||= QuizItem.find_by_section_id(@id)
|
301
|
+
end
|
302
|
+
|
303
|
+
def default_serialization
|
304
|
+
{
|
305
|
+
"id" => self.id,
|
306
|
+
"title" => self.title,
|
307
|
+
"quiz" => self.quiz.serialize(:summary),
|
308
|
+
"sequence" => self.sequence,
|
309
|
+
"item_count" => self.item_count,
|
310
|
+
"description" => self.description,
|
311
|
+
"type" => self.section_type,
|
312
|
+
"typeid" => self.typeid,
|
313
|
+
"status" => self.status
|
314
|
+
}
|
315
|
+
end
|
316
|
+
|
317
|
+
def summary_serialization
|
318
|
+
{
|
319
|
+
"id" => self.id,
|
320
|
+
"title" => self.title,
|
321
|
+
"quiz_id" => self.quiz.id,
|
322
|
+
"sequence" => self.sequence
|
323
|
+
}
|
324
|
+
end
|
325
|
+
|
326
|
+
def quiz_summary_serialization
|
327
|
+
result = summary_serialization
|
328
|
+
result.delete("quiz_id")
|
329
|
+
result
|
330
|
+
end
|
331
|
+
|
332
|
+
def items_serialization
|
333
|
+
{
|
334
|
+
"items" => self.items.collect{|i|i.serialize(:summary)}
|
335
|
+
}
|
336
|
+
end
|
337
|
+
|
338
|
+
def self.all_serializations
|
339
|
+
[:default, :items, :mod]
|
340
|
+
end
|
341
|
+
end
|
342
|
+
|
343
|
+
class PendingQuizSection < QuizSection
|
344
|
+
@@cache = {}
|
345
|
+
def self.find(id)
|
346
|
+
id = id.to_s
|
347
|
+
if @@cache[id].nil?
|
348
|
+
row = DB.connect[:sam_section_t].where(:sectionid => id).first
|
349
|
+
if row.nil?
|
350
|
+
raise ObjectNotFoundException(PendingQuizSection, id)
|
351
|
+
end
|
352
|
+
|
353
|
+
@@cache[id] = PendingQuizSection.new(row)
|
354
|
+
end
|
355
|
+
@@cache[id]
|
356
|
+
end
|
357
|
+
|
358
|
+
def section_type
|
359
|
+
"pending"
|
360
|
+
end
|
361
|
+
end
|
362
|
+
|
363
|
+
class PublishedQuizSection < QuizSection
|
364
|
+
@@cache = {}
|
365
|
+
def self.find(id)
|
366
|
+
id = id.to_s
|
367
|
+
if @@cache[id].nil?
|
368
|
+
row = DB.connect[:sam_publishedsection_t].where(:sectionid => id).first
|
369
|
+
if row.nil?
|
370
|
+
raise ObjectNotFoundException(PublishedQuizSection, id)
|
371
|
+
end
|
372
|
+
|
373
|
+
@@cache[id] = PublishedQuizSection.new(row)
|
374
|
+
end
|
375
|
+
@@cache[id]
|
376
|
+
end
|
377
|
+
|
378
|
+
def section_type
|
379
|
+
"published"
|
380
|
+
end
|
381
|
+
end
|
382
|
+
|
383
|
+
class QuizItem < SakaiObject
|
384
|
+
attr_reader :dbrow, :section, :quiz, :sequence, :typeid
|
385
|
+
|
386
|
+
include ModProps
|
387
|
+
created_by_key :createdby
|
388
|
+
created_at_key :createddate
|
389
|
+
modified_by_key :lastmodifiedby
|
390
|
+
modified_at_key :lastmodifieddate
|
391
|
+
|
392
|
+
def initialize(dbrow)
|
393
|
+
@dbrow = dbrow
|
394
|
+
|
395
|
+
@id = dbrow[:itemid]
|
396
|
+
@section = QuizSection.find(dbrow[:sectionid])
|
397
|
+
@quiz = @section.quiz
|
398
|
+
@sequence = dbrow[:sequence]
|
399
|
+
@typeid = dbrow[:typeid]
|
400
|
+
end
|
401
|
+
|
402
|
+
@@cache = {}
|
403
|
+
def self.find(id)
|
404
|
+
id = id.to_s
|
405
|
+
if @@cache[id].nil?
|
406
|
+
begin
|
407
|
+
@@cache[id] = PendingQuizItem.find(id)
|
408
|
+
rescue ObjectNotFoundException
|
409
|
+
begin
|
410
|
+
@@cache[id] = PublishedQuizItem.find(id)
|
411
|
+
rescue ObjectNotFoundException
|
412
|
+
raise ObjectNotFoundException(QuizItem, id)
|
413
|
+
end
|
414
|
+
end
|
415
|
+
end
|
416
|
+
@@cache[id]
|
417
|
+
end
|
418
|
+
|
419
|
+
def self.table_name_for_type(type)
|
420
|
+
if type == "pending"
|
421
|
+
:sam_item_t
|
422
|
+
else
|
423
|
+
:sam_publisheditem_t
|
424
|
+
end
|
425
|
+
end
|
426
|
+
|
427
|
+
def self.class_for_type(type)
|
428
|
+
if type == "pending"
|
429
|
+
PendingQuizItem
|
430
|
+
else
|
431
|
+
PublishedQuizItem
|
432
|
+
end
|
433
|
+
end
|
434
|
+
|
435
|
+
def self.query_by_section_id(section_id)
|
436
|
+
table = QuizItem.table_name_for_type(QuizSection.find(section_id).section_type)
|
437
|
+
DB.connect[table].where(:sectionid => section_id).order(:sequence)
|
438
|
+
end
|
439
|
+
|
440
|
+
def self.count_by_section_id(section_id)
|
441
|
+
QuizItem.query_by_section_id(section_id).count
|
442
|
+
end
|
443
|
+
|
444
|
+
def self.find_by_section_id(section_id)
|
445
|
+
item_class = QuizItem.class_for_type(QuizSection.find(section_id).section_type)
|
446
|
+
QuizItem.query_by_section_id(section_id).all.collect do |row|
|
447
|
+
item_class.new(row)
|
448
|
+
end
|
449
|
+
end
|
450
|
+
|
451
|
+
def self.query_by_quiz_id(quiz_id)
|
452
|
+
table = QuizItem.table_name_for_type(Quiz.find(quiz_id).quiz_type)
|
453
|
+
DB.connect[table].
|
454
|
+
where(:sectionid => Quiz.find(quiz_id).sections.collect{|s|s.id})
|
455
|
+
end
|
456
|
+
|
457
|
+
def self.count_by_quiz_id(quiz_id)
|
458
|
+
QuizItem.query_by_quiz_id(quiz_id).count
|
459
|
+
end
|
460
|
+
|
461
|
+
def self.find_by_quiz_id(quiz_id)
|
462
|
+
item_class = QuizItem.class_for_type(Quiz.find(quiz_id).quiz_type)
|
463
|
+
QuizItem.query_by_quiz_id(quiz_id).all.collect do |row|
|
464
|
+
item_class.new(row)
|
465
|
+
end
|
466
|
+
end
|
467
|
+
|
468
|
+
def item_type
|
469
|
+
nil
|
470
|
+
end
|
471
|
+
|
472
|
+
def default_serialization
|
473
|
+
{
|
474
|
+
"id" => self.id,
|
475
|
+
"quiz" => self.quiz.serialize(:summary),
|
476
|
+
"section" => self.section.serialize(:summary),
|
477
|
+
"sequence" => self.sequence,
|
478
|
+
"type" => self.item_type,
|
479
|
+
"typeid" => self.typeid
|
480
|
+
}
|
481
|
+
end
|
482
|
+
|
483
|
+
def summary_serialization
|
484
|
+
{
|
485
|
+
"id" => self.id,
|
486
|
+
"quiz_id" => self.quiz.id,
|
487
|
+
"section_id" => self.section.id
|
488
|
+
}
|
489
|
+
end
|
490
|
+
|
491
|
+
def self.all_serializations
|
492
|
+
[:default, :mod]
|
493
|
+
end
|
494
|
+
end
|
495
|
+
|
496
|
+
class PendingQuizItem < QuizItem
|
497
|
+
@@cache = {}
|
498
|
+
def self.find(id)
|
499
|
+
id = id.to_s
|
500
|
+
if @@cache[id].nil?
|
501
|
+
row = DB.connect[:sam_item_t].where(:itemid => id).first
|
502
|
+
if row.nil?
|
503
|
+
raise ObjectNotFoundException(PendingQuizItem, id)
|
504
|
+
end
|
505
|
+
|
506
|
+
@@cache[id] = PendingQuizItem.new(row)
|
507
|
+
end
|
508
|
+
@@cache[id]
|
509
|
+
end
|
510
|
+
|
511
|
+
def item_type
|
512
|
+
"pending"
|
513
|
+
end
|
514
|
+
end
|
515
|
+
|
516
|
+
class PublishedQuizItem < QuizItem
|
517
|
+
@@cache = {}
|
518
|
+
def self.find(id)
|
519
|
+
id = id.to_s
|
520
|
+
if @@cache[id].nil?
|
521
|
+
row = DB.connect[:sam_publisheditem_t].where(:itemid => id).first
|
522
|
+
if row.nil?
|
523
|
+
raise ObjectNotFoundException(PublishedQuizItem, id)
|
524
|
+
end
|
525
|
+
|
526
|
+
@@cache[id] = PublishedQuizItem.new(row)
|
527
|
+
end
|
528
|
+
@@cache[id]
|
529
|
+
end
|
530
|
+
|
531
|
+
def item_type
|
532
|
+
"published"
|
533
|
+
end
|
534
|
+
end
|
535
|
+
end
|