/** * Finds the module id from a resource instance, which is needed for the "get_cm($moduleid)" function, to get module's name. * For that, uses the courses instances information, retrieved using "get_fast_modinfo($courseid)" function. * * @param array $instances Key is resource type name, and value is an array of each instance of the course of that type. * @param int $resourceid The resource we are finding the moduleid of. * @param int $courseid The course the module belongs to. * @return int Module id. */ public static function get_resource_moduleid($instances, $resourceid, $courseid) { $db = new database_helper(); foreach ($instances as $instancetype => $typeinstances) { $typeinstancesids = array_keys($typeinstances); if (in_array($resourceid, $typeinstancesids)) { $typeid = $db->get_module_type_id_by_name($instancetype); $moduleid = $db->get_module_id($courseid, $resourceid, $typeid); break; } } return $moduleid; }
/** * Given the data of the historic users and the current ones, creates a matrix of association coefficients, with the * current users as rows, and the historic user as columns. * * @see cosine_similarity($vector1, $vector2). * @param array $currentdata A 2D array. * @param array $historicdata A 2D array. * @param \text_progress_trace $trace Text output trace. * @return array The association matrix; empty if no association could be made. */ public function create_associations_matrix($currentdata, $historicdata, $trace) { $db = new database_helper(); $trace->output("[mycourse " . date('d/m/Y H:i:s') . "]: Starting creation of associations matrix."); $trace->output("[mycourse " . date('d/m/Y H:i:s') . "]: Transforming receiving data to get a matrix of users x resources. " . " with the views as values."); $currenttransformeddata = $this->matrix->transform_queried_data($currentdata); $historictransformeddata = $this->matrix->transform_queried_data($historicdata); $trace->output('[mycourse ' . date('d/m/Y H:i:s') . ']: Both historic and current data have been transformed.'); $currentusers = array_keys($currenttransformeddata); $historicusers = array_keys($historictransformeddata); $matrix = array(); foreach ($currentusers as $currentuser) { $trace->output('[mycourse ' . date('d/m/Y H:i:s') . "]: Starting calculating associations for current user " . "{$currentuser}."); $currentviewsvector = $currenttransformeddata[$currentuser]; $similarities = null; foreach ($historicusers as $historicuser) { $historicviewsvector = $historictransformeddata[$historicuser]; $trace->output('[mycourse ' . date('d/m/Y H:i:s') . "]: Starting calculating cosine similarity between a vector " . "of " . count($currentviewsvector) . " elements with a vector of " . count($historicviewsvector) . " elements."); $similarity = $this->cosine_similarity($currentviewsvector, $historicviewsvector); $trace->output('[mycourse ' . date('d/m/Y H:i:s') . ']: Cosine similarity between those vectors has been ' . 'calculated.'); $similarity = round($similarity, 4); $similarities[$historicuser] = $similarity; $db->insert_similarity($currentuser, $historicuser, $similarity, $this->currentweek); } $matrix[$currentuser] = $similarities; $trace->output('[mycourse ' . date('d/m/Y H:i:s') . "]: Similarities for current user {$currentuser} have been " . "calculated."); } return $matrix; }
/** * Performs the data importation from Moodle core tables (courses, enrolled users, logs). This importation is done only if * database_helper->has_data_to_be_imported() returns true. * * @param int $courseid The current course id for which the data has to be imported. */ protected function import_data($courseid) { $courseyear = $this->db->get_course_start_week_and_year($courseid)['year']; $previouscourses = $this->db->find_course_previous_teaching_ids_core_tables($courseid, $courseyear); foreach ($previouscourses as $previouscourse) { $this->db->dump_previous_core_info_to_historic_tables($previouscourse); } $previouscourses = $this->db->find_course_previous_teachings_ids_historic_tables($courseid, $courseyear); $this->db->insert_courses_associations($courseid, $previouscourses); }
/** * Initializes the course, when is the first instance of the block, looking if it is personalizable or not, and * saving this in database. * * Currently, the students are being selected independently the course is personalizable or not, because maybe later * a csv importation is made, and like this there's no need to select students later. * * @param int $courseid The course where the first instance of this block has been loaded in. * @param int $courseyear The start year of the course. */ private function initialize_course($courseid, $courseyear) { $this->recommendator->select_students($courseid, $courseyear); $personalizable = course_filter::is_course_personalizable($courseid, $courseyear); if ($personalizable) { $this->db->insert_course_selection($courseid, $courseyear, 1); } else { $this->db->insert_course_selection($courseid, $courseyear, 0); } }
/** * Given the course identificator, selects, randomly, 50% of the students enrolled in the course, * who will be the ones receiving the personalized recommendations. * "array_rand" function returns the randomly selected keys, not values, so, we have to construct * manually the array with random users. * * @param int $courseid The course to select students from. * @param int $year The year the given course belongs to. */ public function select_students($courseid, $year) { $coursestudents = $this->db->get_students_from_course($courseid); $count = count($coursestudents); $selectedstudentsindexes = array_rand($coursestudents, $count / 2); $selectedstudents = array(); foreach ($selectedstudentsindexes as $selectedindex) { $selectedstudent = $coursestudents[$selectedindex]; array_push($selectedstudents, $selectedstudent); } $this->db->insert_selections($selectedstudents, $courseid, $year); }
/** * Imports the log views defined in the csv file, iterating each row. This is made under the transaction initiated in * import_data function. * * @param object $logsfile Course csv file. * @param object $formdata Submitted form data, needed to load the csv. * @param int $courseid Generated course id in this transaction. * @param \block_mycourse_recommendations\database_helper $db Database handler object, passed as argument to instance it * again. */ public static function import_logs($logsfile, $formdata, $courseid, $db) { $iid = \csv_import_reader::get_new_iid('logsfile'); $csvreader = new \csv_import_reader($iid, 'logsfile'); $csvreader->load_csv_content($logsfile, $formdata->encoding, $formdata->delimiter_name); $csvreader->init(); $fields = $csvreader->get_columns(); while ($fields) { $userid = $fields[0]; $resourcename = $fields[1]; $resourcetype = $fields[2]; $resourceid = $fields[3]; $views = $fields[4]; $timecreated = $fields[5]; $db->insert_historic_logs($userid, $courseid, $resourcename, $resourcetype, $resourceid, $views, $timecreated); self::$lastinsertedlogs++; $fields = $csvreader->next(); } $csvreader->close(); }
/** * Determines if the course has had the minimum number of students in previous teachings. * First, looks into Moodle core tables for existing previous students. If it doesn't find any, it tries luck in * plugin's historic table. If it doesn't found neither here, means that the course has not previous students. * * @param int $courseid The course to determine if meets the minimum students. * @param int $currentyear The year of the given current course. * @param \block_mycourse_recommendations\database_helper $db The object with deals with database. * @return boolean If the given course has the minimum students or not. */ public static function meets_minimum_previous_students($courseid, $currentyear, $db) { $previousstudents = $db->get_previous_courses_students_number_core_tables($courseid, $currentyear); $minimum = false; if ($previousstudents >= self::MINIMUM_PREVIOUS_STUDENTS) { $minimum = true; } if (!$minimum) { $previousstudents = $db->get_previous_courses_resources_number_historic_tables($courseid, $currentyear); if ($previousstudents >= self::MINIMUM_PREVIOUS_STUDENTS) { $minimum = true; } } return $minimum; }