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.

Differences Between: [Versions 310 and 401] [Versions 311 and 401] [Versions 39 and 401] [Versions 400 and 401]

   1  <?php
   2  
   3  namespace Box\Spout\Reader\CSV;
   4  
   5  use Box\Spout\Common\Exception\IOException;
   6  use Box\Spout\Common\Helper\GlobalFunctionsHelper;
   7  use Box\Spout\Common\Manager\OptionsManagerInterface;
   8  use Box\Spout\Reader\Common\Creator\InternalEntityFactoryInterface;
   9  use Box\Spout\Reader\Common\Entity\Options;
  10  use Box\Spout\Reader\CSV\Creator\InternalEntityFactory;
  11  use Box\Spout\Reader\ReaderAbstract;
  12  
  13  /**
  14   * Class Reader
  15   * This class provides support to read data from a CSV file.
  16   */
  17  class Reader extends ReaderAbstract
  18  {
  19      /** @var resource Pointer to the file to be written */
  20      protected $filePointer;
  21  
  22      /** @var SheetIterator To iterator over the CSV unique "sheet" */
  23      protected $sheetIterator;
  24  
  25      /** @var string Original value for the "auto_detect_line_endings" INI value */
  26      protected $originalAutoDetectLineEndings;
  27  
  28      /** @var bool Whether the code is running with PHP >= 8.1 */
  29      private $isRunningAtLeastPhp81;
  30  
  31      /**
  32       * @param OptionsManagerInterface $optionsManager
  33       * @param GlobalFunctionsHelper $globalFunctionsHelper
  34       * @param InternalEntityFactoryInterface $entityFactory
  35       */
  36      public function __construct(
  37          OptionsManagerInterface $optionsManager,
  38          GlobalFunctionsHelper $globalFunctionsHelper,
  39          InternalEntityFactoryInterface $entityFactory
  40      ) {
  41          parent::__construct($optionsManager, $globalFunctionsHelper, $entityFactory);
  42          $this->isRunningAtLeastPhp81 = \version_compare(PHP_VERSION, '8.1.0') >= 0;
  43      }
  44  
  45      /**
  46       * Sets the field delimiter for the CSV.
  47       * Needs to be called before opening the reader.
  48       *
  49       * @param string $fieldDelimiter Character that delimits fields
  50       * @return Reader
  51       */
  52      public function setFieldDelimiter($fieldDelimiter)
  53      {
  54          $this->optionsManager->setOption(Options::FIELD_DELIMITER, $fieldDelimiter);
  55  
  56          return $this;
  57      }
  58  
  59      /**
  60       * Sets the field enclosure for the CSV.
  61       * Needs to be called before opening the reader.
  62       *
  63       * @param string $fieldEnclosure Character that enclose fields
  64       * @return Reader
  65       */
  66      public function setFieldEnclosure($fieldEnclosure)
  67      {
  68          $this->optionsManager->setOption(Options::FIELD_ENCLOSURE, $fieldEnclosure);
  69  
  70          return $this;
  71      }
  72  
  73      /**
  74       * Sets the encoding of the CSV file to be read.
  75       * Needs to be called before opening the reader.
  76       *
  77       * @param string $encoding Encoding of the CSV file to be read
  78       * @return Reader
  79       */
  80      public function setEncoding($encoding)
  81      {
  82          $this->optionsManager->setOption(Options::ENCODING, $encoding);
  83  
  84          return $this;
  85      }
  86  
  87      /**
  88       * Returns whether stream wrappers are supported
  89       *
  90       * @return bool
  91       */
  92      protected function doesSupportStreamWrapper()
  93      {
  94          return true;
  95      }
  96  
  97      /**
  98       * Opens the file at the given path to make it ready to be read.
  99       * If setEncoding() was not called, it assumes that the file is encoded in UTF-8.
 100       *
 101       * @param  string $filePath Path of the CSV file to be read
 102       * @throws \Box\Spout\Common\Exception\IOException
 103       * @return void
 104       */
 105      protected function openReader($filePath)
 106      {
 107          // "auto_detect_line_endings" is deprecated in PHP 8.1
 108          if (!$this->isRunningAtLeastPhp81) {
 109              $this->originalAutoDetectLineEndings = \ini_get('auto_detect_line_endings');
 110              \ini_set('auto_detect_line_endings', '1');
 111          }
 112  
 113          $this->filePointer = $this->globalFunctionsHelper->fopen($filePath, 'r');
 114          if (!$this->filePointer) {
 115              throw new IOException("Could not open file $filePath for reading.");
 116          }
 117  
 118          /** @var InternalEntityFactory $entityFactory */
 119          $entityFactory = $this->entityFactory;
 120  
 121          $this->sheetIterator = $entityFactory->createSheetIterator(
 122              $this->filePointer,
 123              $this->optionsManager,
 124              $this->globalFunctionsHelper
 125          );
 126      }
 127  
 128      /**
 129       * Returns an iterator to iterate over sheets.
 130       *
 131       * @return SheetIterator To iterate over sheets
 132       */
 133      protected function getConcreteSheetIterator()
 134      {
 135          return $this->sheetIterator;
 136      }
 137  
 138      /**
 139       * Closes the reader. To be used after reading the file.
 140       *
 141       * @return void
 142       */
 143      protected function closeReader()
 144      {
 145          if ($this->filePointer) {
 146              $this->globalFunctionsHelper->fclose($this->filePointer);
 147          }
 148  
 149          // "auto_detect_line_endings" is deprecated in PHP 8.1
 150          if (!$this->isRunningAtLeastPhp81) {
 151              \ini_set('auto_detect_line_endings', $this->originalAutoDetectLineEndings);
 152          }
 153      }
 154  }