Skip to content

Commit 028fa0f

Browse files
committed
Issue #66: Concatenate texts in same activity
1 parent 67fc491 commit 028fa0f

File tree

2 files changed

+126
-52
lines changed

2 files changed

+126
-52
lines changed

classes/search/cmsfield.php

+59-33
Original file line numberDiff line numberDiff line change
@@ -57,16 +57,25 @@ public function get_document_recordset($modifiedfrom = 0, \context $context = nu
5757
}
5858

5959
// Search area is from customfield_data, but if the record is missing from activity, use default value.
60-
$sql = "SELECT mc.id, mc.course AS courseid, mc.typeid, mcf.name AS fieldname, mcf.type,
61-
mcd.id dataid, mcd.value AS value, mcd.valueformat AS valueformat,
62-
mcd.timecreated AS timecreated, mcd.timemodified AS timemodified
63-
FROM {cms} mc
64-
JOIN {customfield_data} mcd ON mc.id = mcd.instanceid
65-
JOIN {customfield_field} mcf ON mcf.id = mcd.fieldid
66-
JOIN {customfield_category} mcc ON mcf.categoryid = mcc.id
67-
$contextjoin
68-
WHERE mcd.timemodified >= ? AND mcc.component = 'mod_cms' AND mcc.area = 'cmsfield'
69-
AND mcf.type IN ('textarea', 'text')
60+
$sqlgroupconcat = $DB->sql_group_concat("mcd.value", ', ', 'mcf.sortorder');
61+
$sql = "SELECT ccms.id, ccms.course AS courseid, ccms.typeid, cmcf.name AS fieldname, cmcf.type,
62+
cdata.dataid dataid, cdata.value AS value, cdata.valueformat AS valueformat,
63+
cdata.timecreated AS timecreated, cdata.timemodified AS timemodified
64+
FROM {cms} ccms
65+
JOIN (
66+
SELECT mc.id, MAX(mcf.id) AS fieldid,
67+
MAX(mcd.id) dataid, {$sqlgroupconcat} AS value, MAX(mcd.valueformat) AS valueformat,
68+
MAX(mcd.timecreated) AS timecreated, MAX(mcd.timemodified) AS timemodified
69+
FROM {cms} mc
70+
JOIN {customfield_data} mcd ON mc.id = mcd.instanceid
71+
JOIN {customfield_field} mcf ON mcf.id = mcd.fieldid
72+
JOIN {customfield_category} mcc ON mcf.categoryid = mcc.id
73+
$contextjoin
74+
WHERE mcd.timemodified >= ? AND mcc.component = 'mod_cms' AND mcc.area = 'cmsfield'
75+
AND mcf.type IN ('textarea', 'text')
76+
GROUP BY mc.id
77+
) cdata ON ccms.id = cdata.id
78+
JOIN {customfield_field} cmcf ON cmcf.id = cdata.fieldid
7079
UNION
7180
SELECT mc.id, mc.course AS courseid, mc.typeid, null AS fieldname, null AS type,
7281
null AS dataid, null AS value, null AS valueformat,
@@ -101,32 +110,14 @@ public function get_document($record, $options = []) {
101110
return false;
102111
}
103112

104-
// Get default value for cms custom field.
105-
if (is_null($this->defaultvalues)) {
106-
$defaultvalues = [];
107-
$sql = "SELECT mct.id typeid, mcf.configdata, mcf.name fieldname
108-
FROM {cms_types} mct
109-
JOIN {customfield_category} mcc ON mcc.itemid = mct.id
110-
JOIN {customfield_field} mcf ON mcf.categoryid = mcc.id
111-
WHERE mcc.component = 'mod_cms' AND mcc.area = 'cmsfield' AND mcf.type IN ('textarea', 'text')";
112-
$cmstypes = $DB->get_records_sql($sql);
113-
foreach ($cmstypes as $cmstype) {
114-
$data = new \stdClass();
115-
$configdata = json_decode($cmstype->configdata);
116-
$data->value = $configdata->defaultvalue ?? 'Default value';
117-
$data->valueformat = $configdata->defaultvalueformat ?? 0;
118-
$data->fieldname = $cmstype->fieldname;
119-
$defaultvalues[$cmstype->typeid] = $data;
120-
}
121-
$this->defaultvalues = $defaultvalues;
122-
}
113+
$defaultvalues = $this->get_default_values();
123114

