Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 4.3.x will end 7 October 2024 (12 months).
  • Bug fixes for security issues in 4.3.x will end 21 April 2025 (18 months).
  • PHP version: minimum PHP 8.0.0 Note: minimum PHP version has increased since Moodle 4.1. PHP 8.2.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   * Subplugin test helper trait
  19   *
  20   * @package   mod_bigbluebuttonbn
  21   * @copyright 2023 - present, Blindside Networks Inc
  22   * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  23   * @author    Laurent David (laurent@call-learning.fr)
  24   */
  25  
  26  namespace mod_bigbluebuttonbn\test;
  27  
  28  use core_component;
  29  use core_h5p\core;
  30  use core_plugin_manager;
  31  use mod_bigbluebuttonbn\extension;
  32  use ReflectionClass;
  33  
  34  trait subplugins_test_helper_trait {
  35      /**
  36       * Setup a fake extension plugin
  37       *
  38       * This is intended to behave in most case like a real subplugina and will
  39       * allow most functionalities to be tested.
  40       *
  41       * @param string $pluginname plugin name
  42       * @return void
  43       */
  44      protected function setup_fake_plugin(string $pluginname): void {
  45          global $CFG;
  46          require_once("$CFG->libdir/upgradelib.php");
  47          $bbbextpath = "{$CFG->dirroot}/mod/bigbluebuttonbn/tests/fixtures/extension";
  48          // This is similar to accesslib_test::setup_fake_plugin.
  49          $mockedcomponent = new ReflectionClass(core_component::class);
  50  
  51          $mockedplugins = $mockedcomponent->getProperty('plugins');
  52          $mockedplugins->setAccessible(true);
  53          $plugins = $mockedplugins->getValue();
  54          $plugins[extension::BBB_EXTENSION_PLUGIN_NAME] = [$pluginname => $bbbextpath . "/$pluginname"];
  55          $mockedplugins->setValue(null, $plugins);
  56  
  57          $mockedplugintypes = $mockedcomponent->getProperty('plugintypes');
  58          $mockedplugintypes->setAccessible(true);
  59          $pluginstypes = $mockedplugintypes->getValue();
  60          $pluginstypes[extension::BBB_EXTENSION_PLUGIN_NAME] = $bbbextpath;
  61          $mockedplugintypes->setValue(null, $pluginstypes);
  62  
  63          $fillclassmap = $mockedcomponent->getMethod('fill_classmap_cache');
  64          $fillclassmap->setAccessible(true);
  65          $fillclassmap->invoke(null);
  66  
  67          $fillfilemap = $mockedcomponent->getMethod('fill_filemap_cache');
  68          $fillfilemap->setAccessible(true);
  69          $fillfilemap->invoke(null);
  70  
  71          $mockedsubplugins = $mockedcomponent->getProperty('subplugins');
  72          $mockedsubplugins->setAccessible(true);
  73          $subplugins = $mockedsubplugins->getValue();
  74          $subplugins['mod_bigbluebuttonbn'][extension::BBB_EXTENSION_PLUGIN_NAME][] = $pluginname;
  75          $mockedsubplugins->setValue(null, $subplugins);
  76  
  77          // Now write the content of the cache in a file so we can use it later.
  78          $content = core_component::get_cache_content();
  79          self::write_fake_component_cache($content);
  80  
  81          // Make sure the plugin is installed.
  82          ob_start();
  83          upgrade_noncore(false);
  84          upgrade_finished();
  85          ob_end_clean();
  86  
  87          // Cache has been cleared so let's write it again.
  88          self::write_fake_component_cache($content);
  89  
  90      }
  91  
  92      /**
  93       * Write the content of the cache in a file for later use.
  94       *
  95       * This is used exclusively in behat test as the cache is filled with new values at each session/page load.
  96       *
  97       * @param string $content content of the cache
  98       * @return void
  99       */
 100      protected function write_fake_component_cache($content) {
 101          global $CFG;
 102          $cachefile = "$CFG->cachedir/core_component.php";
 103          if (file_exists($cachefile)) {
 104              // Stale cache detected!
 105              unlink($cachefile);
 106          }
 107  
 108          // Permissions might not be setup properly in installers.
 109          $dirpermissions = !isset($CFG->directorypermissions) ? 02777 : $CFG->directorypermissions;
 110          $filepermissions = !isset($CFG->filepermissions) ? ($dirpermissions & 0666) : $CFG->filepermissions;
 111  
 112          clearstatcache();
 113          $cachedir = dirname($cachefile);
 114          if (!is_dir($cachedir)) {
 115              mkdir($cachedir, $dirpermissions, true);
 116          }
 117  
 118          if ($fp = @fopen($cachefile . '.tmp', 'xb')) {
 119              fwrite($fp, $content);
 120              fclose($fp);
 121              @rename($cachefile . '.tmp', $cachefile);
 122              @chmod($cachefile, $filepermissions);
 123          }
 124          @unlink($cachefile . '.tmp'); // Just in case anything fails (race condition).
 125          core_component::invalidate_opcode_php_cache($cachefile);
 126  
 127      }
 128      /**
 129       * Uninstall a fake extension plugin
 130       *
 131       * This is intended to behave in most case like a real subplugina and will
 132       * allow most functionalities to be tested.
 133       *
 134       * @param string $pluginname plugin name
 135       * @return void
 136       */
 137      protected function uninstall_fake_plugin(string $pluginname): void {
 138          global $CFG;
 139          require_once("$CFG->libdir/adminlib.php");
 140          // We just need access to fill_all_caches so everything goes back to normal.
 141          // If we don't do this, there are some side effects that will make other test fails
 142          // (such as mod_bigbluebuttonbn\task\upgrade_recordings_task_test::test_upgrade_recordings_imported_basic).
 143          $cachefile = "$CFG->cachedir/core_component.php";
 144          if (file_exists($cachefile)) {
 145              // Stale cache detected!
 146              unlink($cachefile);
 147          }
 148          $mockedcomponent = new ReflectionClass(core_component::class);
 149          // Here we reset the plugin caches.
 150          $mockedplugintypes = $mockedcomponent->getProperty('plugintypes');
 151          $mockedplugintypes->setAccessible(true);
 152          $mockedplugintypes->setValue(null, null);
 153          $fillclassmap = $mockedcomponent->getMethod('init');
 154          $fillclassmap->setAccessible(true);
 155          $fillclassmap->invoke(null);
 156  
 157          // Now uninstall the plugin and clean everything up for other tests.
 158          $pluginman = core_plugin_manager::instance();
 159          $plugininfo = $pluginman->get_plugins();
 160          foreach ($plugininfo as $type => $plugins) {
 161              foreach ($plugins as $name => $plugin) {
 162                  if ($name === $pluginname) {
 163                      ob_start();
 164                      uninstall_plugin($type, $name);
 165                      ob_end_clean();
 166                  }
 167              }
 168          }
 169      }
 170  }