Reunify AzuraCore and AzuraCast repositories.
This commit is contained in:
parent
14da17c242
commit
4d4d75ad4d
|
@ -6,13 +6,13 @@ ini_set('display_errors', 1);
|
|||
$autoloader = require dirname(__DIR__) . '/vendor/autoload.php';
|
||||
|
||||
$app = App\AppFactory::create($autoloader, [
|
||||
Azura\Settings::BASE_DIR => dirname(__DIR__),
|
||||
App\Settings::BASE_DIR => dirname(__DIR__),
|
||||
]);
|
||||
|
||||
$di = $app->getContainer();
|
||||
|
||||
App\Customization::initCli();
|
||||
|
||||
/** @var Azura\Console\Application $cli */
|
||||
$cli = $di->get(Azura\Console\Application::class);
|
||||
/** @var App\Console\Application $cli */
|
||||
$cli = $di->get(App\Console\Application::class);
|
||||
$cli->run();
|
|
@ -17,43 +17,66 @@
|
|||
"ext-xml": "*",
|
||||
"ext-xmlwriter": "*",
|
||||
|
||||
"azuracast/azuracore": "dev-master",
|
||||
"azuracast/azuraforms": "dev-master",
|
||||
"azuracast/nowplaying": "dev-master",
|
||||
"bacon/bacon-qr-code": "^2.0",
|
||||
"bernard/bernard": "dev-master",
|
||||
"brick/math": "^0.8.4",
|
||||
"cache/array-adapter": "^1.0",
|
||||
"cache/prefixed-cache": "^1.0",
|
||||
"cache/psr-6-doctrine-bridge": "^3.0",
|
||||
"cache/redis-adapter": "^1.0",
|
||||
"cakephp/chronos": "^1.1",
|
||||
"composer/ca-bundle": "^1.2",
|
||||
"doctrine/annotations": "^1.6",
|
||||
"doctrine/data-fixtures": "^1.3",
|
||||
"doctrine/dbal": "^2.8",
|
||||
"doctrine/migrations": "^2",
|
||||
"doctrine/orm": "~2.6",
|
||||
"gettext/gettext": "^4.4",
|
||||
"guzzlehttp/guzzle": ">6.0",
|
||||
"guzzlehttp/oauth-subscriber": "^0.3.0",
|
||||
"http-interop/http-factory-guzzle": "^1.0",
|
||||
"influxdb/influxdb-php": "^1.14.3",
|
||||
"james-heinrich/getid3": "dev-master",
|
||||
"jhofm/flysystem-iterator": "^2.1",
|
||||
"laminas/laminas-config": "^3.3",
|
||||
"league/flysystem": "^1.0",
|
||||
"league/flysystem-aws-s3-v3": "^1.0",
|
||||
"league/flysystem-cached-adapter": "^1.0",
|
||||
"league/plates": "^3.1",
|
||||
"lstrojny/fxmlrpc": "^0.14.0",
|
||||
"maxmind-db/reader": "~1.0",
|
||||
"mezzio/mezzio-session": "^1.3",
|
||||
"mezzio/mezzio-session-cache": "^1.3",
|
||||
"mnapoli/silly-php-di": "^1.2",
|
||||
"mobiledetect/mobiledetectlib": "^2.8",
|
||||
"monolog/monolog": "^2",
|
||||
"myclabs/deep-copy": "^1.9",
|
||||
"ocramius/doctrine-batch-utils": "^2.0",
|
||||
"php-http/socket-client": "^1.2",
|
||||
"php-http/message": "^1.4",
|
||||
"php-di/php-di": "^6.0",
|
||||
"php-di/slim-bridge": "^3.0",
|
||||
"php-http/guzzle6-adapter": "^1.1",
|
||||
"php-http/message": "^1.4",
|
||||
"php-http/socket-client": "^1.2",
|
||||
"ramsey/uuid": "^3.8",
|
||||
"sentry/sentry": "^2",
|
||||
"slim/http": "^0.8",
|
||||
"slim/slim": "^4.2",
|
||||
"spomky-labs/otphp": "^9.1",
|
||||
"studio24/rotate": "^1.0",
|
||||
"supervisorphp/supervisor": "^3.0",
|
||||
"symfony/console": "^4.3",
|
||||
"symfony/event-dispatcher": "^4.3",
|
||||
"symfony/finder": "^4.3",
|
||||
"symfony/process": "^4.3",
|
||||
"symfony/property-access": "^4.3",
|
||||
"ramsey/uuid": "^3.8",
|
||||
"symfony/serializer": "^4.3",
|
||||
"symfony/validator": "^4.3",
|
||||
"voku/portable-utf8": "^5.4",
|
||||
"wikimedia/composer-merge-plugin": "^1.4",
|
||||
"zendframework/zend-config": "^3.3",
|
||||
"zircote/swagger-php": "^3.0",
|
||||
"jhofm/flysystem-iterator": "^2.1"
|
||||
"zircote/swagger-php": "^3.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"codeception/codeception": "^4.0",
|
||||
|
|
|
@ -4,20 +4,20 @@
|
|||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "cc59b6eaf1ea72f6d51c53ada8161095",
|
||||
"content-hash": "b78acc190be3074ca4665d4110be8bc2",
|
||||
"packages": [
|
||||
{
|
||||
"name": "aws/aws-sdk-php",
|
||||
"version": "3.133.6",
|
||||
"version": "3.133.7",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/aws/aws-sdk-php.git",
|
||||
"reference": "cd7bd2fdd159146ef6c7eeb90b73fae4fd11da57"
|
||||
"reference": "cd6fb07aed2cc68088251e3c572d111d67d558a3"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/cd7bd2fdd159146ef6c7eeb90b73fae4fd11da57",
|
||||
"reference": "cd7bd2fdd159146ef6c7eeb90b73fae4fd11da57",
|
||||
"url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/cd6fb07aed2cc68088251e3c572d111d67d558a3",
|
||||
"reference": "cd6fb07aed2cc68088251e3c572d111d67d558a3",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -88,81 +88,7 @@
|
|||
"s3",
|
||||
"sdk"
|
||||
],
|
||||
"time": "2020-01-24T19:11:35+00:00"
|
||||
},
|
||||
{
|
||||
"name": "azuracast/azuracore",
|
||||
"version": "dev-master",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/AzuraCast/azuracore.git",
|
||||
"reference": "544b3526ac42e6d2852e8052193f0221611da97c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/AzuraCast/azuracore/zipball/544b3526ac42e6d2852e8052193f0221611da97c",
|
||||
"reference": "544b3526ac42e6d2852e8052193f0221611da97c",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"cache/array-adapter": "^1.0",
|
||||
"cache/prefixed-cache": "^1.0",
|
||||
"cache/psr-6-doctrine-bridge": "^3.0",
|
||||
"cache/redis-adapter": "^1.0",
|
||||
"composer/ca-bundle": "^1.2",
|
||||
"doctrine/data-fixtures": "^1.3",
|
||||
"doctrine/dbal": "^2.8",
|
||||
"doctrine/migrations": "^2",
|
||||
"doctrine/orm": "~2.6",
|
||||
"ext-fileinfo": "*",
|
||||
"ext-json": "*",
|
||||
"ext-pdo": "*",
|
||||
"ext-redis": "*",
|
||||
"guzzlehttp/guzzle": ">6.0",
|
||||
"http-interop/http-factory-guzzle": "^1.0",
|
||||
"league/plates": "^3.1",
|
||||
"mezzio/mezzio-session": "^1.3",
|
||||
"mezzio/mezzio-session-cache": "^1.3",
|
||||
"mnapoli/silly-php-di": "^1.2",
|
||||
"monolog/monolog": "^2",
|
||||
"php": ">=7.4",
|
||||
"php-di/php-di": "^6.0",
|
||||
"php-di/slim-bridge": "^3.0",
|
||||
"slim/http": "^0.8",
|
||||
"slim/slim": "^4.2",
|
||||
"symfony/console": "^4.3",
|
||||
"symfony/event-dispatcher": "^4.3",
|
||||
"symfony/serializer": "^4.3",
|
||||
"symfony/validator": "^4.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"codeception/codeception": "^4.0",
|
||||
"codeception/module-asserts": "^1.1",
|
||||
"codeception/module-phpbrowser": "^1.0",
|
||||
"mockery/mockery": "^1.0",
|
||||
"overtrue/phplint": "^1.1",
|
||||
"phpstan/phpstan": "^0.11.1",
|
||||
"phpstan/phpstan-strict-rules": "^0.11.0",
|
||||
"roave/security-advisories": "dev-master"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Azura\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"Apache-2.0"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Buster Neece",
|
||||
"email": "buster@busterneece.com"
|
||||
}
|
||||
],
|
||||
"description": "A lightweight core application framework.",
|
||||
"time": "2020-01-18T01:31:14+00:00"
|
||||
"time": "2020-02-04T19:11:15+00:00"
|
||||
},
|
||||
{
|
||||
"name": "azuracast/azuraforms",
|
||||
|
@ -170,12 +96,12 @@
|
|||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/AzuraCast/azuraforms.git",
|
||||
"reference": "6cc5fb9139369cd16d5b09ed5fe9bd43a61720ff"
|
||||
"reference": "3a64e491f99afedf0d2be342b8788867a4b167b7"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/AzuraCast/azuraforms/zipball/6cc5fb9139369cd16d5b09ed5fe9bd43a61720ff",
|
||||
"reference": "6cc5fb9139369cd16d5b09ed5fe9bd43a61720ff",
|
||||
"url": "https://api.github.com/repos/AzuraCast/azuraforms/zipball/3a64e491f99afedf0d2be342b8788867a4b167b7",
|
||||
"reference": "3a64e491f99afedf0d2be342b8788867a4b167b7",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -213,7 +139,7 @@
|
|||
],
|
||||
"description": "A modern, namespaced, configuration-driven forms engine for PHP.",
|
||||
"homepage": "https://github.com/AzuraCast/azuraforms",
|
||||
"time": "2019-09-23T03:15:28+00:00"
|
||||
"time": "2020-02-01T03:18:09+00:00"
|
||||
},
|
||||
{
|
||||
"name": "azuracast/nowplaying",
|
||||
|
@ -491,16 +417,16 @@
|
|||
},
|
||||
{
|
||||
"name": "brick/math",
|
||||
"version": "0.8.11",
|
||||
"version": "0.8.12",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/brick/math.git",
|
||||
"reference": "bf4894d6373d396666d280a42ecdf1ad75f8222f"
|
||||
"reference": "ea9a095b902f5d42126aba4455a64476f5528241"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/brick/math/zipball/bf4894d6373d396666d280a42ecdf1ad75f8222f",
|
||||
"reference": "bf4894d6373d396666d280a42ecdf1ad75f8222f",
|
||||
"url": "https://api.github.com/repos/brick/math/zipball/ea9a095b902f5d42126aba4455a64476f5528241",
|
||||
"reference": "ea9a095b902f5d42126aba4455a64476f5528241",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -508,7 +434,8 @@
|
|||
},
|
||||
"require-dev": {
|
||||
"php-coveralls/php-coveralls": "2.*",
|
||||
"phpunit/phpunit": "7.*"
|
||||
"phpunit/phpunit": "7.*",
|
||||
"vimeo/psalm": "3.*"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
|
@ -531,7 +458,7 @@
|
|||
"brick",
|
||||
"math"
|
||||
],
|
||||
"time": "2020-01-23T00:19:01+00:00"
|
||||
"time": "2020-01-27T13:00:05+00:00"
|
||||
},
|
||||
{
|
||||
"name": "cache/adapter-common",
|
||||
|
@ -1174,16 +1101,16 @@
|
|||
},
|
||||
{
|
||||
"name": "dflydev/fig-cookies",
|
||||
"version": "v2.0.0",
|
||||
"version": "v2.0.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/dflydev/dflydev-fig-cookies.git",
|
||||
"reference": "a59857139b9e30978b5b802b3631b5eaf34e8c66"
|
||||
"reference": "733af78ddad60aec96f7c4a1204619dd4d62afff"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/dflydev/dflydev-fig-cookies/zipball/a59857139b9e30978b5b802b3631b5eaf34e8c66",
|
||||
"reference": "a59857139b9e30978b5b802b3631b5eaf34e8c66",
|
||||
"url": "https://api.github.com/repos/dflydev/dflydev-fig-cookies/zipball/733af78ddad60aec96f7c4a1204619dd4d62afff",
|
||||
"reference": "733af78ddad60aec96f7c4a1204619dd4d62afff",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -1224,7 +1151,7 @@
|
|||
"psr-7",
|
||||
"psr7"
|
||||
],
|
||||
"time": "2018-07-11T06:54:37+00:00"
|
||||
"time": "2020-01-02T16:13:22+00:00"
|
||||
},
|
||||
{
|
||||
"name": "doctrine/annotations",
|
||||
|
@ -3247,16 +3174,16 @@
|
|||
},
|
||||
{
|
||||
"name": "league/flysystem",
|
||||
"version": "1.0.63",
|
||||
"version": "1.0.64",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/thephpleague/flysystem.git",
|
||||
"reference": "8132daec326565036bc8e8d1876f77ec183a7bd6"
|
||||
"reference": "d13c43dbd4b791f815215959105a008515d1a2e0"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/thephpleague/flysystem/zipball/8132daec326565036bc8e8d1876f77ec183a7bd6",
|
||||
"reference": "8132daec326565036bc8e8d1876f77ec183a7bd6",
|
||||
"url": "https://api.github.com/repos/thephpleague/flysystem/zipball/d13c43dbd4b791f815215959105a008515d1a2e0",
|
||||
"reference": "d13c43dbd4b791f815215959105a008515d1a2e0",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -3268,7 +3195,7 @@
|
|||
},
|
||||
"require-dev": {
|
||||
"phpspec/phpspec": "^3.4",
|
||||
"phpunit/phpunit": "^5.7.10"
|
||||
"phpunit/phpunit": "^5.7.26"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-fileinfo": "Required for MimeType",
|
||||
|
@ -3327,7 +3254,7 @@
|
|||
"sftp",
|
||||
"storage"
|
||||
],
|
||||
"time": "2020-01-04T16:30:31+00:00"
|
||||
"time": "2020-02-05T18:14:17+00:00"
|
||||
},
|
||||
{
|
||||
"name": "league/flysystem-aws-s3-v3",
|
||||
|
@ -6041,16 +5968,16 @@
|
|||
},
|
||||
{
|
||||
"name": "symfony/console",
|
||||
"version": "v4.4.3",
|
||||
"version": "v4.4.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/console.git",
|
||||
"reference": "e9ee09d087e2c88eaf6e5fc0f5c574f64d100e4f"
|
||||
"reference": "f512001679f37e6a042b51897ed24a2f05eba656"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/console/zipball/e9ee09d087e2c88eaf6e5fc0f5c574f64d100e4f",
|
||||
"reference": "e9ee09d087e2c88eaf6e5fc0f5c574f64d100e4f",
|
||||
"url": "https://api.github.com/repos/symfony/console/zipball/f512001679f37e6a042b51897ed24a2f05eba656",
|
||||
"reference": "f512001679f37e6a042b51897ed24a2f05eba656",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -6113,11 +6040,11 @@
|
|||
],
|
||||
"description": "Symfony Console Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2020-01-10T21:54:01+00:00"
|
||||
"time": "2020-01-25T12:44:29+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/event-dispatcher",
|
||||
"version": "v4.4.3",
|
||||
"version": "v4.4.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/event-dispatcher.git",
|
||||
|
@ -6245,7 +6172,7 @@
|
|||
},
|
||||
{
|
||||
"name": "symfony/finder",
|
||||
"version": "v4.4.3",
|
||||
"version": "v4.4.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/finder.git",
|
||||
|
@ -6294,7 +6221,7 @@
|
|||
},
|
||||
{
|
||||
"name": "symfony/inflector",
|
||||
"version": "v5.0.3",
|
||||
"version": "v5.0.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/inflector.git",
|
||||
|
@ -6352,7 +6279,7 @@
|
|||
},
|
||||
{
|
||||
"name": "symfony/options-resolver",
|
||||
"version": "v4.4.3",
|
||||
"version": "v4.4.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/options-resolver.git",
|
||||
|
@ -6581,7 +6508,7 @@
|
|||
},
|
||||
{
|
||||
"name": "symfony/process",
|
||||
"version": "v4.4.3",
|
||||
"version": "v4.4.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/process.git",
|
||||
|
@ -6630,7 +6557,7 @@
|
|||
},
|
||||
{
|
||||
"name": "symfony/property-access",
|
||||
"version": "v4.4.3",
|
||||
"version": "v4.4.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/property-access.git",
|
||||
|
@ -6697,7 +6624,7 @@
|
|||
},
|
||||
{
|
||||
"name": "symfony/serializer",
|
||||
"version": "v4.4.3",
|
||||
"version": "v4.4.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/serializer.git",
|
||||
|
@ -6836,7 +6763,7 @@
|
|||
},
|
||||
{
|
||||
"name": "symfony/stopwatch",
|
||||
"version": "v5.0.3",
|
||||
"version": "v5.0.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/stopwatch.git",
|
||||
|
@ -6943,16 +6870,16 @@
|
|||
},
|
||||
{
|
||||
"name": "symfony/validator",
|
||||
"version": "v4.4.3",
|
||||
"version": "v4.4.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/validator.git",
|
||||
"reference": "2f3ec17a371cc56b3a2855b5eae0702f70611e81"
|
||||
"reference": "eb3e15de5c63873ca6e2a88b56a029f7be4c5953"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/validator/zipball/2f3ec17a371cc56b3a2855b5eae0702f70611e81",
|
||||
"reference": "2f3ec17a371cc56b3a2855b5eae0702f70611e81",
|
||||
"url": "https://api.github.com/repos/symfony/validator/zipball/eb3e15de5c63873ca6e2a88b56a029f7be4c5953",
|
||||
"reference": "eb3e15de5c63873ca6e2a88b56a029f7be4c5953",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -7031,11 +6958,11 @@
|
|||
],
|
||||
"description": "Symfony Validator Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2020-01-21T08:20:44+00:00"
|
||||
"time": "2020-01-31T09:11:17+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/yaml",
|
||||
"version": "v5.0.3",
|
||||
"version": "v5.0.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/yaml.git",
|
||||
|
@ -7143,16 +7070,16 @@
|
|||
},
|
||||
{
|
||||
"name": "voku/portable-utf8",
|
||||
"version": "5.4.38",
|
||||
"version": "5.4.39",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/voku/portable-utf8.git",
|
||||
"reference": "0991729d5ca364078b00fe0e107f87ec0d53b0d7"
|
||||
"reference": "e462e8985a80cbd927765fd7e09f52bb103c9797"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/voku/portable-utf8/zipball/0991729d5ca364078b00fe0e107f87ec0d53b0d7",
|
||||
"reference": "0991729d5ca364078b00fe0e107f87ec0d53b0d7",
|
||||
"url": "https://api.github.com/repos/voku/portable-utf8/zipball/e462e8985a80cbd927765fd7e09f52bb103c9797",
|
||||
"reference": "e462e8985a80cbd927765fd7e09f52bb103c9797",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -7213,7 +7140,7 @@
|
|||
"utf-8",
|
||||
"utf8"
|
||||
],
|
||||
"time": "2020-01-14T13:30:41+00:00"
|
||||
"time": "2020-01-30T15:12:06+00:00"
|
||||
},
|
||||
{
|
||||
"name": "webimpress/safe-writer",
|
||||
|
@ -7821,21 +7748,22 @@
|
|||
},
|
||||
{
|
||||
"name": "codeception/module-rest",
|
||||
"version": "1.1.0",
|
||||
"version": "1.2.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Codeception/module-rest.git",
|
||||
"reference": "e6ef1cc7fcc20b392ed2fb73ad809c63dc609781"
|
||||
"reference": "c86417af517bb1fb5b88550455d823a7c9fc167e"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/Codeception/module-rest/zipball/e6ef1cc7fcc20b392ed2fb73ad809c63dc609781",
|
||||
"reference": "e6ef1cc7fcc20b392ed2fb73ad809c63dc609781",
|
||||
"url": "https://api.github.com/repos/Codeception/module-rest/zipball/c86417af517bb1fb5b88550455d823a7c9fc167e",
|
||||
"reference": "c86417af517bb1fb5b88550455d823a7c9fc167e",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"codeception/codeception": "^4.0",
|
||||
"flow/jsonpath": "^0.5",
|
||||
"justinrainbow/json-schema": "^5.2.9",
|
||||
"php": ">=5.6.0 <8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
|
@ -7867,7 +7795,7 @@
|
|||
"codeception",
|
||||
"rest"
|
||||
],
|
||||
"time": "2020-01-24T08:55:04+00:00"
|
||||
"time": "2020-02-01T19:23:56+00:00"
|
||||
},
|
||||
{
|
||||
"name": "codeception/phpunit-wrapper",
|
||||
|
@ -8137,6 +8065,72 @@
|
|||
],
|
||||
"time": "2016-01-20T08:20:44+00:00"
|
||||
},
|
||||
{
|
||||
"name": "justinrainbow/json-schema",
|
||||
"version": "5.2.9",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/justinrainbow/json-schema.git",
|
||||
"reference": "44c6787311242a979fa15c704327c20e7221a0e4"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/justinrainbow/json-schema/zipball/44c6787311242a979fa15c704327c20e7221a0e4",
|
||||
"reference": "44c6787311242a979fa15c704327c20e7221a0e4",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"friendsofphp/php-cs-fixer": "~2.2.20||~2.15.1",
|
||||
"json-schema/json-schema-test-suite": "1.2.0",
|
||||
"phpunit/phpunit": "^4.8.35"
|
||||
},
|
||||
"bin": [
|
||||
"bin/validate-json"
|
||||
],
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "5.0.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"JsonSchema\\": "src/JsonSchema/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Bruno Prieto Reis",
|
||||
"email": "bruno.p.reis@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Justin Rainbow",
|
||||
"email": "justin.rainbow@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Igor Wiedler",
|
||||
"email": "igor@wiedler.ch"
|
||||
},
|
||||
{
|
||||
"name": "Robert Schönthal",
|
||||
"email": "seroscho@googlemail.com"
|
||||
}
|
||||
],
|
||||
"description": "A library to validate a json schema.",
|
||||
"homepage": "https://github.com/justinrainbow/json-schema",
|
||||
"keywords": [
|
||||
"json",
|
||||
"schema"
|
||||
],
|
||||
"time": "2019-09-25T14:49:45+00:00"
|
||||
},
|
||||
{
|
||||
"name": "mockery/mockery",
|
||||
"version": "1.3.1",
|
||||
|
@ -9678,12 +9672,12 @@
|
|||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Roave/SecurityAdvisories.git",
|
||||
"reference": "666ba252853924887ac57dc9f66e6b6af78d5a76"
|
||||
"reference": "af61943caaa512a4f00f1ee80e6e0cfec3fb63d1"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/666ba252853924887ac57dc9f66e6b6af78d5a76",
|
||||
"reference": "666ba252853924887ac57dc9f66e6b6af78d5a76",
|
||||
"url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/af61943caaa512a4f00f1ee80e6e0cfec3fb63d1",
|
||||
"reference": "af61943caaa512a4f00f1ee80e6e0cfec3fb63d1",
|
||||
"shasum": ""
|
||||
},
|
||||
"conflict": {
|
||||
|
@ -9756,6 +9750,7 @@
|
|||
"monolog/monolog": ">=1.8,<1.12",
|
||||
"namshi/jose": "<2.2",
|
||||
"onelogin/php-saml": "<2.10.4",
|
||||
"oneup/uploader-bundle": ">=1,<1.9.3|>=2,<2.1.5",
|
||||
"openid/php-openid": "<2.3",
|
||||
"oro/crm": ">=1.7,<1.7.4",
|
||||
"oro/platform": ">=1.7,<1.7.4",
|
||||
|
@ -9765,7 +9760,7 @@
|
|||
"paypal/merchant-sdk-php": "<3.12",
|
||||
"pear/archive_tar": "<1.4.4",
|
||||
"phpmailer/phpmailer": ">=5,<5.2.27|>=6,<6.0.6",
|
||||
"phpoffice/phpexcel": "<=1.8.1",
|
||||
"phpoffice/phpexcel": "<1.8.2",
|
||||
"phpoffice/phpspreadsheet": "<=1.5",
|
||||
"phpunit/phpunit": ">=4.8.19,<4.8.28|>=5.0.10,<5.6.3",
|
||||
"phpwhois/phpwhois": "<=4.2.5",
|
||||
|
@ -9779,12 +9774,17 @@
|
|||
"sensiolabs/connect": "<4.2.3",
|
||||
"serluck/phpwhois": "<=4.2.6",
|
||||
"shopware/shopware": "<5.3.7",
|
||||
"silverstripe/admin": ">=1.0.3,<1.0.4|>=1.1,<1.1.1",
|
||||
"silverstripe/assets": ">=1,<1.3.5",
|
||||
"silverstripe/cms": ">=3,<=3.0.11|>=3.1,<3.1.11",
|
||||
"silverstripe/comments": ">=1.3,<1.9.99|>=2,<2.9.99|>=3,<3.1.1",
|
||||
"silverstripe/forum": "<=0.6.1|>=0.7,<=0.7.3",
|
||||
"silverstripe/framework": ">=3,<3.6.7|>=3.7,<3.7.3|>=4,<4.4",
|
||||
"silverstripe/framework": ">=3,<3.9.99|>=4,<4.4.4",
|
||||
"silverstripe/graphql": ">=2,<2.0.5|>=3,<3.1.2",
|
||||
"silverstripe/registry": ">=2.1,<2.1.2|>=2.2,<2.2.1",
|
||||
"silverstripe/restfulserver": ">=1,<1.0.9|>=2,<2.0.4",
|
||||
"silverstripe/subsites": ">=2,<2.1.1",
|
||||
"silverstripe/taxonomy": ">=1.3,<1.3.1|>=2,<2.0.1",
|
||||
"silverstripe/userforms": "<3",
|
||||
"simple-updates/phpwhois": "<=1",
|
||||
"simplesamlphp/saml2": "<1.10.6|>=2,<2.3.8|>=3,<3.1.4",
|
||||
|
@ -9803,6 +9803,7 @@
|
|||
"sylius/grid-bundle": ">=1,<1.1.19|>=1.2,<1.2.18|>=1.3,<1.3.13|>=1.4,<1.4.5|>=1.5,<1.5.1",
|
||||
"sylius/resource-bundle": ">=1,<1.3.13|>=1.4,<1.4.6|>=1.5,<1.5.1|>=1.6,<1.6.3",
|
||||
"sylius/sylius": ">=1,<1.3.12|>=1.4,<1.4.4",
|
||||
"symbiote/silverstripe-multivaluefield": ">=3,<3.0.99",
|
||||
"symfony/cache": ">=3.1,<3.4.35|>=4,<4.2.12|>=4.3,<4.3.8",
|
||||
"symfony/dependency-injection": ">=2,<2.0.17|>=2.7,<2.7.51|>=2.8,<2.8.50|>=3,<3.4.26|>=4,<4.1.12|>=4.2,<4.2.7",
|
||||
"symfony/form": ">=2.3,<2.3.35|>=2.4,<2.6.12|>=2.7,<2.7.50|>=2.8,<2.8.49|>=3,<3.4.20|>=4,<4.0.15|>=4.1,<4.1.9|>=4.2,<4.2.1",
|
||||
|
@ -9896,7 +9897,7 @@
|
|||
}
|
||||
],
|
||||
"description": "Prevents installation of composer packages with known security vulnerabilities: no API, simply require it",
|
||||
"time": "2020-01-28T17:25:41+00:00"
|
||||
"time": "2020-02-05T14:02:42+00:00"
|
||||
},
|
||||
{
|
||||
"name": "sebastian/code-unit-reverse-lookup",
|
||||
|
@ -10515,16 +10516,16 @@
|
|||
},
|
||||
{
|
||||
"name": "squizlabs/php_codesniffer",
|
||||
"version": "3.5.3",
|
||||
"version": "3.5.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/squizlabs/PHP_CodeSniffer.git",
|
||||
"reference": "557a1fc7ac702c66b0bbfe16ab3d55839ef724cb"
|
||||
"reference": "dceec07328401de6211037abbb18bda423677e26"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/557a1fc7ac702c66b0bbfe16ab3d55839ef724cb",
|
||||
"reference": "557a1fc7ac702c66b0bbfe16ab3d55839ef724cb",
|
||||
"url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/dceec07328401de6211037abbb18bda423677e26",
|
||||
"reference": "dceec07328401de6211037abbb18bda423677e26",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -10562,11 +10563,11 @@
|
|||
"phpcs",
|
||||
"standards"
|
||||
],
|
||||
"time": "2019-12-04T04:46:47+00:00"
|
||||
"time": "2020-01-30T22:20:29+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/browser-kit",
|
||||
"version": "v5.0.3",
|
||||
"version": "v5.0.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/browser-kit.git",
|
||||
|
@ -10625,7 +10626,7 @@
|
|||
},
|
||||
{
|
||||
"name": "symfony/css-selector",
|
||||
"version": "v5.0.3",
|
||||
"version": "v5.0.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/css-selector.git",
|
||||
|
@ -10678,7 +10679,7 @@
|
|||
},
|
||||
{
|
||||
"name": "symfony/dom-crawler",
|
||||
"version": "v5.0.3",
|
||||
"version": "v5.0.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/dom-crawler.git",
|
||||
|
@ -10829,7 +10830,6 @@
|
|||
"aliases": [],
|
||||
"minimum-stability": "dev",
|
||||
"stability-flags": {
|
||||
"azuracast/azuracore": 20,
|
||||
"azuracast/azuraforms": 20,
|
||||
"azuracast/nowplaying": 20,
|
||||
"bernard/bernard": 20,
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
<?php
|
||||
|
||||
use App\Console\Command;
|
||||
use Azura\Console\Application;
|
||||
use Azura\Settings;
|
||||
use App\Console\Application;
|
||||
use App\Settings;
|
||||
|
||||
return function (Application $console) {
|
||||
// Set console version and name.
|
||||
|
|
|
@ -1,15 +1,79 @@
|
|||
<?php
|
||||
use App\Middleware;
|
||||
use App\Console\Command;
|
||||
|
||||
return function (\Azura\EventDispatcher $dispatcher)
|
||||
{
|
||||
// Build default routes and middleware
|
||||
$dispatcher->addListener(Azura\Event\BuildRoutes::class, function(Azura\Event\BuildRoutes $event) {
|
||||
use App\Console\Command;
|
||||
use App\Event;
|
||||
use App\Middleware;
|
||||
use App\Settings;
|
||||
|
||||
return function (\App\EventDispatcher $dispatcher) {
|
||||
$dispatcher->addListener(Event\BuildConsoleCommands::class, function (Event\BuildConsoleCommands $event) {
|
||||
$console = $event->getConsole();
|
||||
$di = $console->getContainer();
|
||||
|
||||
/** @var Settings $settings */
|
||||
$settings = $di->get(Settings::class);
|
||||
|
||||
if ($settings->enableRedis()) {
|
||||
$console->command('cache:clear', Command\ClearCacheCommand::class)
|
||||
->setDescription('Clear all application caches.');
|
||||
}
|
||||
|
||||
if ($settings->enableDatabase()) {
|
||||
// Doctrine ORM/DBAL
|
||||
Doctrine\ORM\Tools\Console\ConsoleRunner::addCommands($console);
|
||||
|
||||
// Add Doctrine Migrations
|
||||
$defaults = [
|
||||
'table_name' => 'app_migrations',
|
||||
'directory' => $settings[Settings::BASE_DIR] . '/src/Entity/Migration',
|
||||
'namespace' => 'App\Entity\Migration',
|
||||
];
|
||||
|
||||
$user_options = $settings[Settings::DOCTRINE_OPTIONS]['migrations'] ?? [];
|
||||
$options = array_merge($defaults, $user_options);
|
||||
|
||||
/** @var Doctrine\ORM\EntityManager $em */
|
||||
$em = $di->get(Doctrine\ORM\EntityManager::class);
|
||||
$connection = $em->getConnection();
|
||||
|
||||
$helper_set = $console->getHelperSet();
|
||||
$doctrine_helpers = Doctrine\ORM\Tools\Console\ConsoleRunner::createHelperSet($em);
|
||||
|
||||
$helper_set->set($doctrine_helpers->get('db'), 'db');
|
||||
$helper_set->set($doctrine_helpers->get('em'), 'em');
|
||||
|
||||
$migrate_config = new Doctrine\Migrations\Configuration\Configuration($connection);
|
||||
$migrate_config->setMigrationsTableName($options['table_name']);
|
||||
$migrate_config->setMigrationsDirectory($options['directory']);
|
||||
$migrate_config->setMigrationsNamespace($options['namespace']);
|
||||
|
||||
$migrate_config_helper = new Doctrine\Migrations\Tools\Console\Helper\ConfigurationHelper($connection,
|
||||
$migrate_config);
|
||||
$helper_set->set($migrate_config_helper, 'configuration');
|
||||
|
||||
Doctrine\Migrations\Tools\Console\ConsoleRunner::addCommands($console);
|
||||
}
|
||||
|
||||
if (file_exists(__DIR__ . '/cli.php')) {
|
||||
call_user_func(include(__DIR__ . '/cli.php'), $console);
|
||||
}
|
||||
});
|
||||
|
||||
$dispatcher->addListener(Event\BuildRoutes::class, function (Event\BuildRoutes $event) {
|
||||
$app = $event->getApp();
|
||||
|
||||
if (file_exists(__DIR__.'/routes.dev.php')) {
|
||||
$dev_routes = require __DIR__.'/routes.dev.php';
|
||||
// Load app-specific route configuration.
|
||||
$container = $app->getContainer();
|
||||
|
||||
/** @var Settings $settings */
|
||||
$settings = $container->get(Settings::class);
|
||||
|
||||
if (file_exists(__DIR__ . '/routes.php')) {
|
||||
call_user_func(include(__DIR__ . '/routes.php'), $app);
|
||||
}
|
||||
|
||||
if (file_exists(__DIR__ . '/routes.dev.php')) {
|
||||
$dev_routes = require __DIR__ . '/routes.dev.php';
|
||||
$dev_routes($app);
|
||||
}
|
||||
|
||||
|
@ -17,16 +81,34 @@ return function (\Azura\EventDispatcher $dispatcher)
|
|||
$app->add(Middleware\InjectAcl::class);
|
||||
$app->add(Middleware\GetCurrentUser::class);
|
||||
|
||||
}, 2);
|
||||
// Request injection middlewares.
|
||||
$app->add(Middleware\InjectRouter::class);
|
||||
$app->add(Middleware\InjectRateLimit::class);
|
||||
|
||||
// System middleware for routing and body parsing.
|
||||
$app->addBodyParsingMiddleware();
|
||||
$app->addRoutingMiddleware();
|
||||
|
||||
// Redirects and updates that should happen before system middleware.
|
||||
$app->add(new Middleware\RemoveSlashes);
|
||||
$app->add(new Middleware\ApplyXForwardedProto);
|
||||
|
||||
// Error handling, which should always be near the "last" element.
|
||||
$errorMiddleware = $app->addErrorMiddleware(!$settings->isProduction(), true, true);
|
||||
$errorMiddleware->setDefaultErrorHandler(Slim\Interfaces\ErrorHandlerInterface::class);
|
||||
|
||||
// Use PSR-7 compatible sessions.
|
||||
$app->add(Middleware\InjectSession::class);
|
||||
});
|
||||
|
||||
// Build default menus
|
||||
$dispatcher->addListener(App\Event\BuildAdminMenu::class, function(\App\Event\BuildAdminMenu $e) {
|
||||
$callable = require(__DIR__.'/menus/admin.php');
|
||||
$dispatcher->addListener(App\Event\BuildAdminMenu::class, function (\App\Event\BuildAdminMenu $e) {
|
||||
$callable = require(__DIR__ . '/menus/admin.php');
|
||||
$callable($e);
|
||||
});
|
||||
|
||||
$dispatcher->addListener(App\Event\BuildStationMenu::class, function(\App\Event\BuildStationMenu $e) {
|
||||
$callable = require(__DIR__.'/menus/station.php');
|
||||
$dispatcher->addListener(App\Event\BuildStationMenu::class, function (\App\Event\BuildStationMenu $e) {
|
||||
$callable = require(__DIR__ . '/menus/station.php');
|
||||
$callable($e);
|
||||
});
|
||||
|
||||
|
|
|
@ -71,7 +71,7 @@ return [
|
|||
[
|
||||
'label' => __('Time Zone'),
|
||||
'description' => __('Scheduled playlists and other timed items will be controlled by this time zone.'),
|
||||
'options' => \Azura\Timezone::fetchSelect(),
|
||||
'options' => \App\Timezone::fetchSelect(),
|
||||
'default' => \App\Customization::DEFAULT_TIMEZONE,
|
||||
'form_group_class' => 'col-sm-12',
|
||||
]
|
||||
|
|
|
@ -5,7 +5,7 @@ use App\Controller;
|
|||
use App\Http\Response;
|
||||
use App\Http\ServerRequest;
|
||||
use App\Middleware;
|
||||
use Azura\Middleware as AzuraMiddleware;
|
||||
use App\Middleware as AzuraMiddleware;
|
||||
use Slim\App;
|
||||
use Slim\Routing\RouteCollectorProxy;
|
||||
|
||||
|
|
|
@ -3,43 +3,115 @@
|
|||
* PHP-DI Services
|
||||
*/
|
||||
|
||||
use App;
|
||||
use App\Settings;
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use Psr\Container\ContainerInterface;
|
||||
|
||||
return [
|
||||
return array_merge(
|
||||
include(__DIR__ . '/services/cache.php'),
|
||||
include(__DIR__ . '/services/database.php'),
|
||||
include(__DIR__ . '/services/http.php'),
|
||||
include(__DIR__ . '/services/view.php'), [
|
||||
|
||||
/*
|
||||
* Slim Component Overrides
|
||||
*/
|
||||
|
||||
// URL Router helper
|
||||
App\Http\Router::class => function (
|
||||
Settings $settings,
|
||||
\Slim\App $app,
|
||||
App\Entity\Repository\SettingsRepository $settingsRepo
|
||||
) {
|
||||
$route_parser = $app->getRouteCollector()->getRouteParser();
|
||||
return new App\Http\Router($settings, $route_parser, $settingsRepo);
|
||||
// Configuration management
|
||||
App\Config::class => function (App\Settings $settings) {
|
||||
return new App\Config($settings[App\Settings::CONFIG_DIR]);
|
||||
},
|
||||
Azura\Http\RouterInterface::class => DI\Get(App\Http\Router::class),
|
||||
|
||||
// Error Handler
|
||||
App\Http\ErrorHandler::class => DI\autowire(),
|
||||
Slim\Interfaces\ErrorHandlerInterface::class => DI\Get(App\Http\ErrorHandler::class),
|
||||
// Console
|
||||
App\Console\Application::class => function (DI\Container $di, App\EventDispatcher $dispatcher) {
|
||||
$console = new App\Console\Application('Command Line Interface', '1.0.0', $di);
|
||||
|
||||
/*
|
||||
* Doctrine Database
|
||||
*/
|
||||
// Trigger an event for the core app and all plugins to build their CLI commands.
|
||||
$event = new App\Event\BuildConsoleCommands($console);
|
||||
$dispatcher->dispatch($event);
|
||||
|
||||
EntityManager::class => DI\decorate(function (EntityManager $em, ContainerInterface $di) {
|
||||
$event_manager = $em->getEventManager();
|
||||
$event_manager->addEventSubscriber($di->get(App\Doctrine\Event\StationRequiresRestart::class));
|
||||
$event_manager->addEventSubscriber($di->get(App\Doctrine\Event\AuditLog::class));
|
||||
return $console;
|
||||
},
|
||||
|
||||
return $em;
|
||||
}),
|
||||
// Event Dispatcher
|
||||
App\EventDispatcher::class => function (Slim\App $app, App\Plugins $plugins) {
|
||||
$dispatcher = new App\EventDispatcher($app->getCallableResolver());
|
||||
|
||||
// Register application default events.
|
||||
if (file_exists(__DIR__ . '/events.php')) {
|
||||
call_user_func(include(__DIR__ . '/events.php'), $dispatcher);
|
||||
}
|
||||
|
||||
// Register plugin-provided events.
|
||||
$plugins->registerEvents($dispatcher);
|
||||
|
||||
return $dispatcher;
|
||||
},
|
||||
|
||||
// Monolog Logger
|
||||
Monolog\Logger::class => function (App\Settings $settings) {
|
||||
$logger = new Monolog\Logger($settings[App\Settings::APP_NAME] ?? 'app');
|
||||
$logging_level = $settings->isProduction() ? Psr\Log\LogLevel::INFO : Psr\Log\LogLevel::DEBUG;
|
||||
|
||||
if ($settings[App\Settings::IS_DOCKER] || $settings[App\Settings::IS_CLI]) {
|
||||
$log_stderr = new Monolog\Handler\StreamHandler('php://stderr', $logging_level, true);
|
||||
$logger->pushHandler($log_stderr);
|
||||
}
|
||||
|
||||
$log_file = new Monolog\Handler\StreamHandler($settings[App\Settings::TEMP_DIR] . '/app.log',
|
||||
$logging_level, true);
|
||||
$logger->pushHandler($log_file);
|
||||
|
||||
return $logger;
|
||||
},
|
||||
Psr\Log\LoggerInterface::class => DI\get(Monolog\Logger::class),
|
||||
|
||||
// Middleware
|
||||
App\Middleware\InjectRateLimit::class => DI\autowire(),
|
||||
App\Middleware\InjectRouter::class => DI\autowire(),
|
||||
App\Middleware\InjectSession::class => DI\autowire(),
|
||||
App\Middleware\EnableView::class => DI\autowire(),
|
||||
|
||||
// Rate limiter
|
||||
App\RateLimit::class => DI\autowire(),
|
||||
|
||||
// Doctrine annotations reader
|
||||
Doctrine\Common\Annotations\Reader::class => function (
|
||||
Doctrine\Common\Cache\Cache $doctrine_cache,
|
||||
App\Settings $settings
|
||||
) {
|
||||
return new Doctrine\Common\Annotations\CachedReader(
|
||||
new Doctrine\Common\Annotations\AnnotationReader,
|
||||
$doctrine_cache,
|
||||
!$settings->isProduction()
|
||||
);
|
||||
},
|
||||
|
||||
// Symfony Serializer
|
||||
Symfony\Component\Serializer\Serializer::class => function (
|
||||
Doctrine\Common\Annotations\Reader $annotation_reader,
|
||||
Doctrine\ORM\EntityManager $em
|
||||
) {
|
||||
$meta_factory = new Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactory(
|
||||
new Symfony\Component\Serializer\Mapping\Loader\AnnotationLoader($annotation_reader)
|
||||
);
|
||||
|
||||
$normalizers = [
|
||||
new Symfony\Component\Serializer\Normalizer\JsonSerializableNormalizer(),
|
||||
new App\Normalizer\DoctrineEntityNormalizer($em, $annotation_reader, $meta_factory),
|
||||
new Symfony\Component\Serializer\Normalizer\ObjectNormalizer($meta_factory),
|
||||
];
|
||||
return new Symfony\Component\Serializer\Serializer($normalizers);
|
||||
},
|
||||
|
||||
// Symfony Validator
|
||||
Symfony\Component\Validator\ConstraintValidatorFactoryInterface::class => DI\autowire(App\Validator\ConstraintValidatorFactory::class),
|
||||
|
||||
Symfony\Component\Validator\Validator\ValidatorInterface::class => function (
|
||||
Doctrine\Common\Annotations\Reader $annotation_reader,
|
||||
Symfony\Component\Validator\ConstraintValidatorFactoryInterface $cvf
|
||||
) {
|
||||
$builder = new Symfony\Component\Validator\ValidatorBuilder();
|
||||
$builder->setConstraintValidatorFactory($cvf);
|
||||
$builder->enableAnnotationMapping($annotation_reader);
|
||||
return $builder->getValidator();
|
||||
},
|
||||
|
||||
App\Doctrine\Event\AuditLog::class => DI\autowire(),
|
||||
App\Doctrine\Event\StationRequiresRestart::class => DI\autowire(),
|
||||
|
@ -61,66 +133,6 @@ return [
|
|||
App\Entity\Repository\StationStreamerRepository::class => DI\autowire(),
|
||||
App\Entity\Repository\UserRepository::class => DI\autowire(),
|
||||
|
||||
/*
|
||||
* View
|
||||
*/
|
||||
|
||||
Azura\View::class => DI\decorate(function (Azura\View $view, ContainerInterface $di) {
|
||||
$view->registerFunction('mailto', function ($address, $link_text = null) {
|
||||
$address = substr(chunk_split(bin2hex(" $address"), 2, ";&#x"), 3, -3);
|
||||
$link_text = $link_text ?? $address;
|
||||
return '<a href="mailto:' . $address . '">' . $link_text . '</a>';
|
||||
});
|
||||
$view->registerFunction('pluralize', function ($word, $num = 0) {
|
||||
if ((int)$num === 1) {
|
||||
return $word;
|
||||
}
|
||||
return Doctrine\Common\Inflector\Inflector::pluralize($word);
|
||||
});
|
||||
$view->registerFunction('truncate', function ($text, $length = 80) {
|
||||
return App\Utilities::truncateText($text, $length);
|
||||
});
|
||||
$view->registerFunction('truncateUrl', function ($url) {
|
||||
return App\Utilities::truncateUrl($url);
|
||||
});
|
||||
$view->registerFunction('link', function ($url, $external = true, $truncate = true) {
|
||||
$url = htmlspecialchars($url, \ENT_QUOTES, 'UTF-8');
|
||||
|
||||
$a = ['href="' . $url . '"'];
|
||||
if ($external) {
|
||||
$a[] = 'target="_blank"';
|
||||
}
|
||||
|
||||
$a_body = ($truncate) ? App\Utilities::truncateUrl($url) : $url;
|
||||
return '<a ' . implode(' ', $a) . '>' . $a_body . '</a>';
|
||||
});
|
||||
|
||||
$view->addData([
|
||||
'assets' => $di->get(Azura\Assets::class),
|
||||
'auth' => $di->get(App\Auth::class),
|
||||
'acl' => $di->get(App\Acl::class),
|
||||
'customization' => $di->get(App\Customization::class),
|
||||
'version' => $di->get(App\Version::class),
|
||||
]);
|
||||
return $view;
|
||||
}),
|
||||
|
||||
/*
|
||||
* Event Dispatcher
|
||||
*/
|
||||
|
||||
Azura\EventDispatcher::class => DI\decorate(function (Azura\EventDispatcher $dispatcher, ContainerInterface $di) {
|
||||
if ($di->has(App\Plugins::class)) {
|
||||
/** @var App\Plugins $plugins */
|
||||
$plugins = $di->get(App\Plugins::class);
|
||||
|
||||
// Register plugin-provided events.
|
||||
$plugins->registerEvents($dispatcher);
|
||||
}
|
||||
|
||||
return $dispatcher;
|
||||
}),
|
||||
|
||||
/*
|
||||
* AzuraCast-specific dependencies
|
||||
*/
|
||||
|
@ -139,7 +151,7 @@ return [
|
|||
|
||||
// Message queue manager class
|
||||
App\MessageQueue::class => function (
|
||||
\Redis $redis,
|
||||
Redis $redis,
|
||||
ContainerInterface $di,
|
||||
Monolog\Logger $logger,
|
||||
EntityManager $em
|
||||
|
@ -206,22 +218,22 @@ return [
|
|||
$supervisor = new Supervisor\Supervisor($connector);
|
||||
|
||||
if (!$supervisor->isConnected()) {
|
||||
throw new \Azura\Exception(sprintf('Could not connect to supervisord.'));
|
||||
throw new \App\Exception(sprintf('Could not connect to supervisord.'));
|
||||
}
|
||||
|
||||
return $supervisor;
|
||||
},
|
||||
|
||||
Azura\Assets::class => function (Azura\Config $config, Settings $settings) {
|
||||
App\Assets::class => function (App\Config $config, Settings $settings) {
|
||||
$libraries = $config->get('assets');
|
||||
|
||||
$versioned_files = [];
|
||||
$assets_file = $settings[Settings::BASE_DIR] . '/web/static/assets.json';
|
||||
if (file_exists($assets_file)) {
|
||||
$versioned_files = json_decode(file_get_contents($assets_file), true);
|
||||
$versioned_files = json_decode(file_get_contents($assets_file), true, 512, JSON_THROW_ON_ERROR);
|
||||
}
|
||||
|
||||
return new Azura\Assets($libraries, $versioned_files);
|
||||
return new App\Assets($libraries, $versioned_files);
|
||||
},
|
||||
|
||||
/*
|
||||
|
@ -302,7 +314,7 @@ return [
|
|||
|
||||
App\Webhook\Dispatcher::class => function (
|
||||
ContainerInterface $di,
|
||||
Azura\Config $config,
|
||||
App\Config $config,
|
||||
Monolog\Logger $logger
|
||||
) {
|
||||
$webhooks = $config->get('webhooks');
|
||||
|
@ -365,4 +377,4 @@ return [
|
|||
'App\Controller\Stations\*Controller' => DI\autowire(),
|
||||
'App\Controller\Stations\Files\*Controller' => DI\autowire(),
|
||||
'App\Controller\Stations\Reports\*Controller' => DI\autowire(),
|
||||
];
|
||||
]);
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
|
||||
// Cache
|
||||
Psr\Cache\CacheItemPoolInterface::class => function (App\Settings $settings, Psr\Container\ContainerInterface $di) {
|
||||
// Never use the Redis cache for CLI commands, as the CLI commands are where
|
||||
// the Redis cache gets flushed, so this will lead to a race condition that can't
|
||||
// be solved within the application.
|
||||
return $settings->enableRedis() && !$settings->isCli()
|
||||
? new Cache\Adapter\Redis\RedisCachePool($di->get(Redis::class))
|
||||
: new Cache\Adapter\PHPArray\ArrayCachePool;
|
||||
},
|
||||
Psr\SimpleCache\CacheInterface::class => DI\get(Psr\Cache\CacheItemPoolInterface::class),
|
||||
|
||||
// Doctrine cache
|
||||
Doctrine\Common\Cache\Cache::class => function (Psr\Cache\CacheItemPoolInterface $cachePool) {
|
||||
return new Cache\Bridge\Doctrine\DoctrineCacheBridge(new Cache\Prefixed\PrefixedCachePool($cachePool,
|
||||
'doctrine|'));
|
||||
},
|
||||
|
||||
// Session save handler middleware
|
||||
Mezzio\Session\SessionPersistenceInterface::class => function (Cache\Adapter\Redis\RedisCachePool $redisPool) {
|
||||
return new Mezzio\Session\Cache\CacheSessionPersistence(
|
||||
new Cache\Prefixed\PrefixedCachePool($redisPool, 'session|'),
|
||||
'app_session',
|
||||
'/',
|
||||
'nocache',
|
||||
43200,
|
||||
time()
|
||||
);
|
||||
},
|
||||
|
||||
// Redis cache
|
||||
Redis::class => function (App\Settings $settings) {
|
||||
$redis_host = $settings[App\Settings::IS_DOCKER] ? 'redis' : 'localhost';
|
||||
|
||||
$redis = new Redis();
|
||||
$redis->connect($redis_host, 6379, 15);
|
||||
$redis->select(1);
|
||||
|
||||
return $redis;
|
||||
},
|
||||
|
||||
];
|
|
@ -0,0 +1,95 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
// DBAL
|
||||
Doctrine\DBAL\Connection::class => function (Doctrine\ORM\EntityManager $em) {
|
||||
return $em->getConnection();
|
||||
},
|
||||
'db' => DI\Get(Doctrine\DBAL\Connection::class),
|
||||
|
||||
// Doctrine Entity Manager
|
||||
Doctrine\ORM\EntityManager::class => function (
|
||||
Doctrine\Common\Cache\Cache $doctrine_cache,
|
||||
Doctrine\Common\Annotations\Reader $reader,
|
||||
App\Settings $settings,
|
||||
App\Doctrine\Event\StationRequiresRestart $eventRequiresRestart,
|
||||
App\Doctrine\Event\AuditLog $eventAuditLog
|
||||
) {
|
||||
$defaults = [
|
||||
'cache' => $doctrine_cache,
|
||||
'autoGenerateProxies' => !$settings->isProduction(),
|
||||
'proxyNamespace' => 'AppProxy',
|
||||
'proxyPath' => $settings->getTempDirectory() . '/proxies',
|
||||
'modelPath' => $settings->getBaseDirectory() . '/src/Entity',
|
||||
'useSimpleAnnotations' => false,
|
||||
'conn' => [
|
||||
'host' => $_ENV['MYSQL_HOST'] ?? 'mariadb',
|
||||
'port' => $_ENV['MYSQL_PORT'] ?? 3306,
|
||||
'dbname' => $_ENV['MYSQL_DATABASE'],
|
||||
'user' => $_ENV['MYSQL_USER'],
|
||||
'password' => $_ENV['MYSQL_PASSWORD'],
|
||||
'driver' => 'pdo_mysql',
|
||||
'charset' => 'utf8mb4',
|
||||
'defaultTableOptions' => [
|
||||
'charset' => 'utf8mb4',
|
||||
'collate' => 'utf8mb4_general_ci',
|
||||
],
|
||||
'driverOptions' => [
|
||||
// PDO::MYSQL_ATTR_INIT_COMMAND = 1002;
|
||||
1002 => 'SET NAMES utf8mb4 COLLATE utf8mb4_general_ci',
|
||||
],
|
||||
'platform' => new Doctrine\DBAL\Platforms\MariaDb1027Platform(),
|
||||
],
|
||||
];
|
||||
|
||||
if (!$settings[App\Settings::IS_DOCKER]) {
|
||||
$defaults['conn']['host'] = $_ENV['db_host'] ?? 'localhost';
|
||||
$defaults['conn']['port'] = $_ENV['db_port'] ?? '3306';
|
||||
$defaults['conn']['dbname'] = $_ENV['db_name'] ?? 'app';
|
||||
$defaults['conn']['user'] = $_ENV['db_username'] ?? 'app';
|
||||
$defaults['conn']['password'] = $_ENV['db_password'];
|
||||
}
|
||||
|
||||
$app_options = $settings[App\Settings::DOCTRINE_OPTIONS] ?? [];
|
||||
$options = array_merge($defaults, $app_options);
|
||||
|
||||
try {
|
||||
// Fetch and store entity manager.
|
||||
$config = new Doctrine\ORM\Configuration;
|
||||
|
||||
if ($options['useSimpleAnnotations']) {
|
||||
$metadata_driver = $config->newDefaultAnnotationDriver((array)$options['modelPath'],
|
||||
$options['useSimpleAnnotations']);
|
||||
} else {
|
||||
$metadata_driver = new Doctrine\ORM\Mapping\Driver\AnnotationDriver(
|
||||
$reader,
|
||||
(array)$options['modelPath']
|
||||
);
|
||||
}
|
||||
$config->setMetadataDriverImpl($metadata_driver);
|
||||
|
||||
$config->setMetadataCacheImpl($options['cache']);
|
||||
$config->setQueryCacheImpl($options['cache']);
|
||||
$config->setResultCacheImpl($options['cache']);
|
||||
|
||||
$config->setProxyDir($options['proxyPath']);
|
||||
$config->setProxyNamespace($options['proxyNamespace']);
|
||||
$config->setAutoGenerateProxyClasses(Doctrine\Common\Proxy\AbstractProxyFactory::AUTOGENERATE_FILE_NOT_EXISTS);
|
||||
|
||||
if (isset($options['conn']['debug']) && $options['conn']['debug']) {
|
||||
$config->setSQLLogger(new Doctrine\DBAL\Logging\EchoSQLLogger);
|
||||
}
|
||||
|
||||
$config->addCustomNumericFunction('RAND', App\Doctrine\Functions\Rand::class);
|
||||
|
||||
$eventManager = new Doctrine\Common\EventManager;
|
||||
$eventManager->addEventSubscriber($eventRequiresRestart);
|
||||
$eventManager->addEventSubscriber($eventAuditLog);
|
||||
|
||||
return Doctrine\ORM\EntityManager::create($options['conn'], $config, $eventManager);
|
||||
} catch (Exception $e) {
|
||||
throw new App\Exception\BootstrapException($e->getMessage());
|
||||
}
|
||||
},
|
||||
'em' => DI\Get(Doctrine\ORM\EntityManager::class),
|
||||
];
|
|
@ -0,0 +1,46 @@
|
|||
<?php
|
||||
|
||||
use App\Settings;
|
||||
|
||||
return [
|
||||
|
||||
// URL Router helper
|
||||
App\Http\Router::class => function (
|
||||
Settings $settings,
|
||||
Slim\App $app,
|
||||
App\Entity\Repository\SettingsRepository $settingsRepo
|
||||
) {
|
||||
$route_parser = $app->getRouteCollector()->getRouteParser();
|
||||
return new App\Http\Router($settings, $route_parser, $settingsRepo);
|
||||
},
|
||||
App\Http\RouterInterface::class => DI\Get(App\Http\Router::class),
|
||||
|
||||
// Error handler
|
||||
App\Http\ErrorHandler::class => DI\autowire(),
|
||||
Slim\Interfaces\ErrorHandlerInterface::class => DI\Get(App\Http\ErrorHandler::class),
|
||||
|
||||
// HTTP client
|
||||
GuzzleHttp\Client::class => function (Psr\Log\LoggerInterface $logger) {
|
||||
$stack = GuzzleHttp\HandlerStack::create();
|
||||
|
||||
$stack->unshift(function (callable $handler) {
|
||||
return function (Psr\Http\Message\RequestInterface $request, array $options) use ($handler) {
|
||||
$options[GuzzleHttp\RequestOptions::VERIFY] = Composer\CaBundle\CaBundle::getSystemCaRootBundlePath();
|
||||
return $handler($request, $options);
|
||||
};
|
||||
}, 'ssl_verify');
|
||||
|
||||
$stack->push(GuzzleHttp\Middleware::log(
|
||||
$logger,
|
||||
new GuzzleHttp\MessageFormatter('HTTP client {method} call to {uri} produced response {code}'),
|
||||
Monolog\Logger::DEBUG
|
||||
));
|
||||
|
||||
return new GuzzleHttp\Client([
|
||||
'handler' => $stack,
|
||||
GuzzleHttp\RequestOptions::HTTP_ERRORS => false,
|
||||
GuzzleHttp\RequestOptions::TIMEOUT => 3.0,
|
||||
]);
|
||||
},
|
||||
|
||||
];
|
|
@ -0,0 +1,65 @@
|
|||
<?php
|
||||
return [
|
||||
|
||||
// View (Plates Templates)
|
||||
App\View::class => function (
|
||||
Psr\Container\ContainerInterface $di,
|
||||
App\Settings $settings,
|
||||
App\Http\RouterInterface $router,
|
||||
App\EventDispatcher $dispatcher
|
||||
) {
|
||||
$view = new App\View($settings[App\Settings::VIEWS_DIR], 'phtml');
|
||||
|
||||
$view->registerFunction('service', function ($service) use ($di) {
|
||||
return $di->get($service);
|
||||
});
|
||||
|
||||
$view->registerFunction('escapeJs', function ($string) {
|
||||
return json_encode($string, JSON_THROW_ON_ERROR, 512);
|
||||
});
|
||||
|
||||
$view->addData([
|
||||
'settings' => $settings,
|
||||
'router' => $router,
|
||||
'assets' => $di->get(App\Assets::class),
|
||||
'auth' => $di->get(App\Auth::class),
|
||||
'acl' => $di->get(App\Acl::class),
|
||||
'customization' => $di->get(App\Customization::class),
|
||||
'version' => $di->get(App\Version::class),
|
||||
]);
|
||||
|
||||
$view->registerFunction('mailto', function ($address, $link_text = null) {
|
||||
$address = substr(chunk_split(bin2hex(" $address"), 2, ';&#x'), 3, -3);
|
||||
$link_text = $link_text ?? $address;
|
||||
return '<a href="mailto:' . $address . '">' . $link_text . '</a>';
|
||||
});
|
||||
$view->registerFunction('pluralize', function ($word, $num = 0) {
|
||||
if ((int)$num === 1) {
|
||||
return $word;
|
||||
}
|
||||
return Doctrine\Common\Inflector\Inflector::pluralize($word);
|
||||
});
|
||||
$view->registerFunction('truncate', function ($text, $length = 80) {
|
||||
return App\Utilities::truncateText($text, $length);
|
||||
});
|
||||
$view->registerFunction('truncateUrl', function ($url) {
|
||||
return App\Utilities::truncateUrl($url);
|
||||
});
|
||||
$view->registerFunction('link', function ($url, $external = true, $truncate = true) {
|
||||
$url = htmlspecialchars($url, ENT_QUOTES, 'UTF-8');
|
||||
|
||||
$a = ['href="' . $url . '"'];
|
||||
if ($external) {
|
||||
$a[] = 'target="_blank"';
|
||||
}
|
||||
|
||||
$a_body = ($truncate) ? App\Utilities::truncateUrl($url) : $url;
|
||||
return '<a ' . implode(' ', $a) . '>' . $a_body . '</a>';
|
||||
});
|
||||
|
||||
$dispatcher->dispatch(new App\Event\BuildView($view));
|
||||
|
||||
return $view;
|
||||
},
|
||||
|
||||
];
|
|
@ -7,8 +7,8 @@ parameters:
|
|||
bootstrap: %rootDir%/../../../util/phpstan.php
|
||||
|
||||
universalObjectCratesClasses:
|
||||
- Azura\Session\NamespaceInterface
|
||||
- Azura\View
|
||||
- App\Session\NamespaceInterface
|
||||
- App\View
|
||||
|
||||
ignoreErrors:
|
||||
# Caused by Symfony Validator (perhaps wrongly) returning the interface.
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
<?php
|
||||
namespace App;
|
||||
|
||||
use App\Http\Factory\ServerRequestFactory;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use Slim\App as SlimApp;
|
||||
|
||||
class App extends SlimApp
|
||||
{
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function run(?ServerRequestInterface $request = null): void
|
||||
{
|
||||
if (!$request) {
|
||||
$request = $this->createServerRequest();
|
||||
}
|
||||
|
||||
parent::run($request);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ServerRequestInterface
|
||||
*/
|
||||
public function createServerRequest(): ServerRequestInterface
|
||||
{
|
||||
$requestCreator = new ServerRequestFactory;
|
||||
return $requestCreator->createServerRequestFromGlobals();
|
||||
}
|
||||
}
|
|
@ -1,18 +1,22 @@
|
|||
<?php
|
||||
namespace App;
|
||||
|
||||
use App\Http\Factory\ResponseFactory;
|
||||
use App\Http\Factory\ServerRequestFactory;
|
||||
use App\Http\Response;
|
||||
use App\Http\ServerRequest;
|
||||
use Azura\App;
|
||||
use Azura\Exception;
|
||||
use Azura\Http\Factory\ResponseFactory;
|
||||
use Azura\Http\Factory\ServerRequestFactory;
|
||||
use Azura\Logger;
|
||||
use DI;
|
||||
use Doctrine\Common\Annotations\AnnotationRegistry;
|
||||
use Invoker;
|
||||
use Psr\Container\ContainerInterface;
|
||||
use Psr\Http\Message\ResponseFactoryInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Slim\Interfaces\CallableResolverInterface;
|
||||
use Slim\Interfaces\MiddlewareDispatcherInterface;
|
||||
use Slim\Interfaces\RouteCollectorInterface;
|
||||
use Slim\Interfaces\RouteResolverInterface;
|
||||
|
||||
class AppFactory extends \Azura\AppFactory
|
||||
class AppFactory
|
||||
{
|
||||
/**
|
||||
* @inheritDoc
|
||||
|
@ -34,7 +38,6 @@ class AppFactory extends \Azura\AppFactory
|
|||
|
||||
// Override DI definitions for settings.
|
||||
$diDefinitions[Settings::class] = $settings;
|
||||
$diDefinitions[\Azura\Settings::class] = DI\get(Settings::class);
|
||||
$diDefinitions['settings'] = DI\get(Settings::class);
|
||||
|
||||
self::applyPhpSettings($settings);
|
||||
|
@ -81,6 +84,176 @@ class AppFactory extends \Azura\AppFactory
|
|||
$settings[Settings::CONFIG_DIR] = $settings[Settings::BASE_DIR] . '/config';
|
||||
$settings[Settings::VIEWS_DIR] = $settings[Settings::BASE_DIR] . '/templates';
|
||||
|
||||
return parent::buildSettings($settings);
|
||||
if (!isset($settings[Settings::BASE_DIR])) {
|
||||
throw new Exception\BootstrapException('No base directory specified!');
|
||||
}
|
||||
|
||||
if (!isset($settings[Settings::TEMP_DIR])) {
|
||||
$settings[Settings::TEMP_DIR] = dirname($settings[Settings::BASE_DIR]) . '/www_tmp';
|
||||
}
|
||||
|
||||
if (!isset($settings[Settings::CONFIG_DIR])) {
|
||||
$settings[Settings::CONFIG_DIR] = $settings[Settings::BASE_DIR] . '/config';
|
||||
}
|
||||
|
||||
if (!isset($settings[Settings::VIEWS_DIR])) {
|
||||
$settings[Settings::VIEWS_DIR] = $settings[Settings::BASE_DIR] . '/templates';
|
||||
}
|
||||
|
||||
if ($settings[Settings::IS_DOCKER]) {
|
||||
$_ENV = getenv();
|
||||
} elseif (file_exists($settings[Settings::BASE_DIR] . '/env.ini')) {
|
||||
$_ENV = array_merge($_ENV, parse_ini_file($settings[Settings::BASE_DIR] . '/env.ini'));
|
||||
}
|
||||
|
||||
if (!isset($settings[Settings::APP_ENV])) {
|
||||
$settings[Settings::APP_ENV] = $_ENV['APPLICATION_ENV'] ?? Settings::ENV_PRODUCTION;
|
||||
}
|
||||
|
||||
if (isset($_ENV['BASE_URL'])) {
|
||||
$settings[Settings::BASE_URL] = $_ENV['BASE_URL'];
|
||||
}
|
||||
|
||||
if (file_exists($settings[Settings::CONFIG_DIR] . '/settings.php')) {
|
||||
$settingsFile = require($settings[Settings::CONFIG_DIR] . '/settings.php');
|
||||
|
||||
if (is_array($settingsFile)) {
|
||||
$settings = array_merge($settings, $settingsFile);
|
||||
}
|
||||
}
|
||||
|
||||
return $settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Settings $settings
|
||||
*/
|
||||
protected static function applyPhpSettings(Settings $settings): void
|
||||
{
|
||||
ini_set('display_startup_errors', !$settings->isProduction() ? 1 : 0);
|
||||
ini_set('display_errors', !$settings->isProduction() ? 1 : 0);
|
||||
ini_set('log_errors', 1);
|
||||
ini_set('error_log',
|
||||
$settings[Settings::IS_DOCKER] ? '/dev/stderr' : $settings[Settings::TEMP_DIR] . '/php_errors.log');
|
||||
ini_set('error_reporting', E_ALL & ~E_NOTICE & ~E_WARNING & ~E_STRICT);
|
||||
ini_set('session.use_only_cookies', 1);
|
||||
ini_set('session.cookie_httponly', 1);
|
||||
ini_set('session.cookie_lifetime', 86400);
|
||||
ini_set('session.use_strict_mode', 1);
|
||||
|
||||
session_cache_limiter('');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Settings $settings
|
||||
* @param array $diDefinitions
|
||||
*
|
||||
* @return DI\Container
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected static function buildContainer(Settings $settings, array $diDefinitions = []): DI\Container
|
||||
{
|
||||
$containerBuilder = new DI\ContainerBuilder;
|
||||
$containerBuilder->useAnnotations(true);
|
||||
$containerBuilder->useAutowiring(true);
|
||||
|
||||
if ($settings->isProduction()) {
|
||||
$containerBuilder->enableCompilation($settings[Settings::TEMP_DIR]);
|
||||
}
|
||||
|
||||
if (!isset($diDefinitions[Settings::class])) {
|
||||
$diDefinitions[Settings::class] = $settings;
|
||||
$diDefinitions['settings'] = DI\Get(Settings::class);
|
||||
}
|
||||
|
||||
$containerBuilder->addDefinitions($diDefinitions);
|
||||
|
||||
// Check for services.php file and include it if one exists.
|
||||
$config_dir = $settings[Settings::CONFIG_DIR];
|
||||
if (file_exists($config_dir . '/services.php')) {
|
||||
$containerBuilder->addDefinitions($config_dir . '/services.php');
|
||||
}
|
||||
|
||||
return $containerBuilder->build();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ContainerInterface $container
|
||||
*
|
||||
* @return \App\App
|
||||
*/
|
||||
protected static function createFromContainer(ContainerInterface $container): App
|
||||
{
|
||||
$responseFactory = $container->has(ResponseFactoryInterface::class)
|
||||
? $container->get(ResponseFactoryInterface::class)
|
||||
: new Http\Factory\ResponseFactory;
|
||||
|
||||
$callableResolver = $container->has(CallableResolverInterface::class)
|
||||
? $container->get(CallableResolverInterface::class)
|
||||
: null;
|
||||
|
||||
$routeCollector = $container->has(RouteCollectorInterface::class)
|
||||
? $container->get(RouteCollectorInterface::class)
|
||||
: null;
|
||||
|
||||
$routeResolver = $container->has(RouteResolverInterface::class)
|
||||
? $container->get(RouteResolverInterface::class)
|
||||
: null;
|
||||
|
||||
$middlewareDispatcher = $container->has(MiddlewareDispatcherInterface::class)
|
||||
? $container->get(MiddlewareDispatcherInterface::class)
|
||||
: null;
|
||||
|
||||
return new App(
|
||||
$responseFactory,
|
||||
$container,
|
||||
$callableResolver,
|
||||
$routeCollector,
|
||||
$routeResolver,
|
||||
$middlewareDispatcher
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param App $app
|
||||
*/
|
||||
protected static function updateRouteHandling(App $app): void
|
||||
{
|
||||
$di = $app->getContainer();
|
||||
$routeCollector = $app->getRouteCollector();
|
||||
|
||||
/** @var Settings $settings */
|
||||
$settings = $di->get(Settings::class);
|
||||
|
||||
// Use the PHP-DI Bridge's action invocation helper.
|
||||
$resolvers = [
|
||||
// Inject parameters by name first
|
||||
new Invoker\ParameterResolver\AssociativeArrayResolver(),
|
||||
// Then inject services by type-hints for those that weren't resolved
|
||||
new Invoker\ParameterResolver\Container\TypeHintContainerResolver($di),
|
||||
// Then fall back on parameters default values for optional route parameters
|
||||
new Invoker\ParameterResolver\DefaultValueResolver(),
|
||||
];
|
||||
|
||||
$invoker = new Invoker\Invoker(new Invoker\ParameterResolver\ResolverChain($resolvers), $di);
|
||||
$controllerInvoker = new DI\Bridge\Slim\ControllerInvoker($invoker);
|
||||
|
||||
$routeCollector->setDefaultInvocationStrategy($controllerInvoker);
|
||||
|
||||
if ($settings->isProduction()) {
|
||||
$routeCollector->setCacheFile($settings[Settings::TEMP_DIR] . '/app_routes.cache.php');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param App $app
|
||||
*/
|
||||
protected static function buildRoutes(App $app): void
|
||||
{
|
||||
$di = $app->getContainer();
|
||||
|
||||
/** @var EventDispatcher $dispatcher */
|
||||
$dispatcher = $di->get(EventDispatcher::class);
|
||||
$dispatcher->dispatch(new Event\BuildRoutes($app));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,435 @@
|
|||
<?php
|
||||
namespace App;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use function base64_encode;
|
||||
use function is_array;
|
||||
use function is_callable;
|
||||
use function preg_replace;
|
||||
use function random_bytes;
|
||||
|
||||
/**
|
||||
* Asset management helper class.
|
||||
* Inspired by Asseter by Adam Banaszkiewicz: https://github.com/requtize
|
||||
* @link https://github.com/requtize/assetter
|
||||
*/
|
||||
class Assets
|
||||
{
|
||||
/** @var array Known libraries loaded in initialization. */
|
||||
protected $libraries = [];
|
||||
|
||||
/** @var array An optional array lookup for versioned files. */
|
||||
protected $versioned_files = [];
|
||||
|
||||
/** @var array Loaded libraries. */
|
||||
protected $loaded = [];
|
||||
|
||||
/** @var bool Whether the current loaded libraries have been sorted by order. */
|
||||
protected $is_sorted = true;
|
||||
|
||||
/** @var string A randomly generated number-used-once (nonce) for inline CSP. */
|
||||
protected $csp_nonce;
|
||||
|
||||
/** @var array The loaded domains that should be included in the CSP header. */
|
||||
protected $csp_domains;
|
||||
|
||||
/**
|
||||
* Assets constructor.
|
||||
*
|
||||
* @param array $libraries
|
||||
* @param array $versioned_files
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function __construct(array $libraries = [], array $versioned_files = [])
|
||||
{
|
||||
foreach ($libraries as $library_name => $library) {
|
||||
$this->addLibrary($library, $library_name);
|
||||
}
|
||||
|
||||
$this->versioned_files = $versioned_files;
|
||||
$this->csp_nonce = preg_replace('/[^A-Za-z0-9\+\/=]/', '', base64_encode(random_bytes(18)));
|
||||
$this->csp_domains = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a library to the collection.
|
||||
*
|
||||
* @param array $data Array with asset data.
|
||||
* @param string|null $library_name
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function addLibrary(array $data, string $library_name = null): self
|
||||
{
|
||||
$library_name = $library_name ?? uniqid('', false);
|
||||
|
||||
$this->libraries[$library_name] = [
|
||||
'name' => $library_name,
|
||||
'order' => $data['order'] ?? 0,
|
||||
'files' => $data['files'] ?? [],
|
||||
'inline' => $data['inline'] ?? [],
|
||||
'require' => $data['require'] ?? [],
|
||||
'replace' => $data['replace'] ?? [],
|
||||
];
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $library_name
|
||||
*
|
||||
* @return array|null
|
||||
*/
|
||||
public function getLibrary(string $library_name): ?array
|
||||
{
|
||||
return $this->libraries[$library_name] ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the randomly generated nonce for inline CSP for this request.
|
||||
* @return string
|
||||
*/
|
||||
public function getCspNonce(): string
|
||||
{
|
||||
return $this->csp_nonce;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of approved domains for CSP header inclusion.
|
||||
* @return array
|
||||
*/
|
||||
public function getCspDomains(): array
|
||||
{
|
||||
return $this->csp_domains;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a single javascript file.
|
||||
*
|
||||
* @param string|array $js_script
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function addJs($js_script): self
|
||||
{
|
||||
$this->load([
|
||||
'order' => 100,
|
||||
'files' => [
|
||||
'js' => [
|
||||
(is_array($js_script)) ? $js_script : ['src' => $js_script],
|
||||
],
|
||||
],
|
||||
]);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads assets from given name or array definition.
|
||||
*
|
||||
* @param mixed $data Name or array definition of library/asset.
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function load($data): self
|
||||
{
|
||||
if (is_array($data)) {
|
||||
$item = [
|
||||
'name' => $data['name'] ?? uniqid('', false),
|
||||
'order' => $data['order'] ?? 0,
|
||||
'files' => $data['files'] ?? [],
|
||||
'inline' => $data['inline'] ?? [],
|
||||
'require' => $data['require'] ?? [],
|
||||
'replace' => $data['replace'] ?? [],
|
||||
];
|
||||
} elseif (isset($this->libraries[$data])) {
|
||||
$item = $this->libraries[$data];
|
||||
} else {
|
||||
throw new InvalidArgumentException(sprintf('Library %s not found!', $data));
|
||||
}
|
||||
|
||||
$name = $item['name'];
|
||||
|
||||
// Check if a library is "replaced" by other libraries already loaded.
|
||||
$is_replaced = false;
|
||||
foreach ($this->loaded as $loaded_name => $loaded_item) {
|
||||
if (!empty($loaded_item['replace']) && in_array($name, (array)$loaded_item['replace'], true)) {
|
||||
$is_replaced = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$is_replaced && !isset($this->loaded[$name])) {
|
||||
if (!empty($item['replace'])) {
|
||||
foreach ((array)$item['replace'] as $replace_name) {
|
||||
$this->unload($replace_name);
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($item['require'])) {
|
||||
foreach ((array)$item['require'] as $require_name) {
|
||||
$this->load($require_name);
|
||||
}
|
||||
}
|
||||
|
||||
$this->loaded[$name] = $item;
|
||||
$this->is_sorted = false;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unload a given library if it's already loaded.
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function unload(string $name): self
|
||||
{
|
||||
if (isset($this->loaded[$name])) {
|
||||
unset($this->loaded[$name]);
|
||||
$this->is_sorted = false;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a single javascript inline script.
|
||||
*
|
||||
* @param string|array $js_script
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function addInlineJs($js_script, $order = 100): self
|
||||
{
|
||||
$this->load([
|
||||
'order' => $order,
|
||||
'inline' => [
|
||||
'js' => (is_array($js_script)) ? $js_script : [$js_script],
|
||||
],
|
||||
]);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a single CSS file.
|
||||
*
|
||||
* @param string|array $css_script
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function addCss($css_script, $order = 100): self
|
||||
{
|
||||
$this->load([
|
||||
'order' => $order,
|
||||
'files' => [
|
||||
'css' => [
|
||||
(is_array($css_script)) ? $css_script : ['src' => $css_script],
|
||||
],
|
||||
],
|
||||
]);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a single inline CSS file[s].
|
||||
*
|
||||
* @param string|array $css_script
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function addInlineCss($css_script): self
|
||||
{
|
||||
$this->load([
|
||||
'order' => 100,
|
||||
'inline' => [
|
||||
'css' => (is_array($css_script)) ? $css_script : [$css_script],
|
||||
],
|
||||
]);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all CSS includes and inline styles.
|
||||
* @return string HTML tags as string.
|
||||
*/
|
||||
public function css()
|
||||
{
|
||||
$this->_sort();
|
||||
|
||||
$result = [];
|
||||
foreach ($this->loaded as $item) {
|
||||
if (!empty($item['files']['css'])) {
|
||||
foreach ($item['files']['css'] as $file) {
|
||||
$compiled_attributes = $this->compileAttributes($file, [
|
||||
'rel' => 'stylesheet',
|
||||
'type' => 'text/css',
|
||||
]);
|
||||
|
||||
$result[] = '<link ' . implode(' ', $compiled_attributes) . ' />';
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($item['inline']['css'])) {
|
||||
foreach ($item['inline']['css'] as $inline) {
|
||||
if (!empty($inline)) {
|
||||
$result[] = '<style type="text/css" nonce="' . $this->csp_nonce . '">' . "\n" . $inline . '</style>';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return implode("\n", $result) . "\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all script include tags.
|
||||
* @return string HTML tags as string.
|
||||
*/
|
||||
public function js()
|
||||
{
|
||||
$this->_sort();
|
||||
|
||||
$result = [];
|
||||
foreach ($this->loaded as $item) {
|
||||
if (!empty($item['files']['js'])) {
|
||||
foreach ($item['files']['js'] as $file) {
|
||||
$compiled_attributes = $this->compileAttributes($file, [
|
||||
'type' => 'text/javascript',
|
||||
]);
|
||||
|
||||
$result[] = '<script ' . implode(' ', $compiled_attributes) . '></script>';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return implode("\n", $result) . "\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Return any inline JavaScript.
|
||||
*
|
||||
* @param ServerRequestInterface $request
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function inlineJs(ServerRequestInterface $request): string
|
||||
{
|
||||
$this->_sort();
|
||||
|
||||
$result = [];
|
||||
foreach ($this->loaded as $item) {
|
||||
if (!empty($item['inline']['js'])) {
|
||||
foreach ($item['inline']['js'] as $inline) {
|
||||
if (is_callable($inline)) {
|
||||
$inline = $inline($request);
|
||||
}
|
||||
|
||||
if (!empty($inline)) {
|
||||
$result[] = '<script type="text/javascript" nonce="' . $this->csp_nonce . '">' . "\n" . $inline . '</script>';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return implode("\n", $result) . "\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Sort the list of loaded libraries.
|
||||
*/
|
||||
protected function _sort()
|
||||
{
|
||||
if (!$this->is_sorted) {
|
||||
uasort($this->loaded, function ($a, $b) {
|
||||
return $a['order'] <=> $b['order']; // SPACESHIP!
|
||||
});
|
||||
|
||||
$this->is_sorted = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the proper include tag for a JS/CSS include.
|
||||
*
|
||||
* @param array $file
|
||||
* @param array $defaults
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function compileAttributes(array $file, array $defaults = []): array
|
||||
{
|
||||
if (isset($file['src'])) {
|
||||
$defaults['src'] = $this->getUrl($file['src']);
|
||||
unset($file['src']);
|
||||
}
|
||||
|
||||
if (isset($file['href'])) {
|
||||
$defaults['href'] = $this->getUrl($file['href']);
|
||||
unset($file['href']);
|
||||
}
|
||||
|
||||
if (isset($file['integrity'])) {
|
||||
$defaults['crossorigin'] = 'anonymous';
|
||||
}
|
||||
|
||||
$attributes = array_merge($defaults, $file);
|
||||
|
||||
$compiled_attributes = [];
|
||||
foreach ($attributes as $attr_key => $attr_val) {
|
||||
// Check for attributes like "defer"
|
||||
if ($attr_val === true) {
|
||||
$compiled_attributes[] = $attr_key;
|
||||
} else {
|
||||
$compiled_attributes[] = $attr_key . '="' . $attr_val . '"';
|
||||
}
|
||||
}
|
||||
|
||||
return $compiled_attributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve the URI of the resource, whether local or remote/CDN-based.
|
||||
*
|
||||
* @param string $resource_uri
|
||||
*
|
||||
* @return string The resolved resource URL.
|
||||
*/
|
||||
public function getUrl($resource_uri): string
|
||||
{
|
||||
if (isset($this->versioned_files[$resource_uri])) {
|
||||
$resource_uri = $this->versioned_files[$resource_uri];
|
||||
}
|
||||
|
||||
if (preg_match('/^(https?:)?\/\//', $resource_uri)) {
|
||||
$this->addDomainToCsp($resource_uri);
|
||||
return $resource_uri;
|
||||
}
|
||||
|
||||
return '/static/' . $resource_uri;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the loaded domain to the full list of CSP-approved domains.
|
||||
*
|
||||
* @param string $src
|
||||
*/
|
||||
protected function addDomainToCsp($src): void
|
||||
{
|
||||
$src_parts = parse_url($src);
|
||||
|
||||
$domain = $src_parts['scheme'] . '://' . $src_parts['host'];
|
||||
|
||||
if (!isset($this->csp_domains[$domain])) {
|
||||
$this->csp_domains[$domain] = $domain;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -4,7 +4,7 @@ namespace App;
|
|||
use App\Entity\Repository\UserRepository;
|
||||
use App\Entity\User;
|
||||
use App\Exception\NotLoggedInException;
|
||||
use Azura\Exception;
|
||||
use App\Exception;
|
||||
use Mezzio\Session\SessionInterface;
|
||||
|
||||
class Auth
|
||||
|
|
|
@ -0,0 +1,169 @@
|
|||
<?php
|
||||
/**
|
||||
* Lightweight "Collection" class.
|
||||
* Originates from the Slim PHP framework, version 3.
|
||||
* Slim Framework (https://slimframework.com)
|
||||
* @license https://github.com/slimphp/Slim/blob/3.x/LICENSE.md (MIT License)
|
||||
*/
|
||||
|
||||
namespace App;
|
||||
|
||||
use ArrayAccess;
|
||||
use ArrayIterator;
|
||||
use IteratorAggregate;
|
||||
|
||||
/**
|
||||
* Collection
|
||||
* This class provides a common interface used by many other
|
||||
* classes in a Slim application that manage "collections"
|
||||
* of data that must be inspected and/or manipulated
|
||||
*/
|
||||
class Collection implements ArrayAccess, IteratorAggregate
|
||||
{
|
||||
/**
|
||||
* The source data
|
||||
* @var array
|
||||
*/
|
||||
protected $data = [];
|
||||
|
||||
/**
|
||||
* @param array $items Pre-populate collection with this key-value array
|
||||
*/
|
||||
public function __construct(array $items = [])
|
||||
{
|
||||
$this->replace($items);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $items
|
||||
*/
|
||||
public function replace(array $items): void
|
||||
{
|
||||
foreach ($items as $key => $value) {
|
||||
$this->set($key, $value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
*/
|
||||
public function set($key, $value): void
|
||||
{
|
||||
$this->data[$key] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function all(): array
|
||||
{
|
||||
return $this->data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get collection keys
|
||||
* @return array The collection's source data keys
|
||||
*/
|
||||
public function keys(): array
|
||||
{
|
||||
return array_keys($this->data);
|
||||
}
|
||||
|
||||
public function clear(): void
|
||||
{
|
||||
$this->data = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Does this collection have a given key?
|
||||
*
|
||||
* @param string $key The data key
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function offsetExists($key): bool
|
||||
{
|
||||
return $this->has($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function has($key): bool
|
||||
{
|
||||
return array_key_exists($key, $this->data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get collection item for key
|
||||
*
|
||||
* @param string $key The data key
|
||||
*
|
||||
* @return mixed The key's value, or the default value
|
||||
*/
|
||||
public function offsetGet($key)
|
||||
{
|
||||
return $this->get($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
* @param mixed|null $default
|
||||
*
|
||||
* @return mixed|null
|
||||
*/
|
||||
public function get($key, $default = null)
|
||||
{
|
||||
return $this->has($key) ? $this->data[$key] : $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set collection item
|
||||
*
|
||||
* @param string $key The data key
|
||||
* @param mixed $value The data value
|
||||
*/
|
||||
public function offsetSet($key, $value): void
|
||||
{
|
||||
$this->set($key, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove item from collection
|
||||
*
|
||||
* @param string $key The data key
|
||||
*/
|
||||
public function offsetUnset($key): void
|
||||
{
|
||||
$this->remove($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
*/
|
||||
public function remove($key): void
|
||||
{
|
||||
unset($this->data[$key]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get number of items in collection
|
||||
* @return int
|
||||
*/
|
||||
public function count(): int
|
||||
{
|
||||
return count($this->data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get collection iterator
|
||||
* @return ArrayIterator
|
||||
*/
|
||||
public function getIterator(): ArrayIterator
|
||||
{
|
||||
return new ArrayIterator($this->data);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
<?php
|
||||
namespace App;
|
||||
|
||||
use const EXTR_OVERWRITE;
|
||||
|
||||
class Config
|
||||
{
|
||||
protected $_base_folder;
|
||||
|
||||
public function __construct($base_folder)
|
||||
{
|
||||
if (!is_dir($base_folder)) {
|
||||
throw new Exception("Invalid base folder for configurations.");
|
||||
}
|
||||
|
||||
$this->_base_folder = $base_folder;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param array $inject_vars Variables to pass into the scope of the configuration.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get($name, $inject_vars = []): array
|
||||
{
|
||||
$path = $this->_getPath($name);
|
||||
|
||||
if (file_exists($path)) {
|
||||
unset($name);
|
||||
extract($inject_vars, EXTR_OVERWRITE);
|
||||
unset($inject_vars);
|
||||
|
||||
return require $path;
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the configuration path resolved by the specified name.
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function _getPath($name)
|
||||
{
|
||||
return $this->_base_folder . DIRECTORY_SEPARATOR . str_replace(['.', '..'], ['', ''], $name) . '.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicate whether a given configuration file name exists.
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function has($name): bool
|
||||
{
|
||||
return file_exists($this->_getPath($name));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
<?php
|
||||
namespace App\Console;
|
||||
|
||||
use Symfony\Component\Console\Input\ArrayInput;
|
||||
use Symfony\Component\Console\Output\StreamOutput;
|
||||
|
||||
class Application extends \Silly\Edition\PhpDi\Application
|
||||
{
|
||||
/**
|
||||
* Run a one-off command from elsewhere in the application, and pass through the results.
|
||||
*
|
||||
* @param string $command
|
||||
* @param array $args
|
||||
*
|
||||
* @return array [$return_code, $return_output]
|
||||
*/
|
||||
public function runCommandWithArgs($command, array $args = []): array
|
||||
{
|
||||
$input = new ArrayInput(array_merge(['command' => $command], $args));
|
||||
$input->setInteractive(false);
|
||||
|
||||
$temp_stream = fopen('php://temp', 'w+');
|
||||
$output = new StreamOutput($temp_stream);
|
||||
|
||||
$command = $this->find($command);
|
||||
$result_code = $command->run($input, $output);
|
||||
|
||||
rewind($temp_stream);
|
||||
$result_output = stream_get_contents($temp_stream);
|
||||
fclose($temp_stream);
|
||||
|
||||
return [
|
||||
$result_code,
|
||||
$result_output,
|
||||
];
|
||||
}
|
||||
}
|
|
@ -4,7 +4,7 @@ namespace App\Console\Command;
|
|||
use App\Entity;
|
||||
use App\Sync\Task\Backup;
|
||||
use App\Utilities;
|
||||
use Azura\Console\Command\CommandAbstract;
|
||||
use App\Console\Command\CommandAbstract;
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use InfluxDB\Database;
|
||||
use Symfony\Component\Console\Style\SymfonyStyle;
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
<?php
|
||||
namespace App\Console\Command;
|
||||
|
||||
use Redis;
|
||||
use Symfony\Component\Console\Style\SymfonyStyle;
|
||||
|
||||
class ClearCacheCommand extends CommandAbstract
|
||||
{
|
||||
public function __invoke(SymfonyStyle $io, Redis $redis)
|
||||
{
|
||||
// Flush all Redis entries.
|
||||
$redis->flushAll();
|
||||
|
||||
$io->writeln('Local cache flushed.');
|
||||
return 0;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
<?php
|
||||
namespace App\Console\Command;
|
||||
|
||||
use App\Console\Application;
|
||||
use Exception;
|
||||
use Symfony\Component\Console\Input\ArrayInput;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
abstract class CommandAbstract
|
||||
{
|
||||
/** @var Application */
|
||||
protected $application;
|
||||
|
||||
/**
|
||||
* @param Application $application
|
||||
*/
|
||||
public function __construct(Application $application)
|
||||
{
|
||||
$this->application = $application;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Application
|
||||
*/
|
||||
public function getApplication(): Application
|
||||
{
|
||||
return $this->application;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param OutputInterface $output
|
||||
* @param string $command_name
|
||||
* @param array $command_args
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
protected function runCommand(OutputInterface $output, $command_name, $command_args = [])
|
||||
{
|
||||
$command = $this->getApplication()->find($command_name);
|
||||
|
||||
$input = new ArrayInput(['command' => $command_name] + $command_args);
|
||||
$input->setInteractive(false);
|
||||
|
||||
$command->run($input, $output);
|
||||
}
|
||||
}
|
|
@ -3,7 +3,7 @@ namespace App\Console\Command;
|
|||
|
||||
use App\Settings;
|
||||
use App\Version;
|
||||
use Azura\Console\Command\CommandAbstract;
|
||||
use App\Console\Command\CommandAbstract;
|
||||
use Symfony\Component\Console\Style\SymfonyStyle;
|
||||
use function OpenApi\scan;
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ namespace App\Console\Command\Internal;
|
|||
use App\Entity;
|
||||
use App\Radio\Adapters;
|
||||
use App\Radio\Backend\Liquidsoap;
|
||||
use Azura\Console\Command\CommandAbstract;
|
||||
use App\Console\Command\CommandAbstract;
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use Symfony\Component\Console\Style\SymfonyStyle;
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ namespace App\Console\Command\Internal;
|
|||
use App\Entity;
|
||||
use App\Radio\Adapters;
|
||||
use App\Radio\Backend\Liquidsoap;
|
||||
use Azura\Console\Command\CommandAbstract;
|
||||
use App\Console\Command\CommandAbstract;
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use Symfony\Component\Console\Style\SymfonyStyle;
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ namespace App\Console\Command\Internal;
|
|||
use App\Entity;
|
||||
use App\Radio\Adapters;
|
||||
use App\Radio\Backend\Liquidsoap;
|
||||
use Azura\Console\Command\CommandAbstract;
|
||||
use App\Console\Command\CommandAbstract;
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use Symfony\Component\Console\Style\SymfonyStyle;
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ namespace App\Console\Command\Internal;
|
|||
|
||||
use App\Entity;
|
||||
use App\Sync\Task\NowPlaying;
|
||||
use Azura\Console\Command\CommandAbstract;
|
||||
use App\Console\Command\CommandAbstract;
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use Exception;
|
||||
use Symfony\Component\Console\Style\SymfonyStyle;
|
||||
|
|
|
@ -3,7 +3,7 @@ namespace App\Console\Command\Internal;
|
|||
|
||||
use App\Entity;
|
||||
use App\Service\AzuraCastCentral;
|
||||
use Azura\Console\Command\CommandAbstract;
|
||||
use App\Console\Command\CommandAbstract;
|
||||
use Symfony\Component\Console\Style\SymfonyStyle;
|
||||
|
||||
class GetIpCommand extends CommandAbstract
|
||||
|
|
|
@ -3,7 +3,7 @@ namespace App\Console\Command\Internal;
|
|||
|
||||
use App\Entity;
|
||||
use App\Radio\AutoDJ;
|
||||
use Azura\Console\Command\CommandAbstract;
|
||||
use App\Console\Command\CommandAbstract;
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use Symfony\Component\Console\Style\SymfonyStyle;
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
namespace App\Console\Command\Internal;
|
||||
|
||||
use App\Entity\SftpUser;
|
||||
use Azura\Console\Command\CommandAbstract;
|
||||
use App\Console\Command\CommandAbstract;
|
||||
use Brick\Math\BigInteger;
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use Symfony\Component\Console\Style\SymfonyStyle;
|
||||
|
|
|
@ -5,7 +5,7 @@ use App\Entity;
|
|||
use App\Message;
|
||||
use App\MessageQueue;
|
||||
use App\Radio\Filesystem;
|
||||
use Azura\Console\Command\CommandAbstract;
|
||||
use App\Console\Command\CommandAbstract;
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Symfony\Component\Console\Style\SymfonyStyle;
|
||||
|
|
|
@ -3,7 +3,7 @@ namespace App\Console\Command;
|
|||
|
||||
use App\Entity;
|
||||
use App\Utilities;
|
||||
use Azura\Console\Command\CommandAbstract;
|
||||
use App\Console\Command\CommandAbstract;
|
||||
use Symfony\Component\Console\Style\SymfonyStyle;
|
||||
|
||||
class ListSettingsCommand extends CommandAbstract
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
namespace App\Console\Command;
|
||||
|
||||
use App\Settings;
|
||||
use Azura\Console\Command\CommandAbstract;
|
||||
use App\Console\Command\CommandAbstract;
|
||||
use Gettext\Translations;
|
||||
use RecursiveDirectoryIterator;
|
||||
use RecursiveIteratorIterator;
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
namespace App\Console\Command;
|
||||
|
||||
use App\Settings;
|
||||
use Azura\Console\Command\CommandAbstract;
|
||||
use App\Console\Command\CommandAbstract;
|
||||
use Gettext\Translations;
|
||||
use Symfony\Component\Console\Style\SymfonyStyle;
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
namespace App\Console\Command;
|
||||
|
||||
use App\Settings;
|
||||
use Azura\Console\Command\CommandAbstract;
|
||||
use App\Console\Command\CommandAbstract;
|
||||
use Symfony\Component\Console\Style\SymfonyStyle;
|
||||
|
||||
class MigrateConfigCommand extends CommandAbstract
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
namespace App\Console\Command;
|
||||
|
||||
use App\MessageQueue;
|
||||
use Azura\Console\Command\CommandAbstract;
|
||||
use App\Console\Command\CommandAbstract;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use const PHP_INT_MAX;
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ namespace App\Console\Command;
|
|||
use App\Entity;
|
||||
use App\Entity\Repository\StationRepository;
|
||||
use App\Entity\Station;
|
||||
use Azura\Console\Command\CommandAbstract;
|
||||
use App\Console\Command\CommandAbstract;
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use Exception;
|
||||
use Symfony\Component\Console\Style\SymfonyStyle;
|
||||
|
|
|
@ -3,7 +3,7 @@ namespace App\Console\Command;
|
|||
|
||||
use App\Entity;
|
||||
use App\Utilities;
|
||||
use Azura\Console\Command\CommandAbstract;
|
||||
use App\Console\Command\CommandAbstract;
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use Symfony\Component\Console\Style\SymfonyStyle;
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ namespace App\Console\Command;
|
|||
use App\Entity\Repository\StationRepository;
|
||||
use App\Entity\Station;
|
||||
use App\Radio\Configuration;
|
||||
use Azura\Console\Command\CommandAbstract;
|
||||
use App\Console\Command\CommandAbstract;
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use Symfony\Component\Console\Style\SymfonyStyle;
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ namespace App\Console\Command;
|
|||
|
||||
use App\Sync\Task\Backup;
|
||||
use App\Utilities;
|
||||
use Azura\Console\Command\CommandAbstract;
|
||||
use App\Console\Command\CommandAbstract;
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use InfluxDB\Database;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
|
|
@ -3,7 +3,7 @@ namespace App\Console\Command;
|
|||
|
||||
use App\Acl;
|
||||
use App\Entity;
|
||||
use Azura\Console\Command\CommandAbstract;
|
||||
use App\Console\Command\CommandAbstract;
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use Symfony\Component\Console\Style\SymfonyStyle;
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
namespace App\Console\Command;
|
||||
|
||||
use App\Entity;
|
||||
use Azura\Console\Command\CommandAbstract;
|
||||
use App\Console\Command\CommandAbstract;
|
||||
use Symfony\Component\Console\Style\SymfonyStyle;
|
||||
|
||||
class SetSettingCommand extends CommandAbstract
|
||||
|
|
|
@ -4,7 +4,7 @@ namespace App\Console\Command;
|
|||
use App\Entity;
|
||||
use App\Service\AzuraCastCentral;
|
||||
use App\Settings;
|
||||
use Azura\Console\Command\CommandAbstract;
|
||||
use App\Console\Command\CommandAbstract;
|
||||
use Psr\Container\ContainerInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\Console\Style\SymfonyStyle;
|
||||
|
|
|
@ -3,7 +3,7 @@ namespace App\Console\Command;
|
|||
|
||||
use App\Entity\Station;
|
||||
use App\Settings;
|
||||
use Azura\Console\Command\CommandAbstract;
|
||||
use App\Console\Command\CommandAbstract;
|
||||
use Cake\Chronos\Chronos;
|
||||
use Doctrine\Common\DataFixtures\Executor\ORMExecutor;
|
||||
use Doctrine\Common\DataFixtures\Loader;
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
namespace App\Console\Command;
|
||||
|
||||
use App\Settings;
|
||||
use Azura\Console\Command\CommandAbstract;
|
||||
use App\Console\Command\CommandAbstract;
|
||||
use InfluxDB\Database;
|
||||
use Symfony\Component\Console\Style\SymfonyStyle;
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ namespace App\Console\Command;
|
|||
|
||||
use App;
|
||||
use App\Sync\Runner;
|
||||
use Azura\Console\Command\CommandAbstract;
|
||||
use App\Console\Command\CommandAbstract;
|
||||
|
||||
class SyncCommand extends CommandAbstract
|
||||
{
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
namespace App\Console\Command;
|
||||
|
||||
use App;
|
||||
use Azura\Console\Command\CommandAbstract;
|
||||
use App\Console\Command\CommandAbstract;
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use Exception;
|
||||
use InvalidArgumentException;
|
||||
|
|
|
@ -4,7 +4,7 @@ namespace App\Controller\Admin;
|
|||
use App\Form\ApiKeyForm;
|
||||
use App\Http\Response;
|
||||
use App\Http\ServerRequest;
|
||||
use Azura\Session\Flash;
|
||||
use App\Session\Flash;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
|
||||
class ApiController extends AbstractAdminCrudController
|
||||
|
|
|
@ -9,8 +9,8 @@ use App\Form\Form;
|
|||
use App\Http\Response;
|
||||
use App\Http\ServerRequest;
|
||||
use App\Sync\Task\Backup;
|
||||
use Azura\Config;
|
||||
use Azura\Session\Flash;
|
||||
use App\Config;
|
||||
use App\Session\Flash;
|
||||
use Exception;
|
||||
use League\Flysystem\Adapter\Local;
|
||||
use League\Flysystem\Filesystem;
|
||||
|
|
|
@ -4,7 +4,7 @@ namespace App\Controller\Admin;
|
|||
use App\Form\BrandingSettingsForm;
|
||||
use App\Http\Response;
|
||||
use App\Http\ServerRequest;
|
||||
use Azura\Session\Flash;
|
||||
use App\Session\Flash;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
|
||||
class BrandingController
|
||||
|
|
|
@ -5,7 +5,7 @@ use App\Entity;
|
|||
use App\Form\CustomFieldForm;
|
||||
use App\Http\Response;
|
||||
use App\Http\ServerRequest;
|
||||
use Azura\Session\Flash;
|
||||
use App\Session\Flash;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
|
||||
class CustomFieldsController extends AbstractAdminCrudController
|
||||
|
|
|
@ -7,7 +7,7 @@ use App\Form\GeoLiteSettingsForm;
|
|||
use App\Http\Response;
|
||||
use App\Http\ServerRequest;
|
||||
use App\Service\IpGeolocator\GeoLite;
|
||||
use Azura\Session\Flash;
|
||||
use App\Session\Flash;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
|
||||
class InstallGeoLiteController
|
||||
|
|
|
@ -6,7 +6,7 @@ use App\Http\Response;
|
|||
use App\Http\ServerRequest;
|
||||
use App\Radio\Frontend\SHOUTcast;
|
||||
use App\Settings;
|
||||
use Azura\Config;
|
||||
use App\Config;
|
||||
use Exception;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Http\Message\UploadedFileInterface;
|
||||
|
|
|
@ -6,7 +6,7 @@ use App\Entity;
|
|||
use App\Http\Response;
|
||||
use App\Http\ServerRequest;
|
||||
use App\Settings;
|
||||
use Azura\Exception;
|
||||
use App\Exception;
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ use App\Acl;
|
|||
use App\Form\PermissionsForm;
|
||||
use App\Http\Response;
|
||||
use App\Http\ServerRequest;
|
||||
use Azura\Session\Flash;
|
||||
use App\Session\Flash;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
|
||||
class PermissionsController extends AbstractAdminCrudController
|
||||
|
|
|
@ -4,7 +4,7 @@ namespace App\Controller\Admin;
|
|||
use App\Form\SettingsForm;
|
||||
use App\Http\Response;
|
||||
use App\Http\ServerRequest;
|
||||
use Azura\Session\Flash;
|
||||
use App\Session\Flash;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
|
||||
class SettingsController
|
||||
|
|
|
@ -7,7 +7,7 @@ use App\Exception\NotFoundException;
|
|||
use App\Form;
|
||||
use App\Http\Response;
|
||||
use App\Http\ServerRequest;
|
||||
use Azura\Session\Flash;
|
||||
use App\Session\Flash;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
|
||||
class StationsController extends AbstractAdminCrudController
|
||||
|
|
|
@ -7,7 +7,7 @@ use App\Exception\NotFoundException;
|
|||
use App\Form\UserForm;
|
||||
use App\Http\Response;
|
||||
use App\Http\ServerRequest;
|
||||
use Azura\Session\Flash;
|
||||
use App\Session\Flash;
|
||||
use Doctrine\DBAL\Exception\UniqueConstraintViolationException;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
namespace App\Controller\Api;
|
||||
|
||||
use App\Exception\ValidationException;
|
||||
use Azura\Http\RouterInterface;
|
||||
use App\Http\RouterInterface;
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use Doctrine\ORM\OptimisticLockException;
|
||||
use Doctrine\ORM\ORMException;
|
||||
|
|
|
@ -6,8 +6,8 @@ use App\Entity;
|
|||
use App\Http\Response;
|
||||
use App\Http\ServerRequest;
|
||||
use App\Utilities;
|
||||
use Azura\Doctrine\Paginator;
|
||||
use Azura\Exception;
|
||||
use App\Doctrine\Paginator;
|
||||
use App\Exception;
|
||||
use Doctrine\ORM\OptimisticLockException;
|
||||
use Doctrine\ORM\ORMException;
|
||||
use Doctrine\ORM\TransactionRequiredException;
|
||||
|
|
|
@ -4,7 +4,7 @@ namespace App\Controller\Api\Admin;
|
|||
use App\Entity;
|
||||
use App\Http\Response;
|
||||
use App\Http\ServerRequest;
|
||||
use Azura\Doctrine\Paginator;
|
||||
use App\Doctrine\Paginator;
|
||||
use Cake\Chronos\Chronos;
|
||||
use DateTimeZone;
|
||||
use Doctrine\ORM\EntityManager;
|
||||
|
|
|
@ -3,7 +3,7 @@ namespace App\Controller\Api\Admin;
|
|||
|
||||
use App\Entity;
|
||||
use App\Exception\ValidationException;
|
||||
use Azura\Normalizer\DoctrineEntityNormalizer;
|
||||
use App\Normalizer\DoctrineEntityNormalizer;
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use InvalidArgumentException;
|
||||
use OpenApi\Annotations as OA;
|
||||
|
|
|
@ -4,7 +4,7 @@ namespace App\Controller\Api;
|
|||
use App\Entity;
|
||||
use App\Http\Response;
|
||||
use App\Http\ServerRequest;
|
||||
use Azura\Timezone;
|
||||
use App\Timezone;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
|
||||
class IndexController
|
||||
|
|
|
@ -5,7 +5,7 @@ use App\Entity;
|
|||
use App\Event\Radio\LoadNowPlaying;
|
||||
use App\Http\Response;
|
||||
use App\Http\ServerRequest;
|
||||
use Azura\EventDispatcher;
|
||||
use App\EventDispatcher;
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use OpenApi\Annotations as OA;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
|
|
|
@ -6,8 +6,8 @@ use App\Entity;
|
|||
use App\Http\Response;
|
||||
use App\Http\ServerRequest;
|
||||
use App\Utilities;
|
||||
use Azura\Doctrine\Paginator;
|
||||
use Azura\Exception;
|
||||
use App\Doctrine\Paginator;
|
||||
use App\Exception;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
|
||||
|
||||
|
|
|
@ -231,7 +231,7 @@ class BatchAction
|
|||
if ('' !== $directory_path) {
|
||||
$directory_path_meta = $fs->getMetadata($directory_path_full);
|
||||
if ('dir' !== $directory_path_meta['type']) {
|
||||
throw new \Azura\Exception(__('Path "%s" is not a folder.', $directory_path_full));
|
||||
throw new \App\Exception(__('Path "%s" is not a folder.', $directory_path_full));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -246,7 +246,7 @@ class BatchAction
|
|||
$media->setPath($newPath);
|
||||
|
||||
if (!$fs->rename($old_full_path, $media->getPath())) {
|
||||
throw new \Azura\Exception(__('Could not move "%s" to "%s"', $old_full_path,
|
||||
throw new \App\Exception(__('Could not move "%s" to "%s"', $old_full_path,
|
||||
$media->getPath()));
|
||||
}
|
||||
|
||||
|
|
|
@ -5,8 +5,8 @@ use App;
|
|||
use App\Entity;
|
||||
use App\Http\Response;
|
||||
use App\Http\ServerRequest;
|
||||
use Azura\Doctrine\Paginator;
|
||||
use Azura\Utilities\Csv;
|
||||
use App\Doctrine\Paginator;
|
||||
use App\Utilities\Csv;
|
||||
use Cake\Chronos\Chronos;
|
||||
use DateTimeZone;
|
||||
use Doctrine\ORM\EntityManager;
|
||||
|
|
|
@ -6,7 +6,7 @@ use App\Exception\NotFoundException;
|
|||
use App\Http\Response;
|
||||
use App\Http\ServerRequest;
|
||||
use App\Radio\Adapters;
|
||||
use Azura\Exception;
|
||||
use App\Exception;
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use OpenApi\Annotations as OA;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
|
|
|
@ -5,7 +5,7 @@ use App\Entity;
|
|||
use App\Http\Response;
|
||||
use App\Http\ServerRequest;
|
||||
use App\Service\IpGeolocation;
|
||||
use Azura\Utilities\Csv;
|
||||
use App\Utilities\Csv;
|
||||
use Cake\Chronos\Chronos;
|
||||
use DateTimeZone;
|
||||
use Doctrine\ORM\EntityManager;
|
||||
|
|
|
@ -5,9 +5,9 @@ use App\Entity;
|
|||
use App\Exception\NotFoundException;
|
||||
use App\Http\Response;
|
||||
use App\Http\ServerRequest;
|
||||
use Azura\Doctrine\Paginator;
|
||||
use Azura\Exception;
|
||||
use Azura\Http\RouterInterface;
|
||||
use App\Doctrine\Paginator;
|
||||
use App\Exception;
|
||||
use App\Http\RouterInterface;
|
||||
use Cake\Chronos\Chronos;
|
||||
use DateTimeZone;
|
||||
use Doctrine\ORM\EntityManager;
|
||||
|
|
|
@ -5,8 +5,8 @@ use App;
|
|||
use App\Entity;
|
||||
use App\Http\Response;
|
||||
use App\Http\ServerRequest;
|
||||
use Azura\Doctrine\Paginator;
|
||||
use Azura\Http\RouterInterface;
|
||||
use App\Doctrine\Paginator;
|
||||
use App\Http\RouterInterface;
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use InvalidArgumentException;
|
||||
use OpenApi\Annotations as OA;
|
||||
|
|
|
@ -6,8 +6,8 @@ use App\Entity;
|
|||
use App\Http\Response;
|
||||
use App\Http\ServerRequest;
|
||||
use App\Utilities;
|
||||
use Azura\Doctrine\Paginator;
|
||||
use Azura\Exception;
|
||||
use App\Doctrine\Paginator;
|
||||
use App\Exception;
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use OpenApi\Annotations as OA;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
|
|
|
@ -7,7 +7,7 @@ use App\Http\Response;
|
|||
use App\Http\ServerRequest;
|
||||
use App\Radio\Filesystem;
|
||||
use App\Utilities;
|
||||
use Azura\Doctrine\Paginator;
|
||||
use App\Doctrine\Paginator;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
|
||||
class BroadcastsController extends AbstractApiCrudController
|
||||
|
|
|
@ -4,7 +4,7 @@ namespace App\Controller\Api\Stations;
|
|||
use App\Entity;
|
||||
use App\Exception\StationUnsupportedException;
|
||||
use App\Http\ServerRequest;
|
||||
use Azura\Http\RouterInterface;
|
||||
use App\Http\RouterInterface;
|
||||
use OpenApi\Annotations as OA;
|
||||
|
||||
class StreamersController extends AbstractStationApiCrudController
|
||||
|
|
|
@ -8,9 +8,9 @@ use App\Entity\Settings;
|
|||
use App\Entity\User;
|
||||
use App\Http\Response;
|
||||
use App\Http\ServerRequest;
|
||||
use Azura\Exception\RateLimitExceededException;
|
||||
use Azura\RateLimit;
|
||||
use Azura\Session\Flash;
|
||||
use App\Exception\RateLimitExceededException;
|
||||
use App\RateLimit;
|
||||
use App\Session\Flash;
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ namespace App\Controller\Frontend\Account;
|
|||
use App\Auth;
|
||||
use App\Http\Response;
|
||||
use App\Http\ServerRequest;
|
||||
use Azura\Session\Flash;
|
||||
use App\Session\Flash;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
|
||||
class TwoFactorAction
|
||||
|
|
|
@ -6,7 +6,7 @@ use App\Exception\NotFoundException;
|
|||
use App\Form\Form;
|
||||
use App\Http\Response;
|
||||
use App\Http\ServerRequest;
|
||||
use Azura\Config;
|
||||
use App\Config;
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ use App\Http\Response;
|
|||
use App\Http\Router;
|
||||
use App\Http\ServerRequest;
|
||||
use App\Radio\Adapters;
|
||||
use Azura\EventDispatcher;
|
||||
use App\EventDispatcher;
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use InfluxDB\Database;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
|
|
|
@ -3,7 +3,7 @@ namespace App\Controller\Frontend\Profile;
|
|||
|
||||
use App\Http\Response;
|
||||
use App\Http\ServerRequest;
|
||||
use Azura\Session\Flash;
|
||||
use App\Session\Flash;
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ namespace App\Controller\Frontend\Profile;
|
|||
use App\Form\UserProfileForm;
|
||||
use App\Http\Response;
|
||||
use App\Http\ServerRequest;
|
||||
use Azura\Session\Flash;
|
||||
use App\Session\Flash;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
|
||||
class EditAction
|
||||
|
|
|
@ -5,8 +5,8 @@ use App\Auth;
|
|||
use App\Form\Form;
|
||||
use App\Http\Response;
|
||||
use App\Http\ServerRequest;
|
||||
use Azura\Config;
|
||||
use Azura\Session\Flash;
|
||||
use App\Config;
|
||||
use App\Session\Flash;
|
||||
use AzuraForms\Field\AbstractField;
|
||||
use BaconQrCode;
|
||||
use Doctrine\ORM\EntityManager;
|
||||
|
|
|
@ -10,7 +10,7 @@ use App\Form\StationForm;
|
|||
use App\Http\Response;
|
||||
use App\Http\ServerRequest;
|
||||
use App\Settings;
|
||||
use Azura\Session\Flash;
|
||||
use App\Session\Flash;
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
|
||||
|
|
|
@ -5,8 +5,8 @@ use App\Entity\Station;
|
|||
use App\Exception\NotFoundException;
|
||||
use App\Form\EntityForm;
|
||||
use App\Http\ServerRequest;
|
||||
use Azura\Exception;
|
||||
use Azura\Exception\CsrfValidationException;
|
||||
use App\Exception;
|
||||
use App\Exception\CsrfValidationException;
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use Doctrine\ORM\EntityRepository;
|
||||
use Doctrine\ORM\OptimisticLockException;
|
||||
|
|
|
@ -6,8 +6,8 @@ use App\Http\Response;
|
|||
use App\Http\ServerRequest;
|
||||
use App\Settings;
|
||||
use App\Sync\Task\RadioAutomation;
|
||||
use Azura\Config;
|
||||
use Azura\Session\Flash;
|
||||
use App\Config;
|
||||
use App\Session\Flash;
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use Exception;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
|
|
|
@ -4,7 +4,7 @@ namespace App\Controller\Stations;
|
|||
use App\Controller\Traits\LogViewerTrait;
|
||||
use App\Http\Response;
|
||||
use App\Http\ServerRequest;
|
||||
use Azura\Exception;
|
||||
use App\Exception;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
|
||||
class LogsController
|
||||
|
|
|
@ -5,7 +5,7 @@ use App\Exception\StationUnsupportedException;
|
|||
use App\Form\StationMountForm;
|
||||
use App\Http\Response;
|
||||
use App\Http\ServerRequest;
|
||||
use Azura\Session\Flash;
|
||||
use App\Session\Flash;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
|
||||
class MountsController extends AbstractStationCrudController
|
||||
|
|
|
@ -3,7 +3,7 @@ namespace App\Controller\Stations;
|
|||
|
||||
use App\Http\Response;
|
||||
use App\Http\ServerRequest;
|
||||
use Azura\Exception;
|
||||
use App\Exception;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
|
||||
class PlaylistsController
|
||||
|
|
|
@ -7,7 +7,7 @@ use App\Exception\PermissionDeniedException;
|
|||
use App\Form\StationRemoteForm;
|
||||
use App\Http\Response;
|
||||
use App\Http\ServerRequest;
|
||||
use Azura\Session\Flash;
|
||||
use App\Session\Flash;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
|
||||
class RemotesController extends AbstractStationCrudController
|
||||
|
|
|
@ -5,7 +5,7 @@ use App\Entity;
|
|||
use App\Http\Response;
|
||||
use App\Http\ServerRequest;
|
||||
use App\Radio\Filesystem;
|
||||
use Azura\Session\Flash;
|
||||
use App\Session\Flash;
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ namespace App\Controller\Stations\Reports;
|
|||
use App\Http\Response;
|
||||
use App\Http\ServerRequest;
|
||||
use App\Sync\Task\RadioAutomation;
|
||||
use Azura\Utilities\Csv;
|
||||
use App\Utilities\Csv;
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ namespace App\Controller\Stations\Reports;
|
|||
use App\Entity;
|
||||
use App\Http\Response;
|
||||
use App\Http\ServerRequest;
|
||||
use Azura\Session\Flash;
|
||||
use App\Session\Flash;
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ use App\Entity;
|
|||
use App\Form\Form;
|
||||
use App\Http\Response;
|
||||
use App\Http\ServerRequest;
|
||||
use Azura\Config;
|
||||
use App\Config;
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use GuzzleHttp\Client;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
|
|
|
@ -7,7 +7,7 @@ use App\Http\Response;
|
|||
use App\Http\ServerRequest;
|
||||
use App\Service\AzuraCastCentral;
|
||||
use App\Service\SftpGo;
|
||||
use Azura\Session\Flash;
|
||||
use App\Session\Flash;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
|
||||
class SftpUsersController extends AbstractStationCrudController
|
||||
|
|
|
@ -7,7 +7,7 @@ use App\Form\StationStreamerForm;
|
|||
use App\Http\Response;
|
||||
use App\Http\ServerRequest;
|
||||
use App\Service\AzuraCastCentral;
|
||||
use Azura\Session\Flash;
|
||||
use App\Session\Flash;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
|
||||
class StreamersController extends AbstractStationCrudController
|
||||
|
|
|
@ -6,7 +6,7 @@ use App\Form\StationWebhookForm;
|
|||
use App\Http\Response;
|
||||
use App\Http\ServerRequest;
|
||||
use App\Webhook\Dispatcher;
|
||||
use Azura\Session\Flash;
|
||||
use App\Session\Flash;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
|
||||
class WebhooksController extends AbstractStationCrudController
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
<?php
|
||||
/**
|
||||
* Deferred Callable
|
||||
* Used from:
|
||||
* Slim Framework (https://slimframework.com)
|
||||
* @license https://github.com/slimphp/Slim/blob/4.x/LICENSE.md (MIT License)
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App;
|
||||
|
||||
use Slim\Interfaces\CallableResolverInterface;
|
||||
|
||||
class DeferredCallable
|
||||
{
|
||||
/**
|
||||
* @var callable|string
|
||||
*/
|
||||
protected $callable;
|
||||
|
||||
/**
|
||||
* @var CallableResolverInterface|null
|
||||
*/
|
||||
protected $callableResolver;
|
||||
|
||||
/**
|
||||
* @param callable|string $callable
|
||||
* @param CallableResolverInterface|null $resolver
|
||||
*/
|
||||
public function __construct($callable, ?CallableResolverInterface $resolver = null)
|
||||
{
|
||||
$this->callable = $callable;
|
||||
$this->callableResolver = $resolver;
|
||||
}
|
||||
|
||||
public function __invoke(...$args)
|
||||
{
|
||||
/** @var callable $callable */
|
||||
$callable = $this->callable;
|
||||
if ($this->callableResolver) {
|
||||
$callable = $this->callableResolver->resolve($callable);
|
||||
}
|
||||
|
||||
return $callable(...$args);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
<?php
|
||||
namespace App\Doctrine\Functions;
|
||||
|
||||
use Doctrine\ORM\Query\AST\Functions\FunctionNode;
|
||||
use Doctrine\ORM\Query\Lexer;
|
||||
use Doctrine\ORM\Query\Parser;
|
||||
use Doctrine\ORM\Query\SqlWalker;
|
||||
|
||||
/**
|
||||
* RandFunction ::= "RAND" "(" ")"
|
||||
*/
|
||||
class Rand extends FunctionNode
|
||||
{
|
||||
public function parse(Parser $parser)
|
||||
{
|
||||
$parser->match(Lexer::T_IDENTIFIER);
|
||||
$parser->match(Lexer::T_OPEN_PARENTHESIS);
|
||||
$parser->match(Lexer::T_CLOSE_PARENTHESIS);
|
||||
}
|
||||
|
||||
public function getSql(SqlWalker $sqlWalker)
|
||||
{
|
||||
return 'RAND()';
|
||||
}
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* DoctrineExtensions Paginate
|
||||
* LICENSE
|
||||
* This source file is subject to the new BSD license that is bundled
|
||||
* with this package in the file LICENSE.txt.
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to kontakt@beberlei.de so I can send you a copy immediately.
|
||||
*/
|
||||
|
||||
namespace App\Doctrine\Paginate;
|
||||
|
||||
use Doctrine\ORM\Query\AST\AggregateExpression;
|
||||
use Doctrine\ORM\Query\AST\PathExpression;
|
||||
use Doctrine\ORM\Query\AST\SelectExpression;
|
||||
use Doctrine\ORM\Query\AST\SelectStatement;
|
||||
use Doctrine\ORM\Query\TreeWalkerAdapter;
|
||||
|
||||
class CountWalker extends TreeWalkerAdapter
|
||||
{
|
||||
|
||||
/**
|
||||
* Walks down a SelectStatement AST node, modifying it to retrieve a COUNT
|
||||
*
|
||||
* @param SelectStatement $AST
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function walkSelectStatement(SelectStatement $AST)
|
||||
{
|
||||
$parent = null;
|
||||
$parentName = null;
|
||||
|
||||
foreach ($this->_getQueryComponents() AS $dqlAlias => $qComp) {
|
||||
// skip mixed data in query
|
||||
if (isset($qComp['resultVariable'])) {
|
||||
continue;
|
||||
}
|
||||
if ($qComp['parent'] === null && $qComp['nestingLevel'] == 0) {
|
||||
$parent = $qComp;
|
||||
$parentName = $dqlAlias;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$pathExpression = new PathExpression(
|
||||
PathExpression::TYPE_STATE_FIELD | PathExpression::TYPE_SINGLE_VALUED_ASSOCIATION, $parentName,
|
||||
$parent['metadata']->getSingleIdentifierFieldName()
|
||||
);
|
||||
$pathExpression->type = PathExpression::TYPE_STATE_FIELD;
|
||||
|
||||
$AST->selectClause->selectExpressions = [
|
||||
new SelectExpression(
|
||||
new AggregateExpression('count', $pathExpression, true), null
|
||||
),
|
||||
];
|
||||
|
||||
// ORDER BY is not needed, only increases query execution through unnecessary sorting.
|
||||
$AST->orderByClause = null;
|
||||
|
||||
// GROUP BY will break things, we are trying to get a count of all
|
||||
$AST->groupByClause = null;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,221 @@
|
|||
<?php
|
||||
namespace App\Doctrine;
|
||||
|
||||
use App\Http\RequestHelper;
|
||||
use App\Http\Response;
|
||||
use App\Http\ResponseHelper;
|
||||
use App\Http\Router;
|
||||
use App\Http\ServerRequest;
|
||||
use Doctrine\ORM\Query;
|
||||
use Doctrine\ORM\QueryBuilder;
|
||||
use Doctrine\ORM\Tools\Pagination\Paginator as DoctrinePaginator;
|
||||
use InvalidArgumentException;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
|
||||
class Paginator
|
||||
{
|
||||
/** @var Query */
|
||||
protected $query;
|
||||
|
||||
/** @var Router */
|
||||
protected $router;
|
||||
|
||||
/** @var int */
|
||||
protected $current_page = 1;
|
||||
|
||||
/** @var int */
|
||||
protected $per_page = 15;
|
||||
|
||||
/** @var int */
|
||||
protected $max_per_page = 50;
|
||||
|
||||
/** @var bool Whether the current request is from jQuery Bootgrid */
|
||||
protected $is_bootgrid = false;
|
||||
|
||||
/** @var bool Whether to show pagination controls. */
|
||||
protected $is_disabled = false;
|
||||
|
||||
/** @var callable|null A callable postprocessor that can be run on each result. */
|
||||
protected $postprocessor;
|
||||
|
||||
public function __construct($query)
|
||||
{
|
||||
if ($query instanceof QueryBuilder) {
|
||||
$query = $query->getQuery();
|
||||
}
|
||||
|
||||
if (!($query instanceof Query)) {
|
||||
throw new InvalidArgumentException('Query specified is not a Doctrine query.');
|
||||
}
|
||||
|
||||
$this->query = $query;
|
||||
}
|
||||
|
||||
public function getQuery(): Query
|
||||
{
|
||||
return $this->query;
|
||||
}
|
||||
|
||||
public function getCurrentPage(): int
|
||||
{
|
||||
return $this->current_page;
|
||||
}
|
||||
|
||||
public function setCurrentPage(int $current_page): void
|
||||
{
|
||||
$this->current_page = ($current_page > 0) ? $current_page : 1;
|
||||
}
|
||||
|
||||
public function setMaxPerPage(int $max_per_page): void
|
||||
{
|
||||
$this->max_per_page = ($max_per_page > 0) ? $max_per_page : 1;
|
||||
$this->is_disabled = false;
|
||||
}
|
||||
|
||||
public function getPerPage(): int
|
||||
{
|
||||
return $this->per_page;
|
||||
}
|
||||
|
||||
public function setPerPage(int $per_page): void
|
||||
{
|
||||
if ($per_page > 0) {
|
||||
$this->per_page = ($per_page <= $this->max_per_page) ? $per_page : $this->max_per_page;
|
||||
} else {
|
||||
$this->per_page = -1;
|
||||
}
|
||||
|
||||
$this->is_disabled = false;
|
||||
}
|
||||
|
||||
public function getRouter(): Router
|
||||
{
|
||||
return $this->router;
|
||||
}
|
||||
|
||||
public function setRouter(Router $router): void
|
||||
{
|
||||
$this->router = $router;
|
||||
}
|
||||
|
||||
public function isFromBootgrid(): bool
|
||||
{
|
||||
return $this->is_bootgrid;
|
||||
}
|
||||
|
||||
public function setFromRequest(ServerRequest $request): void
|
||||
{
|
||||
$params = $request->getQueryParams();
|
||||
|
||||
$this->is_disabled = true;
|
||||
$this->is_bootgrid = isset($params['rowCount']) || isset($params['searchPhrase']);
|
||||
|
||||
if ($this->is_bootgrid) {
|
||||
$this->setCurrentPage((int)$params['current']);
|
||||
$this->setPerPage((int)$params['rowCount']);
|
||||
} else {
|
||||
if (isset($params['page'])) {
|
||||
$this->setCurrentPage((int)$params['page']);
|
||||
}
|
||||
if (isset($params['per_page'])) {
|
||||
$this->setPerPage((int)$params['per_page']);
|
||||
}
|
||||
}
|
||||
|
||||
$router = $request->getRouter();
|
||||
$this->setRouter($router);
|
||||
}
|
||||
|
||||
public function setPostprocessor(callable $postprocessor)
|
||||
{
|
||||
$this->postprocessor = $postprocessor;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isDisabled(): bool
|
||||
{
|
||||
return $this->is_disabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $is_disabled
|
||||
*/
|
||||
public function setIsDisabled(bool $is_disabled): void
|
||||
{
|
||||
$this->is_disabled = $is_disabled;
|
||||
}
|
||||
|
||||
public function write(Response $response): ResponseInterface
|
||||
{
|
||||
$paginator = $this->getPaginator();
|
||||
|
||||
$total = count($paginator);
|
||||
$total_pages = ($this->per_page === -1)
|
||||
? 1
|
||||
: ceil($total / $this->per_page);
|
||||
|
||||
if ($this->postprocessor) {
|
||||
$results = [];
|
||||
$postprocessor = $this->postprocessor;
|
||||
foreach ($paginator as $result) {
|
||||
$results[] = $postprocessor($result);
|
||||
}
|
||||
} else {
|
||||
$results = iterator_to_array($paginator);
|
||||
}
|
||||
|
||||
if ($this->is_disabled) {
|
||||
return $response->withJson($results);
|
||||
}
|
||||
|
||||
if ($this->is_bootgrid) {
|
||||
return $response->withJson([
|
||||
'current' => $this->current_page,
|
||||
'rowCount' => $this->per_page,
|
||||
'total' => $paginator->count(),
|
||||
'rows' => $results,
|
||||
]);
|
||||
}
|
||||
|
||||
$page_links = [];
|
||||
if ($this->router instanceof Router) {
|
||||
$page_links['first'] = $this->router->fromHereWithQuery(null, [], ['page' => 1]);
|
||||
|
||||
$prev_page = ($this->current_page > 1) ? $this->current_page - 1 : 1;
|
||||
$page_links['previous'] = $this->router->fromHereWithQuery(null, [], ['page' => $prev_page]);
|
||||
|
||||
$next_page = ($this->current_page < $total_pages) ? $this->current_page + 1 : $total_pages;
|
||||
$page_links['next'] = $this->router->fromHereWithQuery(null, [], ['page' => $next_page]);
|
||||
|
||||
$page_links['last'] = $this->router->fromHereWithQuery(null, [], ['page' => $total_pages]);
|
||||
}
|
||||
|
||||
return $response->withJson([
|
||||
'page' => $this->current_page,
|
||||
'per_page' => $this->per_page,
|
||||
'total' => $paginator->count(),
|
||||
'total_pages' => $total_pages,
|
||||
'links' => $page_links,
|
||||
'rows' => $results,
|
||||
]);
|
||||
}
|
||||
|
||||
public function getPaginator()
|
||||
{
|
||||
static $paginator;
|
||||
|
||||
if (!$paginator) {
|
||||
if (!$this->is_disabled && $this->per_page !== -1) {
|
||||
$offset = ($this->current_page - 1) * $this->per_page;
|
||||
$this->query->setFirstResult($offset);
|
||||
$this->query->setMaxResults($this->per_page);
|
||||
}
|
||||
|
||||
$paginator = new DoctrinePaginator($this->query);
|
||||
}
|
||||
|
||||
return $paginator;
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue