From 86b3daedca39a262113424ed29cd358362a3afd8 Mon Sep 17 00:00:00 2001 From: Uldis Jansons Date: Tue, 5 Feb 2019 11:58:57 +0200 Subject: [PATCH 01/12] Add info comment to not change index file --- index.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/index.php b/index.php index 7ca24c8..b9ba23c 100644 --- a/index.php +++ b/index.php @@ -3,6 +3,9 @@ require_once 'Logger.php'; +// Do not change this file + + function process() { for ($i = 0; $i < 3; $i++) { From 87bc8834b9a8aa486003ed21e9f7ce3e642bd517 Mon Sep 17 00:00:00 2001 From: Roberts Lataria Date: Mon, 28 Nov 2022 12:04:04 +0200 Subject: [PATCH 02/12] feat: add composer.json --- .gitignore | 3 +++ composer.json | 18 ++++++++++++++++++ 2 files changed, 21 insertions(+) create mode 100644 composer.json diff --git a/.gitignore b/.gitignore index 485dee6..dfffa9f 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,4 @@ .idea +application.log +/vendor/ +composer.lock diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..9548d87 --- /dev/null +++ b/composer.json @@ -0,0 +1,18 @@ +{ + "name": "catsand/homework", + "description": "Test task for Mobily", + "type": "project", + "license": "MIT", + "authors": [ + { + "name": "catsAND", + "email": "cv@left.lv" + } + ], + "require": { + "php": "^7.4" + }, + "require-dev": { + "phpunit/phpunit": "^9.0" + } +} From 2eb7487d2d47a29d833b932461439e0785954f08 Mon Sep 17 00:00:00 2001 From: Roberts Lataria Date: Mon, 28 Nov 2022 17:31:08 +0200 Subject: [PATCH 03/12] fix: refactor logger class as singleton --- Logger.php | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/Logger.php b/Logger.php index 3caccbb..04dd6b5 100644 --- a/Logger.php +++ b/Logger.php @@ -1,11 +1,20 @@ Date: Mon, 28 Nov 2022 18:01:51 +0200 Subject: [PATCH 04/12] fix: add logger interface --- Logger.php | 10 ++++++---- LoggerInterface.php | 29 +++++++++++++++++++++++++++++ composer.json | 3 +++ 3 files changed, 38 insertions(+), 4 deletions(-) create mode 100644 LoggerInterface.php diff --git a/Logger.php b/Logger.php index 04dd6b5..e45cb44 100644 --- a/Logger.php +++ b/Logger.php @@ -4,7 +4,9 @@ require './vendor/autoload.php'; -class Logger +use Homework\LoggerInterface; + +class Logger implements LoggerInterface { private static $instance = null; @@ -17,16 +19,16 @@ public static function get() return self::$instance; } - public function logError($message) + public function logError(string $message): void { $logFile = fopen('application.log', 'w'); fwrite($logFile, 'ERROR: ' . $message); fclose($logFile); } - public function logSuccess($msg) + public function logSuccess(string $message): void { $logFile = fopen('application.log', 'a'); - fwrite($logFile, 'SUCCESS: ' . $msg); + fwrite($logFile, 'SUCCESS: ' . $message); } } diff --git a/LoggerInterface.php b/LoggerInterface.php new file mode 100644 index 0000000..fc49c5f --- /dev/null +++ b/LoggerInterface.php @@ -0,0 +1,29 @@ + Date: Tue, 29 Nov 2022 10:37:25 +0200 Subject: [PATCH 05/12] fix: fixed logger class --- Logger.php | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Logger.php b/Logger.php index e45cb44..bc1f378 100644 --- a/Logger.php +++ b/Logger.php @@ -10,7 +10,7 @@ class Logger implements LoggerInterface { private static $instance = null; - public static function get() + public static function get(): LoggerInterface { if (self::$instance == null) { self::$instance = new Logger(); @@ -21,14 +21,15 @@ public static function get() public function logError(string $message): void { - $logFile = fopen('application.log', 'w'); - fwrite($logFile, 'ERROR: ' . $message); + $logFile = fopen('application.log', 'a'); + fwrite($logFile, sprintf("ERROR: %s\n", $message)); fclose($logFile); } public function logSuccess(string $message): void { $logFile = fopen('application.log', 'a'); - fwrite($logFile, 'SUCCESS: ' . $message); + fwrite($logFile, sprintf("SUCCESS: %s\n", $message)); + fclose($logFile); } } From 1d4cfb7fa50e6ef8a9f1f92d7728511b4bec0b46 Mon Sep 17 00:00:00 2001 From: Roberts Lataria Date: Tue, 29 Nov 2022 11:02:06 +0200 Subject: [PATCH 06/12] fix: add editorconfig; fix code style --- .editorconfig | 9 +++++++++ LoggerInterface.php | 35 ++++++++++++++++++----------------- 2 files changed, 27 insertions(+), 17 deletions(-) create mode 100644 .editorconfig diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..e291365 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,9 @@ +root = true + +[*] +charset = utf-8 +indent_style = space +indent_size = 4 +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true diff --git a/LoggerInterface.php b/LoggerInterface.php index fc49c5f..815866c 100644 --- a/LoggerInterface.php +++ b/LoggerInterface.php @@ -7,23 +7,24 @@ /** * Main interface for loggers. */ -interface LoggerInterface { +interface LoggerInterface +{ - /** - * Add error entity to log. - * - * @param string $message - * - * @return void - */ - public function logError(string $message): void; + /** + * Add error entity to log. + * + * @param string $message + * + * @return void + */ + public function logError(string $message): void; - /** - * Add success entity to log. - * - * @param string $message - * - * @return void - */ - public function logSuccess(string $message): void; + /** + * Add success entity to log. + * + * @param string $message + * + * @return void + */ + public function logSuccess(string $message): void; } From 7421b7af85ad908b70584118f384b332ba84d26c Mon Sep 17 00:00:00 2001 From: Roberts Lataria Date: Tue, 29 Nov 2022 15:39:20 +0200 Subject: [PATCH 07/12] feat: refactor logger class; move class to logger directory; create handler interface; create file handler; bump php version to latest --- Logger.php | 19 ++++---- Logger/AbstractHandler.php | 21 ++++++++ Logger/FileHandler.php | 48 +++++++++++++++++++ Logger/HandlerInterface.php | 13 +++++ .../LoggerInterface.php | 2 +- Logger/Status.php | 19 ++++++++ composer.json | 2 +- 7 files changed, 112 insertions(+), 12 deletions(-) create mode 100644 Logger/AbstractHandler.php create mode 100644 Logger/FileHandler.php create mode 100644 Logger/HandlerInterface.php rename LoggerInterface.php => Logger/LoggerInterface.php (94%) create mode 100644 Logger/Status.php diff --git a/Logger.php b/Logger.php index bc1f378..09cf8b9 100644 --- a/Logger.php +++ b/Logger.php @@ -2,18 +2,21 @@ declare(strict_types=1); -require './vendor/autoload.php'; +require 'vendor/autoload.php'; -use Homework\LoggerInterface; +use Homework\Logger\HandlerInterface; +use Homework\Logger\LoggerInterface; +use Homework\Logger\AbstractHandler; +use Homework\Logger\FileHandler; class Logger implements LoggerInterface { private static $instance = null; - public static function get(): LoggerInterface + public static function get(): HandlerInterface { if (self::$instance == null) { - self::$instance = new Logger(); + self::$instance = new FileHandler(); } return self::$instance; @@ -21,15 +24,11 @@ public static function get(): LoggerInterface public function logError(string $message): void { - $logFile = fopen('application.log', 'a'); - fwrite($logFile, sprintf("ERROR: %s\n", $message)); - fclose($logFile); + self::$instance->logError($message); } public function logSuccess(string $message): void { - $logFile = fopen('application.log', 'a'); - fwrite($logFile, sprintf("SUCCESS: %s\n", $message)); - fclose($logFile); + self::$instance->logSuccess($message); } } diff --git a/Logger/AbstractHandler.php b/Logger/AbstractHandler.php new file mode 100644 index 0000000..c070b7a --- /dev/null +++ b/Logger/AbstractHandler.php @@ -0,0 +1,21 @@ +log(Status::ERROR, $message); + } + + public function logSuccess(string $message): void + { + $this->log(Status::SUCCESS, $message); + } +} diff --git a/Logger/FileHandler.php b/Logger/FileHandler.php new file mode 100644 index 0000000..cb8cdba --- /dev/null +++ b/Logger/FileHandler.php @@ -0,0 +1,48 @@ +LOG_FILE = __DIR__ . '/../application.log'; + } + + public function log(Status $type, string $message): bool + { + if (!$this->createFile()) { + return false; + } + + if (trim($message) === '') { + return false; + } + + $file = fopen($this->LOG_FILE, 'a'); + + fwrite($file, sprintf("%s: %s\n", $type->getLabel(), $message)); + + return fclose($file); + } + + private function fileExists(): bool + { + return file_exists($this->LOG_FILE) && is_file($this->LOG_FILE) && is_writable($this->LOG_FILE); + } + + private function createFile(): bool + { + if (!$this->fileExists() && !fopen($this->LOG_FILE, 'c')) { + throw new Exception('Cannot create file'); + } + + return $this->fileExists(); + } +} diff --git a/Logger/HandlerInterface.php b/Logger/HandlerInterface.php new file mode 100644 index 0000000..27f556c --- /dev/null +++ b/Logger/HandlerInterface.php @@ -0,0 +1,13 @@ + 'Error', + Status::SUCCESS => 'Success' + }; + } +} diff --git a/composer.json b/composer.json index af711d7..c7b2a28 100644 --- a/composer.json +++ b/composer.json @@ -13,7 +13,7 @@ "psr-4": {"Homework\\": "./"} }, "require": { - "php": "^7.4" + "php": "^8.1" }, "require-dev": { "phpunit/phpunit": "^9.0" From 5443614f8f58f7d99a93a9469a47b70203c2e594 Mon Sep 17 00:00:00 2001 From: Roberts Lataria Date: Tue, 29 Nov 2022 15:47:40 +0200 Subject: [PATCH 08/12] fix: add factory pattern; fix code style --- Logger.php | 9 ++++----- Logger/ConsoleHandler.php | 28 ++++++++++++++++++++++++++++ Logger/HandlerFactory.php | 16 ++++++++++++++++ Logger/Type.php | 11 +++++++++++ 4 files changed, 59 insertions(+), 5 deletions(-) create mode 100644 Logger/ConsoleHandler.php create mode 100644 Logger/HandlerFactory.php create mode 100644 Logger/Type.php diff --git a/Logger.php b/Logger.php index 09cf8b9..1187de9 100644 --- a/Logger.php +++ b/Logger.php @@ -4,19 +4,18 @@ require 'vendor/autoload.php'; -use Homework\Logger\HandlerInterface; -use Homework\Logger\LoggerInterface; use Homework\Logger\AbstractHandler; -use Homework\Logger\FileHandler; +use Homework\Logger\LoggerInterface; +use Homework\Logger\HandlerFactory; class Logger implements LoggerInterface { private static $instance = null; - public static function get(): HandlerInterface + public static function get(): AbstractHandler { if (self::$instance == null) { - self::$instance = new FileHandler(); + self::$instance = HandlerFactory::get(); } return self::$instance; diff --git a/Logger/ConsoleHandler.php b/Logger/ConsoleHandler.php new file mode 100644 index 0000000..8460fbd --- /dev/null +++ b/Logger/ConsoleHandler.php @@ -0,0 +1,28 @@ +LOG_FILE = 'php://stdout'; + } + + public function log(Status $type, string $message): bool + { + if (trim($message) === '') { + return false; + } + + $file = fopen($this->LOG_FILE, 'a'); + + fwrite($file, sprintf("%s: %s\n", $type->getLabel(), $message)); + + return fclose($file); + } +} diff --git a/Logger/HandlerFactory.php b/Logger/HandlerFactory.php new file mode 100644 index 0000000..26f16d8 --- /dev/null +++ b/Logger/HandlerFactory.php @@ -0,0 +1,16 @@ + new FileHandler(), + Type::CONSOLE => new ConsoleHandler() + }; + } +} diff --git a/Logger/Type.php b/Logger/Type.php new file mode 100644 index 0000000..7e180bc --- /dev/null +++ b/Logger/Type.php @@ -0,0 +1,11 @@ + Date: Tue, 29 Nov 2022 16:36:37 +0200 Subject: [PATCH 09/12] fix: remove unused function from logger; remove not used interface; add trait for message validation; add phpdoc --- Logger.php | 13 +------------ Logger/AbstractHandler.php | 22 ++++++++++++++++++---- Logger/ConsoleHandler.php | 24 +++++++++++++++--------- Logger/FileHandler.php | 30 +++++++++++++++++++++++++++++- Logger/HandlerFactory.php | 10 ++++++++++ Logger/HandlerInterface.php | 8 ++++++++ Logger/LoggerInterface.php | 30 ------------------------------ Logger/Status.php | 8 ++++++++ Logger/Type.php | 3 +++ Logger/ValidationTrait.php | 35 +++++++++++++++++++++++++++++++++++ composer.json | 3 ++- 11 files changed, 129 insertions(+), 57 deletions(-) delete mode 100644 Logger/LoggerInterface.php create mode 100644 Logger/ValidationTrait.php diff --git a/Logger.php b/Logger.php index 1187de9..6042e75 100644 --- a/Logger.php +++ b/Logger.php @@ -5,10 +5,9 @@ require 'vendor/autoload.php'; use Homework\Logger\AbstractHandler; -use Homework\Logger\LoggerInterface; use Homework\Logger\HandlerFactory; -class Logger implements LoggerInterface +class Logger { private static $instance = null; @@ -20,14 +19,4 @@ public static function get(): AbstractHandler return self::$instance; } - - public function logError(string $message): void - { - self::$instance->logError($message); - } - - public function logSuccess(string $message): void - { - self::$instance->logSuccess($message); - } } diff --git a/Logger/AbstractHandler.php b/Logger/AbstractHandler.php index c070b7a..4bd721b 100644 --- a/Logger/AbstractHandler.php +++ b/Logger/AbstractHandler.php @@ -9,13 +9,27 @@ */ abstract class AbstractHandler { - public function logError(string $message): void + /** + * Add error entity to log. + * + * @param string $message + * + * @return boolean + */ + public function logError(string $message): bool { - $this->log(Status::ERROR, $message); + return $this->log(Status::ERROR, $message); } - public function logSuccess(string $message): void + /** + * Add success entity to log. + * + * @param string $message + * + * @return boolean + */ + public function logSuccess(string $message): bool { - $this->log(Status::SUCCESS, $message); + return $this->log(Status::SUCCESS, $message); } } diff --git a/Logger/ConsoleHandler.php b/Logger/ConsoleHandler.php index 8460fbd..1434b37 100644 --- a/Logger/ConsoleHandler.php +++ b/Logger/ConsoleHandler.php @@ -4,22 +4,28 @@ namespace Homework\Logger; +/** + * Console logger handler. + */ class ConsoleHandler extends AbstractHandler implements HandlerInterface { - private string $LOG_FILE; - - public function __construct() - { - $this->LOG_FILE = 'php://stdout'; - } - + use ValidationTrait; + + /** + * Add log entity to console. + * + * @param Status $type + * @param string $message + * + * @return boolean + */ public function log(Status $type, string $message): bool { - if (trim($message) === '') { + if (!$this->validate($message)) { return false; } - $file = fopen($this->LOG_FILE, 'a'); + $file = fopen('php://stdout', 'a'); fwrite($file, sprintf("%s: %s\n", $type->getLabel(), $message)); diff --git a/Logger/FileHandler.php b/Logger/FileHandler.php index cb8cdba..0a0c9ab 100644 --- a/Logger/FileHandler.php +++ b/Logger/FileHandler.php @@ -6,8 +6,18 @@ use Exception; +/** + * File logger handler. + */ class FileHandler extends AbstractHandler implements HandlerInterface { + use ValidationTrait; + + /** + * Path to log file. + * + * @var string + */ private string $LOG_FILE; public function __construct() @@ -15,13 +25,21 @@ public function __construct() $this->LOG_FILE = __DIR__ . '/../application.log'; } + /** + * Add log entity to file. + * + * @param Status $type + * @param string $message + * + * @return boolean + */ public function log(Status $type, string $message): bool { if (!$this->createFile()) { return false; } - if (trim($message) === '') { + if (!$this->validate($message)) { return false; } @@ -32,11 +50,21 @@ public function log(Status $type, string $message): bool return fclose($file); } + /** + * Check if file exists or not. + * + * @return boolean + */ private function fileExists(): bool { return file_exists($this->LOG_FILE) && is_file($this->LOG_FILE) && is_writable($this->LOG_FILE); } + /** + * Create file if not exists. + * + * @return boolean + */ private function createFile(): bool { if (!$this->fileExists() && !fopen($this->LOG_FILE, 'c')) { diff --git a/Logger/HandlerFactory.php b/Logger/HandlerFactory.php index 26f16d8..7c13097 100644 --- a/Logger/HandlerFactory.php +++ b/Logger/HandlerFactory.php @@ -4,8 +4,18 @@ namespace Homework\Logger; +/** + * Handler factory. + */ class HandlerFactory { + /** + * Get handler instance. + * + * @param Type $type + * + * @return AbstractHandler + */ public static function get(Type $type = Type::FILE): AbstractHandler { return match ($type) { diff --git a/Logger/HandlerInterface.php b/Logger/HandlerInterface.php index 27f556c..645704a 100644 --- a/Logger/HandlerInterface.php +++ b/Logger/HandlerInterface.php @@ -9,5 +9,13 @@ */ interface HandlerInterface { + /** + * Add entity to log. + * + * @param Status $type + * @param string $message + * + * @return boolean + */ public function log(Status $type, string $message): bool; } diff --git a/Logger/LoggerInterface.php b/Logger/LoggerInterface.php deleted file mode 100644 index d2efd93..0000000 --- a/Logger/LoggerInterface.php +++ /dev/null @@ -1,30 +0,0 @@ - Date: Tue, 29 Nov 2022 17:11:00 +0200 Subject: [PATCH 10/12] fix: add -c argument to switch logger output to console --- Logger.php | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/Logger.php b/Logger.php index 6042e75..d05eec1 100644 --- a/Logger.php +++ b/Logger.php @@ -6,6 +6,7 @@ use Homework\Logger\AbstractHandler; use Homework\Logger\HandlerFactory; +use Homework\Logger\Type; class Logger { @@ -14,9 +15,25 @@ class Logger public static function get(): AbstractHandler { if (self::$instance == null) { - self::$instance = HandlerFactory::get(); + self::$instance = HandlerFactory::get(self::getHandlerType()); } return self::$instance; } + + /** + * Get handler type. + * + * @return Type + */ + private static function getHandlerType(): Type + { + if (count($_SERVER['argv']) > 1) { + if ($_SERVER['argv'][1] === '-c' || $_SERVER['argv'][1] === '--console') { + return Type::CONSOLE; + } + } + + return Type::FILE; + } } From 0eca58a9f1a726f388e92f1b425d37ff68a9a7b1 Mon Sep 17 00:00:00 2001 From: AND Date: Wed, 30 Nov 2022 17:31:25 +0200 Subject: [PATCH 11/12] fix: fixed code style --- Logger/FileHandler.php | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/Logger/FileHandler.php b/Logger/FileHandler.php index 0a0c9ab..7304c7e 100644 --- a/Logger/FileHandler.php +++ b/Logger/FileHandler.php @@ -13,16 +13,8 @@ class FileHandler extends AbstractHandler implements HandlerInterface { use ValidationTrait; - /** - * Path to log file. - * - * @var string - */ - private string $LOG_FILE; - - public function __construct() + public function __construct(private string $LOG_FILE = __DIR__ . '/../application.log') { - $this->LOG_FILE = __DIR__ . '/../application.log'; } /** From 4161165274039203cc94fe0a4a5c79fdc06e814e Mon Sep 17 00:00:00 2001 From: AND Date: Wed, 30 Nov 2022 17:32:15 +0200 Subject: [PATCH 12/12] feat: add tests --- composer.json | 2 +- tests/FileHandlerTest.php | 56 +++++++++++++++++++++++++++++++++++ tests/HandlerFactoryTest.php | 30 +++++++++++++++++++ tests/LoggerTest.php | 20 +++++++++++++ tests/ValidationTraitTest.php | 47 +++++++++++++++++++++++++++++ 5 files changed, 154 insertions(+), 1 deletion(-) create mode 100644 tests/FileHandlerTest.php create mode 100644 tests/HandlerFactoryTest.php create mode 100644 tests/LoggerTest.php create mode 100644 tests/ValidationTraitTest.php diff --git a/composer.json b/composer.json index 5b89e66..b261577 100644 --- a/composer.json +++ b/composer.json @@ -17,6 +17,6 @@ "ext-mbstring": "*" }, "require-dev": { - "phpunit/phpunit": "^9.0" + "phpunit/phpunit": "^9.5" } } diff --git a/tests/FileHandlerTest.php b/tests/FileHandlerTest.php new file mode 100644 index 0000000..6f28ebe --- /dev/null +++ b/tests/FileHandlerTest.php @@ -0,0 +1,56 @@ +fileHandler = new FileHandler(); + $this->fileContent = file_get_contents(self::FILE_PATH); + } + + protected function tearDown(): void + { + parent::tearDown(); + + unset($this->fileHandler); + unset($this->fileContent); + } + + public function testLogSuccess(): void + { + $this->assertTrue($this->fileHandler->log(Status::SUCCESS, 'Test success')); + $this->assertStringEqualsFile(self::FILE_PATH, $this->fileContent . "Success: Test success\n"); + } + + public function testLogError(): void + { + $this->assertTrue($this->fileHandler->log(Status::ERROR, 'Test error')); + $this->assertStringEqualsFile(self::FILE_PATH, $this->fileContent . "Error: Test error\n"); + } + + public function testLogWithEmptyMessage(): void + { + $this->assertFalse($this->fileHandler->log(Status::SUCCESS, '')); + $this->assertStringEqualsFile(self::FILE_PATH, $this->fileContent); + } + + public function testLogFileWritable(): void + { + $this->assertFileIsWritable(self::FILE_PATH); + } +} diff --git a/tests/HandlerFactoryTest.php b/tests/HandlerFactoryTest.php new file mode 100644 index 0000000..eb69ed8 --- /dev/null +++ b/tests/HandlerFactoryTest.php @@ -0,0 +1,30 @@ +assertInstanceOf('Homework\Logger\FileHandler', $instance); + $this->assertInstanceOf('Homework\Logger\HandlerInterface', $instance); + $this->assertInstanceOf('Homework\Logger\AbstractHandler', $instance); + } + + public function testConsoleHandler(): void + { + $instance = HandlerFactory::get(Type::CONSOLE); + + $this->assertInstanceOf('Homework\Logger\ConsoleHandler', $instance); + $this->assertInstanceOf('Homework\Logger\HandlerInterface', $instance); + $this->assertInstanceOf('Homework\Logger\AbstractHandler', $instance); + } +} diff --git a/tests/LoggerTest.php b/tests/LoggerTest.php new file mode 100644 index 0000000..1465f98 --- /dev/null +++ b/tests/LoggerTest.php @@ -0,0 +1,20 @@ +assertInstanceOf('Homework\Logger\FileHandler', $instance); + $this->assertInstanceOf('Homework\Logger\HandlerInterface', $instance); + $this->assertInstanceOf('Homework\Logger\AbstractHandler', $instance); + } +} diff --git a/tests/ValidationTraitTest.php b/tests/ValidationTraitTest.php new file mode 100644 index 0000000..e3c4519 --- /dev/null +++ b/tests/ValidationTraitTest.php @@ -0,0 +1,47 @@ +validationTrait = $this->getMockForTrait(ValidationTrait::class); + } + + protected function tearDown(): void + { + parent::tearDown(); + + unset($this->validationTrait); + } + + /** + * @dataProvider validationProvider + */ + public function testValidate($message, $result): void + { + $this->assertSame($this->validationTrait->validate($message), $result); + } + + public function validationProvider(): array + { + $data = [ + ['test', true], + ['🔰', true], + ["\xd1", false], // Test broken UTF-8 + ['', false] + ]; + + return $data; + } +}