Skip to content

Commit eddc103

Browse files
authored
Merge pull request #1428 from adaptlearning/issue/1427
Make sure courseassets are cleaned up on object delete
2 parents e0f10db + 569c8d6 commit eddc103

1 file changed

Lines changed: 59 additions & 23 deletions

File tree

plugins/content/courseasset/index.js

Lines changed: 59 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -42,38 +42,81 @@ CourseAssetContent.prototype.getModelName = function () {
4242
function initialize() {
4343
// Content Hook for updatedAt and updatedBy:
4444
['course', 'contentobject', 'article', 'block', 'component'].forEach(function (contentType) {
45-
app.contentmanager.addContentHook('destroy', contentType, { when: 'pre' }, function (contentType, data, next) {
46-
45+
app.contentmanager.addContentHook('destroy', contentType, { when: 'pre' }, function (contentType, data, next) {
4746
database.getDatabase(function (err, db) {
4847
db.retrieve(contentType, data[0], function(err, items) {
4948
if (err) {
5049
logger.log('err', err);
5150
return next(err);
5251
}
53-
5452
if (items && items.length == 1) {
5553
var itemForDeletion = items[0].toObject();
5654
var criteria = {};
57-
55+
5856
async.series([
57+
function(callback){
58+
if (contentType !== 'contentobject') {
59+
return callback(null, 'Not processing a content object');
60+
}
61+
db.retrieve('article', { _courseId: itemForDeletion._courseId, _parentId: itemForDeletion._id }, function(err, articles) {
62+
if (err) {
63+
return callback(err, 'Unable to retrieve child articles of contentobject ' + itemForDeletion._id);
64+
}
65+
var parentIds = [];
66+
if (articles && articles.length !== 0) {
67+
criteria._courseId = itemForDeletion._courseId;
68+
parentIds = _.pluck(articles, '_id');
69+
// add the contentObject id as parent for assets on articles
70+
parentIds.push(itemForDeletion._id);
71+
}
72+
async.each(articles, function(article, cb) {
73+
db.retrieve('block', {_courseId: article._courseId, _parentId: article._id}, function(err, blocks) {
74+
if (err) {
75+
return callback(err, 'Unable to retrieve child blocks of article ' + article._id);
76+
}
77+
if (blocks && blocks.length !== 0) {
78+
parentIds = parentIds.concat(_.pluck(blocks, '_id'));
79+
}
80+
if(parentIds.length > 0) {
81+
criteria.$or = [
82+
{ _contentTypeParentId: { $in: parentIds } },
83+
{ _contentTypeId: itemForDeletion._id }
84+
];
85+
} else {
86+
criteria._contentTypeId = itemForDeletion._id;
87+
}
88+
cb();
89+
});
90+
}, function(error) {
91+
if (error) {
92+
callback(error);
93+
} else {
94+
callback(null, 'Child content objects added to criteria object');
95+
}
96+
});
97+
});
98+
},
5999
function(callback){
60100
if (contentType !== 'article') {
61101
return callback(null, 'Not processing an article');
62102
}
63-
64103
// When processing an article we need to retrieve the blocks in order to remove the associated assets.
65104
db.retrieve('block', {_courseId: itemForDeletion._courseId, _parentId: itemForDeletion._id}, function(err, blocks) {
66105
if (err) {
67106
return callback(err, 'Unable to retrieve child blocks of article ' + itemForDeletion._id);
68107
}
69-
70108
// Formulate the block search criteria.
71109
if (blocks && blocks.length !== 0) {
72-
// We have enough information to start removing course assets.
73-
criteria._contentTypeParentId = { $in: [_.pluck(blocks, '_id')] };
74110
criteria._courseId = itemForDeletion._courseId;
75-
}
76-
111+
// find any assets associated with the blocks as parent
112+
var parentArray = _.pluck(blocks, '_id');
113+
114+
parentArray.push(itemForDeletion._id);
115+
criteria.$or = [
116+
{ _contentTypeParentId: { $in: parentArray } },
117+
{ _contentTypeId: itemForDeletion._id }
118+
];
119+
}
77120
callback(null, 'Blocks added to criteria object');
78121
});
79122
},
@@ -84,23 +127,20 @@ function initialize() {
84127
case 'course':
85128
criteria._courseId = itemForDeletion._id;
86129
break;
87-
case 'contentobject':
130+
case 'block':
88131
criteria._courseId = itemForDeletion._courseId;
89-
criteria._contentType = itemForDeletion._type;
90-
criteria._contentTypeId = itemForDeletion._id;
91-
break;
92-
case 'block':
93-
criteria._courseId = itemForDeletion._courseId;
94-
criteria._contentTypeParentId = itemForDeletion._id;
95-
criteria._contentType = 'component';
132+
// Find assets directly associated with the block or with block as parent
133+
criteria.$or = [
134+
{ _contentTypeId: itemForDeletion._id },
135+
{ _contentTypeParentId: itemForDeletion._id }
136+
]
96137
break;
97138
case 'component':
98139
criteria._courseId = itemForDeletion._courseId;
99140
criteria._contentTypeId = itemForDeletion._id;
100141
criteria._contentType = 'component';
101142
break;
102143
}
103-
104144
callback(null, 'Search criteria successfully set up');
105145
}
106146
],
@@ -110,15 +150,13 @@ function initialize() {
110150
logger.log('error', err);
111151
return next(err);
112152
}
113-
114153
// Only remove the courseasset if there is enough critera to search on.
115154
if (Object.keys(criteria).length !== 0) {
116155
db.destroy('courseasset', criteria, function (err) {
117156
if (err) {
118157
logger.log('error', err);
119158
return next(err);
120159
}
121-
122160
next(null, data);
123161
});
124162
} else {
@@ -133,9 +171,7 @@ function initialize() {
133171
}
134172
});
135173
});
136-
137174
}.bind(null, contentType));
138-
139175
});
140176
}
141177

0 commit comments

Comments
 (0)