Search moodle.org's
Developer Documentation

See Release Notes
Long Term Support Release

  • Bug fixes for general core bugs in 3.9.x will end* 10 May 2021 (12 months).
  • Bug fixes for security issues in 3.9.x will end* 8 May 2023 (36 months).
  • PHP version: minimum PHP 7.2.0 Note: minimum PHP version has increased since Moodle 3.8. PHP 7.3.x and 7.4.x are supported too.

Differences Between: [Versions 39 and 311] [Versions 39 and 400] [Versions 39 and 401] [Versions 39 and 402] [Versions 39 and 403]

   1  <?php
   2  
   3  namespace PhpOffice\PhpSpreadsheet\Helper;
   4  
   5  use PhpOffice\PhpSpreadsheet\IOFactory;
   6  use PhpOffice\PhpSpreadsheet\Spreadsheet;
   7  use PhpOffice\PhpSpreadsheet\Writer\IWriter;
   8  use PhpOffice\PhpSpreadsheet\Writer\Pdf;
   9  use RecursiveDirectoryIterator;
  10  use RecursiveIteratorIterator;
  11  use RecursiveRegexIterator;
  12  use ReflectionClass;
  13  use RegexIterator;
  14  
  15  /**
  16   * Helper class to be used in sample code.
  17   */
  18  class Sample
  19  {
  20      /**
  21       * Returns whether we run on CLI or browser.
  22       *
  23       * @return bool
  24       */
  25      public function isCli()
  26      {
  27          return PHP_SAPI === 'cli';
  28      }
  29  
  30      /**
  31       * Return the filename currently being executed.
  32       *
  33       * @return string
  34       */
  35      public function getScriptFilename()
  36      {
  37          return basename($_SERVER['SCRIPT_FILENAME'], '.php');
  38      }
  39  
  40      /**
  41       * Whether we are executing the index page.
  42       *
  43       * @return bool
  44       */
  45      public function isIndex()
  46      {
  47          return $this->getScriptFilename() === 'index';
  48      }
  49  
  50      /**
  51       * Return the page title.
  52       *
  53       * @return string
  54       */
  55      public function getPageTitle()
  56      {
  57          return $this->isIndex() ? 'PHPSpreadsheet' : $this->getScriptFilename();
  58      }
  59  
  60      /**
  61       * Return the page heading.
  62       *
  63       * @return string
  64       */
  65      public function getPageHeading()
  66      {
  67          return $this->isIndex() ? '' : '<h1>' . str_replace('_', ' ', $this->getScriptFilename()) . '</h1>';
  68      }
  69  
  70      /**
  71       * Returns an array of all known samples.
  72       *
  73       * @return string[] [$name => $path]
  74       */
  75      public function getSamples()
  76      {
  77          // Populate samples
  78          $baseDir = realpath(__DIR__ . '/../../../samples');
  79          $directory = new RecursiveDirectoryIterator($baseDir);
  80          $iterator = new RecursiveIteratorIterator($directory);
  81          $regex = new RegexIterator($iterator, '/^.+\.php$/', RecursiveRegexIterator::GET_MATCH);
  82  
  83          $files = [];
  84          foreach ($regex as $file) {
  85              $file = str_replace(str_replace('\\', '/', $baseDir) . '/', '', str_replace('\\', '/', $file[0]));
  86              $info = pathinfo($file);
  87              $category = str_replace('_', ' ', $info['dirname']);
  88              $name = str_replace('_', ' ', preg_replace('/(|\.php)/', '', $info['filename']));
  89              if (!in_array($category, ['.', 'boostrap', 'templates'])) {
  90                  if (!isset($files[$category])) {
  91                      $files[$category] = [];
  92                  }
  93                  $files[$category][$name] = $file;
  94              }
  95          }
  96  
  97          // Sort everything
  98          ksort($files);
  99          foreach ($files as &$f) {
 100              asort($f);
 101          }
 102  
 103          return $files;
 104      }
 105  
 106      /**
 107       * Write documents.
 108       *
 109       * @param Spreadsheet $spreadsheet
 110       * @param string $filename
 111       * @param string[] $writers
 112       */
 113      public function write(Spreadsheet $spreadsheet, $filename, array $writers = ['Xlsx', 'Xls'])
 114      {
 115          // Set active sheet index to the first sheet, so Excel opens this as the first sheet
 116          $spreadsheet->setActiveSheetIndex(0);
 117  
 118          // Write documents
 119          foreach ($writers as $writerType) {
 120              $path = $this->getFilename($filename, mb_strtolower($writerType));
 121              $writer = IOFactory::createWriter($spreadsheet, $writerType);
 122              if ($writer instanceof Pdf) {
 123                  // PDF writer needs temporary directory
 124                  $tempDir = $this->getTemporaryFolder();
 125                  $writer->setTempDir($tempDir);
 126              }
 127              $callStartTime = microtime(true);
 128              $writer->save($path);
 129              $this->logWrite($writer, $path, $callStartTime);
 130          }
 131  
 132          $this->logEndingNotes();
 133      }
 134  
 135      /**
 136       * Returns the temporary directory and make sure it exists.
 137       *
 138       * @return string
 139       */
 140      private function getTemporaryFolder()
 141      {
 142          $tempFolder = sys_get_temp_dir() . '/phpspreadsheet';
 143          if (!is_dir($tempFolder)) {
 144              if (!mkdir($tempFolder) && !is_dir($tempFolder)) {
 145                  throw new \RuntimeException(sprintf('Directory "%s" was not created', $tempFolder));
 146              }
 147          }
 148  
 149          return $tempFolder;
 150      }
 151  
 152      /**
 153       * Returns the filename that should be used for sample output.
 154       *
 155       * @param string $filename
 156       * @param string $extension
 157       *
 158       * @return string
 159       */
 160      public function getFilename($filename, $extension = 'xlsx')
 161      {
 162          $originalExtension = pathinfo($filename, PATHINFO_EXTENSION);
 163  
 164          return $this->getTemporaryFolder() . '/' . str_replace('.' . $originalExtension, '.' . $extension, basename($filename));
 165      }
 166  
 167      /**
 168       * Return a random temporary file name.
 169       *
 170       * @param string $extension
 171       *
 172       * @return string
 173       */
 174      public function getTemporaryFilename($extension = 'xlsx')
 175      {
 176          $temporaryFilename = tempnam($this->getTemporaryFolder(), 'phpspreadsheet-');
 177          unlink($temporaryFilename);
 178  
 179          return $temporaryFilename . '.' . $extension;
 180      }
 181  
 182      public function log($message)
 183      {
 184          $eol = $this->isCli() ? PHP_EOL : '<br />';
 185          echo date('H:i:s ') . $message . $eol;
 186      }
 187  
 188      /**
 189       * Log ending notes.
 190       */
 191      public function logEndingNotes()
 192      {
 193          // Do not show execution time for index
 194          $this->log('Peak memory usage: ' . (memory_get_peak_usage(true) / 1024 / 1024) . 'MB');
 195      }
 196  
 197      /**
 198       * Log a line about the write operation.
 199       *
 200       * @param IWriter $writer
 201       * @param string $path
 202       * @param float $callStartTime
 203       */
 204      public function logWrite(IWriter $writer, $path, $callStartTime)
 205      {
 206          $callEndTime = microtime(true);
 207          $callTime = $callEndTime - $callStartTime;
 208          $reflection = new ReflectionClass($writer);
 209          $format = $reflection->getShortName();
 210          $message = "Write {$format} format to <code>{$path}</code>  in " . sprintf('%.4f', $callTime) . ' seconds';
 211  
 212          $this->log($message);
 213      }
 214  
 215      /**
 216       * Log a line about the read operation.
 217       *
 218       * @param string $format
 219       * @param string $path
 220       * @param float $callStartTime
 221       */
 222      public function logRead($format, $path, $callStartTime)
 223      {
 224          $callEndTime = microtime(true);
 225          $callTime = $callEndTime - $callStartTime;
 226          $message = "Read {$format} format from <code>{$path}</code>  in " . sprintf('%.4f', $callTime) . ' seconds';
 227  
 228          $this->log($message);
 229      }
 230  }