MDL-59030 analytics: Social breadth accepting more than level 2
[moodle.git] / course / classes / analytics / indicator / potential_social_breadth.php
1 <?php
2 // This file is part of Moodle - http://moodle.org/
3 //
4 // Moodle is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // Moodle is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
17 /**
18  * Potential social breadth indicator.
19  *
20  * @package   core_course
21  * @copyright 2017 David Monllao {@link http://www.davidmonllao.com}
22  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23  */
25 namespace core_course\analytics\indicator;
27 defined('MOODLE_INTERNAL') || die();
29 use \core_analytics\local\indicator\community_of_inquiry_activity;
31 /**
32  * Potential social breadth indicator.
33  *
34  * It extends linear instead of discrete as there is a linear relation between
35  * the different social levels activities can reach.
36  *
37  * @package   core_course
38  * @copyright 2017 David Monllao {@link http://www.davidmonllao.com}
39  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
40  */
41 class potential_social_breadth extends \core_analytics\local\indicator\linear {
43     /**
44      * get_name
45      *
46      * @return \lang_string
47      */
48     public static function get_name() : \lang_string {
49         return new \lang_string('indicator:potentialsocial', 'moodle');
50     }
52     /**
53      * Specify the required data to process this indicator.
54      *
55      * @return string[]
56      */
57     public static function required_sample_data() {
58         // We require course because, although this indicator can also work with course_modules we can't
59         // calculate anything without the course.
60         return array('course');
61     }
63     /**
64      * calculate_sample
65      *
66      * @param int $sampleid
67      * @param string $sampleorigin
68      * @param int|false $notusedstarttime
69      * @param int|false $notusedendtime
70      * @return float
71      */
72     public function calculate_sample($sampleid, $sampleorigin, $notusedstarttime = false, $notusedendtime = false) {
74         if ($sampleorigin === 'course_modules') {
75             $cm = $this->retrieve('course_modules', $sampleid);
76             $cminfo = \cm_info::create($cm);
78             $socialbreadthindicator = $this->get_social_indicator($cminfo->modname);
79             $potentiallevel = $socialbreadthindicator->get_social_breadth_level($cminfo);
80             if ($potentiallevel > community_of_inquiry_activity::MAX_SOCIAL_LEVEL) {
81                 $this->level_not_accepted($potentiallevel);
82             }
84         } else {
85             $course = $this->retrieve('course', $sampleid);
86             $modinfo = get_fast_modinfo($course);
88             $cms = $modinfo->get_cms();
89             if (!$cms) {
90                 return self::get_min_value();
91             }
93             $potentiallevel = 0;
94             foreach ($cms as $cm) {
95                 if (!$socialbreadthindicator = $this->get_social_indicator($cm->modname)) {
96                     continue;
97                 }
98                 $level = $socialbreadthindicator->get_social_breadth_level($cm);
99                 if ($level > community_of_inquiry_activity::MAX_SOCIAL_LEVEL) {
100                     $this->level_not_accepted($level);
101                 }
102                 if ($level > $potentiallevel) {
103                     $potentiallevel = $level;
104                 }
105             }
106         }
108         // Core activities social breadth only reaches level 2, until core activities social
109         // breadth do not reach level 5 we limit it to what we currently support, which is level 2.
110         if ($potentiallevel > 2) {
111             $potentiallevel = 2;
112         }
114         // Supporting only social breadth level 1 and 2 the possible values are -1 or 1.
115         $levelscore = round(self::get_max_value() - self::get_min_value(), 2);
117         // We substract $levelscore because we want to start from the lower socre and there is no cognitive depth level 0.
118         return self::get_min_value() + ($levelscore * $potentiallevel) - $levelscore;
119     }
121     /**
122      * Returns the social breadth class of this indicator.
123      *
124      * @param string $modname
125      * @return \core_analytics\local\indicator\base|false
126      */
127     protected function get_social_indicator($modname) {
128         $indicators = \core_analytics\manager::get_all_indicators();
129         foreach ($indicators as $indicator) {
130             if ($indicator instanceof community_of_inquiry_activity &&
131                     $indicator->get_indicator_type() === community_of_inquiry_activity::INDICATOR_SOCIAL &&
132                     $indicator->get_activity_type() === $modname) {
133                 return $indicator;
134             }
135         }
136         return false;
137     }
139     /**
140      * Throw a \coding_exception.
141      *
142      * @param int $level
143      */
144     protected function level_not_accepted($level) {
145         throw new \coding_exception('Activities\' potential social breadth go from 1 to ' .
146             community_of_inquiry_activity::MAX_SOCIAL_LEVEL . '.');
147     }