124115
// Check if it's default value or not.
125116
if (empty($record->dataid)) {
126-
$title = $this->defaultvalues[$record->typeid]->fieldname ?? '';
127-
$value = $this->defaultvalues[$record->typeid]->value ?? '';
128-
if (isset($this->defaultvalues[$record->typeid]->valueformat)) {
129-
$valueformat = $this->defaultvalues[$record->typeid]->valueformat;
117+
$title = $defaultvalues[$record->typeid]->fieldname ?? '';
118+
$value = $defaultvalues[$record->typeid]->value ?? '';
119+
if (isset($defaultvalues[$record->typeid]->valueformat)) {
120+
$valueformat = $defaultvalues[$record->typeid]->valueformat;
130121
} else {
131122
if ($record->type == 'textarea') {
132123
$valueformat = FORMAT_HTML;
@@ -158,6 +149,41 @@ public function get_document($record, $options = []) {
158149
return $doc;
159150
}
160151

152+
/**
153+
* Get default value for cms custom field.
154+
*
155+
* @return array
156+
*/
157+
protected function get_default_values() {
158+
global $DB;
159+
if (is_null($this->defaultvalues)) {
160+
$defaultvalues = [];
161+
$sql = "SELECT mcf.id fieldid, mct.id typeid, mcf.configdata, mcf.name fieldname
162+
FROM {cms_types} mct
163+
JOIN {customfield_category} mcc ON mcc.itemid = mct.id
164+
JOIN {customfield_field} mcf ON mcf.categoryid = mcc.id
165+
WHERE mcc.component = 'mod_cms' AND mcc.area = 'cmsfield' AND mcf.type IN ('textarea', 'text')
166+
ORDER BY mct.id, mcf.sortorder";
167+
$cmstypes = $DB->get_records_sql($sql);
168+
foreach ($cmstypes as $cmstype) {
169+
if (empty($defaultvalues[$cmstype->typeid])) {
170+
$data = new \stdClass();
171+
$configdata = json_decode($cmstype->configdata);
172+
$data->value = $configdata->defaultvalue ?? 'Default value';
173+
$data->valueformat = $configdata->defaultvalueformat ?? 0;
174+
$data->fieldname = $cmstype->fieldname;
175+
} else {
176+
$data = $defaultvalues[$cmstype->typeid];
177+
$configdata = json_decode($cmstype->configdata);
178+
$data->value .= ', ' . $configdata->defaultvalue;
179+
}
180+
$defaultvalues[$cmstype->typeid] = $data;
181+
}
182+
$this->defaultvalues = $defaultvalues;
183+
}
184+
return $this->defaultvalues;
185+
}
186+
161187
/**
162188
* Whether the user can access the document or not.
163189
*

tests/search/search_test.php

+67-19
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,8 @@ public function test_get_document_recordset(): void {
171171
$record->course = $course->id;
172172
$record->customfield_overview = 'Test overview text 3';
173173
$record->typeid = $this->cmstype->get('id');
174-
$generator->create_instance_with_data($record);
174+
$cms3 = $generator->create_instance_with_data($record);
175+
$context = \context_module::instance($cms3->cmid);
175176

176177
// Return only new search.
177178
$recordset = $searcharea->get_document_recordset($time);
@@ -184,7 +185,7 @@ public function test_get_document_recordset(): void {
184185
$this->assertEquals('mod_cms-cmsfield-' . $record->id, $doc->get('id'));
185186
$this->assertEquals($record->id, $doc->get('itemid'));
186187
$this->assertEquals($course->id, $doc->get('courseid'));
187-
$this->assertEquals($data->contextid, $doc->get('contextid'));
188+
$this->assertEquals($context->id, $doc->get('contextid'));
188189
$this->assertEquals($this->field->get('name'), $doc->get('title'));
189190
$this->assertEquals($data->value, $doc->get('content'));
190191

@@ -217,20 +218,76 @@ public function test_get_document_recordset(): void {
217218
* @covers ::get_document
218219
*/
219220
public function test_default_content(): void {
221+
$searcharea = \core_search\manager::get_search_area($this->cmsareaid);
222+
$this->assertInstanceOf('\mod_cms\search\cmsfield', $searcharea);
223+
224+
$course = self::getDataGenerator()->create_course();
225+
226+
// Create cms activity without customfield.
227+
$generator = self::getDataGenerator()->get_plugin_generator('mod_cms');
228+
$record = new \stdClass();
229+
$record->course = $course->id;
230+
$record->typeid = $this->cmstype->get('id');
231+
$cms1 = $generator->create_instance_with_data($record);
232+
233+
$recordset = $searcharea->get_document_recordset();
234+
$count = 0;
235+
foreach ($recordset as $record) {
236+
$this->assertInstanceOf('stdClass', $record);
237+
$this->assertEmpty($record->dataid);
238+
$doc = $searcharea->get_document($record);
239+
$this->assertInstanceOf('\core_search\document', $doc);
240+
// Confirm the content is from defaultvalue from cms fieldtype.
241+
$this->assertEquals('Default Text Overview', $doc->get('content'));
242+
$count++;
243+
}
244+
$this->assertEquals(1, $count);
245+
$recordset->close();
246+
247+
// Add custom data for the cms activity.
248+
$cms1->customfield_overview = 'Update test 1';
249+
$handler = cmsfield_handler::create($cms1->typeid);
250+
$handler->instance_form_save($cms1);
251+
$recordset = $searcharea->get_document_recordset();
252+
$count = 0;
253+
foreach ($recordset as $record) {
254+
$this->assertInstanceOf('stdClass', $record);
255+
$doc = $searcharea->get_document($record);
256+
$this->assertEquals('Update test 1', $doc->get('content'));
257+
$count++;
258+
}
259+
$this->assertEquals(1, $count);
260+
$recordset->close();
261+
}
262+
263+
/**
264+
* Test multiple contents in one cms activity
265+
*
266+
* @return void
267+
* @covers ::get_document_recordset
268+
* @covers ::get_document
269+
*/
270+
public function test_multiple_contents(): void {
220271
global $DB;
221272

222273
// Returns the instance as long as the area is supported.
223274
$searcharea = \core_search\manager::get_search_area($this->cmsareaid);
224275
$this->assertInstanceOf('\mod_cms\search\cmsfield', $searcharea);
225276

226277
$course = self::getDataGenerator()->create_course();
278+
$field = self::getDataGenerator()->create_custom_field([
279+
'name' => 'Details',
280+
'shortname' => 'details',
281+
'type' => 'text',
282+
'categoryid' => $this->fieldcategory->get('id'),
283+
'configdata' => json_encode(['defaultvalue' => 'Default Text Details']),
284+
]);
227285

228286
$generator = self::getDataGenerator()->get_plugin_generator('mod_cms');
229287
$record = new \stdClass();
230288
$record->course = $course->id;
231289
$record->typeid = $this->cmstype->get('id');
232290
$cms1 = $generator->create_instance_with_data($record);
233-
$context = \context_module::instance($cms1->cmid);
234291

235292
$recordset = $searcharea->get_document_recordset();
236293
$count = 0;
@@ -239,35 +296,26 @@ public function test_default_content(): void {
239296
$this->assertEmpty($record->dataid);
240297
$doc = $searcharea->get_document($record);
241298
$this->assertInstanceOf('\core_search\document', $doc);
242-
$this->assertEquals('mod_cms-cmsfield-' . $record->id, $doc->get('id'));
243-
$this->assertEquals($record->id, $doc->get('itemid'));
244-
$this->assertEquals($course->id, $doc->get('courseid'));
245-
$this->assertEquals($context->id, $doc->get('contextid'));
246-
$this->assertEquals($this->field->get('name'), $doc->get('title'));
247-
$this->assertEquals('Default Text Overview', $doc->get('content'));
299+
$this->assertStringContainsString('Default Text Overview', $doc->get('content'));
300+
$this->assertStringContainsString('Default Text Details', $doc->get('content'));
248301
$count++;
249302
}
250303
$this->assertEquals(1, $count);
251304
$recordset->close();
252305

253306
// Add data for the cms activity.
254-
$cms1->customfield_overview = 'Update test 1';
307+
$cms1->customfield_overview = 'Overview test 1';
308+
$cms1->customfield_details = 'Details test 1';
255309
$handler = cmsfield_handler::create($cms1->typeid);
256310
$handler->instance_form_save($cms1);
257311
$recordset = $searcharea->get_document_recordset();
258312
$count = 0;
259313
foreach ($recordset as $record) {
260314
$this->assertInstanceOf('stdClass', $record);
261-
$data = $DB->get_record('customfield_data', ['id' => $record->dataid]);
262315
$doc = $searcharea->get_document($record);
263-
$this->assertInstanceOf('\core_search\document', $doc);
264-
$this->assertEquals('mod_cms-cmsfield-' . $record->id, $doc->get('id'));
265-
$this->assertEquals($record->id, $doc->get('itemid'));
266-
$this->assertEquals($course->id, $doc->get('courseid'));
267-
$this->assertEquals($data->contextid, $doc->get('contextid'));
268-
$this->assertEquals($this->field->get('name'), $doc->get('title'));
269-
$this->assertEquals($data->value, $doc->get('content'));
270-
$this->assertEquals('Update test 1', $doc->get('content'));
316+
// Both strings are contained in the cms activity.
317+
$this->assertStringContainsString('Overview test 1', $doc->get('content'));
318+
$this->assertStringContainsString('Details test 1', $doc->get('content'));
271319
$count++;
272320
}
273321
$this->assertEquals(1, $count);

0 commit comments

Comments
 (0)