Search moodle.org's
Developer Documentation

See Release Notes
Long Term Support Release

  • Bug fixes for general core bugs in 4.1.x will end 13 November 2023 (12 months).
  • Bug fixes for security issues in 4.1.x will end 10 November 2025 (36 months).
  • PHP version: minimum PHP 7.4.0 Note: minimum PHP version has increased since Moodle 4.0. PHP 8.0.x is supported too.
   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  /**
  18   * Plugin version and other meta-data are defined here.
  19   *
  20   * @package     tool_policy
  21   * @copyright   2018 David Mudrák <david@moodle.com>
  22   * @license     http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  23   */
  24  
  25  defined('MOODLE_INTERNAL') || die();
  26  
  27  use core_user\output\myprofile\tree;
  28  use tool_policy\api;
  29  use tool_policy\policy_version;
  30  
  31  /**
  32   * Add nodes to myprofile page.
  33   *
  34   * @param tree $tree Tree object
  35   * @param stdClass $user User object
  36   * @param bool $iscurrentuser
  37   * @param stdClass $course Course object
  38   * @return bool
  39   * @throws coding_exception
  40   * @throws dml_exception
  41   * @throws moodle_exception
  42   */
  43  function tool_policy_myprofile_navigation(tree $tree, $user, $iscurrentuser, $course) {
  44      global $CFG;
  45  
  46      // Do nothing if we are not set as the site policies handler.
  47      if (empty($CFG->sitepolicyhandler) || $CFG->sitepolicyhandler !== 'tool_policy') {
  48          return;
  49      }
  50  
  51      // Get the Privacy and policies category.
  52      if (!array_key_exists('privacyandpolicies', $tree->__get('categories'))) {
  53          // Create the category.
  54          $categoryname = get_string('privacyandpolicies', 'admin');
  55          $category = new core_user\output\myprofile\category('privacyandpolicies', $categoryname, 'contact');
  56          $tree->add_category($category);
  57      } else {
  58          // Get the existing category.
  59          $category = $tree->__get('categories')['privacyandpolicies'];
  60      }
  61  
  62      // Add "Policies and agreements" node only for current user or users who can accept on behalf of current user.
  63      $usercontext = \context_user::instance($user->id);
  64      if ($iscurrentuser || has_capability('tool/policy:acceptbehalf', $usercontext)) {
  65          $url = new moodle_url('/admin/tool/policy/user.php', ['userid' => $user->id]);
  66          $node = new core_user\output\myprofile\node('privacyandpolicies', 'tool_policy',
  67              get_string('policiesagreements', 'tool_policy'), null, $url);
  68          $category->add_node($node);
  69      }
  70  
  71      return true;
  72  }
  73  
  74  /**
  75   * Load policy message for guests.
  76   *
  77   * @return string The HTML code to insert before the head.
  78   */
  79  function tool_policy_before_standard_html_head() {
  80      global $CFG, $PAGE, $USER;
  81  
  82      $message = null;
  83      if (!empty($CFG->sitepolicyhandler)
  84              && $CFG->sitepolicyhandler == 'tool_policy'
  85              && empty($USER->policyagreed)
  86              && (isguestuser() || !isloggedin())) {
  87          $output = $PAGE->get_renderer('tool_policy');
  88          try {
  89              $page = new \tool_policy\output\guestconsent();
  90              $message = $output->render($page);
  91          } catch (dml_read_exception $e) {
  92              // During upgrades, the new plugin code with new SQL could be in place but the DB not upgraded yet.
  93              $message = null;
  94          }
  95      }
  96  
  97      return $message;
  98  }
  99  
 100  /**
 101   * Callback to add footer elements.
 102   *
 103   * @return string HTML footer content
 104   */
 105  function tool_policy_standard_footer_html() {
 106      global $CFG, $PAGE;
 107  
 108      $output = '';
 109      if (!empty($CFG->sitepolicyhandler)
 110              && $CFG->sitepolicyhandler == 'tool_policy') {
 111          $policies = api::get_current_versions_ids();
 112          if (!empty($policies)) {
 113              $url = new moodle_url('/admin/tool/policy/viewall.php', ['returnurl' => $PAGE->url]);
 114              $output .= html_writer::link($url, get_string('userpolicysettings', 'tool_policy'));
 115              $output = html_writer::div($output, 'policiesfooter');
 116          }
 117      }
 118  
 119      return $output;
 120  }
 121  
 122  /**
 123   * Hooks redirection to policy acceptance pages before sign up.
 124   */
 125  function tool_policy_pre_signup_requests() {
 126      global $CFG;
 127  
 128      // Do nothing if we are not set as the site policies handler.
 129      if (empty($CFG->sitepolicyhandler) || $CFG->sitepolicyhandler !== 'tool_policy') {
 130          return;
 131      }
 132  
 133      $policies = api::get_current_versions_ids(policy_version::AUDIENCE_LOGGEDIN);
 134      $userpolicyagreed = cache::make('core', 'presignup')->get('tool_policy_userpolicyagreed');
 135      if (!empty($policies) && !$userpolicyagreed) {
 136          // Redirect to "Policy" pages for consenting before creating the user.
 137          cache::make('core', 'presignup')->set('tool_policy_issignup', 1);
 138          redirect(new \moodle_url('/admin/tool/policy/index.php'));
 139      }
 140  }
 141  
 142  /**
 143   * Serve the embedded files.
 144   *
 145   * @param stdClass $course the course object
 146   * @param stdClass $cm the course module object
 147   * @param stdClass $context the context
 148   * @param string $filearea the name of the file area
 149   * @param array $args extra arguments (itemid, path)
 150   * @param bool $forcedownload whether or not force download
 151   * @param array $options additional options affecting the file serving
 152   * @return bool false if the file not found, just send the file otherwise and do not return anything
 153   */
 154  function tool_policy_pluginfile($course, $cm, $context, $filearea, $args, $forcedownload, array $options=array()) {
 155      global $CFG, $PAGE;
 156  
 157      // Do not allow access to files if we are not set as the site policy handler.
 158      if (empty($CFG->sitepolicyhandler) || $CFG->sitepolicyhandler !== 'tool_policy') {
 159          return false;
 160      }
 161  
 162      if ($context->contextlevel != CONTEXT_SYSTEM) {
 163          return false;
 164      }
 165  
 166      $PAGE->set_context($context);
 167  
 168      if ($filearea !== 'policydocumentsummary' && $filearea !== 'policydocumentcontent') {
 169          return false;
 170      }
 171  
 172      $itemid = array_shift($args);
 173  
 174      $policy = api::get_policy_version($itemid);
 175  
 176      if ($policy->status != policy_version::STATUS_ACTIVE) {
 177          require_login();
 178      }
 179  
 180      if (!api::can_user_view_policy_version($policy)) {
 181          return false;
 182      }
 183  
 184      $filename = array_pop($args);
 185  
 186      if (!$args) {
 187          $filepath = '/';
 188      } else {
 189          $filepath = '/'.implode('/', $args).'/';
 190      }
 191  
 192      $fs = get_file_storage();
 193      $file = $fs->get_file($context->id, 'tool_policy', $filearea, $itemid, $filepath, $filename);
 194  
 195      if (!$file) {
 196          return false;
 197      }
 198  
 199      send_stored_file($file, null, 0, $forcedownload, $options);
 200  }
 201  
 202  /**
 203   * Map icons for font-awesome themes.
 204   */
 205  function tool_policy_get_fontawesome_icon_map() {
 206      return [
 207          'tool_policy:agreed' => 'fa-check text-success',
 208          'tool_policy:declined' => 'fa-times text-danger',
 209          'tool_policy:pending' => 'fa-clock-o text-warning',
 210          'tool_policy:partial' => 'fa-exclamation-triangle text-warning',
 211          'tool_policy:level' => 'fa-level-up fa-rotate-90 text-muted',
 212      ];
 213  }
 214  
 215  /**
 216   * Serve the new group form as a fragment.
 217   *
 218   * @param array $args List of named arguments for the fragment loader.
 219   * @return string
 220   */
 221  function tool_policy_output_fragment_accept_on_behalf($args) {
 222      $args = (object) $args;
 223  
 224      $data = [];
 225      if (!empty($args->jsonformdata)) {
 226          $serialiseddata = json_decode($args->jsonformdata);
 227          parse_str($serialiseddata, $data);
 228      }
 229  
 230      $mform = new \tool_policy\form\accept_policy(null, $data);
 231  
 232      if (!empty($args->jsonformdata)) {
 233          // If we were passed non-empty form data we want the mform to call validation functions and show errors.
 234          $mform->is_validated();
 235      }
 236  
 237      return $mform->render();
 238  }