From a2bbe806d39aa29024b9b06a20c74761a795532e Mon Sep 17 00:00:00 2001 From: michnhokn Date: Sat, 13 Nov 2021 11:41:30 +0100 Subject: [PATCH] add first functional implementation --- README.md | 13 +- {src => classes}/Log.php | 2 + classes/Logger.php | 346 +++++++++++ composer.json | 9 +- composer.lock | 744 ++++++++++++++++++++++++ index.css | 2 +- index.js | 2 +- index.php | 46 +- package.json | 6 - src/Logger.php | 210 ------- src/components/LoggerArea.vue | 246 ++++---- vendor/autoload.php | 7 + vendor/composer/ClassLoader.php | 572 ++++++++++++++++++ vendor/composer/InstalledVersions.php | 337 +++++++++++ vendor/composer/autoload_classmap.php | 16 + vendor/composer/autoload_namespaces.php | 9 + vendor/composer/autoload_psr4.php | 11 + vendor/composer/autoload_real.php | 57 ++ vendor/composer/autoload_static.php | 50 ++ vendor/composer/installed.php | 32 + vendor/composer/platform_check.php | 26 + 21 files changed, 2399 insertions(+), 344 deletions(-) rename {src => classes}/Log.php (99%) create mode 100644 classes/Logger.php create mode 100644 composer.lock delete mode 100644 src/Logger.php create mode 100644 vendor/autoload.php create mode 100644 vendor/composer/ClassLoader.php create mode 100644 vendor/composer/InstalledVersions.php create mode 100644 vendor/composer/autoload_classmap.php create mode 100644 vendor/composer/autoload_namespaces.php create mode 100644 vendor/composer/autoload_psr4.php create mode 100644 vendor/composer/autoload_real.php create mode 100644 vendor/composer/autoload_static.php create mode 100644 vendor/composer/installed.php create mode 100644 vendor/composer/platform_check.php diff --git a/README.md b/README.md index 60f7e48..96e743f 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,8 @@ ![Release](https://flat.badgen.net/packagist/v/michnhokn/kirby3-logger?color=92a9c4) ![Last Commit](https://flat.badgen.net/github/last-commit/michnhokn/kirby3-logger?color=92c496) +![Kirby Logger](https://user-images.githubusercontent.com/38752255/141615310-f35b7dde-c732-4d5e-81b7-506d5dfc55db.png) + ## Commercial Usage This plugin is free but if you use it in a commercial project please consider to @@ -17,13 +19,22 @@ This plugin is free but if you use it in a commercial project please consider to - `composer require michnhokn/kirby3-logger` ## Features - +⚠️ This plugin is under development. Please rethink using it in a commercial project. +* Log the following actions to a searchable and filterable table: `user`, `file`, `page`, `site` +* Seperate panel view ## Setup +Just install the plugin. At the moment there are no settings what soever. +## Upcomming features +* Permissions to view the logs +* More configuration for the panel view +* More details in the panel view ## Misc **License**: `MIT` **Credits**: [MichnHokn](https://github.com/michnhokn) + +**Inspiration**: [Kirby Logger](https://github.com/texnixe/kirby-logger) by @texnixe | [Logger for Kirby 3](https://github.com/medienbaecker/kirby-logger) by @medienbaecker diff --git a/src/Log.php b/classes/Log.php similarity index 99% rename from src/Log.php rename to classes/Log.php index 63ebf0e..5ff4ac9 100644 --- a/src/Log.php +++ b/classes/Log.php @@ -1,5 +1,7 @@ root('logs') . '/kirby3-logger/'; + $schema = F::read(__DIR__ . '/../logs-schema.sql'); + + Dir::make($logDir, true); + + static::$connection = new Database(['type' => 'sqlite', 'database' => $logDir . 'logs.sqlite']); + if (!self::$connection->validateTable('logs')) { + self::$connection->execute($schema); + } + + return self::$connection; + } + + /** + * @param int $page + * @param int $limit + * @param array $filter + * @return array + */ + public static function logs(int $page = 1, int $limit = 10, array $filter = []): array + { + if (!self::$connection->validateTable('logs')) { + return []; + } + + $query = self::$connection->table('logs')->select('*'); + + if (!empty($filter['timestamp'])) { + $query->where("timestamp >= '{$filter['timestamp']}'"); + } + if (!empty($filter['oldSearch'])) { + $query->where("oldData LIKE '%{$filter['oldSearch']}%'"); + } + if (!empty($filter['newSearch'])) { + $query->where("newData LIKE '%{$filter['newSearch']}%'"); + } + if (!empty($filter['slug'])) { + $query->where("slug LIKE '%{$filter['slug']}%'"); + } + if (!empty($filter['action'])) { + $query->where(['action' => $filter['action']]); + } + if (!empty($filter['type'])) { + $query->where(['type' => $filter['type']]); + } + if (!empty($filter['user'])) { + $query->where(['user' => $filter['user']]); + } + if (!empty($filter['language'])) { + $query->where(['language' => $filter['language']]); + } + + $totalQuery = clone $query; + + $total = $totalQuery->count(); + /** @var Collection $result */ + $result = $query->page($page, $limit); + + return [ + 'logs' => $result ? array_values($result->toArray()) : [], + 'total' => $total ?? 0, + ]; + } + + /** + * @return int + */ + public static function total(): int + { + if (!self::$connection->validateTable('logs')) { + return 0; + } + + return self::$connection + ->table('logs') + ->count(); + } + + /** + * @param string $field + * @return array + */ + public static function options(string $field): array + { + if (!self::$connection->validateTable('logs')) { + return []; + } + $results = self::$connection + ->table('logs') + ->select($field) + ->distinct() + ->fetch('array') + ->all() + ->data(); + + return array_map(function ($result) { + return [ + 'value' => current($result), + 'text' => current($result), + ]; + }, $results); + } + + /** + * @param Event $event + */ + public static function log(Event $event): void + { + if (!in_array($event->type(), self::TYPES)) { + return; + } + + $log = self::getLog($event); + self::$connection->table('logs')->insert($log->toArray()); + } + + /** + * @param Event $event + * @return Log + */ + private static function getLog(Event $event): Log + { + $log = new Log([ + 'type' => $event->type(), + 'action' => $event->action(), + 'user' => kirby()->user()->email(), + 'language' => kirby()->languageCode(), + ]); + $type = $event->type(); + $action = $event->action(); + + switch ($type) { + case 'site': + $log->setSlug($event->newSite()->id()); + switch ($action) { + case 'changeTitle': + $log->setOldData($event->oldSite()->title()->toString()); + $log->setNewData($event->newSite()->title()->toString()); + + return $log; + case 'update': + $log->setOldData($event->oldSite()->content()->toArray()); + $log->setNewData($event->newSite()->content()->toArray()); + + return $log; + } + break; + case 'page': + switch ($action) { + case 'changeNum': + $log->setSlug($event->newPage()->id()); + $log->setOldData($event->oldPage()->num()); + $log->setNewData($event->newPage()->num()); + + return $log; + case 'changeSlug': + $log->setSlug($event->newPage()->id()); + $log->setOldData($event->oldPage()->slug()); + $log->setNewData($event->newPage()->slug()); + + return $log; + case 'changeStatus': + $log->setSlug($event->newPage()->id()); + $log->setOldData($event->oldPage()->status()); + $log->setNewData($event->newPage()->status()); + + return $log; + case 'changeTemplate': + $log->setSlug($event->newPage()->id()); + $log->setOldData($event->oldPage()->template()->name()); + $log->setNewData($event->newPage()->template()->name()); + + return $log; + case 'changeTitle': + $log->setSlug($event->newPage()->id()); + $log->setOldData($event->oldPage()->title()->toString()); + $log->setNewData($event->newPage()->title()->toString()); + + return $log; + case 'create': + $log->setSlug($event->page()->id()); + $log->setOldData(); + $log->setNewData($event->page()->toArray()); + + return $log; + case 'delete': + $log->setSlug($event->page()->id()); + $log->setOldData($event->page()->toArray()); + $log->setNewData('x'); + + return $log; + case 'duplicate': + $log->setSlug($event->duplicatePage()->id()); + $log->setOldData($event->originalPage()->toArray()); + $log->setNewData($event->duplicatePage()->toArray()); + + return $log; + case 'update': + $log->setSlug($event->newPage()->id()); + $log->setOldData($event->oldPage()->content()->toArray()); + $log->setNewData($event->newPage()->content()->toArray()); + + return $log; + } + break; + case 'file': + switch ($action) { + case 'changeName': + $log->setSlug($event->newFile()->id()); + $log->setOldData($event->oldFile()->title()->toString()); + $log->setNewData($event->newFile()->title()->toString()); + + return $log; + case 'changeSort': + $log->setSlug($event->newFile()->id()); + $log->setOldData($event->oldFile()->sort()); + $log->setNewData($event->newFile()->sort()); + + return $log; + case 'create': + $log->setSlug($event->file()->id()); + $log->setOldData(); + $log->setNewData($event->file()->toArray()); + + return $log; + case 'delete': + $log->setSlug($event->file()->id()); + $log->setOldData($event->file()->toArray()); + $log->setNewData('x'); + + return $log; + case 'update': + case 'replace': + $log->setSlug($event->newFile()->id()); + $log->setOldData($event->oldFile()->toArray()); + $log->setNewData($event->newFile()->toArray()); + + return $log; + } + break; + case 'user': + switch ($action) { + case 'changeEmail': + $log->setSlug($event->newUser()->id()); + $log->setOldData($event->oldUser()->email()); + $log->setNewData($event->newUser()->email()); + + return $log; + case 'changeLanguage': + $log->setSlug($event->newUser()->id()); + $log->setOldData($event->oldUser()->language()); + $log->setNewData($event->newUser()->language()); + + return $log; + case 'changeName': + $log->setSlug($event->newUser()->id()); + $log->setOldData($event->oldUser()->name()->toString()); + $log->setNewData($event->newUser()->name()->toString()); + + return $log; + case 'changePassword': + $log->setSlug($event->newUser()->id()); + $log->setOldData($event->oldUser()->password()); + $log->setNewData('●●●●●●●●'); + + return $log; + case 'changeRole': + $log->setSlug($event->newUser()->id()); + $log->setOldData($event->oldUser()->role()->name()); + $log->setNewData($event->newUser()->role()->name()); + + return $log; + case 'create': + $log->setSlug($event->user()->id()); + $log->setOldData(''); + $log->setNewData($event->user()->toArray()); + + return $log; + case 'delete': + $log->setSlug($event->user()->id()); + $log->setOldData($event->user()->toArray()); + $log->setNewData('x'); + + return $log; + case 'update': + $log->setSlug($event->newUser()->id()); + $log->setOldData($event->oldUser()->toArray()); + $log->setNewData($event->newUser()->toArray()); + + return $log; + case 'login': + $log->setSlug($event->user()->id()); + $log->setOldData(); + $log->setNewData('-'); + + return $log; + case 'logout': + $log->setSlug($event->user()->id()); + $log->setOldData(); + $log->setNewData('x'); + + return $log; + } + break; + } + + $log->setSlug('error'); + $log->setOldData('-'); + $log->setNewData('-'); + + return $log; + } +} diff --git a/composer.json b/composer.json index 70d6ad9..1ae01dc 100644 --- a/composer.json +++ b/composer.json @@ -16,12 +16,19 @@ "kirby3-plugin", "logger", "website-log", - "user-log" + "user-log", + "panel-log" ], "config": { "optimize-autoloader": true }, + "autoload": { + "psr-4": { + "Michnhokn\\": "classes/" + } + }, "require": { + "php": ">=8.0.0", "getkirby/composer-installer": "^1.1" } } diff --git a/composer.lock b/composer.lock new file mode 100644 index 0000000..4e3a6db --- /dev/null +++ b/composer.lock @@ -0,0 +1,744 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", + "This file is @generated automatically" + ], + "content-hash": "1a98da105a8991d1384172d086b5e240", + "packages": [ + { + "name": "getkirby/composer-installer", + "version": "1.2.1", + "source": { + "type": "git", + "url": "https://github.com/getkirby/composer-installer.git", + "reference": "c98ece30bfba45be7ce457e1102d1b169d922f3d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/getkirby/composer-installer/zipball/c98ece30bfba45be7ce457e1102d1b169d922f3d", + "reference": "c98ece30bfba45be7ce457e1102d1b169d922f3d", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^1.0 || ^2.0" + }, + "require-dev": { + "composer/composer": "^1.8 || ^2.0" + }, + "type": "composer-plugin", + "extra": { + "class": "Kirby\\ComposerInstaller\\Plugin" + }, + "autoload": { + "psr-4": { + "Kirby\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Kirby's custom Composer installer for the Kirby CMS and for Kirby plugins", + "homepage": "https://getkirby.com", + "support": { + "issues": "https://github.com/getkirby/composer-installer/issues", + "source": "https://github.com/getkirby/composer-installer/tree/1.2.1" + }, + "funding": [ + { + "url": "https://getkirby.com/buy", + "type": "custom" + } + ], + "time": "2020-12-28T12:54:39+00:00" + } + ], + "packages-dev": [ + { + "name": "claviska/simpleimage", + "version": "3.6.3", + "source": { + "type": "git", + "url": "https://github.com/claviska/SimpleImage.git", + "reference": "21b6f4bf4ef1927158b3e29bd0c2d99c6681c750" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/claviska/SimpleImage/zipball/21b6f4bf4ef1927158b3e29bd0c2d99c6681c750", + "reference": "21b6f4bf4ef1927158b3e29bd0c2d99c6681c750", + "shasum": "" + }, + "require": { + "ext-gd": "*", + "league/color-extractor": "0.3.*", + "php": ">=5.6.0" + }, + "type": "library", + "autoload": { + "psr-0": { + "claviska": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Cory LaViska", + "homepage": "http://www.abeautifulsite.net/", + "role": "Developer" + } + ], + "description": "A PHP class that makes working with images as simple as possible.", + "support": { + "issues": "https://github.com/claviska/SimpleImage/issues", + "source": "https://github.com/claviska/SimpleImage/tree/3.6.3" + }, + "funding": [ + { + "url": "https://github.com/claviska", + "type": "github" + } + ], + "time": "2021-04-20T12:18:18+00:00" + }, + { + "name": "filp/whoops", + "version": "2.14.4", + "source": { + "type": "git", + "url": "https://github.com/filp/whoops.git", + "reference": "f056f1fe935d9ed86e698905a957334029899895" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/filp/whoops/zipball/f056f1fe935d9ed86e698905a957334029899895", + "reference": "f056f1fe935d9ed86e698905a957334029899895", + "shasum": "" + }, + "require": { + "php": "^5.5.9 || ^7.0 || ^8.0", + "psr/log": "^1.0.1 || ^2.0 || ^3.0" + }, + "require-dev": { + "mockery/mockery": "^0.9 || ^1.0", + "phpunit/phpunit": "^4.8.36 || ^5.7.27 || ^6.5.14 || ^7.5.20 || ^8.5.8 || ^9.3.3", + "symfony/var-dumper": "^2.6 || ^3.0 || ^4.0 || ^5.0" + }, + "suggest": { + "symfony/var-dumper": "Pretty print complex values better with var-dumper available", + "whoops/soap": "Formats errors as SOAP responses" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.7-dev" + } + }, + "autoload": { + "psr-4": { + "Whoops\\": "src/Whoops/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Filipe Dobreira", + "homepage": "https://github.com/filp", + "role": "Developer" + } + ], + "description": "php error handling for cool kids", + "homepage": "https://filp.github.io/whoops/", + "keywords": [ + "error", + "exception", + "handling", + "library", + "throwable", + "whoops" + ], + "support": { + "issues": "https://github.com/filp/whoops/issues", + "source": "https://github.com/filp/whoops/tree/2.14.4" + }, + "funding": [ + { + "url": "https://github.com/denis-sokolov", + "type": "github" + } + ], + "time": "2021-10-03T12:00:00+00:00" + }, + { + "name": "getkirby/cms", + "version": "3.6.0-rc.5", + "source": { + "type": "git", + "url": "https://github.com/getkirby/kirby.git", + "reference": "e49fd8265823ec630085aa310c335864b8f8e65c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/getkirby/kirby/zipball/e49fd8265823ec630085aa310c335864b8f8e65c", + "reference": "e49fd8265823ec630085aa310c335864b8f8e65c", + "shasum": "" + }, + "require": { + "claviska/simpleimage": "3.6.3", + "ext-ctype": "*", + "ext-mbstring": "*", + "filp/whoops": "2.14.4", + "getkirby/composer-installer": "^1.2.1", + "laminas/laminas-escaper": "2.9.0", + "michelf/php-smartypants": "1.8.1", + "mustangostang/spyc": "0.6.3", + "php": ">=7.4.0 <8.1.0", + "phpmailer/phpmailer": "6.5.1", + "psr/log": "1.1.4", + "true/punycode": "2.1.1" + }, + "type": "kirby-cms", + "autoload": { + "psr-4": { + "Kirby\\": "src/" + }, + "classmap": [ + "dependencies/" + ], + "files": [ + "config/setup.php", + "config/helpers.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "proprietary" + ], + "authors": [ + { + "name": "Kirby Team", + "email": "support@getkirby.com", + "homepage": "https://getkirby.com" + } + ], + "description": "The Kirby 3 core", + "homepage": "https://getkirby.com", + "keywords": [ + "cms", + "core", + "kirby" + ], + "support": { + "email": "support@getkirby.com", + "forum": "https://forum.getkirby.com", + "issues": "https://github.com/getkirby/kirby/issues", + "source": "https://github.com/getkirby/kirby" + }, + "funding": [ + { + "url": "https://getkirby.com/buy", + "type": "custom" + } + ], + "time": "2021-11-12T15:56:35+00:00" + }, + { + "name": "laminas/laminas-escaper", + "version": "2.9.0", + "source": { + "type": "git", + "url": "https://github.com/laminas/laminas-escaper.git", + "reference": "891ad70986729e20ed2e86355fcf93c9dc238a5f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laminas/laminas-escaper/zipball/891ad70986729e20ed2e86355fcf93c9dc238a5f", + "reference": "891ad70986729e20ed2e86355fcf93c9dc238a5f", + "shasum": "" + }, + "require": { + "php": "^7.3 || ~8.0.0 || ~8.1.0" + }, + "conflict": { + "zendframework/zend-escaper": "*" + }, + "require-dev": { + "laminas/laminas-coding-standard": "~2.3.0", + "phpunit/phpunit": "^9.3", + "psalm/plugin-phpunit": "^0.12.2", + "vimeo/psalm": "^3.16" + }, + "suggest": { + "ext-iconv": "*", + "ext-mbstring": "*" + }, + "type": "library", + "autoload": { + "psr-4": { + "Laminas\\Escaper\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "Securely and safely escape HTML, HTML attributes, JavaScript, CSS, and URLs", + "homepage": "https://laminas.dev", + "keywords": [ + "escaper", + "laminas" + ], + "support": { + "chat": "https://laminas.dev/chat", + "docs": "https://docs.laminas.dev/laminas-escaper/", + "forum": "https://discourse.laminas.dev", + "issues": "https://github.com/laminas/laminas-escaper/issues", + "rss": "https://github.com/laminas/laminas-escaper/releases.atom", + "source": "https://github.com/laminas/laminas-escaper" + }, + "funding": [ + { + "url": "https://funding.communitybridge.org/projects/laminas-project", + "type": "community_bridge" + } + ], + "time": "2021-09-02T17:10:53+00:00" + }, + { + "name": "league/color-extractor", + "version": "0.3.2", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/color-extractor.git", + "reference": "837086ec60f50c84c611c613963e4ad2e2aec806" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/color-extractor/zipball/837086ec60f50c84c611c613963e4ad2e2aec806", + "reference": "837086ec60f50c84c611c613963e4ad2e2aec806", + "shasum": "" + }, + "require": { + "ext-gd": "*", + "php": ">=5.4.0" + }, + "replace": { + "matthecat/colorextractor": "*" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "~2", + "phpunit/phpunit": "~5" + }, + "type": "library", + "autoload": { + "psr-4": { + "": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mathieu Lechat", + "email": "math.lechat@gmail.com", + "homepage": "http://matthecat.com", + "role": "Developer" + } + ], + "description": "Extract colors from an image as a human would do.", + "homepage": "https://github.com/thephpleague/color-extractor", + "keywords": [ + "color", + "extract", + "human", + "image", + "palette" + ], + "support": { + "issues": "https://github.com/thephpleague/color-extractor/issues", + "source": "https://github.com/thephpleague/color-extractor/tree/master" + }, + "time": "2016-12-15T09:30:02+00:00" + }, + { + "name": "michelf/php-smartypants", + "version": "1.8.1", + "source": { + "type": "git", + "url": "https://github.com/michelf/php-smartypants.git", + "reference": "47d17c90a4dfd0ccf1f87e25c65e6c8012415aad" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/michelf/php-smartypants/zipball/47d17c90a4dfd0ccf1f87e25c65e6c8012415aad", + "reference": "47d17c90a4dfd0ccf1f87e25c65e6c8012415aad", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "autoload": { + "psr-0": { + "Michelf": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Michel Fortin", + "email": "michel.fortin@michelf.ca", + "homepage": "https://michelf.ca/", + "role": "Developer" + }, + { + "name": "John Gruber", + "homepage": "https://daringfireball.net/" + } + ], + "description": "PHP SmartyPants", + "homepage": "https://michelf.ca/projects/php-smartypants/", + "keywords": [ + "dashes", + "quotes", + "spaces", + "typographer", + "typography" + ], + "support": { + "issues": "https://github.com/michelf/php-smartypants/issues", + "source": "https://github.com/michelf/php-smartypants/tree/1.8.1" + }, + "time": "2016-12-13T01:01:17+00:00" + }, + { + "name": "mustangostang/spyc", + "version": "0.6.3", + "source": { + "type": "git", + "url": "git@github.com:mustangostang/spyc.git", + "reference": "4627c838b16550b666d15aeae1e5289dd5b77da0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/mustangostang/spyc/zipball/4627c838b16550b666d15aeae1e5289dd5b77da0", + "reference": "4627c838b16550b666d15aeae1e5289dd5b77da0", + "shasum": "" + }, + "require": { + "php": ">=5.3.1" + }, + "require-dev": { + "phpunit/phpunit": "4.3.*@dev" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "0.5.x-dev" + } + }, + "autoload": { + "files": [ + "Spyc.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "mustangostang", + "email": "vlad.andersen@gmail.com" + } + ], + "description": "A simple YAML loader/dumper class for PHP", + "homepage": "https://github.com/mustangostang/spyc/", + "keywords": [ + "spyc", + "yaml", + "yml" + ], + "time": "2019-09-10T13:16:29+00:00" + }, + { + "name": "phpmailer/phpmailer", + "version": "v6.5.1", + "source": { + "type": "git", + "url": "https://github.com/PHPMailer/PHPMailer.git", + "reference": "dd803df5ad7492e1b40637f7ebd258fee5ca7355" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/dd803df5ad7492e1b40637f7ebd258fee5ca7355", + "reference": "dd803df5ad7492e1b40637f7ebd258fee5ca7355", + "shasum": "" + }, + "require": { + "ext-ctype": "*", + "ext-filter": "*", + "ext-hash": "*", + "php": ">=5.5.0" + }, + "require-dev": { + "dealerdirect/phpcodesniffer-composer-installer": "^0.7.0", + "doctrine/annotations": "^1.2", + "php-parallel-lint/php-console-highlighter": "^0.5.0", + "php-parallel-lint/php-parallel-lint": "^1.3", + "phpcompatibility/php-compatibility": "^9.3.5", + "roave/security-advisories": "dev-latest", + "squizlabs/php_codesniffer": "^3.6.0", + "yoast/phpunit-polyfills": "^1.0.0" + }, + "suggest": { + "ext-mbstring": "Needed to send email in multibyte encoding charset or decode encoded addresses", + "hayageek/oauth2-yahoo": "Needed for Yahoo XOAUTH2 authentication", + "league/oauth2-google": "Needed for Google XOAUTH2 authentication", + "psr/log": "For optional PSR-3 debug logging", + "stevenmaguire/oauth2-microsoft": "Needed for Microsoft XOAUTH2 authentication", + "symfony/polyfill-mbstring": "To support UTF-8 if the Mbstring PHP extension is not enabled (^1.2)" + }, + "type": "library", + "autoload": { + "psr-4": { + "PHPMailer\\PHPMailer\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "LGPL-2.1-only" + ], + "authors": [ + { + "name": "Marcus Bointon", + "email": "phpmailer@synchromedia.co.uk" + }, + { + "name": "Jim Jagielski", + "email": "jimjag@gmail.com" + }, + { + "name": "Andy Prevost", + "email": "codeworxtech@users.sourceforge.net" + }, + { + "name": "Brent R. Matzelle" + } + ], + "description": "PHPMailer is a full-featured email creation and transfer class for PHP", + "support": { + "issues": "https://github.com/PHPMailer/PHPMailer/issues", + "source": "https://github.com/PHPMailer/PHPMailer/tree/v6.5.1" + }, + "funding": [ + { + "url": "https://github.com/Synchro", + "type": "github" + } + ], + "time": "2021-08-18T09:14:16+00:00" + }, + { + "name": "psr/log", + "version": "1.1.4", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "d49695b909c3b7628b6289db5479a1c204601f11" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/d49695b909c3b7628b6289db5479a1c204601f11", + "reference": "d49695b909c3b7628b6289db5479a1c204601f11", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Log\\": "Psr/Log/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", + "keywords": [ + "log", + "psr", + "psr-3" + ], + "support": { + "source": "https://github.com/php-fig/log/tree/1.1.4" + }, + "time": "2021-05-03T11:20:27+00:00" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.23.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "9174a3d80210dca8daa7f31fec659150bbeabfc6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9174a3d80210dca8daa7f31fec659150bbeabfc6", + "reference": "9174a3d80210dca8daa7f31fec659150bbeabfc6", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.23-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for the Mbstring extension", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "mbstring", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.23.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-05-27T12:26:48+00:00" + }, + { + "name": "true/punycode", + "version": "v2.1.1", + "source": { + "type": "git", + "url": "https://github.com/true/php-punycode.git", + "reference": "a4d0c11a36dd7f4e7cd7096076cab6d3378a071e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/true/php-punycode/zipball/a4d0c11a36dd7f4e7cd7096076cab6d3378a071e", + "reference": "a4d0c11a36dd7f4e7cd7096076cab6d3378a071e", + "shasum": "" + }, + "require": { + "php": ">=5.3.0", + "symfony/polyfill-mbstring": "^1.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.7", + "squizlabs/php_codesniffer": "~2.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "TrueBV\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Renan Gonçalves", + "email": "renan.saddam@gmail.com" + } + ], + "description": "A Bootstring encoding of Unicode for Internationalized Domain Names in Applications (IDNA)", + "homepage": "https://github.com/true/php-punycode", + "keywords": [ + "idna", + "punycode" + ], + "support": { + "issues": "https://github.com/true/php-punycode/issues", + "source": "https://github.com/true/php-punycode/tree/master" + }, + "time": "2016-11-16T10:37:54+00:00" + } + ], + "aliases": [], + "minimum-stability": "RC", + "stability-flags": [], + "prefer-stable": false, + "prefer-lowest": false, + "platform": { + "php": ">=8.0.0" + }, + "platform-dev": [], + "plugin-api-version": "2.1.0" +} diff --git a/index.css b/index.css index da79c05..b73a575 100644 --- a/index.css +++ b/index.css @@ -1 +1 @@ -table{width:100%;border-collapse:collapse}table td,table th{padding:6px 12px;text-align:left;border:1px solid var(--color-border)}.selected{font-weight:bold} +table[data-v-bfa507fc]{width:100%;border-collapse:collapse;display:block}@media screen and (min-width: 65em){table[data-v-bfa507fc]{display:table}}table td[data-v-bfa507fc],table th[data-v-bfa507fc]{border:1px solid var(--color-border);overflow:auto;vertical-align:baseline;text-overflow:unset;white-space:normal} diff --git a/index.js b/index.js index af2c58a..4bfae52 100644 --- a/index.js +++ b/index.js @@ -1 +1 @@ -(()=>{(function(){"use strict";var h=function(){var e=this,n=e.$createElement,t=e._self._c||n;return t("k-inside",[t("k-view",{staticClass:"k-logger-view"},[t("k-header",[e._v("Logger")]),e.logs?t("table",{staticClass:"k-system-plugins"},[t("thead",[t("tr",[t("th",[e._v("Timestamp")]),t("th",[t("k-input",{class:{selected:e.filter.user!==""},attrs:{options:e.userOptions,type:"select",placeholder:"User",icon:"angle-down"},model:{value:e.filter.user,callback:function(s){e.$set(e.filter,"user",s)},expression:"filter.user"}})],1),t("th",[t("k-input",{class:{selected:e.filter.type!==""},attrs:{options:e.typeOptions,type:"select",placeholder:"Type",icon:"angle-down"},model:{value:e.filter.type,callback:function(s){e.$set(e.filter,"type",s)},expression:"filter.type"}})],1),t("th",[t("k-input",{class:{selected:e.filter.action!==""},attrs:{options:e.actionOptions,type:"select",placeholder:"Action",icon:"angle-down"},model:{value:e.filter.action,callback:function(s){e.$set(e.filter,"action",s)},expression:"filter.action"}})],1),t("th",[t("k-input",{class:{selected:e.filter.slug!==""},attrs:{options:e.slugOptions,type:"select",placeholder:"Slug",icon:"angle-down"},model:{value:e.filter.slug,callback:function(s){e.$set(e.filter,"slug",s)},expression:"filter.slug"}})],1),t("th",[t("k-input",{class:{selected:e.filter.language!==""},attrs:{options:e.languageOptions,type:"select",placeholder:"Language",icon:"angle-down"},model:{value:e.filter.language,callback:function(s){e.$set(e.filter,"language",s)},expression:"filter.language"}})],1),t("th",[t("k-input",{class:{selected:e.filter.oldSearch!==""},attrs:{type:"text",placeholder:"Suche ...",icon:"search"},model:{value:e.filter.oldSearch,callback:function(s){e.$set(e.filter,"oldSearch",s)},expression:"filter.oldSearch"}})],1),t("th",[t("k-input",{class:{selected:e.filter.newSearch!==""},attrs:{type:"text",placeholder:"Suche ...",icon:"search"},model:{value:e.filter.newSearch,callback:function(s){e.$set(e.filter,"newSearch",s)},expression:"filter.newSearch"}})],1)])]),t("tbody",e._l(e.logs,function(s){return t("tr",{key:s.id},[t("td",[e._v(e._s(s.timestamp))]),t("td",[e._v(e._s(s.user))]),t("td",[e._v(e._s(s.type))]),t("td",[e._v(e._s(s.action))]),t("td",[e._v(e._s(s.slug))]),t("td",[e._v(e._s(s.language))]),t("td",[e._v(e._s(s.oldData))]),t("td",[e._v(e._s(s.newData))])])}),0)]):e._e(),t("k-pagination",{attrs:{align:"right",details:!0,keys:!0,page:e.page,limit:e.limit,total:e.total},on:{paginate:e.paginate}})],1)],1)},d=[],$="";function f(e,n,t,s,o,u,c,k){var i=typeof e=="function"?e.options:e;n&&(i.render=n,i.staticRenderFns=t,i._compiled=!0),s&&(i.functional=!0),u&&(i._scopeId="data-v-"+u);var l;if(c?(l=function(a){a=a||this.$vnode&&this.$vnode.ssrContext||this.parent&&this.parent.$vnode&&this.parent.$vnode.ssrContext,!a&&typeof __VUE_SSR_CONTEXT__!="undefined"&&(a=__VUE_SSR_CONTEXT__),o&&o.call(this,a),a&&a._registeredComponents&&a._registeredComponents.add(c)},i._ssrRegister=l):o&&(l=k?function(){o.call(this,(i.functional?this.parent:this).$root.$options.shadowRoot)}:o),l)if(i.functional){i._injectStyles=l;var S=i.render;i.render=function(w,g){return l.call(g),S(w,g)}}else{var p=i.beforeCreate;i.beforeCreate=p?[].concat(p,l):[l]}return{exports:e,options:i}}const _={name:"LoggerArea",data(){return{logs:[],total:0,page:1,limit:15,filter:{oldSearch:"",newSearch:"",action:"",type:"",user:"",slug:"",language:""}}},mounted(){this.fetch(this.page,this.limit)},watch:{filter:{handler(e){this.fetch(this.page,this.limit,e)},deep:!0}},methods:{fetch(e=1,n=10,t=null){return this.$api.post("logs.json",{page:e,limit:n,filter:t}).then(s=>{this.logs=s.logs,console.log(this.logs),this.total=s.total})},paginate({page:e,limit:n}){this.page=e,this.limit=n,this.fetch(e,n)}},computed:{userOptions(){const e=this.logs.map(t=>t.user);return[...new Set(e)].map(t=>({value:t,text:t}))},typeOptions(){const e=this.logs.map(t=>t.type);return[...new Set(e)].map(t=>({value:t,text:t}))},actionOptions(){const e=this.logs.map(t=>t.action);return[...new Set(e)].map(t=>({value:t,text:t}))},slugOptions(){const e=this.logs.map(t=>t.slug);return[...new Set(e)].map(t=>({value:t,text:t}))},languageOptions(){const e=this.logs.map(t=>t.language);return[...new Set(e)].map(t=>({value:t,text:t}))}}},r={};var v=f(_,h,d,!1,m,null,null,null);function m(e){for(let n in r)this[n]=r[n]}var y=function(){return v.exports}();window.panel.plugin("michnhokn/logger",{components:{"k-logger-area":y}})})();})(); +(()=>{(function(){"use strict";var g=function(){var t=this,a=t.$createElement,e=t._self._c||a;return e("k-inside",[e("k-view",{staticClass:"k-logger-view"},[e("k-header",[t._v(" "+t._s(t.$t("michnhokn.logger.title"))+" "),e("k-button-group",{attrs:{slot:"left"},slot:"left"},[e("k-button",{attrs:{icon:"refresh"},on:{click:t.reset}},[t._v(t._s(t.$t("michnhokn.logger.reset")))])],1),e("template",{slot:"right"},[e("k-pagination",{attrs:{align:"right",details:!0,page:t.page,limit:t.limit,total:t.total},on:{paginate:t.paginate}})],1)],2),e("k-grid",{attrs:{gutter:"medium"}},[e("k-column",{attrs:{width:"2/6"}},[e("k-select-field",{attrs:{options:t.userOptions,label:t.$t("user"),type:"select",icon:"angle-down"},model:{value:t.filter.user,callback:function(l){t.$set(t.filter,"user",l)},expression:"filter.user"}})],1),e("k-column",{attrs:{width:"1/6"}},[e("k-date-field",{attrs:{display:"YYYY-MM-DD",label:t.$t("date"),calendar:!0,type:"date"},model:{value:t.filter.timestamp,callback:function(l){t.$set(t.filter,"timestamp",l)},expression:"filter.timestamp"}})],1),e("k-column",{attrs:{width:"1/6"}},[e("k-select-field",{attrs:{options:t.typeOptions,label:t.$t("michnhokn.logger.type"),type:"select",icon:"angle-down"},model:{value:t.filter.type,callback:function(l){t.$set(t.filter,"type",l)},expression:"filter.type"}})],1),e("k-column",{attrs:{width:"1/6"}},[e("k-select-field",{attrs:{options:t.actionOptions,label:t.$t("michnhokn.logger.action"),type:"select",icon:"angle-down"},model:{value:t.filter.action,callback:function(l){t.$set(t.filter,"action",l)},expression:"filter.action"}})],1),e("k-column",{attrs:{width:"1/6"}},[e("k-select-field",{attrs:{options:t.languageOptions,label:t.$t("language"),type:"select",icon:"angle-down"},model:{value:t.filter.language,callback:function(l){t.$set(t.filter,"language",l)},expression:"filter.language"}})],1),e("k-column",{attrs:{width:"1/3"}},[e("k-text-field",{attrs:{type:"text",label:t.$t("michnhokn.logger.slug"),placeholder:"Suche ...",icon:"search"},model:{value:t.filter.slug,callback:function(l){t.$set(t.filter,"slug",l)},expression:"filter.slug"}})],1),e("k-column",{attrs:{width:"1/3"}},[e("k-text-field",{attrs:{type:"text",label:t.$t("michnhokn.logger.searchOld"),placeholder:t.$t("search"),icon:"search"},model:{value:t.filter.oldSearch,callback:function(l){t.$set(t.filter,"oldSearch",l)},expression:"filter.oldSearch"}})],1),e("k-column",{attrs:{width:"1/3"}},[e("k-text-field",{attrs:{type:"text",label:t.$t("michnhokn.logger.searchNew"),placeholder:t.$t("search"),icon:"search"},model:{value:t.filter.newSearch,callback:function(l){t.$set(t.filter,"newSearch",l)},expression:"filter.newSearch"}})],1),e("k-column",{staticStyle:{overflow:"auto"},attrs:{width:"1/1"}},[t.logs.length?e("table",{staticClass:"k-system-plugins"},[e("thead",[e("tr",[e("th",{staticStyle:{width:"175px"}},[t._v(t._s(t.$t("date")))]),e("th",[t._v(t._s(t.$t("user")))]),e("th",{staticStyle:{width:"70px"}},[t._v(t._s(t.$t("michnhokn.logger.type")))]),e("th",{staticStyle:{width:"140px"}},[t._v(t._s(t.$t("michnhokn.logger.action")))]),e("th",[t._v(t._s(t.$t("michnhokn.logger.slug")))]),e("th",{staticStyle:{width:"90px"}},[t._v(t._s(t.$t("language")))]),e("th",[t._v(t._s(t.$t("michnhokn.logger.old")))]),e("th",[t._v(t._s(t.$t("michnhokn.logger.new")))])])]),e("tbody",t._l(t.logs,function(l){return e("tr",{key:l.id},[e("td",[t._v(t._s(l.timestamp))]),e("td",[t._v(t._s(l.user))]),e("td",[t._v(t._s(l.type))]),e("td",[t._v(t._s(l.action))]),e("td",[t._v(t._s(l.slug))]),e("td",[t._v(t._s(l.language))]),e("td",[t._v(t._s(l.oldData))]),e("td",[t._v(t._s(l.newData))])])}),0)]):e("k-empty",{attrs:{icon:"table",layout:"cards"}},[t._v(t._s(t.$t("michnhokn.logger.empty")))])],1)],1)],1)],1)},p=[],b="";function f(t,a,e,l,o,c,h,$){var i=typeof t=="function"?t.options:t;a&&(i.render=a,i.staticRenderFns=e,i._compiled=!0),l&&(i.functional=!0),c&&(i._scopeId="data-v-"+c);var s;if(h?(s=function(n){n=n||this.$vnode&&this.$vnode.ssrContext||this.parent&&this.parent.$vnode&&this.parent.$vnode.ssrContext,!n&&typeof __VUE_SSR_CONTEXT__!="undefined"&&(n=__VUE_SSR_CONTEXT__),o&&o.call(this,n),n&&n._registeredComponents&&n._registeredComponents.add(h)},i._ssrRegister=s):o&&(s=$?function(){o.call(this,(i.functional?this.parent:this).$root.$options.shadowRoot)}:o),s)if(i.functional){i._injectStyles=s;var y=i.render;i.render=function(w,d){return s.call(d),y(w,d)}}else{var u=i.beforeCreate;i.beforeCreate=u?[].concat(u,s):[s]}return{exports:t,options:i}}const _={name:"LoggerArea",props:["userOptions","typeOptions","actionOptions","languageOptions"],data(){return{logs:[],total:0,page:1,limit:10,filter:{timestamp:"",oldSearch:"",newSearch:"",action:"",type:"",user:"",slug:"",language:""}}},mounted(){this.fetch(this.page,this.limit)},watch:{filter:{handler(t){this.fetch(this.page,this.limit,t)},deep:!0}},methods:{fetch(t=1,a=10,e=null){return this.$api.post("logs.json",{page:t,limit:a,filter:e}).then(l=>{this.logs=l.logs,this.total=l.total})},paginate({page:t,limit:a}){this.page=t,this.limit=a,this.fetch(t,a)},reset(){this.filter={timestamp:"",oldSearch:"",newSearch:"",action:"",type:"",user:"",slug:"",language:""}}}},r={};var m=f(_,g,p,!1,k,"bfa507fc",null,null);function k(t){for(let a in r)this[a]=r[a]}var v=function(){return m.exports}();window.panel.plugin("michnhokn/logger",{components:{"k-logger-area":v}})})();})(); diff --git a/index.php b/index.php index 3d5ddad..bcab3a5 100644 --- a/index.php +++ b/index.php @@ -1,14 +1,42 @@ [ + 'en' => [ + 'michnhokn.logger.title' => 'Logger', + 'michnhokn.logger.logs' => 'Logs', + 'michnhokn.logger.reset' => 'Reset filter', + 'michnhokn.logger.type' => 'Type', + 'michnhokn.logger.action' => 'Action', + 'michnhokn.logger.slug' => 'Slug', + 'michnhokn.logger.old' => 'Old data', + 'michnhokn.logger.searchOld' => 'Search old data', + 'michnhokn.logger.new' => 'New data', + 'michnhokn.logger.searchNew' => 'Search new data', + 'michnhokn.logger.empty' => 'No log entries yet', + ], + 'de' => [ + 'michnhokn.logger.title' => 'Logger', + 'michnhokn.logger.logs' => 'Logs', + 'michnhokn.logger.reset' => 'Filter zurücksetzten', + 'michnhokn.logger.type' => 'Typ', + 'michnhokn.logger.action' => 'Aktion', + 'michnhokn.logger.slug' => 'Slug', + 'michnhokn.logger.old' => 'Alte Daten', + 'michnhokn.logger.searchOld' => 'Alte Daten durchsuchen', + 'michnhokn.logger.new' => 'Neue Daten', + 'michnhokn.logger.searchNew' => 'Neue Daten durchsuchen', + 'michnhokn.logger.empty' => 'Bisher keine Log Einträge', + ], + ], 'hooks' => [ 'system.loadPlugins:after' => function () { - Logger::connect(); + \Michnhokn\Logger::connect(); }, '*:after' => function (\Kirby\Cms\Event $event) { - Logger::log($event); + \Michnhokn\Logger::log($event); }, ], 'api' => [ @@ -17,7 +45,7 @@ 'pattern' => 'logs.json', 'method' => 'POST', 'action' => function () { - return Logger::logs( + return \Michnhokn\Logger::logs( $this->requestBody('page', 1), $this->requestBody('limit', 10), $this->requestBody('filter', []) @@ -29,7 +57,7 @@ 'areas' => [ 'kirby3-logger' => function () { return [ - 'label' => 'Logger', + 'label' => t('michnhokn.logger.title'), 'icon' => 'table', 'menu' => true, 'link' => 'logger', @@ -39,7 +67,13 @@ 'action' => function () { return [ 'component' => 'k-logger-area', - 'title' => 'Logs', + 'title' => t('michnhokn.logger.logs'), + 'props' => [ + 'userOptions' => \Michnhokn\Logger::options('user'), + 'typeOptions' => \Michnhokn\Logger::options('type'), + 'actionOptions' => \Michnhokn\Logger::options('action'), + 'languageOptions' => \Michnhokn\Logger::options('language'), + ], ]; }, ], diff --git a/package.json b/package.json index e9bca0e..a933ea2 100644 --- a/package.json +++ b/package.json @@ -2,11 +2,5 @@ "scripts": { "dev": "npx -y kirbyup src/index.js --watch", "build": "npx -y kirbyup src/index.js" - }, - "dependencies": { - "fuse.js": "^6.4.6", - "vue-json-component": "^0.4.1", - "vue-json-pretty": "^1.8.2", - "vue-json-tree-view": "^2.1.6" } } diff --git a/src/Logger.php b/src/Logger.php deleted file mode 100644 index 81c046e..0000000 --- a/src/Logger.php +++ /dev/null @@ -1,210 +0,0 @@ -root('logs') . '/kirby3-logger/'; - $schema = F::read(__DIR__ . '/../logs-schema.sql'); - - Dir::make($logDir, true); - - static::$connection = new Database(['type' => 'sqlite', 'database' => $logDir . 'logs.sqlite']); - if (!self::$connection->validateTable('logs')) { - self::$connection->execute($schema); - } - - return self::$connection; - } - - /** - * @param int $page - * @param int $limit - * @param array $filter - * @return array - */ - public static function logs(int $page = 1, int $limit = 10, array $filter = []): array - { - if (!self::$connection->validateTable('logs')) { - return []; - } - - $query = self::$connection->table('logs')->select('*'); - - if (!empty($filter['oldSearch'])) { - $query->where("oldData LIKE '%{$filter['oldSearch']}%'"); - } - if (!empty($filter['newSearch'])) { - $query->where("newData LIKE '%{$filter['newSearch']}%'"); - } - if (!empty($filter['action'])) { - $query->where(['action' => $filter['action']]); - } - if (!empty($filter['type'])) { - $query->where(['type' => $filter['type']]); - } - if (!empty($filter['user'])) { - $query->where(['user' => $filter['user']]); - } - if (!empty($filter['slug'])) { - $query->where(['slug' => $filter['slug']]); - } - if (!empty($filter['language'])) { - $query->where(['language' => $filter['language']]); - } - - $totalQuery = clone $query; - - $total = $totalQuery->count(); - /** @var \Kirby\Cms\Collection $result */ - $result = $query->page($page, $limit); - - return [ - 'logs' => $result ? array_values($result->toArray()) : [], - 'total' => $total ?? 0, - ]; - } - - /** - * @return int - */ - public static function total(): int - { - return self::$connection->table('logs')->count(); - } - - /** - * @param Event $event - */ - public static function log(Event $event): void - { - if (!in_array($event->type(), self::TYPES)) { - return; - } - - $log = self::getLog($event); - self::$connection->table('logs')->insert($log->toArray()); - } - - /** - * @param Event $event - * @return Log - */ - private static function getLog(Event $event): Log - { - $log = new Log([ - 'type' => $event->type(), - 'action' => $event->action(), - 'user' => kirby()->user()->email(), - 'language' => kirby()->languageCode(), - ]); - $type = $event->type(); - $action = $event->action(); - - switch ($type) { - case 'site': - $log->setSlug('site'); - switch ($action) { - case 'changeTitle': - $log->setOldData($event->oldSite()->title()->toString()); - $log->setNewData($event->newSite()->title()->toString()); - - return $log; - case 'update': - $log->setOldData($event->oldSite()->content()->toArray()); - $log->setNewData($event->newSite()->content()->toArray()); - - return $log; - } - break; - case 'page': - switch ($action) { - case 'changeNum': - $log->setSlug($event->newPage()->slug()); - $log->setOldData($event->oldPage()->num()); - $log->setNewData($event->newPage()->num()); - - return $log; - case 'changeSlug': - $log->setSlug($event->newPage()->slug()); - $log->setOldData($event->oldPage()->slug()); - $log->setNewData($event->newPage()->slug()); - - return $log; - case 'changeStatus': - $log->setSlug($event->newPage()->slug()); - $log->setOldData($event->oldPage()->status()); - $log->setNewData($event->newPage()->status()); - - return $log; - case 'changeTemplate': - $log->setSlug($event->newPage()->slug()); - $log->setOldData($event->oldPage()->template()->name()); - $log->setNewData($event->newPage()->template()->name()); - - return $log; - case 'changeTitle': - $log->setSlug($event->newPage()->slug()); - $log->setOldData($event->oldPage()->title()->toString()); - $log->setNewData($event->newPage()->title()->toString()); - - return $log; - case 'create': - $log->setSlug($event->page()->slug()); - $log->setOldData(); - $log->setNewData($event->page()->toArray()); - - return $log; - case 'delete': - $log->setSlug($event->page()->slug()); - $log->setOldData($event->page()->toArray()); - $log->setNewData('x'); - - return $log; - case 'duplicate': - $log->setSlug($event->duplicatePage()->slug()); - $log->setOldData($event->originalPage()->toArray()); - $log->setNewData($event->duplicatePage()->toArray()); - - return $log; - case 'update': - $log->setSlug($event->newPage()->slug()); - $log->setOldData($event->oldPage()->content()->toArray()); - $log->setNewData($event->newPage()->content()->toArray()); - - return $log; - } - } - - $log->setSlug('error'); - $log->setOldData('-'); - $log->setNewData('-'); - - return $log; - } -} diff --git a/src/components/LoggerArea.vue b/src/components/LoggerArea.vue index 9e9f635..f5c133f 100644 --- a/src/components/LoggerArea.vue +++ b/src/components/LoggerArea.vue @@ -1,88 +1,109 @@ @@ -90,14 +111,15 @@ - \ No newline at end of file diff --git a/vendor/autoload.php b/vendor/autoload.php new file mode 100644 index 0000000..b84184c --- /dev/null +++ b/vendor/autoload.php @@ -0,0 +1,7 @@ + + * Jordi Boggiano + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Composer\Autoload; + +/** + * ClassLoader implements a PSR-0, PSR-4 and classmap class loader. + * + * $loader = new \Composer\Autoload\ClassLoader(); + * + * // register classes with namespaces + * $loader->add('Symfony\Component', __DIR__.'/component'); + * $loader->add('Symfony', __DIR__.'/framework'); + * + * // activate the autoloader + * $loader->register(); + * + * // to enable searching the include path (eg. for PEAR packages) + * $loader->setUseIncludePath(true); + * + * In this example, if you try to use a class in the Symfony\Component + * namespace or one of its children (Symfony\Component\Console for instance), + * the autoloader will first look for the class under the component/ + * directory, and it will then fallback to the framework/ directory if not + * found before giving up. + * + * This class is loosely based on the Symfony UniversalClassLoader. + * + * @author Fabien Potencier + * @author Jordi Boggiano + * @see https://www.php-fig.org/psr/psr-0/ + * @see https://www.php-fig.org/psr/psr-4/ + */ +class ClassLoader +{ + /** @var ?string */ + private $vendorDir; + + // PSR-4 + /** + * @var array[] + * @psalm-var array> + */ + private $prefixLengthsPsr4 = array(); + /** + * @var array[] + * @psalm-var array> + */ + private $prefixDirsPsr4 = array(); + /** + * @var array[] + * @psalm-var array + */ + private $fallbackDirsPsr4 = array(); + + // PSR-0 + /** + * @var array[] + * @psalm-var array> + */ + private $prefixesPsr0 = array(); + /** + * @var array[] + * @psalm-var array + */ + private $fallbackDirsPsr0 = array(); + + /** @var bool */ + private $useIncludePath = false; + + /** + * @var string[] + * @psalm-var array + */ + private $classMap = array(); + + /** @var bool */ + private $classMapAuthoritative = false; + + /** + * @var bool[] + * @psalm-var array + */ + private $missingClasses = array(); + + /** @var ?string */ + private $apcuPrefix; + + /** + * @var self[] + */ + private static $registeredLoaders = array(); + + /** + * @param ?string $vendorDir + */ + public function __construct($vendorDir = null) + { + $this->vendorDir = $vendorDir; + } + + /** + * @return string[] + */ + public function getPrefixes() + { + if (!empty($this->prefixesPsr0)) { + return call_user_func_array('array_merge', array_values($this->prefixesPsr0)); + } + + return array(); + } + + /** + * @return array[] + * @psalm-return array> + */ + public function getPrefixesPsr4() + { + return $this->prefixDirsPsr4; + } + + /** + * @return array[] + * @psalm-return array + */ + public function getFallbackDirs() + { + return $this->fallbackDirsPsr0; + } + + /** + * @return array[] + * @psalm-return array + */ + public function getFallbackDirsPsr4() + { + return $this->fallbackDirsPsr4; + } + + /** + * @return string[] Array of classname => path + * @psalm-var array + */ + public function getClassMap() + { + return $this->classMap; + } + + /** + * @param string[] $classMap Class to filename map + * @psalm-param array $classMap + * + * @return void + */ + public function addClassMap(array $classMap) + { + if ($this->classMap) { + $this->classMap = array_merge($this->classMap, $classMap); + } else { + $this->classMap = $classMap; + } + } + + /** + * Registers a set of PSR-0 directories for a given prefix, either + * appending or prepending to the ones previously set for this prefix. + * + * @param string $prefix The prefix + * @param string[]|string $paths The PSR-0 root directories + * @param bool $prepend Whether to prepend the directories + * + * @return void + */ + public function add($prefix, $paths, $prepend = false) + { + if (!$prefix) { + if ($prepend) { + $this->fallbackDirsPsr0 = array_merge( + (array) $paths, + $this->fallbackDirsPsr0 + ); + } else { + $this->fallbackDirsPsr0 = array_merge( + $this->fallbackDirsPsr0, + (array) $paths + ); + } + + return; + } + + $first = $prefix[0]; + if (!isset($this->prefixesPsr0[$first][$prefix])) { + $this->prefixesPsr0[$first][$prefix] = (array) $paths; + + return; + } + if ($prepend) { + $this->prefixesPsr0[$first][$prefix] = array_merge( + (array) $paths, + $this->prefixesPsr0[$first][$prefix] + ); + } else { + $this->prefixesPsr0[$first][$prefix] = array_merge( + $this->prefixesPsr0[$first][$prefix], + (array) $paths + ); + } + } + + /** + * Registers a set of PSR-4 directories for a given namespace, either + * appending or prepending to the ones previously set for this namespace. + * + * @param string $prefix The prefix/namespace, with trailing '\\' + * @param string[]|string $paths The PSR-4 base directories + * @param bool $prepend Whether to prepend the directories + * + * @throws \InvalidArgumentException + * + * @return void + */ + public function addPsr4($prefix, $paths, $prepend = false) + { + if (!$prefix) { + // Register directories for the root namespace. + if ($prepend) { + $this->fallbackDirsPsr4 = array_merge( + (array) $paths, + $this->fallbackDirsPsr4 + ); + } else { + $this->fallbackDirsPsr4 = array_merge( + $this->fallbackDirsPsr4, + (array) $paths + ); + } + } elseif (!isset($this->prefixDirsPsr4[$prefix])) { + // Register directories for a new namespace. + $length = strlen($prefix); + if ('\\' !== $prefix[$length - 1]) { + throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); + } + $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; + $this->prefixDirsPsr4[$prefix] = (array) $paths; + } elseif ($prepend) { + // Prepend directories for an already registered namespace. + $this->prefixDirsPsr4[$prefix] = array_merge( + (array) $paths, + $this->prefixDirsPsr4[$prefix] + ); + } else { + // Append directories for an already registered namespace. + $this->prefixDirsPsr4[$prefix] = array_merge( + $this->prefixDirsPsr4[$prefix], + (array) $paths + ); + } + } + + /** + * Registers a set of PSR-0 directories for a given prefix, + * replacing any others previously set for this prefix. + * + * @param string $prefix The prefix + * @param string[]|string $paths The PSR-0 base directories + * + * @return void + */ + public function set($prefix, $paths) + { + if (!$prefix) { + $this->fallbackDirsPsr0 = (array) $paths; + } else { + $this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths; + } + } + + /** + * Registers a set of PSR-4 directories for a given namespace, + * replacing any others previously set for this namespace. + * + * @param string $prefix The prefix/namespace, with trailing '\\' + * @param string[]|string $paths The PSR-4 base directories + * + * @throws \InvalidArgumentException + * + * @return void + */ + public function setPsr4($prefix, $paths) + { + if (!$prefix) { + $this->fallbackDirsPsr4 = (array) $paths; + } else { + $length = strlen($prefix); + if ('\\' !== $prefix[$length - 1]) { + throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); + } + $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; + $this->prefixDirsPsr4[$prefix] = (array) $paths; + } + } + + /** + * Turns on searching the include path for class files. + * + * @param bool $useIncludePath + * + * @return void + */ + public function setUseIncludePath($useIncludePath) + { + $this->useIncludePath = $useIncludePath; + } + + /** + * Can be used to check if the autoloader uses the include path to check + * for classes. + * + * @return bool + */ + public function getUseIncludePath() + { + return $this->useIncludePath; + } + + /** + * Turns off searching the prefix and fallback directories for classes + * that have not been registered with the class map. + * + * @param bool $classMapAuthoritative + * + * @return void + */ + public function setClassMapAuthoritative($classMapAuthoritative) + { + $this->classMapAuthoritative = $classMapAuthoritative; + } + + /** + * Should class lookup fail if not found in the current class map? + * + * @return bool + */ + public function isClassMapAuthoritative() + { + return $this->classMapAuthoritative; + } + + /** + * APCu prefix to use to cache found/not-found classes, if the extension is enabled. + * + * @param string|null $apcuPrefix + * + * @return void + */ + public function setApcuPrefix($apcuPrefix) + { + $this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null; + } + + /** + * The APCu prefix in use, or null if APCu caching is not enabled. + * + * @return string|null + */ + public function getApcuPrefix() + { + return $this->apcuPrefix; + } + + /** + * Registers this instance as an autoloader. + * + * @param bool $prepend Whether to prepend the autoloader or not + * + * @return void + */ + public function register($prepend = false) + { + spl_autoload_register(array($this, 'loadClass'), true, $prepend); + + if (null === $this->vendorDir) { + return; + } + + if ($prepend) { + self::$registeredLoaders = array($this->vendorDir => $this) + self::$registeredLoaders; + } else { + unset(self::$registeredLoaders[$this->vendorDir]); + self::$registeredLoaders[$this->vendorDir] = $this; + } + } + + /** + * Unregisters this instance as an autoloader. + * + * @return void + */ + public function unregister() + { + spl_autoload_unregister(array($this, 'loadClass')); + + if (null !== $this->vendorDir) { + unset(self::$registeredLoaders[$this->vendorDir]); + } + } + + /** + * Loads the given class or interface. + * + * @param string $class The name of the class + * @return true|null True if loaded, null otherwise + */ + public function loadClass($class) + { + if ($file = $this->findFile($class)) { + includeFile($file); + + return true; + } + + return null; + } + + /** + * Finds the path to the file where the class is defined. + * + * @param string $class The name of the class + * + * @return string|false The path if found, false otherwise + */ + public function findFile($class) + { + // class map lookup + if (isset($this->classMap[$class])) { + return $this->classMap[$class]; + } + if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) { + return false; + } + if (null !== $this->apcuPrefix) { + $file = apcu_fetch($this->apcuPrefix.$class, $hit); + if ($hit) { + return $file; + } + } + + $file = $this->findFileWithExtension($class, '.php'); + + // Search for Hack files if we are running on HHVM + if (false === $file && defined('HHVM_VERSION')) { + $file = $this->findFileWithExtension($class, '.hh'); + } + + if (null !== $this->apcuPrefix) { + apcu_add($this->apcuPrefix.$class, $file); + } + + if (false === $file) { + // Remember that this class does not exist. + $this->missingClasses[$class] = true; + } + + return $file; + } + + /** + * Returns the currently registered loaders indexed by their corresponding vendor directories. + * + * @return self[] + */ + public static function getRegisteredLoaders() + { + return self::$registeredLoaders; + } + + /** + * @param string $class + * @param string $ext + * @return string|false + */ + private function findFileWithExtension($class, $ext) + { + // PSR-4 lookup + $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext; + + $first = $class[0]; + if (isset($this->prefixLengthsPsr4[$first])) { + $subPath = $class; + while (false !== $lastPos = strrpos($subPath, '\\')) { + $subPath = substr($subPath, 0, $lastPos); + $search = $subPath . '\\'; + if (isset($this->prefixDirsPsr4[$search])) { + $pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1); + foreach ($this->prefixDirsPsr4[$search] as $dir) { + if (file_exists($file = $dir . $pathEnd)) { + return $file; + } + } + } + } + } + + // PSR-4 fallback dirs + foreach ($this->fallbackDirsPsr4 as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) { + return $file; + } + } + + // PSR-0 lookup + if (false !== $pos = strrpos($class, '\\')) { + // namespaced class name + $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1) + . strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR); + } else { + // PEAR-like class name + $logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext; + } + + if (isset($this->prefixesPsr0[$first])) { + foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) { + if (0 === strpos($class, $prefix)) { + foreach ($dirs as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { + return $file; + } + } + } + } + } + + // PSR-0 fallback dirs + foreach ($this->fallbackDirsPsr0 as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { + return $file; + } + } + + // PSR-0 include paths. + if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) { + return $file; + } + + return false; + } +} + +/** + * Scope isolated include. + * + * Prevents access to $this/self from included files. + * + * @param string $file + * @return void + * @private + */ +function includeFile($file) +{ + include $file; +} diff --git a/vendor/composer/InstalledVersions.php b/vendor/composer/InstalledVersions.php new file mode 100644 index 0000000..7c5502c --- /dev/null +++ b/vendor/composer/InstalledVersions.php @@ -0,0 +1,337 @@ + + * Jordi Boggiano + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Composer; + +use Composer\Autoload\ClassLoader; +use Composer\Semver\VersionParser; + +/** + * This class is copied in every Composer installed project and available to all + * + * See also https://getcomposer.org/doc/07-runtime.md#installed-versions + * + * To require its presence, you can require `composer-runtime-api ^2.0` + */ +class InstalledVersions +{ + private static $installed; + private static $canGetVendors; + private static $installedByVendor = array(); + + /** + * Returns a list of all package names which are present, either by being installed, replaced or provided + * + * @return string[] + * @psalm-return list + */ + public static function getInstalledPackages() + { + $packages = array(); + foreach (self::getInstalled() as $installed) { + $packages[] = array_keys($installed['versions']); + } + + if (1 === \count($packages)) { + return $packages[0]; + } + + return array_keys(array_flip(\call_user_func_array('array_merge', $packages))); + } + + /** + * Returns a list of all package names with a specific type e.g. 'library' + * + * @param string $type + * @return string[] + * @psalm-return list + */ + public static function getInstalledPackagesByType($type) + { + $packagesByType = array(); + + foreach (self::getInstalled() as $installed) { + foreach ($installed['versions'] as $name => $package) { + if (isset($package['type']) && $package['type'] === $type) { + $packagesByType[] = $name; + } + } + } + + return $packagesByType; + } + + /** + * Checks whether the given package is installed + * + * This also returns true if the package name is provided or replaced by another package + * + * @param string $packageName + * @param bool $includeDevRequirements + * @return bool + */ + public static function isInstalled($packageName, $includeDevRequirements = true) + { + foreach (self::getInstalled() as $installed) { + if (isset($installed['versions'][$packageName])) { + return $includeDevRequirements || empty($installed['versions'][$packageName]['dev_requirement']); + } + } + + return false; + } + + /** + * Checks whether the given package satisfies a version constraint + * + * e.g. If you want to know whether version 2.3+ of package foo/bar is installed, you would call: + * + * Composer\InstalledVersions::satisfies(new VersionParser, 'foo/bar', '^2.3') + * + * @param VersionParser $parser Install composer/semver to have access to this class and functionality + * @param string $packageName + * @param string|null $constraint A version constraint to check for, if you pass one you have to make sure composer/semver is required by your package + * @return bool + */ + public static function satisfies(VersionParser $parser, $packageName, $constraint) + { + $constraint = $parser->parseConstraints($constraint); + $provided = $parser->parseConstraints(self::getVersionRanges($packageName)); + + return $provided->matches($constraint); + } + + /** + * Returns a version constraint representing all the range(s) which are installed for a given package + * + * It is easier to use this via isInstalled() with the $constraint argument if you need to check + * whether a given version of a package is installed, and not just whether it exists + * + * @param string $packageName + * @return string Version constraint usable with composer/semver + */ + public static function getVersionRanges($packageName) + { + foreach (self::getInstalled() as $installed) { + if (!isset($installed['versions'][$packageName])) { + continue; + } + + $ranges = array(); + if (isset($installed['versions'][$packageName]['pretty_version'])) { + $ranges[] = $installed['versions'][$packageName]['pretty_version']; + } + if (array_key_exists('aliases', $installed['versions'][$packageName])) { + $ranges = array_merge($ranges, $installed['versions'][$packageName]['aliases']); + } + if (array_key_exists('replaced', $installed['versions'][$packageName])) { + $ranges = array_merge($ranges, $installed['versions'][$packageName]['replaced']); + } + if (array_key_exists('provided', $installed['versions'][$packageName])) { + $ranges = array_merge($ranges, $installed['versions'][$packageName]['provided']); + } + + return implode(' || ', $ranges); + } + + throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); + } + + /** + * @param string $packageName + * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present + */ + public static function getVersion($packageName) + { + foreach (self::getInstalled() as $installed) { + if (!isset($installed['versions'][$packageName])) { + continue; + } + + if (!isset($installed['versions'][$packageName]['version'])) { + return null; + } + + return $installed['versions'][$packageName]['version']; + } + + throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); + } + + /** + * @param string $packageName + * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present + */ + public static function getPrettyVersion($packageName) + { + foreach (self::getInstalled() as $installed) { + if (!isset($installed['versions'][$packageName])) { + continue; + } + + if (!isset($installed['versions'][$packageName]['pretty_version'])) { + return null; + } + + return $installed['versions'][$packageName]['pretty_version']; + } + + throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); + } + + /** + * @param string $packageName + * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as reference + */ + public static function getReference($packageName) + { + foreach (self::getInstalled() as $installed) { + if (!isset($installed['versions'][$packageName])) { + continue; + } + + if (!isset($installed['versions'][$packageName]['reference'])) { + return null; + } + + return $installed['versions'][$packageName]['reference']; + } + + throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); + } + + /** + * @param string $packageName + * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as install path. Packages of type metapackages also have a null install path. + */ + public static function getInstallPath($packageName) + { + foreach (self::getInstalled() as $installed) { + if (!isset($installed['versions'][$packageName])) { + continue; + } + + return isset($installed['versions'][$packageName]['install_path']) ? $installed['versions'][$packageName]['install_path'] : null; + } + + throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); + } + + /** + * @return array + * @psalm-return array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string} + */ + public static function getRootPackage() + { + $installed = self::getInstalled(); + + return $installed[0]['root']; + } + + /** + * Returns the raw installed.php data for custom implementations + * + * @deprecated Use getAllRawData() instead which returns all datasets for all autoloaders present in the process. getRawData only returns the first dataset loaded, which may not be what you expect. + * @return array[] + * @psalm-return array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array} + */ + public static function getRawData() + { + @trigger_error('getRawData only returns the first dataset loaded, which may not be what you expect. Use getAllRawData() instead which returns all datasets for all autoloaders present in the process.', E_USER_DEPRECATED); + + if (null === self::$installed) { + // only require the installed.php file if this file is loaded from its dumped location, + // and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937 + if (substr(__DIR__, -8, 1) !== 'C') { + self::$installed = include __DIR__ . '/installed.php'; + } else { + self::$installed = array(); + } + } + + return self::$installed; + } + + /** + * Returns the raw data of all installed.php which are currently loaded for custom implementations + * + * @return array[] + * @psalm-return list}> + */ + public static function getAllRawData() + { + return self::getInstalled(); + } + + /** + * Lets you reload the static array from another file + * + * This is only useful for complex integrations in which a project needs to use + * this class but then also needs to execute another project's autoloader in process, + * and wants to ensure both projects have access to their version of installed.php. + * + * A typical case would be PHPUnit, where it would need to make sure it reads all + * the data it needs from this class, then call reload() with + * `require $CWD/vendor/composer/installed.php` (or similar) as input to make sure + * the project in which it runs can then also use this class safely, without + * interference between PHPUnit's dependencies and the project's dependencies. + * + * @param array[] $data A vendor/composer/installed.php data set + * @return void + * + * @psalm-param array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array} $data + */ + public static function reload($data) + { + self::$installed = $data; + self::$installedByVendor = array(); + } + + /** + * @return array[] + * @psalm-return list}> + */ + private static function getInstalled() + { + if (null === self::$canGetVendors) { + self::$canGetVendors = method_exists('Composer\Autoload\ClassLoader', 'getRegisteredLoaders'); + } + + $installed = array(); + + if (self::$canGetVendors) { + foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) { + if (isset(self::$installedByVendor[$vendorDir])) { + $installed[] = self::$installedByVendor[$vendorDir]; + } elseif (is_file($vendorDir.'/composer/installed.php')) { + $installed[] = self::$installedByVendor[$vendorDir] = require $vendorDir.'/composer/installed.php'; + if (null === self::$installed && strtr($vendorDir.'/composer', '\\', '/') === strtr(__DIR__, '\\', '/')) { + self::$installed = $installed[count($installed) - 1]; + } + } + } + } + + if (null === self::$installed) { + // only require the installed.php file if this file is loaded from its dumped location, + // and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937 + if (substr(__DIR__, -8, 1) !== 'C') { + self::$installed = require __DIR__ . '/installed.php'; + } else { + self::$installed = array(); + } + } + $installed[] = self::$installed; + + return $installed; + } +} diff --git a/vendor/composer/autoload_classmap.php b/vendor/composer/autoload_classmap.php new file mode 100644 index 0000000..6c294b3 --- /dev/null +++ b/vendor/composer/autoload_classmap.php @@ -0,0 +1,16 @@ + $vendorDir . '/composer/InstalledVersions.php', + 'Kirby\\ComposerInstaller\\CmsInstaller' => $vendorDir . '/getkirby/composer-installer/src/ComposerInstaller/CmsInstaller.php', + 'Kirby\\ComposerInstaller\\Installer' => $vendorDir . '/getkirby/composer-installer/src/ComposerInstaller/Installer.php', + 'Kirby\\ComposerInstaller\\Plugin' => $vendorDir . '/getkirby/composer-installer/src/ComposerInstaller/Plugin.php', + 'Kirby\\ComposerInstaller\\PluginInstaller' => $vendorDir . '/getkirby/composer-installer/src/ComposerInstaller/PluginInstaller.php', + 'Michnhokn\\Log' => $baseDir . '/classes/Log.php', + 'Michnhokn\\Logger' => $baseDir . '/classes/Logger.php', +); diff --git a/vendor/composer/autoload_namespaces.php b/vendor/composer/autoload_namespaces.php new file mode 100644 index 0000000..b7fc012 --- /dev/null +++ b/vendor/composer/autoload_namespaces.php @@ -0,0 +1,9 @@ + array($baseDir . '/classes'), + 'Kirby\\' => array($vendorDir . '/getkirby/composer-installer/src'), +); diff --git a/vendor/composer/autoload_real.php b/vendor/composer/autoload_real.php new file mode 100644 index 0000000..c300918 --- /dev/null +++ b/vendor/composer/autoload_real.php @@ -0,0 +1,57 @@ += 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded()); + if ($useStaticLoader) { + require __DIR__ . '/autoload_static.php'; + + call_user_func(\Composer\Autoload\ComposerStaticInit7e68e9e02ab58512172fe5c7171b95ec::getInitializer($loader)); + } else { + $map = require __DIR__ . '/autoload_namespaces.php'; + foreach ($map as $namespace => $path) { + $loader->set($namespace, $path); + } + + $map = require __DIR__ . '/autoload_psr4.php'; + foreach ($map as $namespace => $path) { + $loader->setPsr4($namespace, $path); + } + + $classMap = require __DIR__ . '/autoload_classmap.php'; + if ($classMap) { + $loader->addClassMap($classMap); + } + } + + $loader->register(true); + + return $loader; + } +} diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php new file mode 100644 index 0000000..6284b5f --- /dev/null +++ b/vendor/composer/autoload_static.php @@ -0,0 +1,50 @@ + + array ( + 'Michnhokn\\' => 10, + ), + 'K' => + array ( + 'Kirby\\' => 6, + ), + ); + + public static $prefixDirsPsr4 = array ( + 'Michnhokn\\' => + array ( + 0 => __DIR__ . '/../..' . '/classes', + ), + 'Kirby\\' => + array ( + 0 => __DIR__ . '/..' . '/getkirby/composer-installer/src', + ), + ); + + public static $classMap = array ( + 'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php', + 'Kirby\\ComposerInstaller\\CmsInstaller' => __DIR__ . '/..' . '/getkirby/composer-installer/src/ComposerInstaller/CmsInstaller.php', + 'Kirby\\ComposerInstaller\\Installer' => __DIR__ . '/..' . '/getkirby/composer-installer/src/ComposerInstaller/Installer.php', + 'Kirby\\ComposerInstaller\\Plugin' => __DIR__ . '/..' . '/getkirby/composer-installer/src/ComposerInstaller/Plugin.php', + 'Kirby\\ComposerInstaller\\PluginInstaller' => __DIR__ . '/..' . '/getkirby/composer-installer/src/ComposerInstaller/PluginInstaller.php', + 'Michnhokn\\Log' => __DIR__ . '/../..' . '/classes/Log.php', + 'Michnhokn\\Logger' => __DIR__ . '/../..' . '/classes/Logger.php', + ); + + public static function getInitializer(ClassLoader $loader) + { + return \Closure::bind(function () use ($loader) { + $loader->prefixLengthsPsr4 = ComposerStaticInit7e68e9e02ab58512172fe5c7171b95ec::$prefixLengthsPsr4; + $loader->prefixDirsPsr4 = ComposerStaticInit7e68e9e02ab58512172fe5c7171b95ec::$prefixDirsPsr4; + $loader->classMap = ComposerStaticInit7e68e9e02ab58512172fe5c7171b95ec::$classMap; + + }, null, ClassLoader::class); + } +} diff --git a/vendor/composer/installed.php b/vendor/composer/installed.php new file mode 100644 index 0000000..1180956 --- /dev/null +++ b/vendor/composer/installed.php @@ -0,0 +1,32 @@ + array( + 'pretty_version' => '0.9.0', + 'version' => '0.9.0.0', + 'type' => 'kirby-plugin', + 'install_path' => __DIR__ . '/../../', + 'aliases' => array(), + 'reference' => NULL, + 'name' => 'michnhokn/kirby3-logger', + 'dev' => false, + ), + 'versions' => array( + 'getkirby/composer-installer' => array( + 'pretty_version' => '1.2.1', + 'version' => '1.2.1.0', + 'type' => 'composer-plugin', + 'install_path' => __DIR__ . '/../getkirby/composer-installer', + 'aliases' => array(), + 'reference' => 'c98ece30bfba45be7ce457e1102d1b169d922f3d', + 'dev_requirement' => false, + ), + 'michnhokn/kirby3-logger' => array( + 'pretty_version' => '0.9.0', + 'version' => '0.9.0.0', + 'type' => 'kirby-plugin', + 'install_path' => __DIR__ . '/../../', + 'aliases' => array(), + 'reference' => NULL, + 'dev_requirement' => false, + ), + ), +); diff --git a/vendor/composer/platform_check.php b/vendor/composer/platform_check.php new file mode 100644 index 0000000..adfb472 --- /dev/null +++ b/vendor/composer/platform_check.php @@ -0,0 +1,26 @@ += 80000)) { + $issues[] = 'Your Composer dependencies require a PHP version ">= 8.0.0". You are running ' . PHP_VERSION . '.'; +} + +if ($issues) { + if (!headers_sent()) { + header('HTTP/1.1 500 Internal Server Error'); + } + if (!ini_get('display_errors')) { + if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') { + fwrite(STDERR, 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . implode(PHP_EOL, $issues) . PHP_EOL.PHP_EOL); + } elseif (!headers_sent()) { + echo 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . str_replace('You are running '.PHP_VERSION.'.', '', implode(PHP_EOL, $issues)) . PHP_EOL.PHP_EOL; + } + } + trigger_error( + 'Composer detected issues in your platform: ' . implode(' ', $issues), + E_USER_ERROR + ); +}