Skip to content

Commit f40d50c

Browse files
committed
Issue #66: Add default value and update unit test
1 parent 7ab1b5d commit f40d50c

File tree

3 files changed

+143
-31
lines changed

3 files changed

+143
-31
lines changed

classes/search/cmsfield.php

+58-19
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,6 @@
1414
// You should have received a copy of the GNU General Public License
1515
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
1616

17-
/**
18-
* Define search area.
19-
*
20-
* @package mod_cms
21-
* @author Tomo Tsuyuki <[email protected]>
22-
* @copyright 2024 Catalyst IT
23-
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24-
*/
2517
namespace mod_cms\search;
2618

2719
defined('MOODLE_INTERNAL') || die();
@@ -43,12 +35,17 @@ class cmsfield extends \core_search\base_mod {
4335
*/
4436
protected $cmsdata = [];
4537

38+
/**
39+
* @var array Internal quick static cache.
40+
*/
41+
protected $defaultvalues = null;
42+
4643
/**
4744
* Returns recordset containing required data for indexing cmsfield records.
4845
*
4946
* @param int $modifiedfrom timestamp
5047
* @param \context|null $context Optional context to restrict scope of returned results
51-
* @return moodle_recordset|null Recordset (or null if no results)
48+
* @return \moodle_recordset|null Recordset (or null if no results)
5249
*/
5350
public function get_document_recordset($modifiedfrom = 0, \context $context = null) {
5451
global $DB;
@@ -59,15 +56,25 @@ public function get_document_recordset($modifiedfrom = 0, \context $context = nu
5956
return null;
6057
}
6158

62-
$sql = "SELECT mcd.*, mc.id AS cmsid, mc.course AS courseid, mcf.name AS fieldname
63-
FROM {customfield_data} mcd
64-
JOIN {cms} mc ON mc.id = mcd.instanceid
59+
$sql = "SELECT mc.id, mc.course AS courseid, mc.typeid, mcf.name AS fieldname, mcd.id dataid,
60+
mcd.value AS value, mcd.valueformat AS valueformat,
61+
mcd.timecreated AS timecreated, mcd.timemodified AS timemodified
62+
FROM {cms} mc
63+
JOIN {customfield_data} mcd ON mc.id = mcd.instanceid
6564
JOIN {customfield_field} mcf ON mcf.id = mcd.fieldid
6665
JOIN {customfield_category} mcc ON mcf.categoryid = mcc.id
6766
$contextjoin
6867
WHERE mcd.timemodified >= ? AND mcc.component = 'mod_cms' AND mcc.area = 'cmsfield'
69-
ORDER BY mcd.timemodified ASC";
70-
return $DB->get_recordset_sql($sql, array_merge($contextparams, [$modifiedfrom]));
68+
AND mcf.type IN ('textarea', 'text')
69+
UNION
70+
SELECT mc.id, mc.course AS courseid, mc.typeid, null AS fieldname, null dataid,
71+
null AS value, null AS valueformat,
72+
mc.timecreated timecreated, mc.timemodified timemodified
73+
FROM {cms} mc
74+
LEFT JOIN {customfield_data} mcd ON mc.id = mcd.instanceid
75+
WHERE mcd.id IS NULL AND mc.timecreated >= ?
76+
ORDER BY timemodified ASC";
77+
return $DB->get_recordset_sql($sql, array_merge($contextparams, [$modifiedfrom, $modifiedfrom]));
7178
}
7279

7380
/**
@@ -78,8 +85,9 @@ public function get_document_recordset($modifiedfrom = 0, \context $context = nu
7885
* @return \core_search\document
7986
*/
8087
public function get_document($record, $options = []) {
88+
global $DB;
8189
try {
82-
$cm = $this->get_cm('cms', $record->cmsid, $record->courseid);
90+
$cm = $this->get_cm('cms', $record->id, $record->courseid);
8391
$context = \context_module::instance($cm->id);
8492
} catch (\dml_missing_record_exception $ex) {
8593
// Notify it as we run here as admin, we should see everything.
@@ -92,10 +100,42 @@ public function get_document($record, $options = []) {
92100
return false;
93101
}
94102

103+
if (is_null($this->defaultvalues)) {
104+
$defaultvalues = [];
105+
// Get default value for cms custom field.
106+
$sql = "SELECT mct.id typeid, mcf.configdata, mcf.name fieldname
107+
FROM {cms_types} mct
108+
JOIN {customfield_category} mcc ON mcc.itemid = mct.id
109+
JOIN {customfield_field} mcf ON mcf.categoryid = mcc.id
110+
WHERE mcc.component = 'mod_cms' AND mcc.area = 'cmsfield' AND mcf.type IN ('textarea', 'text')";
111+
$cmstypes = $DB->get_records_sql($sql);
112+
$defaultvalues = [];
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+
}
123+
124+
// Check if it's default value or not.
125+
if (empty($record->dataid)) {
126+
$title = $this->defaultvalues[$record->typeid]->fieldname ?? 'Default title';
127+
$value = $this->defaultvalues[$record->typeid]->value ?? 'Default value';
128+
$valueformat = $this->defaultvalues[$record->typeid]->valueformat ?? 'Default valueformat';
129+
} else {
130+
$title = $record->fieldname;
131+
$value = $record->value;
132+
$valueformat = $record->valueformat;
133+
}
134+
95135
// Prepare associative array with data from DB.
96136
$doc = \core_search\document_factory::instance($record->id, $this->componentname, $this->areaname);
97-
$doc->set('title', content_to_text($record->fieldname, false));
98-
$doc->set('content', content_to_text($record->value, $record->valueformat));
137+
$doc->set('title', content_to_text($title, false));
138+
$doc->set('content', content_to_text($value, $valueformat));
99139
$doc->set('contextid', $context->id);
100140
$doc->set('courseid', $record->courseid);
101141
$doc->set('owneruserid', \core_search\manager::NO_OWNER_ID);
@@ -120,6 +160,7 @@ public function check_access($id) {
120160
try {
121161
$data = $this->get_data($id);
122162
$cminfo = $this->get_cm('cms', $data->instanceid, $data->courseid);
163+
$context = \context_module::instance($cminfo->id);
123164
} catch (\dml_missing_record_exception $ex) {
124165
return \core_search\manager::ACCESS_DELETED;
125166
} catch (\dml_exception $ex) {
@@ -131,8 +172,6 @@ public function check_access($id) {
131172
return \core_search\manager::ACCESS_DENIED;
132173
}
133174

134-
$context = \context_module::instance($cminfo->id);
135-
136175
if (!has_capability('mod/cms:view', $context)) {
137176
return \core_search\manager::ACCESS_DENIED;
138177
}

lang/en/cms.php

-3
Original file line numberDiff line numberDiff line change
@@ -105,9 +105,6 @@
105105

106106
// Search strings.
107107
$string['search:cmsfield'] = 'CMS';
108-
$string['search:settings'] = 'Search settings';
109-
$string['search:settings:area'] = 'Search area';
110-
$string['search:settings:area_desc'] = 'Search area for global search';
111108

112109
// Site datasource strings.
113110
$string['site:displayname'] = 'Site Info';

tests/search/search_test.php

+85-9
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626

2727
namespace mod_cms\search;
2828

29+
use mod_cms\customfield\cmsfield_handler;
2930
use mod_cms\local\model\cms_types;
3031

3132
defined('MOODLE_INTERNAL') || die();
@@ -93,6 +94,7 @@ public function setUp(): void {
9394
'shortname' => 'overview',
9495
'type' => 'text',
9596
'categoryid' => $fieldcategory->get('id'),
97+
'configdata' => json_encode(['defaultvalue' => 'Default Text Overview']),
9698
]);
9799
$this->cmstype = $cmstype;
98100
$this->fieldcategory = $fieldcategory;
@@ -138,45 +140,45 @@ public function test_get_document_recordset(): void {
138140
$record->course = $course->id;
139141
$record->customfield_overview = 'Test overview text 1';
140142
$record->typeid = $this->cmstype->get('id');
141-
$generator->create_instance_with_data($record);
143+
$cms1 = $generator->create_instance_with_data($record);
142144

143145
$record = new \stdClass();
144146
$record->course = $course->id;
145147
$record->customfield_overview = 'Test overview text 2';
146148
$record->typeid = $this->cmstype->get('id');
147-
$generator->create_instance_with_data($record);
149+
$cms2 = $generator->create_instance_with_data($record);
148150

149151
// All records.
150152
$recordset = $searcharea->get_document_recordset();
151153
$this->assertTrue($recordset->valid());
152154
$this->assertEquals(2, iterator_count($recordset));
153155
$recordset->close();
154156

155-
// The +2 is to prevent race conditions.
157+
// Search again by current time + 2 sec.
156158
$recordset = $searcharea->get_document_recordset(time() + 2);
157-
158159
// No new records.
159160
$this->assertFalse($recordset->valid());
160161
$recordset->close();
161162

162163
// Wait 1 sec to have new search string.
163164
sleep(1);
165+
$time = time();
164166
$record = new \stdClass();
165167
$record->course = $course->id;
166168
$record->customfield_overview = 'Test overview text 3';
167169
$record->typeid = $this->cmstype->get('id');
168170
$generator->create_instance_with_data($record);
169171

170172
// Return only new search.
171-
$recordset = $searcharea->get_document_recordset(time());
173+
$recordset = $searcharea->get_document_recordset($time);
172174
$count = 0;
173175
foreach ($recordset as $record) {
174176
$this->assertInstanceOf('stdClass', $record);
175-
$data = $DB->get_record('customfield_data', ['id' => $record->id]);
177+
$data = $DB->get_record('customfield_data', ['id' => $record->dataid]);
176178
$doc = $searcharea->get_document($record);
177179
$this->assertInstanceOf('\core_search\document', $doc);
178-
$this->assertEquals('mod_cms-cmsfield-' . $data->id, $doc->get('id'));
179-
$this->assertEquals($data->id, $doc->get('itemid'));
180+
$this->assertEquals('mod_cms-cmsfield-' . $record->id, $doc->get('id'));
181+
$this->assertEquals($record->id, $doc->get('itemid'));
180182
$this->assertEquals($course->id, $doc->get('courseid'));
181183
$this->assertEquals($data->contextid, $doc->get('contextid'));
182184
$this->assertEquals($this->field->get('name'), $doc->get('title'));
@@ -191,10 +193,84 @@ public function test_get_document_recordset(): void {
191193
}
192194
$this->assertEquals(1, $count);
193195
$recordset->close();
196+
197+
// Update existing data.
198+
$cms1->customfield_overview = 'Update test 1';
199+
$handler = cmsfield_handler::create($cms1->typeid);
200+
$handler->instance_form_save($cms1);
201+
// Return 2 records.
202+
$recordset = $searcharea->get_document_recordset($time);
203+
$this->assertTrue($recordset->valid());
204+
$this->assertEquals(2, iterator_count($recordset));
205+
$recordset->close();
206+
}
207+
208+
/**
209+
* Test default value from cms content type
210+
*
211+
* @return void
212+
*/
213+
public function test_default_content(): void {
214+
global $DB;
215+
216+
// Returns the instance as long as the area is supported.
217+
$searcharea = \core_search\manager::get_search_area($this->cmsareaid);
218+
$this->assertInstanceOf('\mod_cms\search\cmsfield', $searcharea);
219+
220+
$course = self::getDataGenerator()->create_course();
221+
222+
// Name for cms is coming from "title_mustache" in cms_type.
223+
$generator = self::getDataGenerator()->get_plugin_generator('mod_cms');
224+
$record = new \stdClass();
225+
$record->course = $course->id;
226+
$record->typeid = $this->cmstype->get('id');
227+
$cms1 = $generator->create_instance_with_data($record);
228+
$context = \context_module::instance($cms1->cmid);
229+
230+
$recordset = $searcharea->get_document_recordset();
231+
$count = 0;
232+
foreach ($recordset as $record) {
233+
$this->assertInstanceOf('stdClass', $record);
234+
$this->assertEmpty($record->dataid);
235+
$doc = $searcharea->get_document($record);
236+
$this->assertInstanceOf('\core_search\document', $doc);
237+
$this->assertEquals('mod_cms-cmsfield-' . $record->id, $doc->get('id'));
238+
$this->assertEquals($record->id, $doc->get('itemid'));
239+
$this->assertEquals($course->id, $doc->get('courseid'));
240+
$this->assertEquals($context->id, $doc->get('contextid'));
241+
$this->assertEquals($this->field->get('name'), $doc->get('title'));
242+
$this->assertEquals('Default Text Overview', $doc->get('content'));
243+
$count++;
244+
}
245+
$this->assertEquals(1, $count);
246+
$recordset->close();
247+
248+
// Add data for the cms activity.
249+
$cms1->customfield_overview = 'Update test 1';
250+
$handler = cmsfield_handler::create($cms1->typeid);
251+
$handler->instance_form_save($cms1);
252+
$recordset = $searcharea->get_document_recordset();
253+
$count = 0;
254+
foreach ($recordset as $record) {
255+
$this->assertInstanceOf('stdClass', $record);
256+
$data = $DB->get_record('customfield_data', ['id' => $record->dataid]);
257+
$doc = $searcharea->get_document($record);
258+
$this->assertInstanceOf('\core_search\document', $doc);
259+
$this->assertEquals('mod_cms-cmsfield-' . $record->id, $doc->get('id'));
260+
$this->assertEquals($record->id, $doc->get('itemid'));
261+
$this->assertEquals($course->id, $doc->get('courseid'));
262+
$this->assertEquals($data->contextid, $doc->get('contextid'));
263+
$this->assertEquals($this->field->get('name'), $doc->get('title'));
264+
$this->assertEquals($data->value, $doc->get('content'));
265+
$this->assertEquals('Update test 1', $doc->get('content'));
266+
$count++;
267+
}
268+
$this->assertEquals(1, $count);
269+
$recordset->close();
194270
}
195271

196272
/**
197-
* Document contents.
273+
* Test check_access.
198274
*
199275
* @return void
200276
*/

0 commit comments

Comments
 (0)