MDL-55127 mod_data: added database entries to globalsearch

This commit is contained in:
Devang Gaur
2016-08-19 13:58:19 +05:30
parent 3ca3cc77a2
commit 2af9ad7d30
14 changed files with 1375 additions and 60 deletions
+330
View File
@@ -0,0 +1,330 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Search area for mod_data activity entries.
*
* @package mod_data
* @copyright 2016 Devang Gaur
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_data\search;
defined('MOODLE_INTERNAL') || die();
require_once($CFG->dirroot . '/mod/data/lib.php');
require_once($CFG->dirroot . '/lib/grouplib.php');
/**
* Search area for mod_data activity entries.
*
* @package mod_data
* @copyright 2016 Devang Gaur
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class entry extends \core_search\base_mod {
/**
* @var array Internal quick static cache.
*/
protected $entriesdata = array();
/**
* Returns recordset containing required data for indexing database entries.
*
* @param int $modifiedfrom timestamp
* @return moodle_recordset
*/
public function get_recordset_by_timestamp($modifiedfrom = 0) {
global $DB;
$sql = "SELECT dr.*, d.course
FROM {data_records} dr
JOIN {data} d ON d.id = dr.dataid
WHERE dr.timemodified >= :timemodified";
return $DB->get_recordset_sql($sql, array('timemodified' => $modifiedfrom));
}
/**
* Returns the documents associated with this glossary entry id.
*
* @param stdClass $entry glossary entry.
* @param array $options
* @return \core_search\document
*/
public function get_document($entry, $options = array()) {
global $DB;
try {
$cm = $this->get_cm('data', $entry->dataid, $entry->course);
$context = \context_module::instance($cm->id);
} catch (\dml_missing_record_exception $ex) {
// Notify it as we run here as admin, we should see everything.
debugging('Error retrieving mod_data ' . $entry->id . ' document, not all required data is available: ' .
$ex->getMessage(), DEBUG_DEVELOPER);
return false;
} catch (\dml_exception $ex) {
// Notify it as we run here as admin, we should see everything.
debugging('Error retrieving mod_data' . $entry->id . ' document: ' . $ex->getMessage(), DEBUG_DEVELOPER);
return false;
}
// Prepare associative array with data from DB.
$doc = \core_search\document_factory::instance($entry->id, $this->componentname, $this->areaname);
$doc->set('contextid', $context->id);
$doc->set('courseid', $entry->course);
$doc->set('userid', $entry->userid);
$doc->set('owneruserid', \core_search\manager::NO_OWNER_ID);
$doc->set('modified', $entry->timemodified);
$indexfields = $this->get_fields_for_entries($entry);
if (count($indexfields) < 2) {
return false;
}
$doc->set('title', $indexfields[0]);
$doc->set('content', $indexfields[1]);
if (isset($indexfields[2])) {
$doc->set('description1', $indexfields[2]);
}
if (isset($indexfields[3])) {
$doc->set('description2', $indexfields[3]);
}
return $doc;
}
/**
* Whether the user can access the document or not.
*
* @throws \dml_missing_record_exception
* @throws \dml_exception
* @param int $id Glossary entry id
* @return bool
*/
public function check_access($id) {
global $DB, $USER;
if (isguestuser()) {
return \core_search\manager::ACCESS_DENIED;
}
$now = time();
$sql = "SELECT dr.*, d.*
FROM {data_records} dr
JOIN {data} d ON d.id = dr.dataid
WHERE dr.id = ?";
$entry = $DB->get_record_sql($sql, array( $id ), IGNORE_MISSING);
if (!$entry) {
return \core_search\manager::ACCESS_DELETED;
}
if (($entry->timeviewfrom && $now < $entry->timeviewfrom) || ($entry->timeviewto && $now > $entry->timeviewto)) {
return \core_search\manager::ACCESS_DENIED;
}
$cm = $this->get_cm('data', $entry->dataid, $entry->course);
$context = \context_module::instance($cm->id);
$canmanageentries = has_capability('mod/data:manageentries', $context);
if (!has_capability('mod/data:viewentry', $context)) {
return \core_search\manager::ACCESS_DENIED;
}
$numberofentriesindb = $DB->count_records('data_records', array('dataid' => $entry->dataid));
$requiredentriestoview = $entry->requiredentriestoview;
if ($requiredentriestoview && ($requiredentriestoview > $numberofentriesindb) &&
($USER->id != $entry->userid) && !$canmanageentries) {
return \core_search\manager::ACCESS_DENIED;
}
if ($entry->approval && !$entry->approved && ($entry->userid != $USER->id) && !$canmanageentries) {
return \core_search\manager::ACCESS_DENIED;
}
$currentgroup = groups_get_activity_group($cm, true);
$groupmode = groups_get_activity_groupmode($cm);
if (($groupmode == 1) && ($entry->groupid != $currentgroup) && !$canmanageentries) {
return \core_search\manager::ACCESS_DENIED;
}
return \core_search\manager::ACCESS_GRANTED;
}
/**
* Link to database entry.
*
* @param \core_search\document $doc
* @return \moodle_url
*/
public function get_doc_url(\core_search\document $doc) {
$entry = $this->get_entry($doc->get('itemid'));
return new \moodle_url('/mod/data/view.php', array( 'd' => $entry->dataid, 'rid' => $entry->id ));
}
/**
* Link to the database activity.
*
* @param \core_search\document $doc
* @return \moodle_url
*/
public function get_context_url(\core_search\document $doc) {
$entry = $this->get_entry($doc->get('itemid'));
return new \moodle_url('/mod/data/view.php', array('d' => $entry->dataid));
}
/**
* Returns true if this area uses file indexing.
*
* @return bool
*/
public function uses_file_indexing() {
return true;
}
/**
* Add the database entries attachments.
*
* @param \core_search\document $doc
* @return void
*/
public function attach_files($doc) {
global $DB;
$entryid = $doc->get('itemid');
try {
$entry = $this->get_entry($entryid);
} catch (\dml_missing_record_exception $e) {
debugging('Could not get record to attach files to '.$doc->get('id'), DEBUG_DEVELOPER);
return;
}
$cm = $this->get_cm('data', $entry->dataid, $doc->get('courseid'));
$context = \context_module::instance($cm->id);
// Get the files and attach them.
$fs = get_file_storage();
$files = $fs->get_area_files($context->id, 'mod_data', 'content', $entryid, 'filename', false);
foreach ($files as $file) {
$doc->add_stored_file($file);
}
}
/**
* Get database entry data
*
* @throws \dml_exception
* @param int $entryid
* @return stdClass
*/
protected function get_entry($entryid) {
global $DB;
if (empty($this->entriesdata[$entryid])) {
$this->entriesdata[$entryid] = $DB->get_record('data_records', array( 'id' => $entryid ), '*', MUST_EXIST);
}
return $this->entriesdata[$entryid];
}
/**
* get_fields_for_entries
*
* @param StdClass $entry
* @return array
*/
protected function get_fields_for_entries($entry) {
global $DB;
$indexfields = array();
$validfieldtypes = array('text', 'textarea', 'menu', 'radiobutton', 'checkbox', 'multimenu', 'url');
$sql = "SELECT dc.id, dc.content, df.name AS fldname,
df.type AS fieldtype, df.required
FROM {data_content} dc, {data_fields} df
WHERE dc.fieldid = df.id
AND dc.recordid = :recordid";
$contents = $DB->get_records_sql($sql, array('recordid' => $entry->id));
$filteredcontents = array();
$template = $DB->get_record_sql('SELECT addtemplate FROM {data} WHERE id = ?', array($entry->dataid));
$template = $template->addtemplate;
// Filtering out the data_content records having invalid fieldtypes.
foreach ($contents as $content) {
if (in_array($content->fieldtype, $validfieldtypes)) {
$filteredcontents[] = $content;
}
}
foreach ($filteredcontents as $content) {
$classname = 'data_field_' . trim($content->fieldtype);
$content->priority = $classname::get_priority();
$content->addtemplateposition = strpos($template, '[['.$content->fldname.']]');
}
$orderqueue = new \SPLPriorityQueue();
// Filtering out contents which belong to fields that aren't present in the addtemplate of the database activity instance.
foreach ($filteredcontents as $content) {
if ($content->addtemplateposition >= 0) {
$orderqueue->insert($content, $content->addtemplateposition);
}
}
$filteredcontents = array();
while ($orderqueue->valid()) {
$filteredcontents[] = $orderqueue->extract();
}
// SPLPriorityQueue sorts according to descending order of the priority (here, addtemplateposition).
$filteredcontents = array_reverse($filteredcontents);
// Using a CUSTOM SPLPriorityQueure instance to sort out the filtered contents according to these rules :
// 1. Priorities in $fieldtypepriorities
// 2. Compulsory fieldtypes are to be given the top priority.
$contentqueue = new sortedcontentqueue($filteredcontents);
foreach ($filteredcontents as $key => $content) {
$contentqueue->insert($content, $key);
}
while ($contentqueue->valid()) {
$content = $contentqueue->extract();
$classname = 'data_field_' . trim($content->fieldtype);
$indexfields[] = $classname::get_content_value($content->content);
}
return $indexfields;
}
}
@@ -0,0 +1,80 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Priority Queue class to sort out db entry contents.
*
* @package mod_data
* @copyright 2016 Devang Gaur
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_data\search;
defined('MOODLE_INTERNAL') || die();
/**
* Priority Queue class to sort out db entry contents.
*
* @package mod_data
* @copyright 2016 Devang Gaur
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class sortedcontentqueue extends \SPLPriorityQueue {
/**
* @var array All contents that will be sorted.
*/
private $contents;
/**
* contructor
*
* @param array $contents
* @return void
*/
public function __construct($contents) {
$this->contents = $contents;
}
/**
* comparator function overriden for sorting the records
* ...as per 'required' and 'priotirity' field values
*
* @param int $key1
* @param int $key2
* @return bool
*/
public function compare($key1 , $key2) {
$record1 = $this->contents[$key1];
$record2 = $this->contents[$key2];
// If a content's fieldtype is compulsory in the database than it would have priority than any other noncompulsory content.
if ( ($record1->required && $record2->required) || (!$record1->required && !$record2->required)) {
if ($record1->priority === $record2->priority) {
return $key1 < $key2 ? 1 : -1;
}
return $record1->priority < $record2->priority ? -1 : 1;
} else if ($record1->required && !$record2->required) {
return 1;
} else {
return -1;
}
}
}
+21
View File
@@ -25,6 +25,12 @@
class data_field_checkbox extends data_field_base {
var $type = 'checkbox';
/**
* priority for globalsearch indexing
*
* @var int
*/
protected static $priority = self::LOW_PRIORITY;
function display_add_field($recordid = 0, $formdata = null) {
global $CFG, $DB, $OUTPUT;
@@ -242,4 +248,19 @@ class data_field_checkbox extends data_field_base {
return $found;
}
/**
* Returns the presentable string value for a field content.
* @param string $value
* @return string
*/
public static function get_content_value($value) {
$arr = explode('##', $value);
$content = '';
foreach ($arr as $a) {
$content .= $a.' ';
}
return trim($content);
}
}
+6
View File
@@ -25,6 +25,12 @@
class data_field_menu extends data_field_base {
var $type = 'menu';
/**
* priority for globalsearch indexing
*
* @var int
*/
protected static $priority = self::HIGH_PRIORITY;
function display_add_field($recordid = 0, $formdata = null) {
global $DB, $OUTPUT;
+23
View File
@@ -25,6 +25,12 @@
class data_field_multimenu extends data_field_base {
var $type = 'multimenu';
/**
* priority for globalsearch indexing
*
* @var int
* */
protected static $priority = self::LOW_PRIORITY;
function display_add_field($recordid = 0, $formdata = null) {
global $DB, $OUTPUT;
@@ -267,4 +273,21 @@ class data_field_multimenu extends data_field_base {
unset($value['xxx']);
return !empty($value);
}
/**
* Returns the presentable string value for a field content.
* @param string $value
* @return string
*/
public static function get_content_value($value) {
$arr = explode('##', $value);
$content = '';
foreach ($arr as $a) {
$content .= $a.' ';
}
return trim($content);
}
}
@@ -25,6 +25,12 @@
class data_field_radiobutton extends data_field_base {
var $type = 'radiobutton';
/**
* priority for globalsearch indexing
*
* @var int
*/
protected static $priority = self::HIGH_PRIORITY;
function display_add_field($recordid = 0, $formdata = null) {
global $CFG, $DB, $OUTPUT;
+6
View File
@@ -25,6 +25,12 @@
class data_field_text extends data_field_base {
var $type = 'text';
/**
* priority for globalsearch indexing
*
* @var int
*/
protected static $priority = self::MAX_PRIORITY;
function display_search_field($value = '') {
return '<label class="accesshide" for="f_' . $this->field->id . '">'. $this->field->name.'</label>' . '<input type="text" size="16" id="f_'.$this->field->id.'" name="f_'.$this->field->id.'" value="'.s($value).'" />';
+16
View File
@@ -27,6 +27,12 @@ require_once($CFG->dirroot.'/repository/lib.php');
class data_field_textarea extends data_field_base {
var $type = 'textarea';
/**
* priority for globalsearch indexing
*
* @var int
*/
protected static $priority = self::LOW_PRIORITY;
/**
* Returns options for embedded files
@@ -275,4 +281,14 @@ class data_field_textarea extends data_field_base {
}
return false;
}
/**
* Returns the presentable string value for a field content.
* @param string $value
* @return string
*/
public static function get_content_value($value) {
return clean_param($value, PARAM_NOTAGS);
}
}
+6
View File
@@ -24,6 +24,12 @@
class data_field_url extends data_field_base {
var $type = 'url';
/**
* priority for globalsearch indexing
*
* @var int
*/
protected static $priority = self::MIN_PRIORITY;
function display_add_field($recordid = 0, $formdata = null) {
global $CFG, $DB, $OUTPUT, $PAGE;
+1
View File
@@ -324,6 +324,7 @@ $string['savesuccess'] = 'Saved successfully. Your preset will now be available
$string['savetemplate'] = 'Save template';
$string['search'] = 'Search';
$string['search:activity'] = 'Database - activity information';
$string['search:entry'] = 'Database - entries';
$string['selectedrequired'] = 'All selected required';
$string['showall'] = 'Show all entries';
$string['single'] = 'View single';
+30
View File
@@ -64,6 +64,18 @@ class data_field_base { // Base class for Database Field Types (see field/*/
var $cm;
/** @var object activity context */
var $context;
/** @var priority for globalsearch indexing */
protected static $priority = self::NO_PRIORITY;
/** priority value for invalid fields regarding indexing */
const NO_PRIORITY = 0;
/** priority value for minimum priority */
const MIN_PRIORITY = 1;
/** priority value for low priority */
const LOW_PRIORITY = 2;
/** priority value for high priority */
const HIGH_PRIORITY = 3;
/** priority value for maximum priority */
const MAX_PRIORITY = 4;
/**
* Constructor function
@@ -527,6 +539,24 @@ class data_field_base { // Base class for Database Field Types (see field/*/
function file_ok($relativepath) {
return false;
}
/**
* Returns the priority for being indexed by globalsearch
*
* @return int
*/
public static function get_priority() {
return static::$priority;
}
/**
* Returns the presentable string value for a field content.
* @param string $value
* @return string
*/
public static function get_content_value($value) {
return trim($value);
}
}
+17 -14
View File
@@ -133,8 +133,10 @@ class mod_data_generator extends testing_module_generator {
}
if (!isset($record['param1'])) {
if (in_array($record['type'], array('checkbox', 'menu', 'multimenu', 'radiobutton'))) {
$record['param1'] = implode("\n", array('one', 'two', 'three', 'four'));
if (in_array($record['type'], array('checkbox', 'radiobutton'))) {
$record['param1'] = implode("\n", array('opt1', 'opt2', 'opt3', 'opt4'));
} else if (in_array($record['type'], array('multimenu', 'menu'))) {
$record['param1'] = implode("\n", array('menu1', 'menu2', 'menu3', 'menu4'));
} else if (($record['type'] === 'text') || ($record['type'] === 'url')) {
$record['param1'] = 1;
} else {
@@ -185,6 +187,8 @@ class mod_data_generator extends testing_module_generator {
/**
* Creates a field for a mod_data instance.
* Keep in mind the default data field params created in create_field() function!
* ...if you haven't provided your own custom data field parameters there.
* Currently, the field types in the ignoredfieldtypes array aren't supported.
* The developers using the generator must adhere to the following format :
*
@@ -203,12 +207,12 @@ class mod_data_generator extends testing_module_generator {
* @param array $contents
* @return data_field_{type}
*/
public function create_entry($data, array $contents) {
public function create_entry($data, array $contents, $groupid = 0) {
global $DB;
$this->databaserecordcount++;
$recordid = data_add_record($data);
$recordid = data_add_record($data, $groupid);
$fields = $DB->get_records('data_fields', array('dataid' => $data->id));
@@ -254,11 +258,11 @@ class mod_data_generator extends testing_module_generator {
$contents[$fieldid] = $values;
foreach ($values as $fieldname => $value) {
if (!$field->notemptyfield($value, $fieldname)) {
$fieldhascontent = false;
}
$fieldname = 'field_' . $fieldid;
if (!$field->notemptyfield($values[$fieldname], $fieldname)) {
$fieldhascontent = false;
}
} else if ($field->type === 'url') {
$values = array();
@@ -271,12 +275,11 @@ class mod_data_generator extends testing_module_generator {
}
$contents[$fieldid] = $values;
foreach ($values as $fieldname => $value) {
if (!$field->notemptyfield($value, $fieldname)) {
$fieldhascontent = false;
}
$fieldname = 'field_' . $fieldid . '_0';
if (!$field->notemptyfield($values[$fieldname], $fieldname)) {
$fieldhascontent = false;
}
} else {
if ($field->notemptyfield($contents[$fieldid], 'field_' . $fieldid . '_0')) {
continue;
@@ -291,7 +294,7 @@ class mod_data_generator extends testing_module_generator {
foreach ($contents as $fieldid => $content) {
$field = data_get_field_from_id($fieldid, $data);
if (is_array($content)) {
if (is_array($content) and in_array($field->type, array('date', 'textarea', 'url'))) {
foreach ($content as $fieldname => $value) {
$field->update_content($recordid, $value, $fieldname);
+39 -6
View File
@@ -136,7 +136,12 @@ class mod_data_generator_testcase extends advanced_testcase {
$this->setAdminUser();
$this->assertEquals(0, $DB->count_records('data'));
$user1 = $this->getDataGenerator()->create_user();
$course = $this->getDataGenerator()->create_course();
$this->getDataGenerator()->enrol_user($user1->id, $course->id, 'student');
$groupa = $this->getDataGenerator()->create_group(array('courseid' => $course->id, 'name' => 'groupA'));
$this->getDataGenerator()->create_group_member(array('userid' => $user1->id, 'groupid' => $groupa->id));
/** @var mod_data_generator $generator */
$generator = $this->getDataGenerator()->get_plugin_generator('mod_data');
@@ -166,6 +171,7 @@ class mod_data_generator_testcase extends advanced_testcase {
$record = new StdClass();
$record->name = $fieldname;
$record->type = $fieldtype;
$record->required = 1;
${$fieldname} = $this->getDataGenerator()->get_plugin_generator('mod_data')->create_field($record, $data);
$this->assertInstanceOf('data_field_' . $fieldtype, ${$fieldname});
@@ -177,12 +183,12 @@ class mod_data_generator_testcase extends advanced_testcase {
$fields = $DB->get_records('data_fields', array('dataid' => $data->id), 'id');
$contents = array();
$contents[] = array('one', 'two', 'three', 'four');
$contents[] = array('opt1', 'opt2', 'opt3', 'opt4');
$contents[] = '01-01-2037'; // It should be lower than 2038, to avoid failing on 32-bit windows.
$contents[] = 'one';
$contents[] = array('one', 'two', 'three', 'four');
$contents[] = 'menu1';
$contents[] = array('menu1', 'menu2', 'menu3', 'menu4');
$contents[] = '12345';
$contents[] = 'one';
$contents[] = 'opt1';
$contents[] = 'text for testing';
$contents[] = '<p>text area testing<br /></p>';
$contents[] = array('example.url', 'sampleurl');
@@ -192,9 +198,36 @@ class mod_data_generator_testcase extends advanced_testcase {
$fieldcontents[$fieldrecord->id] = $contents[$count++];
}
$datarecordid = $this->getDataGenerator()->get_plugin_generator('mod_data')->create_entry($data, $fieldcontents);
$datarecordid = $this->getDataGenerator()->get_plugin_generator('mod_data')->create_entry($data, $fieldcontents,
$groupa->id);
$this->assertEquals(1, $DB->count_records('data_records', array('dataid' => $data->id)));
$this->assertEquals(count($contents), $DB->count_records('data_content', array('recordid' => $datarecordid)));
$entry = $DB->get_record('data_records', array('id' => $datarecordid));
$this->assertEquals($entry->groupid, $groupa->id);
$contents = $DB->get_records('data_content', array('recordid' => $datarecordid));
$contentstartid = 0;
$flag = 0;
foreach ($contents as $key => $content) {
if (!$flag++) {
$contentstartid = $key;
}
$this->assertFalse($content->content == null);
}
$this->assertEquals($contents[$contentstartid]->content, 'opt1##opt2##opt3##opt4');
$this->assertEquals($contents[++$contentstartid]->content, '2114380800');
$this->assertEquals($contents[++$contentstartid]->content, 'menu1');
$this->assertEquals($contents[++$contentstartid]->content, 'menu1##menu2##menu3##menu4');
$this->assertEquals($contents[++$contentstartid]->content, '12345');
$this->assertEquals($contents[++$contentstartid]->content, 'opt1');
$this->assertEquals($contents[++$contentstartid]->content, 'text for testing');
$this->assertEquals($contents[++$contentstartid]->content, '<p>text area testing<br /></p>');
$this->assertEquals($contents[$contentstartid]->content1, '1');
$this->assertEquals($contents[++$contentstartid]->content, 'http://example.url');
$this->assertEquals($contents[$contentstartid]->content1, 'sampleurl');
}
}
}
+794 -40
View File
@@ -28,8 +28,10 @@ defined('MOODLE_INTERNAL') || die();
global $CFG;
require_once($CFG->dirroot . '/mod/data/lib.php');
require_once($CFG->dirroot . '/lib/datalib.php');
require_once($CFG->dirroot . '/lib/csvlib.class.php');
require_once($CFG->dirroot . '/search/tests/fixtures/testable_core_search.php');
require_once($CFG->dirroot . '/mod/data/tests/generator/lib.php');
/**
* Unit tests for {@see data_get_all_recordids()}.
@@ -41,7 +43,7 @@ require_once($CFG->dirroot . '/lib/csvlib.class.php');
* @copyright 2012 Adrian Greeve
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class data_advanced_search_sql_test extends advanced_testcase {
class mod_data_search_test extends advanced_testcase {
/**
* @var stdObject $recorddata An object that holds information from the table data.
*/
@@ -90,6 +92,11 @@ class data_advanced_search_sql_test extends advanced_testcase {
*/
public $approvedatarecordcount = 89;
/**
* @var string Area id
*/
protected $databaseentryareaid = null;
/**
* Set up function. In this instance we are setting up database
* records to be used in the unit tests.
@@ -100,6 +107,43 @@ class data_advanced_search_sql_test extends advanced_testcase {
$this->resetAfterTest(true);
set_config('enableglobalsearch', true);
$this->databaseentryareaid = \core_search\manager::generate_areaid('mod_data', 'entry');
// Set \core_search::instance to the mock_search_engine as we don't require the search engine to be working to test this.
$search = testable_core_search::instance();
}
/**
* Test 1: The function data_get_all_recordids.
*
* Test 2: This tests the data_get_advance_search_ids() function. The function takes a set
* of all the record IDs in the database and then with the search details ($this->recordsearcharray)
* returns a comma seperated string of record IDs that match the search criteria.
*
* Test 3: This function tests data_get_recordids(). This is the function that is nested in the last
* function (see data_get_advance_search_ids). This function takes a couple of
* extra parameters. $alias is the field alias used in the sql query and $commaid
* is a comma seperated string of record IDs.
*
* Test 3.1: This tests that if no recordids are provided (In a situation where a search is done on an empty database)
* That an empty array is returned.
*
* Test 4: data_get_advanced_search_sql provides an array which contains an sql string to be used for displaying records
* to the user when they use the advanced search criteria and the parameters that go with the sql statement. This test
* takes that information and does a search on the database, returning a record.
*
* Test 5: Returning to data_get_all_recordids(). Here we are ensuring that the total amount of record ids is reduced to
* match the group conditions that are provided. There are 25 entries which relate to group 2. They are removed
* from the total so we should only have 75 records total.
*
* Test 6: data_get_all_recordids() again. This time we are testing approved database records. We only want to
* display the records that have been approved. In this record set we have 89 approved records.
*/
public function test_advanced_search_sql_section() {
global $DB;
// we already have 2 users, we need 98 more - let's ignore the fact that guest can not post anywhere
// We reset the user sequence here to ensure we get the expected numbers.
@@ -116,9 +160,9 @@ class data_advanced_search_sql_test extends advanced_testcase {
// Set up data for the test database.
$files = array(
'data_fields' => __DIR__.'/fixtures/test_data_fields.csv',
'data_records' => __DIR__.'/fixtures/test_data_records.csv',
'data_content' => __DIR__.'/fixtures/test_data_content.csv',
'data_fields' => __DIR__.'/fixtures/test_data_fields.csv',
'data_records' => __DIR__.'/fixtures/test_data_records.csv',
'data_content' => __DIR__.'/fixtures/test_data_content.csv',
);
$this->loadDataSet($this->createCsvDataSet($files));
// Set dataid to the correct value now the data has been inserted by csv file.
@@ -127,10 +171,10 @@ class data_advanced_search_sql_test extends advanced_testcase {
// Create the search array which contains our advanced search criteria.
$fieldinfo = array('0' => new stdClass(),
'1' => new stdClass(),
'2' => new stdClass(),
'3' => new stdClass(),
'4' => new stdClass());
'1' => new stdClass(),
'2' => new stdClass(),
'3' => new stdClass(),
'4' => new stdClass());
$fieldinfo['0']->id = 1;
$fieldinfo['0']->data = '3.721,46.6126';
$fieldinfo['1']->id = 2;
@@ -175,36 +219,6 @@ class data_advanced_search_sql_test extends advanced_testcase {
$this->finalrecord[6]->picture = $user->picture;
$this->finalrecord[6]->imagealt = $user->imagealt;
$this->finalrecord[6]->email = $user->email;
}
/**
* Test 1: The function data_get_all_recordids.
*
* Test 2: This tests the data_get_advance_search_ids() function. The function takes a set
* of all the record IDs in the database and then with the search details ($this->recordsearcharray)
* returns a comma seperated string of record IDs that match the search criteria.
*
* Test 3: This function tests data_get_recordids(). This is the function that is nested in the last
* function (@see data_get_advance_search_ids). This function takes a couple of
* extra parameters. $alias is the field alias used in the sql query and $commaid
* is a comma seperated string of record IDs.
*
* Test 3.1: This tests that if no recordids are provided (In a situation where a search is done on an empty database)
* That an empty array is returned.
*
* Test 4: data_get_advanced_search_sql provides an array which contains an sql string to be used for displaying records
* to the user when they use the advanced search criteria and the parameters that go with the sql statement. This test
* takes that information and does a search on the database, returning a record.
*
* Test 5: Returning to data_get_all_recordids(). Here we are ensuring that the total amount of record ids is reduced to
* match the group conditions that are provided. There are 25 entries which relate to group 2. They are removed
* from the total so we should only have 75 records total.
*
* Test 6: data_get_all_recordids() again. This time we are testing approved database records. We only want to
* display the records that have been approved. In this record set we have 89 approved records.
*/
function test_advanced_search_sql_section() {
global $DB;
// Test 1
$recordids = data_get_all_recordids($this->recorddata->id);
@@ -242,4 +256,744 @@ class data_advanced_search_sql_test extends advanced_testcase {
$recordids = data_get_all_recordids($this->recorddata->id, $approvesql, $params);
$this->assertEquals($this->approvedatarecordcount, count($recordids));
}
}
/**
* Indexing database entries contents.
*
* @return void
*/
public function test_data_entries_indexing() {
global $DB;
// Returns the instance as long as the area is supported.
$searcharea = \core_search\manager::get_search_area($this->databaseentryareaid);
$this->assertInstanceOf('\mod_data\search\entry', $searcharea);
$user1 = self::getDataGenerator()->create_user();
$course1 = self::getDataGenerator()->create_course();
$this->getDataGenerator()->enrol_user($user1->id, $course1->id, 'student');
$record = new stdClass();
$record->course = $course1->id;
$this->setUser($user1);
// Available for both student and teacher.
$data1 = $this->getDataGenerator()->create_module('data', $record);
// Excluding LatLong and Picture as we aren't indexing LatLong and Picture fields any way
// ...and they're complex and not of any use to consider for this test.
// Excluding File as we are indexing files seperately and its complex to implement.
$fieldtypes = array( 'checkbox', 'date', 'menu', 'multimenu', 'number', 'radiobutton', 'text', 'textarea', 'url' );
$this->create_default_data_fields($fieldtypes, $data1);
$data1record1id = $this->create_default_data_record($data1);
// All records.
$recordset = $searcharea->get_recordset_by_timestamp(0);
$this->assertTrue($recordset->valid());
$nrecords = 0;
foreach ($recordset as $record) {
$this->assertInstanceOf('stdClass', $record);
$doc = $searcharea->get_document($record);
$this->assertInstanceOf('\core_search\document', $doc);
$nrecords++;
}
// If there would be an error/failure in the foreach above the recordset would be closed on shutdown.
$recordset->close();
$this->assertEquals(1, $nrecords);
// The +2 is to prevent race conditions.
$recordset = $searcharea->get_recordset_by_timestamp(time() + 2);
// No new records.
$this->assertFalse($recordset->valid());
$recordset->close();
}
/**
* Document contents.
*
* @return void
*/
public function test_data_entries_document() {
global $DB;
// Returns the instance as long as the area is supported.
$searcharea = \core_search\manager::get_search_area($this->databaseentryareaid);
$this->assertInstanceOf('\mod_data\search\entry', $searcharea);
$user1 = self::getDataGenerator()->create_user();
$course = self::getDataGenerator()->create_course();
$this->getDataGenerator()->enrol_user($user1->id, $course->id, 'student');
$record = new stdClass();
$record->course = $course->id;
$this->setAdminUser();
// First Case.
$data1 = $this->getDataGenerator()->create_module('data', $record);
$fieldtypes = array( 'checkbox', 'date', 'menu', 'multimenu', 'number', 'radiobutton', 'text', 'textarea', 'url' );
$this->create_default_data_fields($fieldtypes, $data1);
$data1record1id = $this->create_default_data_record($data1);
$data1entry1 = $this->get_entry_for_id($data1record1id);
$data1doc = $searcharea->get_document($data1entry1);
$this->assertEquals($data1doc->get('courseid'), $course->id);
$this->assertEquals($data1doc->get('title'), 'text for testing');
$this->assertEquals($data1doc->get('content'), 'menu1');
$this->assertEquals($data1doc->get('description1'), 'opt1');
$this->assertEquals($data1doc->get('description2'), 'opt1 opt2 opt3 opt4');
// Second Case.
$data2 = $this->getDataGenerator()->create_module('data', $record);
$fieldtypes = array(
array('checkbox', 1),
array('textarea', 0),
array('menu', 0),
array('number', 1),
array('url', 0),
array('text', 0)
);
$this->create_default_data_fields($fieldtypes, $data2);
$data2record1id = $this->create_default_data_record($data2);
$data2entry1 = $this->get_entry_for_id($data2record1id);
$data2doc = $searcharea->get_document($data2entry1);
$this->assertEquals($data2doc->get('courseid'), $course->id);
$this->assertEquals($data2doc->get('title'), 'opt1 opt2 opt3 opt4');
$this->assertEquals($data2doc->get('content'), 'text for testing');
$this->assertEquals($data2doc->get('description1'), 'menu1');
$this->assertEquals($data2doc->get('description2'), 'text area testing');
// Third Case.
$data3 = $this->getDataGenerator()->create_module('data', $record);
$fieldtypes = array( 'url' );
$this->create_default_data_fields($fieldtypes, $data3);
$data3record1id = $this->create_default_data_record($data3);
$data3entry1 = $this->get_entry_for_id($data3record1id);
$this->assertFalse($searcharea->get_document($data3entry1));
// Fourth Case.
$data4 = $this->getDataGenerator()->create_module('data', $record);
$fieldtypes = array( array('date', 1), array('text', 1));
$this->create_default_data_fields($fieldtypes, $data4);
$data4record1id = $this->create_default_data_record($data4);
$data4entry1 = $this->get_entry_for_id($data4record1id);
$this->assertFalse($searcharea->get_document($data4entry1));
// Fifth Case.
$data5 = $this->getDataGenerator()->create_module('data', $record);
$fieldtypes = array(
array('checkbox', 0),
array('number', 1),
array('text', 0),
array('date', 1),
array('textarea', 0),
array('url', 1));
$this->create_default_data_fields($fieldtypes, $data5);
$data5record1id = $this->create_default_data_record($data5);
$data5entry1 = $this->get_entry_for_id($data5record1id);
$data5doc = $searcharea->get_document($data5entry1);
$this->assertEquals($data5doc->get('courseid'), $course->id);
$this->assertEquals($data5doc->get('title'), 'http://example.url');
$this->assertEquals($data5doc->get('content'), 'text for testing');
$this->assertEquals($data5doc->get('description1'), 'opt1 opt2 opt3 opt4');
$this->assertEquals($data5doc->get('description2'), 'text area testing');
// Sixth Case.
$data6 = $this->getDataGenerator()->create_module('data', $record);
$fieldtypes = array( array('date', 1), array('number', 1));
$this->create_default_data_fields($fieldtypes, $data6);
$data6record1id = $this->create_default_data_record($data6);
$data6entry1 = $this->get_entry_for_id($data6record1id);
$data6doc = $searcharea->get_document($data6entry1);
$this->assertFalse($data6doc);
// Seventh Case.
$data7 = $this->getDataGenerator()->create_module('data', $record);
$fieldtypes = array( array('date', 1), array('number', 1),
array('text', 0), array('textarea', 0));
$this->create_default_data_fields($fieldtypes, $data7);
$data7record1id = $this->create_default_data_record($data7);
$data7entry1 = $this->get_entry_for_id($data7record1id);
$data7doc = $searcharea->get_document($data7entry1);
$this->assertEquals($data7doc->get('courseid'), $course->id);
$this->assertEquals($data7doc->get('title'), 'text for testing');
$this->assertEquals($data7doc->get('content'), 'text area testing');
// Eight Case.
$data8 = $this->getDataGenerator()->create_module('data', $record);
$fieldtypes = array('url', 'url', 'url', 'text');
$this->create_default_data_fields($fieldtypes, $data8);
$data8record1id = $this->create_default_data_record($data8);
$data8entry1 = $this->get_entry_for_id($data8record1id);
$data8doc = $searcharea->get_document($data8entry1);
$this->assertEquals($data8doc->get('courseid'), $course->id);
$this->assertEquals($data8doc->get('title'), 'text for testing');
$this->assertEquals($data8doc->get('content'), 'http://example.url');
$this->assertEquals($data8doc->get('description1'), 'http://example.url');
$this->assertEquals($data8doc->get('description2'), 'http://example.url');
// Ninth Case.
$data9 = $this->getDataGenerator()->create_module('data', $record);
$fieldtypes = array('radiobutton', 'menu', 'multimenu');
$this->create_default_data_fields($fieldtypes, $data9);
$data9record1id = $this->create_default_data_record($data9);
$data9entry1 = $this->get_entry_for_id($data9record1id);
$data9doc = $searcharea->get_document($data9entry1);
$this->assertEquals($data9doc->get('courseid'), $course->id);
$this->assertEquals($data9doc->get('title'), 'opt1');
$this->assertEquals($data9doc->get('content'), 'menu1');
$this->assertEquals($data9doc->get('description1'), 'menu1 menu2 menu3 menu4');
// Tenth Case.
$data10 = $this->getDataGenerator()->create_module('data', $record);
$fieldtypes = array('checkbox', 'textarea', 'multimenu');
$this->create_default_data_fields($fieldtypes, $data10);
$data10record1id = $this->create_default_data_record($data10);
$data10entry1 = $this->get_entry_for_id($data10record1id);
$data10doc = $searcharea->get_document($data10entry1);
$this->assertEquals($data10doc->get('courseid'), $course->id);
$this->assertEquals($data10doc->get('title'), 'opt1 opt2 opt3 opt4');
$this->assertEquals($data10doc->get('content'), 'text area testing');
$this->assertEquals($data10doc->get('description1'), 'menu1 menu2 menu3 menu4');
}
/**
* Document accesses.
*
* @return void
*/
public function test_data_entries_access() {
global $DB;
// Returns the instance as long as the area is supported.
$searcharea = \core_search\manager::get_search_area($this->databaseentryareaid);
$this->assertInstanceOf('\mod_data\search\entry', $searcharea);
$user1 = self::getDataGenerator()->create_user();
$user2 = self::getDataGenerator()->create_user();
$user3 = self::getDataGenerator()->create_user();
$userteacher1 = self::getDataGenerator()->create_user();
$course1 = self::getDataGenerator()->create_course();
$course2 = self::getDataGenerator()->create_course();
$this->getDataGenerator()->enrol_user($user1->id, $course1->id, 'student');
$this->getDataGenerator()->enrol_user($user2->id, $course1->id, 'student');
$this->getDataGenerator()->enrol_user($userteacher1->id, $course1->id, 'teacher');
$this->getDataGenerator()->enrol_user($user3->id, $course2->id, 'student');
$record = new stdClass();
$record->course = $course1->id;
$this->setUser($userteacher1);
$data1 = $this->getDataGenerator()->create_module('data', $record);
$fieldtypes = array( 'checkbox', 'date', 'menu', 'multimenu', 'number', 'radiobutton', 'text', 'textarea', 'url' );
$this->create_default_data_fields($fieldtypes, $data1);
$this->setUser($user1);
$data1record1id = $this->create_default_data_record($data1);
$this->assertEquals(\core_search\manager::ACCESS_GRANTED, $searcharea->check_access($data1record1id));
$this->assertEquals(\core_search\manager::ACCESS_DELETED, $searcharea->check_access(-1));
$this->setUser($user2);
$this->assertEquals(\core_search\manager::ACCESS_GRANTED, $searcharea->check_access($data1record1id));
$this->setUser($user3);
$this->assertEquals(\core_search\manager::ACCESS_DENIED, $searcharea->check_access($data1record1id));
$this->setUser($userteacher1);
$this->assertEquals(\core_search\manager::ACCESS_GRANTED, $searcharea->check_access($data1record1id));
$this->setAdminUser();
$this->assertEquals(\core_search\manager::ACCESS_GRANTED, $searcharea->check_access($data1record1id));
$this->setGuestUser();
$this->assertEquals(\core_search\manager::ACCESS_DENIED, $searcharea->check_access($data1record1id));
// Case with groups.
$user1 = self::getDataGenerator()->create_user();
$user2 = self::getDataGenerator()->create_user();
$user3 = self::getDataGenerator()->create_user();
$userteacher1 = self::getDataGenerator()->create_user();
$course = self::getDataGenerator()->create_course(array('groupmode' => 1, 'groupmodeforce' => 1));
$this->getDataGenerator()->enrol_user($user1->id, $course->id, 'student');
$this->getDataGenerator()->enrol_user($user2->id, $course->id, 'student');
$this->getDataGenerator()->enrol_user($userteacher1->id, $course->id, 'teacher');
$this->getDataGenerator()->enrol_user($user3->id, $course->id, 'student');
$groupa = $this->getDataGenerator()->create_group(array('courseid' => $course->id, 'name' => 'groupA'));
$groupb = $this->getDataGenerator()->create_group(array('courseid' => $course->id, 'name' => 'groupB'));
$this->getDataGenerator()->create_group_member(array('userid' => $user1->id, 'groupid' => $groupa->id));
$this->getDataGenerator()->create_group_member(array('userid' => $user2->id, 'groupid' => $groupa->id));
$this->getDataGenerator()->create_group_member(array('userid' => $userteacher1->id, 'groupid' => $groupa->id));
$this->getDataGenerator()->create_group_member(array('userid' => $user3->id, 'groupid' => $groupb->id));
$record = new stdClass();
$record->course = $course->id;
$this->setUser($userteacher1);
$data2 = $this->getDataGenerator()->create_module('data', $record);
$cm = get_coursemodule_from_instance('data', $data2->id, $course->id);
$cm->groupmode = '1';
$cm->effectivegroupmode = '1';
$fieldtypes = array( 'checkbox', 'date', 'menu', 'multimenu', 'number', 'radiobutton', 'text', 'textarea', 'url' );
$this->create_default_data_fields($fieldtypes, $data2);
$this->setUser($user1);
$data2record1id = $this->create_default_data_record($data2, $groupa->id);
$this->assertEquals(\core_search\manager::ACCESS_GRANTED, $searcharea->check_access($data2record1id));
$this->assertEquals(\core_search\manager::ACCESS_DELETED, $searcharea->check_access(-1));
$this->setUser($user2);
$this->assertEquals(\core_search\manager::ACCESS_GRANTED, $searcharea->check_access($data2record1id));
$this->setUser($user3);
$this->assertEquals(\core_search\manager::ACCESS_DENIED, $searcharea->check_access($data2record1id));
$this->setUser($userteacher1);
$this->assertEquals(\core_search\manager::ACCESS_GRANTED, $searcharea->check_access($data2record1id));
$this->setAdminUser();
$this->assertEquals(\core_search\manager::ACCESS_GRANTED, $searcharea->check_access($data2record1id));
$this->setGuestUser();
$this->assertEquals(\core_search\manager::ACCESS_DENIED, $searcharea->check_access($data2record1id));
// Case with approval.
$user1 = self::getDataGenerator()->create_user();
$user2 = self::getDataGenerator()->create_user();
$userteacher1 = self::getDataGenerator()->create_user();
$course = self::getDataGenerator()->create_course();
$this->getDataGenerator()->enrol_user($user1->id, $course->id, 'student');
$this->getDataGenerator()->enrol_user($user2->id, $course->id, 'student');
$this->getDataGenerator()->enrol_user($userteacher1->id, $course->id, 'teacher');
$record = new stdClass();
$record->course = $course->id;
$this->setUser($userteacher1);
$data3 = $this->getDataGenerator()->create_module('data', $record);
$DB->update_record('data', array('id' => $data3->id, 'approval' => 1));
$fieldtypes = array( 'checkbox', 'date', 'menu', 'multimenu', 'number', 'radiobutton', 'text', 'textarea', 'url' );
$this->create_default_data_fields($fieldtypes, $data3);
$this->setUser($user1);
$data3record1id = $this->create_default_data_record($data3);
$this->assertEquals(\core_search\manager::ACCESS_GRANTED, $searcharea->check_access($data3record1id));
$this->assertEquals(\core_search\manager::ACCESS_DELETED, $searcharea->check_access(-1));
$this->setUser($user2);
$this->assertEquals(\core_search\manager::ACCESS_DENIED, $searcharea->check_access($data3record1id));
$this->setUser($userteacher1);
$this->assertEquals(\core_search\manager::ACCESS_GRANTED, $searcharea->check_access($data3record1id));
$this->setAdminUser();
$this->assertEquals(\core_search\manager::ACCESS_GRANTED, $searcharea->check_access($data3record1id));
$this->setGuestUser();
$this->assertEquals(\core_search\manager::ACCESS_DENIED, $searcharea->check_access($data3record1id));
$DB->update_record('data_records', array('id' => $data3record1id, 'approved' => 1));
$this->setUser($user1);
$this->assertEquals(\core_search\manager::ACCESS_GRANTED, $searcharea->check_access($data3record1id));
$this->assertEquals(\core_search\manager::ACCESS_DELETED, $searcharea->check_access(-1));
$this->setUser($user2);
$this->assertEquals(\core_search\manager::ACCESS_GRANTED, $searcharea->check_access($data3record1id));
$this->setUser($userteacher1);
$this->assertEquals(\core_search\manager::ACCESS_GRANTED, $searcharea->check_access($data3record1id));
$this->setAdminUser();
$this->assertEquals(\core_search\manager::ACCESS_GRANTED, $searcharea->check_access($data3record1id));
$this->setGuestUser();
$this->assertEquals(\core_search\manager::ACCESS_DENIED, $searcharea->check_access($data3record1id));
// Case with requiredentriestoview.
$this->setAdminUser();
$record->requiredentriestoview = 2;
$data4 = $this->getDataGenerator()->create_module('data', $record);
$fieldtypes = array( 'checkbox', 'date', 'menu', 'multimenu', 'number', 'radiobutton', 'text', 'textarea', 'url' );
$this->create_default_data_fields($fieldtypes, $data4);
$data4record1id = $this->create_default_data_record($data4);
$this->setUser($user1);
$this->assertEquals(\core_search\manager::ACCESS_DENIED, $searcharea->check_access($data4record1id));
$data4record2id = $this->create_default_data_record($data4);
$this->assertEquals(\core_search\manager::ACCESS_GRANTED, $searcharea->check_access($data4record1id));
$this->assertEquals(\core_search\manager::ACCESS_GRANTED, $searcharea->check_access($data4record2id));
}
/**
* Test for file contents.
*
* @return void
*/
public function test_attach_files() {
global $DB, $USER;
$fs = get_file_storage();
// Returns the instance as long as the area is supported.
$searcharea = \core_search\manager::get_search_area($this->databaseentryareaid);
$this->assertInstanceOf('\mod_data\search\entry', $searcharea);
$user1 = self::getDataGenerator()->create_user();
$course = self::getDataGenerator()->create_course();
$this->getDataGenerator()->enrol_user($user1->id, $course->id, 'student');
$record = new stdClass();
$record->course = $course->id;
$this->setAdminUser();
// Creating database activity instance.
$data1 = $this->getDataGenerator()->create_module('data', $record);
// Creating file field.
$record = new stdClass;
$record->type = 'file';
$record->dataid = $data1->id;
$record->required = 0;
$record->name = 'FileFld';
$record->description = 'Just another file field';
$record->param3 = 0;
$record->param1 = '';
$record->param2 = '';
$data1filefieldid = $DB->insert_record('data_fields', $record);
// Creating text field.
$record = new stdClass;
$record->type = 'text';
$record->dataid = $data1->id;
$record->required = 0;
$record->name = 'TextFld';
$record->description = 'Just another text field';
$record->param3 = 0;
$record->param1 = '';
$record->param2 = '';
$data1textfieldid = $DB->insert_record('data_fields', $record);
// Creating textarea field.
$record = new stdClass;
$record->type = 'textarea';
$record->dataid = $data1->id;
$record->required = 0;
$record->name = 'TextAreaFld';
$record->description = 'Just another textarea field';
$record->param1 = '';
$record->param2 = 60;
$record->param3 = 35;
$record->param3 = 1;
$record->param3 = 0;
$data1textareafieldid = $DB->insert_record('data_fields', $record);
// Creating 1st entry.
$record = new stdClass;
$record->userid = $USER->id;
$record->dataid = $data1->id;
$record->groupid = 0;
$data1record1id = $DB->insert_record('data_records', $record);
$filerecord = array(
'contextid' => context_module::instance($data1->cmid)->id,
'component' => 'mod_data',
'filearea' => 'content',
'itemid' => $data1record1id,
'filepath' => '/',
'filename' => 'myfile1.txt'
);
$data1record1file = $fs->create_file_from_string($filerecord, 'Some contents 1');
$record = new stdClass;
$record->fieldid = $data1filefieldid;
$record->recordid = $data1record1id;
$record->content = 'myfile1.txt';
$DB->insert_record('data_content', $record);
$record = new stdClass;
$record->fieldid = $data1textfieldid;
$record->recordid = $data1record1id;
$record->content = 'sample text';
$DB->insert_record('data_content', $record);
$record = new stdClass;
$record->fieldid = $data1textareafieldid;
$record->recordid = $data1record1id;
$record->content = '<br>sample text<p /><br/>';
$record->content1 = 1;
$DB->insert_record('data_content', $record);
// Creating 2nd entry.
$record = new stdClass;
$record->userid = $USER->id;
$record->dataid = $data1->id;
$record->groupid = 0;
$data1record2id = $DB->insert_record('data_records', $record);
$filerecord['itemid'] = $data1record2id;
$filerecord['filename'] = 'myfile2.txt';
$data1record2file = $fs->create_file_from_string($filerecord, 'Some contents 2');
$record = new stdClass;
$record->fieldid = $data1filefieldid;
$record->recordid = $data1record2id;
$record->content = 'myfile2.txt';
$DB->insert_record('data_content', $record);
$record = new stdClass;
$record->fieldid = $data1textfieldid;
$record->recordid = $data1record2id;
$record->content = 'sample text';
$DB->insert_record('data_content', $record);
$record = new stdClass;
$record->fieldid = $data1textareafieldid;
$record->recordid = $data1record2id;
$record->content = '<br>sample text<p /><br/>';
$record->content1 = 1;
$DB->insert_record('data_content', $record);
// Now get all the posts and see if they have the right files attached.
$searcharea = \core_search\manager::get_search_area($this->databaseentryareaid);
$recordset = $searcharea->get_recordset_by_timestamp(0);
$nrecords = 0;
foreach ($recordset as $record) {
$doc = $searcharea->get_document($record);
$searcharea->attach_files($doc);
$files = $doc->get_files();
// Now check that each doc has the right files on it.
switch ($doc->get('itemid')) {
case ($data1record1id):
$this->assertCount(1, $files);
$this->assertEquals($data1record1file->get_id(), $files[$data1record1file->get_id()]->get_id());
break;
case ($data1record2id):
$this->assertCount(1, $files);
$this->assertEquals($data1record2file->get_id(), $files[$data1record2file->get_id()]->get_id());
break;
default:
$this->fail('Unexpected entry returned');
break;
}
$nrecords++;
}
$recordset->close();
$this->assertEquals(2, $nrecords);
}
/**
* Creates default fields for a database instance
*
* @param array $fieldtypes
* @param mod_data $data
* @return void
*/
protected function create_default_data_fields($fieldtypes = array(), $data) {
$count = 1;
// Creating test Fields with default parameter values.
foreach ($fieldtypes as $fieldtype) {
// Creating variables dynamically.
$fieldname = 'field-'.$count;
$record = new stdClass();
$record->name = $fieldname;
if (is_array($fieldtype)) {
$record->type = $fieldtype[0];
$record->required = $fieldtype[1];
} else {
$record->type = $fieldtype;
$record->required = 0;
}
${$fieldname} = $this->getDataGenerator()->get_plugin_generator('mod_data')->create_field($record, $data);
$count++;
}
}
/**
* Creates default database entry content values for default field param values
*
* @param mod_data $data
* @param int $groupid
* @return int
*/
protected function create_default_data_record($data, $groupid = 0) {
global $DB;
$fields = $DB->get_records('data_fields', array('dataid' => $data->id));
$fieldcontents = array();
foreach ($fields as $fieldrecord) {
switch ($fieldrecord->type) {
case 'checkbox':
$fieldcontents[$fieldrecord->id] = array('opt1', 'opt2', 'opt3', 'opt4');
break;
case 'multimenu':
$fieldcontents[$fieldrecord->id] = array('menu1', 'menu2', 'menu3', 'menu4');
break;
case 'date':
$fieldcontents[$fieldrecord->id] = '27-07-2016';
break;
case 'menu':
$fieldcontents[$fieldrecord->id] = 'menu1';
break;
case 'radiobutton':
$fieldcontents[$fieldrecord->id] = 'opt1';
break;
case 'number':
$fieldcontents[$fieldrecord->id] = '12345';
break;
case 'text':
$fieldcontents[$fieldrecord->id] = 'text for testing';
break;
case 'textarea':
$fieldcontents[$fieldrecord->id] = '<p>text area testing<br /></p>';
break;
case 'url':
$fieldcontents[$fieldrecord->id] = array('example.url', 'sampleurl');
break;
default:
$this->fail('Unexpected field type');
break;
}
}
return $this->getDataGenerator()->get_plugin_generator('mod_data')->create_entry($data, $fieldcontents, $groupid);
}
/**
* Creates default database entry content values for default field param values
*
* @param int $recordid
* @return stdClass
*/
protected function get_entry_for_id($recordid ) {
global $DB;
$sql = "SELECT dr.*, d.course
FROM {data_records} dr
JOIN {data} d ON d.id = dr.dataid
WHERE dr.id = :drid";
return $DB->get_record_sql($sql, array('drid' => $recordid));
}
}