Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 4.0.x will end 8 May 2023 (12 months).
  • Bug fixes for security issues in 4.0.x will end 13 November 2023 (18 months).
  • PHP version: minimum PHP 7.3.0 Note: the minimum PHP version has increased since Moodle 3.10. PHP 7.4.x is also supported.
   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/>.
  16  
  17  declare(strict_types=1);
  18  
  19  namespace core_cohort\reportbuilder\audience;
  20  
  21  use context;
  22  use context_system;
  23  use core_course_category;
  24  use stdClass;
  25  use core_reportbuilder\local\audiences\base;
  26  use core_reportbuilder\local\helpers\database;
  27  use MoodleQuickForm;
  28  
  29  /**
  30   * The backend class for Cohort member audience type
  31   *
  32   * @package     core_reportbuilder
  33   * @copyright   2021 David Matamoros <davidmc@moodle.com>
  34   * @license     http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  35   */
  36  class cohortmember extends base {
  37  
  38      /**
  39       * Adds audience's elements to the given mform
  40       *
  41       * @param MoodleQuickForm $mform The form to add elements to
  42       */
  43      public function get_config_form(MoodleQuickForm $mform): void {
  44          $cohorts = self::get_cohorts();
  45          $mform->addElement('autocomplete', 'cohorts', get_string('selectfromcohort', 'cohort'),
  46              $cohorts, ['multiple' => true]);
  47          $mform->addRule('cohorts', null, 'required', null, 'client');
  48      }
  49  
  50      /**
  51       * Helps to build SQL to retrieve users that matches the current report audience
  52       *
  53       * @param string $usertablealias
  54       * @return array array of three elements [$join, $where, $params]
  55       */
  56      public function get_sql(string $usertablealias): array {
  57          global $DB;
  58  
  59          $cm = database::generate_alias();
  60          $cohorts = $this->get_configdata()['cohorts'];
  61          $prefix = database::generate_param_name() . '_';
  62          [$insql, $inparams] = $DB->get_in_or_equal($cohorts, SQL_PARAMS_NAMED, $prefix);
  63  
  64          $join = "JOIN {cohort_members} {$cm}
  65                     ON ({$cm}.userid = {$usertablealias}.id)";
  66  
  67          return [$join, "{$cm}.cohortid " . $insql, $inparams];
  68      }
  69  
  70      /**
  71       * Return user friendly name of this audience type
  72       *
  73       * @return string
  74       */
  75      public function get_name(): string {
  76          return get_string('memberofcohort', 'cohort');
  77      }
  78  
  79      /**
  80       * Return the description for the audience.
  81       *
  82       * @return string
  83       */
  84      public function get_description(): string {
  85          global $DB;
  86  
  87          $cohortlist = [];
  88  
  89          $cohortids = $this->get_configdata()['cohorts'];
  90          $cohorts = $DB->get_records_list('cohort', 'id', $cohortids, 'name');
  91          foreach ($cohorts as $cohort) {
  92              $cohortlist[] = format_string($cohort->name, true, ['context' => $cohort->contextid, 'escape' => false]);
  93          }
  94  
  95          return $this->format_description_for_multiselect($cohortlist);
  96      }
  97  
  98      /**
  99       * If the current user is able to add this audience.
 100       *
 101       * @return bool
 102       */
 103      public function user_can_add(): bool {
 104          // Check system context first.
 105          if (has_capability('moodle/cohort:view', context_system::instance())) {
 106              return true;
 107          }
 108          // If there is at least one category with given permissions, user can add.
 109          return !empty(core_course_category::make_categories_list('moodle/cohort:view'));
 110      }
 111  
 112      /**
 113       * Returns if this audience type is available for the user
 114       *
 115       * Check if there are available cohorts in the system for this user to use.
 116       *
 117       * @return bool
 118       */
 119      public function is_available(): bool {
 120          return !empty(self::get_cohorts());
 121      }
 122  
 123      /**
 124       * If the current user is able to edit this audience.
 125       *
 126       * @return bool
 127       */
 128      public function user_can_edit(): bool {
 129          global $DB;
 130  
 131          $canedit = true;
 132          $cohortids = $this->get_configdata()['cohorts'];
 133          $cohorts = $DB->get_records_list('cohort', 'id', $cohortids);
 134          foreach ($cohorts as $cohort) {
 135              $context = context::instance_by_id($cohort->contextid, MUST_EXIST);
 136              $canedit = $canedit && has_capability('moodle/cohort:view', $context);
 137              if ($canedit === false) {
 138                  break;
 139              }
 140          }
 141  
 142          return $canedit;
 143      }
 144  
 145      /**
 146       * Cohorts selector.
 147       *
 148       * @return array
 149       */
 150      private static function get_cohorts(): array {
 151          global $CFG;
 152  
 153          require_once($CFG->dirroot.'/cohort/lib.php');
 154  
 155          $cohortslist = [];
 156  
 157          // Search cohorts user can view.
 158          $usercohorts = cohort_get_all_cohorts(0, 0);
 159  
 160          // The previous method doesn't check cohorts on system context.
 161          $syscontext = context_system::instance();
 162          $cohorts = array_filter($usercohorts['cohorts'], static function(stdClass $cohort) use ($syscontext): bool {
 163              return ($cohort->contextid != $syscontext->id) || has_capability('moodle/cohort:view', $syscontext);
 164          });
 165  
 166          foreach ($cohorts as $cohort) {
 167              $cohortslist[$cohort->id] = format_string($cohort->name, true, [
 168                  'context' => $cohort->contextid,
 169                  'escape' => false,
 170              ]);
 171          }
 172  
 173          return $cohortslist;
 174      }
 175  }