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 401 and 402] [Versions 401 and 403]

   1  <?php
   2  /*
   3   * Copyright 2014 Google Inc.
   4   *
   5   * Licensed under the Apache License, Version 2.0 (the "License");
   6   * you may not use this file except in compliance with the License.
   7   * You may obtain a copy of the License at
   8   *
   9   *     http://www.apache.org/licenses/LICENSE-2.0
  10   *
  11   * Unless required by applicable law or agreed to in writing, software
  12   * distributed under the License is distributed on an "AS IS" BASIS,
  13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14   * See the License for the specific language governing permissions and
  15   * limitations under the License.
  16   */
  17  
  18  if (!class_exists('Google_Client')) {
  19    require_once dirname(__FILE__) . '/../autoload.php';
  20  }
  21  
  22  /**
  23   * File logging class based on the PSR-3 standard.
  24   *
  25   * This logger writes to a PHP stream resource.
  26   */
  27  class Google_Logger_File extends Google_Logger_Abstract
  28  {
  29    /**
  30     * @var string|resource $file Where logs are written
  31     */
  32    private $file;
  33    /**
  34     * @var integer $mode The mode to use if the log file needs to be created
  35     */
  36    private $mode = 0640;
  37    /**
  38     * @var boolean $lock If a lock should be attempted before writing to the log
  39     */
  40    private $lock = false;
  41  
  42    /**
  43     * @var integer $trappedErrorNumber Trapped error number
  44     */
  45    private $trappedErrorNumber;
  46    /**
  47     * @var string $trappedErrorString Trapped error string
  48     */
  49    private $trappedErrorString;
  50  
  51    /**
  52     * {@inheritdoc}
  53     */
  54    public function __construct(Google_Client $client)
  55    {
  56      parent::__construct($client);
  57  
  58      $file = $client->getClassConfig('Google_Logger_File', 'file');
  59      if (!is_string($file) && !is_resource($file)) {
  60        throw new Google_Logger_Exception(
  61            'File logger requires a filename or a valid file pointer'
  62        );
  63      }
  64  
  65      $mode = $client->getClassConfig('Google_Logger_File', 'mode');
  66      if (!$mode) {
  67        $this->mode = $mode;
  68      }
  69  
  70      $this->lock = (bool) $client->getClassConfig('Google_Logger_File', 'lock');
  71      $this->file = $file;
  72    }
  73  
  74    /**
  75     * {@inheritdoc}
  76     */
  77    protected function write($message)
  78    {
  79      if (is_string($this->file)) {
  80        $this->open();
  81      } elseif (!is_resource($this->file)) {
  82        throw new Google_Logger_Exception('File pointer is no longer available');
  83      }
  84  
  85      if ($this->lock) {
  86        flock($this->file, LOCK_EX);
  87      }
  88  
  89      fwrite($this->file, (string) $message);
  90  
  91      if ($this->lock) {
  92        flock($this->file, LOCK_UN);
  93      }
  94    }
  95  
  96    /**
  97     * Opens the log for writing.
  98     *
  99     * @return resource
 100     */
 101    private function open()
 102    {
 103      // Used for trapping `fopen()` errors.
 104      $this->trappedErrorNumber = null;
 105      $this->trappedErrorString = null;
 106  
 107      $old = set_error_handler(array($this, 'trapError'));
 108  
 109      $needsChmod = !file_exists($this->file);
 110      $fh = fopen($this->file, 'a');
 111  
 112      restore_error_handler();
 113  
 114      // Handles trapped `fopen()` errors.
 115      if ($this->trappedErrorNumber) {
 116        throw new Google_Logger_Exception(
 117            sprintf(
 118                "Logger Error: '%s'",
 119                $this->trappedErrorString
 120            ),
 121            $this->trappedErrorNumber
 122        );
 123      }
 124  
 125      if ($needsChmod) {
 126        @chmod($this->file, $this->mode & ~umask());
 127      }
 128  
 129      return $this->file = $fh;
 130    }
 131  
 132    /**
 133     * Closes the log stream resource.
 134     */
 135    private function close()
 136    {
 137      if (is_resource($this->file)) {
 138        fclose($this->file);
 139      }
 140    }
 141  
 142    /**
 143     * Traps `fopen()` errors.
 144     *
 145     * @param integer $errno The error number
 146     * @param string $errstr The error string
 147     */
 148    private function trapError($errno, $errstr)
 149    {
 150      $this->trappedErrorNumber = $errno;
 151      $this->trappedErrorString = $errstr;
 152    }
 153  
 154    public function __destruct()
 155    {
 156      $this->close();
 157    }
 158  }