/libs/google-api-php-client/vendor/monolog/monolog/src/Monolog/Handler/StreamHandler.php

https://github.com/sendtogeo/Seo-Panel · PHP · 176 lines · 103 code · 20 blank · 53 comment · 17 complexity · 17a9b3e47aff0bce5d9f885e8c8f4912 MD5 · raw file

  1. <?php
  2. /*
  3. * This file is part of the Monolog package.
  4. *
  5. * (c) Jordi Boggiano <j.boggiano@seld.be>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Monolog\Handler;
  11. use Monolog\Logger;
  12. /**
  13. * Stores to any stream resource
  14. *
  15. * Can be used to store into php://stderr, remote and local files, etc.
  16. *
  17. * @author Jordi Boggiano <j.boggiano@seld.be>
  18. */
  19. class StreamHandler extends AbstractProcessingHandler
  20. {
  21. protected $stream;
  22. protected $url;
  23. private $errorMessage;
  24. protected $filePermission;
  25. protected $useLocking;
  26. private $dirCreated;
  27. /**
  28. * @param resource|string $stream
  29. * @param int $level The minimum logging level at which this handler will be triggered
  30. * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not
  31. * @param int|null $filePermission Optional file permissions (default (0644) are only for owner read/write)
  32. * @param Boolean $useLocking Try to lock log file before doing any writes
  33. *
  34. * @throws \Exception If a missing directory is not buildable
  35. * @throws \InvalidArgumentException If stream is not a resource or string
  36. */
  37. public function __construct($stream, $level = Logger::DEBUG, $bubble = true, $filePermission = null, $useLocking = false)
  38. {
  39. parent::__construct($level, $bubble);
  40. if (is_resource($stream)) {
  41. $this->stream = $stream;
  42. } elseif (is_string($stream)) {
  43. $this->url = $stream;
  44. } else {
  45. throw new \InvalidArgumentException('A stream must either be a resource or a string.');
  46. }
  47. $this->filePermission = $filePermission;
  48. $this->useLocking = $useLocking;
  49. }
  50. /**
  51. * {@inheritdoc}
  52. */
  53. public function close()
  54. {
  55. if ($this->url && is_resource($this->stream)) {
  56. fclose($this->stream);
  57. }
  58. $this->stream = null;
  59. }
  60. /**
  61. * Return the currently active stream if it is open
  62. *
  63. * @return resource|null
  64. */
  65. public function getStream()
  66. {
  67. return $this->stream;
  68. }
  69. /**
  70. * Return the stream URL if it was configured with a URL and not an active resource
  71. *
  72. * @return string|null
  73. */
  74. public function getUrl()
  75. {
  76. return $this->url;
  77. }
  78. /**
  79. * {@inheritdoc}
  80. */
  81. protected function write(array $record)
  82. {
  83. if (!is_resource($this->stream)) {
  84. if (null === $this->url || '' === $this->url) {
  85. throw new \LogicException('Missing stream url, the stream can not be opened. This may be caused by a premature call to close().');
  86. }
  87. $this->createDir();
  88. $this->errorMessage = null;
  89. set_error_handler(array($this, 'customErrorHandler'));
  90. $this->stream = fopen($this->url, 'a');
  91. if ($this->filePermission !== null) {
  92. @chmod($this->url, $this->filePermission);
  93. }
  94. restore_error_handler();
  95. if (!is_resource($this->stream)) {
  96. $this->stream = null;
  97. throw new \UnexpectedValueException(sprintf('The stream or file "%s" could not be opened: '.$this->errorMessage, $this->url));
  98. }
  99. }
  100. if ($this->useLocking) {
  101. // ignoring errors here, there's not much we can do about them
  102. flock($this->stream, LOCK_EX);
  103. }
  104. $this->streamWrite($this->stream, $record);
  105. if ($this->useLocking) {
  106. flock($this->stream, LOCK_UN);
  107. }
  108. }
  109. /**
  110. * Write to stream
  111. * @param resource $stream
  112. * @param array $record
  113. */
  114. protected function streamWrite($stream, array $record)
  115. {
  116. fwrite($stream, (string) $record['formatted']);
  117. }
  118. private function customErrorHandler($code, $msg)
  119. {
  120. $this->errorMessage = preg_replace('{^(fopen|mkdir)\(.*?\): }', '', $msg);
  121. }
  122. /**
  123. * @param string $stream
  124. *
  125. * @return null|string
  126. */
  127. private function getDirFromStream($stream)
  128. {
  129. $pos = strpos($stream, '://');
  130. if ($pos === false) {
  131. return dirname($stream);
  132. }
  133. if ('file://' === substr($stream, 0, 7)) {
  134. return dirname(substr($stream, 7));
  135. }
  136. return;
  137. }
  138. private function createDir()
  139. {
  140. // Do not try to create dir if it has already been tried.
  141. if ($this->dirCreated) {
  142. return;
  143. }
  144. $dir = $this->getDirFromStream($this->url);
  145. if (null !== $dir && !is_dir($dir)) {
  146. $this->errorMessage = null;
  147. set_error_handler(array($this, 'customErrorHandler'));
  148. $status = mkdir($dir, 0777, true);
  149. restore_error_handler();
  150. if (false === $status) {
  151. throw new \UnexpectedValueException(sprintf('There is no existing directory at "%s" and its not buildable: '.$this->errorMessage, $dir));
  152. }
  153. }
  154. $this->dirCreated = true;
  155. }
  156. }