mirror of
				https://github.com/getgrav/grav.git
				synced 2025-10-31 02:15:55 +01:00 
			
		
		
		
	Monolog 3 compatible shim to handle upgrades
Signed-off-by: Andy Miller <rhuk@mac.com>
This commit is contained in:
		| @@ -33,6 +33,14 @@ if (!class_exists(\Symfony\Component\ErrorHandler\Exception\FlattenException::cl | |||||||
|     class_alias(\Symfony\Component\HttpKernel\Exception\FlattenException::class, \Symfony\Component\ErrorHandler\Exception\FlattenException::class); |     class_alias(\Symfony\Component\HttpKernel\Exception\FlattenException::class, \Symfony\Component\ErrorHandler\Exception\FlattenException::class); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | if (!class_exists(\Monolog\Logger::class, false)) { | ||||||
|  |     class_exists(\Monolog\Logger::class); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | if (defined('Monolog\Logger::API') && \Monolog\Logger::API < 3) { | ||||||
|  |     require_once __DIR__ . '/system/src/Grav/Framework/Compat/Monolog/bootstrap.php'; | ||||||
|  | } | ||||||
|  |  | ||||||
| // Set timezone to default, falls back to system if php.ini not set | // Set timezone to default, falls back to system if php.ini not set | ||||||
| date_default_timezone_set(@date_default_timezone_get()); | date_default_timezone_set(@date_default_timezone_get()); | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										183
									
								
								system/src/Grav/Framework/Compat/Monolog/Utils.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										183
									
								
								system/src/Grav/Framework/Compat/Monolog/Utils.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,183 @@ | |||||||
|  | <?php | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Backport of Monolog\Utils providing DEFAULT_JSON_FLAGS for older Monolog versions. | ||||||
|  |  * | ||||||
|  |  * This is a trimmed copy of the Monolog 1.x Utils class with a compatible constant so | ||||||
|  |  * that Grav 1.7 can interoperate with code targeting Monolog 3. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | namespace Monolog; | ||||||
|  |  | ||||||
|  | class Utils | ||||||
|  | { | ||||||
|  |     public const DEFAULT_JSON_FLAGS = JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * @internal | ||||||
|  |      */ | ||||||
|  |     public static function getClass($object) | ||||||
|  |     { | ||||||
|  |         $class = \get_class($object); | ||||||
|  |  | ||||||
|  |         return 'c' === $class[0] && 0 === strpos($class, "class@anonymous\0") ? get_parent_class($class).'@anonymous' : $class; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Makes sure if a relative path is passed in it is turned into an absolute path | ||||||
|  |      * | ||||||
|  |      * @param string $streamUrl stream URL or path without protocol | ||||||
|  |      * | ||||||
|  |      * @return string | ||||||
|  |      */ | ||||||
|  |     public static function canonicalizePath($streamUrl) | ||||||
|  |     { | ||||||
|  |         $prefix = ''; | ||||||
|  |         if ('file://' === substr($streamUrl, 0, 7)) { | ||||||
|  |             $streamUrl = substr($streamUrl, 7); | ||||||
|  |             $prefix = 'file://'; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         if (false !== strpos($streamUrl, '://')) { | ||||||
|  |             return $streamUrl; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         if (substr($streamUrl, 0, 1) === '/' || substr($streamUrl, 1, 1) === ':' || substr($streamUrl, 0, 2) === '\\\\') { | ||||||
|  |             return $prefix.$streamUrl; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         $streamUrl = getcwd() . '/' . $streamUrl; | ||||||
|  |  | ||||||
|  |         return $prefix.$streamUrl; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Return the JSON representation of a value | ||||||
|  |      * | ||||||
|  |      * @param  mixed $data | ||||||
|  |      * @param  int   $encodeFlags | ||||||
|  |      * @param  bool  $ignoreErrors | ||||||
|  |      * @return string | ||||||
|  |      */ | ||||||
|  |     public static function jsonEncode($data, $encodeFlags = null, $ignoreErrors = false) | ||||||
|  |     { | ||||||
|  |         if (null === $encodeFlags) { | ||||||
|  |             $encodeFlags = self::DEFAULT_JSON_FLAGS; | ||||||
|  |             if (defined('JSON_PRESERVE_ZERO_FRACTION')) { | ||||||
|  |                 $encodeFlags |= JSON_PRESERVE_ZERO_FRACTION; | ||||||
|  |             } | ||||||
|  |             if (defined('JSON_INVALID_UTF8_SUBSTITUTE')) { | ||||||
|  |                 $encodeFlags |= JSON_INVALID_UTF8_SUBSTITUTE; | ||||||
|  |             } | ||||||
|  |             if (defined('JSON_PARTIAL_OUTPUT_ON_ERROR')) { | ||||||
|  |                 $encodeFlags |= JSON_PARTIAL_OUTPUT_ON_ERROR; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         if ($ignoreErrors) { | ||||||
|  |             $json = @json_encode($data, $encodeFlags); | ||||||
|  |             if (false === $json) { | ||||||
|  |                 return 'null'; | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             return $json; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         $json = json_encode($data, $encodeFlags); | ||||||
|  |         if (false === $json) { | ||||||
|  |             $json = self::handleJsonError(json_last_error(), $data); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         return $json; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Handle a json_encode failure. | ||||||
|  |      * | ||||||
|  |      * @param  int   $code | ||||||
|  |      * @param  mixed $data | ||||||
|  |      * @param  int   $encodeFlags | ||||||
|  |      * @return string | ||||||
|  |      */ | ||||||
|  |     public static function handleJsonError($code, $data, $encodeFlags = null) | ||||||
|  |     { | ||||||
|  |         if ($code !== JSON_ERROR_UTF8) { | ||||||
|  |             self::throwEncodeError($code, $data); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         if (is_string($data)) { | ||||||
|  |             self::detectAndCleanUtf8($data); | ||||||
|  |         } elseif (is_array($data)) { | ||||||
|  |             array_walk_recursive($data, array('Monolog\Utils', 'detectAndCleanUtf8')); | ||||||
|  |         } else { | ||||||
|  |             self::throwEncodeError($code, $data); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         if (null === $encodeFlags) { | ||||||
|  |             $encodeFlags = self::DEFAULT_JSON_FLAGS; | ||||||
|  |             if (defined('JSON_PRESERVE_ZERO_FRACTION')) { | ||||||
|  |                 $encodeFlags |= JSON_PRESERVE_ZERO_FRACTION; | ||||||
|  |             } | ||||||
|  |             if (defined('JSON_INVALID_UTF8_SUBSTITUTE')) { | ||||||
|  |                 $encodeFlags |= JSON_INVALID_UTF8_SUBSTITUTE; | ||||||
|  |             } | ||||||
|  |             if (defined('JSON_PARTIAL_OUTPUT_ON_ERROR')) { | ||||||
|  |                 $encodeFlags |= JSON_PARTIAL_OUTPUT_ON_ERROR; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         $json = json_encode($data, $encodeFlags); | ||||||
|  |  | ||||||
|  |         if ($json === false) { | ||||||
|  |             self::throwEncodeError(json_last_error(), $data); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         return $json; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * @param  int   $code | ||||||
|  |      * @param  mixed $data | ||||||
|  |      * @throws \RuntimeException | ||||||
|  |      */ | ||||||
|  |     private static function throwEncodeError($code, $data) | ||||||
|  |     { | ||||||
|  |         switch ($code) { | ||||||
|  |             case JSON_ERROR_DEPTH: | ||||||
|  |                 $msg = 'Maximum stack depth exceeded'; | ||||||
|  |                 break; | ||||||
|  |             case JSON_ERROR_STATE_MISMATCH: | ||||||
|  |                 $msg = 'Underflow or the modes mismatch'; | ||||||
|  |                 break; | ||||||
|  |             case JSON_ERROR_CTRL_CHAR: | ||||||
|  |                 $msg = 'Unexpected control character found'; | ||||||
|  |                 break; | ||||||
|  |             case JSON_ERROR_UTF8: | ||||||
|  |                 $msg = 'Malformed UTF-8 characters, possibly incorrectly encoded'; | ||||||
|  |                 break; | ||||||
|  |             default: | ||||||
|  |                 $msg = 'Unknown error'; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         throw new \RuntimeException('JSON encoding failed: '.$msg.'. Encoding: '.var_export($data, true)); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * @param mixed $data | ||||||
|  |      */ | ||||||
|  |     public static function detectAndCleanUtf8(&$data) | ||||||
|  |     { | ||||||
|  |         if (is_string($data) && !preg_match('//u', $data)) { | ||||||
|  |             $data = preg_replace_callback( | ||||||
|  |                 '/[\x80-\xFF]+/', | ||||||
|  |                 function ($m) { return utf8_encode($m[0]); }, | ||||||
|  |                 $data | ||||||
|  |             ); | ||||||
|  |             $data = str_replace( | ||||||
|  |                 array('¤', '¦', '¨', '´', '¸', '¼', '½', '¾'), | ||||||
|  |                 array('€', 'Š', 'š', 'Ž', 'ž', 'Œ', 'œ', 'Ÿ'), | ||||||
|  |                 $data | ||||||
|  |             ); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										28
									
								
								system/src/Grav/Framework/Compat/Monolog/bootstrap.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								system/src/Grav/Framework/Compat/Monolog/bootstrap.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,28 @@ | |||||||
|  | <?php | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * @package    Grav\Framework\Compat | ||||||
|  |  * | ||||||
|  |  * Provides lightweight shims for legacy Monolog installations used in Grav 1.7 | ||||||
|  |  * so that newer Grav code (targeting Monolog 3) can run without fatal errors. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | declare(strict_types=1); | ||||||
|  |  | ||||||
|  | namespace Grav\Framework\Compat\Monolog; | ||||||
|  |  | ||||||
|  | if (!class_exists(\Monolog\Utils::class, false)) { | ||||||
|  |     spl_autoload_register( | ||||||
|  |         static function (string $class): bool { | ||||||
|  |             if ($class === 'Monolog\\Utils') { | ||||||
|  |                 require __DIR__ . '/Utils.php'; | ||||||
|  |  | ||||||
|  |                 return true; | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             return false; | ||||||
|  |         }, | ||||||
|  |         true, | ||||||
|  |         true | ||||||
|  |     ); | ||||||
|  | } | ||||||
		Reference in New Issue
	
	Block a user