diff --git a/mod/data/classes/search/entry.php b/mod/data/classes/search/entry.php
new file mode 100644
index 00000000000..0a2e8ceb641
--- /dev/null
+++ b/mod/data/classes/search/entry.php
@@ -0,0 +1,330 @@
+.
+
+/**
+ * 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;
+ }
+
+}
\ No newline at end of file
diff --git a/mod/data/classes/search/sortedcontentqueue.php b/mod/data/classes/search/sortedcontentqueue.php
new file mode 100644
index 00000000000..12a555b47c5
--- /dev/null
+++ b/mod/data/classes/search/sortedcontentqueue.php
@@ -0,0 +1,80 @@
+.
+
+/**
+ * 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;
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/mod/data/field/checkbox/field.class.php b/mod/data/field/checkbox/field.class.php
index c1b60a836f5..c8675d98c35 100644
--- a/mod/data/field/checkbox/field.class.php
+++ b/mod/data/field/checkbox/field.class.php
@@ -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);
+ }
}
diff --git a/mod/data/field/menu/field.class.php b/mod/data/field/menu/field.class.php
index 53e2d4f0410..1b62356e460 100644
--- a/mod/data/field/menu/field.class.php
+++ b/mod/data/field/menu/field.class.php
@@ -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;
diff --git a/mod/data/field/multimenu/field.class.php b/mod/data/field/multimenu/field.class.php
index 34beb47d41b..fb7e290b6c2 100644
--- a/mod/data/field/multimenu/field.class.php
+++ b/mod/data/field/multimenu/field.class.php
@@ -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);
+ }
+
}
diff --git a/mod/data/field/radiobutton/field.class.php b/mod/data/field/radiobutton/field.class.php
index 6dd1d3ecee3..dbc5c1e29ed 100644
--- a/mod/data/field/radiobutton/field.class.php
+++ b/mod/data/field/radiobutton/field.class.php
@@ -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;
diff --git a/mod/data/field/text/field.class.php b/mod/data/field/text/field.class.php
index 9489db71f3b..dd72649249e 100644
--- a/mod/data/field/text/field.class.php
+++ b/mod/data/field/text/field.class.php
@@ -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 '' . '';
diff --git a/mod/data/field/textarea/field.class.php b/mod/data/field/textarea/field.class.php
index 659fed60b2d..a6d6248c1d2 100644
--- a/mod/data/field/textarea/field.class.php
+++ b/mod/data/field/textarea/field.class.php
@@ -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);
+ }
+
}
diff --git a/mod/data/field/url/field.class.php b/mod/data/field/url/field.class.php
index 521891146b3..6769c81a764 100644
--- a/mod/data/field/url/field.class.php
+++ b/mod/data/field/url/field.class.php
@@ -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;
diff --git a/mod/data/lang/en/data.php b/mod/data/lang/en/data.php
index a8127e0dfa1..4b0e332b58b 100644
--- a/mod/data/lang/en/data.php
+++ b/mod/data/lang/en/data.php
@@ -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';
diff --git a/mod/data/lib.php b/mod/data/lib.php
index 6c03edf4921..5accbeb46ab 100644
--- a/mod/data/lib.php
+++ b/mod/data/lib.php
@@ -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);
+ }
}
diff --git a/mod/data/tests/generator/lib.php b/mod/data/tests/generator/lib.php
index 86480c91e21..e511bbb8788 100644
--- a/mod/data/tests/generator/lib.php
+++ b/mod/data/tests/generator/lib.php
@@ -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);
diff --git a/mod/data/tests/generator_test.php b/mod/data/tests/generator_test.php
index c554423f66f..ebcfa335dec 100644
--- a/mod/data/tests/generator_test.php
+++ b/mod/data/tests/generator_test.php
@@ -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[] = '
text area testing
';
$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, 'text area testing
');
+ $this->assertEquals($contents[$contentstartid]->content1, '1');
+ $this->assertEquals($contents[++$contentstartid]->content, 'http://example.url');
+ $this->assertEquals($contents[$contentstartid]->content1, 'sampleurl');
}
-}
+}
\ No newline at end of file
diff --git a/mod/data/tests/search_test.php b/mod/data/tests/search_test.php
index 1e54d95e9d2..ee6b073ddae 100644
--- a/mod/data/tests/search_test.php
+++ b/mod/data/tests/search_test.php
@@ -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 = '
sample text
';
+ $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 = '
sample text
';
+ $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] = 'text area testing
';
+ 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));
+ }
+
+}
\ No newline at end of file