Architecture change: Integrate common AzuraCore code (#944)
* Update composer.json/lock * Update CLI console commands * All AzuraCore refactors except folder moves. * MVP for all core functionality. * Working unit/functional tests * Remove DB dump from util/, replace with direct migration. * Update AzuraCore, define testing mode earlier.
This commit is contained in:
parent
83ebaab952
commit
854cb93261
|
@ -1,88 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Global bootstrap file.
|
||||
*/
|
||||
|
||||
// Security settings
|
||||
define('APP_IS_COMMAND_LINE', PHP_SAPI === 'cli');
|
||||
define('APP_IS_SECURE', !APP_IS_COMMAND_LINE && (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === "on"));
|
||||
|
||||
if (!defined('APP_TESTING_MODE')) {
|
||||
define('APP_TESTING_MODE', false);
|
||||
}
|
||||
|
||||
// General includes
|
||||
define('APP_INCLUDE_BASE', __DIR__);
|
||||
define('APP_INCLUDE_ROOT', dirname(__DIR__));
|
||||
define('APP_INCLUDE_WEB', APP_INCLUDE_ROOT . '/web');
|
||||
define('APP_INCLUDE_STATIC', APP_INCLUDE_WEB . '/static');
|
||||
|
||||
// Detect Docker containerization
|
||||
define('APP_INSIDE_DOCKER', file_exists(APP_INCLUDE_ROOT.'/../.docker'));
|
||||
|
||||
define('APP_INCLUDE_VENDOR', APP_INCLUDE_ROOT . '/vendor');
|
||||
|
||||
define('APP_INCLUDE_TEMP', dirname(APP_INCLUDE_ROOT) . '/www_tmp');
|
||||
define('APP_INCLUDE_CACHE', APP_INCLUDE_TEMP . '/cache');
|
||||
|
||||
// Set up application environment.
|
||||
if (APP_INSIDE_DOCKER) {
|
||||
$_ENV = getenv();
|
||||
} else if (file_exists(APP_INCLUDE_ROOT.'/env.ini')) {
|
||||
$_ENV = array_merge($_ENV, parse_ini_file(APP_INCLUDE_ROOT.'/env.ini'));
|
||||
} else if (file_exists(APP_INCLUDE_ROOT.'/app/env.ini')) {
|
||||
// Legacy file location.
|
||||
$_ENV = array_merge($_ENV, parse_ini_file(APP_INCLUDE_ROOT.'/app/env.ini'));
|
||||
}
|
||||
|
||||
// Application environment.
|
||||
define('APP_APPLICATION_ENV', $_ENV['application_env'] ?? $_ENV['APPLICATION_ENV'] ?? 'production');
|
||||
define('APP_IN_PRODUCTION', APP_APPLICATION_ENV === 'production');
|
||||
|
||||
define('APP_DOCKER_REVISION', $_ENV['AZURACAST_DC_REVISION'] ?? 1);
|
||||
|
||||
if (isset($_SERVER['HTTP_X_FORWARDED_PROTO'])) {
|
||||
$_SERVER['HTTPS'] = (strtolower($_SERVER['HTTP_X_FORWARDED_PROTO']) === 'https');
|
||||
}
|
||||
|
||||
// Apply PHP settings.
|
||||
ini_set('display_startup_errors', !APP_IN_PRODUCTION ? 1 : 0);
|
||||
ini_set('display_errors', !APP_IN_PRODUCTION ? 1 : 0);
|
||||
ini_set('log_errors', 1);
|
||||
ini_set('error_log', (APP_INSIDE_DOCKER) ? '/dev/stderr' : APP_INCLUDE_TEMP.'/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);
|
||||
|
||||
// Disable sessions sending their own Cache-Control/Expires headers.
|
||||
session_cache_limiter('');
|
||||
|
||||
// Composer autoload.
|
||||
$autoloader = require(APP_INCLUDE_VENDOR . '/autoload.php');
|
||||
|
||||
// Initialize plugins
|
||||
$plugins = new \App\Plugins(APP_INCLUDE_ROOT.'/plugins');
|
||||
$plugins->registerAutoloaders($autoloader);
|
||||
|
||||
// Set up DI container.
|
||||
$di = new \Slim\Container([
|
||||
'settings' => [
|
||||
'outputBuffering' => false,
|
||||
'displayErrorDetails' => !APP_IN_PRODUCTION,
|
||||
'addContentLengthHeader' => false,
|
||||
'routerCacheFile' => (APP_IN_PRODUCTION) ? APP_INCLUDE_TEMP . '/app_routes.cache.php' : false,
|
||||
'determineRouteBeforeAppMiddleware' => true,
|
||||
]
|
||||
]);
|
||||
|
||||
$di[\App\Plugins::class] = $plugins;
|
||||
|
||||
// Define services.
|
||||
$settings = require(dirname(__DIR__).'/config/settings.php');
|
||||
call_user_func(include(dirname(__DIR__).'/config/services.php'), $di, $settings);
|
||||
|
||||
$plugins->registerServices($di, $settings);
|
||||
|
||||
return $di;
|
|
@ -1,27 +0,0 @@
|
|||
<?php
|
||||
error_reporting(E_ALL & ~E_NOTICE & ~E_STRICT);
|
||||
ini_set('display_errors', 1);
|
||||
|
||||
$di = require __DIR__.'/app.php';
|
||||
|
||||
// Load app, to generate routes, etc.
|
||||
$di->get('app');
|
||||
|
||||
// Placeholder locale functions
|
||||
$translator = new \Gettext\Translator();
|
||||
$translator->register();
|
||||
|
||||
/** @var \Doctrine\ORM\EntityManager $em */
|
||||
$em = $di[\Doctrine\ORM\EntityManager::class];
|
||||
|
||||
/** @var \App\Version $version */
|
||||
$version = $di[\App\Version::class];
|
||||
|
||||
$helperSet = \Doctrine\ORM\Tools\Console\ConsoleRunner::createHelperSet($em);
|
||||
$helperSet->set(new \Symfony\Component\Console\Helper\QuestionHelper, 'dialog');
|
||||
|
||||
$cli = new \App\Console\Application($settings['name'].' Command Line Tools ('.APP_APPLICATION_ENV.')', $version->getVersion());
|
||||
$cli->setContainer($di);
|
||||
$cli->setHelperSet($helperSet);
|
||||
|
||||
return $cli;
|
|
@ -19,24 +19,13 @@ coverage:
|
|||
include:
|
||||
- src/*
|
||||
exclude:
|
||||
# Loaded before tests
|
||||
- src/Tests/Module.php
|
||||
- src/Doctrine/EntityManagerFactory.php
|
||||
|
||||
# Not used in entire application
|
||||
- src/Doctrine/Platform/*.php
|
||||
- src/Doctrine/Paginate/*.php
|
||||
|
||||
# Used in application, but not used in tests
|
||||
- src/Radio/Frontend/ShoutCast2.php
|
||||
- src/Console/Command/*.php
|
||||
- src/Doctrine/Logger/EchoSQL.php
|
||||
- src/Session/Temporary.php
|
||||
- src/Console/Command/*.php
|
||||
- src/Entity/Fixture/*
|
||||
- src/Entity/Migration/*
|
||||
|
||||
# Exceptions
|
||||
- src/Exception.php
|
||||
- src/Exception/*.php
|
||||
- src/Mvc/ErrorHandler.php
|
||||
|
|
123
composer.json
123
composer.json
|
@ -1,72 +1,57 @@
|
|||
{
|
||||
"name": "AzuraCast/AzuraCast",
|
||||
"description": "The AzuraCast standalone radio station management tool.",
|
||||
"license": "Apache-2.0",
|
||||
"require": {
|
||||
"php": ">=7.2",
|
||||
"ext-fileinfo": "*",
|
||||
"ext-gd": "*",
|
||||
"ext-intl": "*",
|
||||
"ext-json": "*",
|
||||
"ext-PDO": "*",
|
||||
"ext-redis": "*",
|
||||
"ext-simplexml": "*",
|
||||
"ext-xml": "*",
|
||||
"ext-xmlwriter": "*",
|
||||
"name": "AzuraCast/AzuraCast",
|
||||
"description": "The AzuraCast standalone radio station management suite.",
|
||||
"license": "Apache-2.0",
|
||||
"require": {
|
||||
"php": ">=7.2",
|
||||
"ext-fileinfo": "*",
|
||||
"ext-gd": "*",
|
||||
"ext-intl": "*",
|
||||
"ext-simplexml": "*",
|
||||
"ext-xml": "*",
|
||||
"ext-xmlwriter": "*",
|
||||
|
||||
"azuracast/azuraforms": "dev-master",
|
||||
"azuracast/nowplaying": "dev-master",
|
||||
"cakephp/chronos": "^1.1",
|
||||
"doctrine/data-fixtures": "^1.3",
|
||||
"doctrine/dbal": "^2.8",
|
||||
"doctrine/migrations": "^1.5",
|
||||
"doctrine/orm": "~2.6",
|
||||
"filp/whoops": "2.*",
|
||||
"gettext/gettext": "^4.4",
|
||||
"guzzlehttp/guzzle": ">6.0",
|
||||
"guzzlehttp/oauth-subscriber": "^0.3.0",
|
||||
"influxdb/influxdb-php": "^1.14.3",
|
||||
"james-heinrich/getid3": "dev-master",
|
||||
"league/plates": "^3.1",
|
||||
"lstrojny/fxmlrpc": "^0.14.0",
|
||||
"maxmind-db/reader": "~1.0",
|
||||
"mobiledetect/mobiledetectlib": "^2.8",
|
||||
"monolog/monolog": "^1.23",
|
||||
"paragonie/certainty": "^2",
|
||||
"php-http/socket-client": "^1.2",
|
||||
"php-http/message": "^1.4",
|
||||
"php-http/guzzle6-adapter": "^1.1",
|
||||
"slim/slim": "^3.0",
|
||||
"studio24/rotate": "^1.0",
|
||||
"supervisorphp/supervisor": "^3.0",
|
||||
"symfony/console": "^4.1",
|
||||
"symfony/event-dispatcher": "^4.1",
|
||||
"symfony/finder": "^4.1",
|
||||
"symfony/process": "^4.1",
|
||||
"zendframework/zend-config": "^3.1.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"codeception/codeception": "^2.2",
|
||||
"flow/jsonpath": "^0.3.4",
|
||||
"mockery/mockery": "^1.0",
|
||||
"roave/security-advisories": "dev-master",
|
||||
"squizlabs/php_codesniffer": "3.*",
|
||||
"zircote/swagger-php": "^3.0"
|
||||
},
|
||||
"authors": [
|
||||
{
|
||||
"name": "Buster Neece",
|
||||
"email": "buster@busterneece.com"
|
||||
}
|
||||
],
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"App\\": "src"
|
||||
}
|
||||
},
|
||||
"config": {
|
||||
"preferred-install": "dist"
|
||||
},
|
||||
"prefer-stable": true,
|
||||
"minimum-stability": "dev"
|
||||
"azuracast/azuracore": "dev-master",
|
||||
"azuracast/azuraforms": "dev-master",
|
||||
"azuracast/nowplaying": "dev-master",
|
||||
"cakephp/chronos": "^1.1",
|
||||
"gettext/gettext": "^4.4",
|
||||
"guzzlehttp/oauth-subscriber": "^0.3.0",
|
||||
"influxdb/influxdb-php": "^1.14.3",
|
||||
"james-heinrich/getid3": "dev-master",
|
||||
"lstrojny/fxmlrpc": "^0.14.0",
|
||||
"maxmind-db/reader": "~1.0",
|
||||
"mobiledetect/mobiledetectlib": "^2.8",
|
||||
"php-http/socket-client": "^1.2",
|
||||
"php-http/message": "^1.4",
|
||||
"php-http/guzzle6-adapter": "^1.1",
|
||||
"studio24/rotate": "^1.0",
|
||||
"supervisorphp/supervisor": "^3.0",
|
||||
"symfony/finder": "^4.1",
|
||||
"symfony/process": "^4.1"
|
||||
},
|
||||
"require-dev": {
|
||||
"codeception/codeception": "^2.2",
|
||||
"flow/jsonpath": "^0.3.4",
|
||||
"mockery/mockery": "^1.0",
|
||||
"roave/security-advisories": "dev-master",
|
||||
"squizlabs/php_codesniffer": "3.*",
|
||||
"zircote/swagger-php": "^3.0"
|
||||
},
|
||||
"authors": [
|
||||
{
|
||||
"name": "Buster Neece",
|
||||
"email": "buster@busterneece.com"
|
||||
}
|
||||
],
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"App\\": "src"
|
||||
}
|
||||
},
|
||||
"config": {
|
||||
"preferred-install": "dist"
|
||||
},
|
||||
"prefer-stable": true,
|
||||
"minimum-stability": "dev"
|
||||
}
|
||||
|
|
|
@ -4,8 +4,66 @@
|
|||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "988f73420ee8c51c179ed07afb9a0a97",
|
||||
"content-hash": "2580b6ed9dfc5dcaaa2846f267386636",
|
||||
"packages": [
|
||||
{
|
||||
"name": "azuracast/azuracore",
|
||||
"version": "dev-master",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/AzuraCast/azuracore.git",
|
||||
"reference": "4605cd9dc87269463aac78ee557cd489baa84f88"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/AzuraCast/azuracore/zipball/4605cd9dc87269463aac78ee557cd489baa84f88",
|
||||
"reference": "4605cd9dc87269463aac78ee557cd489baa84f88",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"doctrine/data-fixtures": "^1.3",
|
||||
"doctrine/dbal": "^2.8",
|
||||
"doctrine/migrations": "^1.5",
|
||||
"doctrine/orm": "~2.6",
|
||||
"ext-json": "*",
|
||||
"ext-pdo": "*",
|
||||
"ext-redis": "*",
|
||||
"filp/whoops": "2.*",
|
||||
"guzzlehttp/guzzle": ">6.0",
|
||||
"league/plates": "^3.1",
|
||||
"monolog/monolog": "^1.23",
|
||||
"paragonie/certainty": "^2",
|
||||
"php": ">=7.2",
|
||||
"slim/slim": "^3.0",
|
||||
"symfony/console": "^4.1",
|
||||
"symfony/event-dispatcher": "^4.1",
|
||||
"symfony/var-dumper": "^4.1",
|
||||
"zendframework/zend-config": "^3.1.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"codeception/codeception": "^2.2",
|
||||
"mockery/mockery": "^1.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": "2018-11-12T07:55:59+00:00"
|
||||
},
|
||||
{
|
||||
"name": "azuracast/azuraforms",
|
||||
"version": "dev-master",
|
||||
|
@ -95,16 +153,16 @@
|
|||
},
|
||||
{
|
||||
"name": "cakephp/chronos",
|
||||
"version": "1.2.2",
|
||||
"version": "1.2.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/cakephp/chronos.git",
|
||||
"reference": "30f5b26bcf76a5e53ecc274700ad1ec49dc05567"
|
||||
"reference": "395110125ff577f080fa064dca5c5608a4e77ee1"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/cakephp/chronos/zipball/30f5b26bcf76a5e53ecc274700ad1ec49dc05567",
|
||||
"reference": "30f5b26bcf76a5e53ecc274700ad1ec49dc05567",
|
||||
"url": "https://api.github.com/repos/cakephp/chronos/zipball/395110125ff577f080fa064dca5c5608a4e77ee1",
|
||||
"reference": "395110125ff577f080fa064dca5c5608a4e77ee1",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -148,7 +206,7 @@
|
|||
"datetime",
|
||||
"time"
|
||||
],
|
||||
"time": "2018-07-11T18:51:56+00:00"
|
||||
"time": "2018-10-18T22:02:21+00:00"
|
||||
},
|
||||
{
|
||||
"name": "clue/stream-filter",
|
||||
|
@ -1225,16 +1283,16 @@
|
|||
},
|
||||
{
|
||||
"name": "filp/whoops",
|
||||
"version": "2.2.1",
|
||||
"version": "2.3.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/filp/whoops.git",
|
||||
"reference": "e79cd403fb77fc8963a99ecc30e80ddd885b3311"
|
||||
"reference": "bc0fd11bc455cc20ee4b5edabc63ebbf859324c7"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/filp/whoops/zipball/e79cd403fb77fc8963a99ecc30e80ddd885b3311",
|
||||
"reference": "e79cd403fb77fc8963a99ecc30e80ddd885b3311",
|
||||
"url": "https://api.github.com/repos/filp/whoops/zipball/bc0fd11bc455cc20ee4b5edabc63ebbf859324c7",
|
||||
"reference": "bc0fd11bc455cc20ee4b5edabc63ebbf859324c7",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -1282,7 +1340,7 @@
|
|||
"throwable",
|
||||
"whoops"
|
||||
],
|
||||
"time": "2018-06-30T13:14:06+00:00"
|
||||
"time": "2018-10-23T09:00:00+00:00"
|
||||
},
|
||||
{
|
||||
"name": "gettext/gettext",
|
||||
|
@ -1705,12 +1763,12 @@
|
|||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/JamesHeinrich/getID3.git",
|
||||
"reference": "dd1099bcef91ee9d750bba4eb3a0c93a73edebb8"
|
||||
"reference": "50db613408bf3ffee85e4bab49fd756c4db97b98"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/JamesHeinrich/getID3/zipball/dd1099bcef91ee9d750bba4eb3a0c93a73edebb8",
|
||||
"reference": "dd1099bcef91ee9d750bba4eb3a0c93a73edebb8",
|
||||
"url": "https://api.github.com/repos/JamesHeinrich/getID3/zipball/50db613408bf3ffee85e4bab49fd756c4db97b98",
|
||||
"reference": "50db613408bf3ffee85e4bab49fd756c4db97b98",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -1760,7 +1818,7 @@
|
|||
"php",
|
||||
"tags"
|
||||
],
|
||||
"time": "2018-09-28T23:48:50+00:00"
|
||||
"time": "2018-11-11T03:13:18+00:00"
|
||||
},
|
||||
{
|
||||
"name": "league/plates",
|
||||
|
@ -2001,16 +2059,16 @@
|
|||
},
|
||||
{
|
||||
"name": "monolog/monolog",
|
||||
"version": "1.23.0",
|
||||
"version": "1.24.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Seldaek/monolog.git",
|
||||
"reference": "fd8c787753b3a2ad11bc60c063cff1358a32a3b4"
|
||||
"reference": "bfc9ebb28f97e7a24c45bdc3f0ff482e47bb0266"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/Seldaek/monolog/zipball/fd8c787753b3a2ad11bc60c063cff1358a32a3b4",
|
||||
"reference": "fd8c787753b3a2ad11bc60c063cff1358a32a3b4",
|
||||
"url": "https://api.github.com/repos/Seldaek/monolog/zipball/bfc9ebb28f97e7a24c45bdc3f0ff482e47bb0266",
|
||||
"reference": "bfc9ebb28f97e7a24c45bdc3f0ff482e47bb0266",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -2075,7 +2133,7 @@
|
|||
"logging",
|
||||
"psr-3"
|
||||
],
|
||||
"time": "2017-06-19T01:22:40+00:00"
|
||||
"time": "2018-11-05T09:00:11+00:00"
|
||||
},
|
||||
{
|
||||
"name": "nikic/fast-route",
|
||||
|
@ -2244,16 +2302,16 @@
|
|||
},
|
||||
{
|
||||
"name": "paragonie/certainty",
|
||||
"version": "v2.1.0",
|
||||
"version": "v2.2.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/paragonie/certainty.git",
|
||||
"reference": "30364451a3615d4b3813bb0857b85b10815b4487"
|
||||
"reference": "d3e2777e1ca2b1401329a49c7d56d112e6414f23"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/paragonie/certainty/zipball/30364451a3615d4b3813bb0857b85b10815b4487",
|
||||
"reference": "30364451a3615d4b3813bb0857b85b10815b4487",
|
||||
"url": "https://api.github.com/repos/paragonie/certainty/zipball/d3e2777e1ca2b1401329a49c7d56d112e6414f23",
|
||||
"reference": "d3e2777e1ca2b1401329a49c7d56d112e6414f23",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -2263,6 +2321,7 @@
|
|||
"php": "^5.5|^7"
|
||||
},
|
||||
"require-dev": {
|
||||
"composer/composer": "^1",
|
||||
"phpunit/phpunit": "^4|^5|^6"
|
||||
},
|
||||
"bin": [
|
||||
|
@ -2299,7 +2358,7 @@
|
|||
"ssl",
|
||||
"tls"
|
||||
],
|
||||
"time": "2018-05-03T17:31:41+00:00"
|
||||
"time": "2018-10-30T01:14:53+00:00"
|
||||
},
|
||||
{
|
||||
"name": "paragonie/constant_time_encoding",
|
||||
|
@ -2670,16 +2729,16 @@
|
|||
},
|
||||
{
|
||||
"name": "php-http/message",
|
||||
"version": "1.7.0",
|
||||
"version": "1.7.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/php-http/message.git",
|
||||
"reference": "741f2266a202d59c4ed75436671e1b8e6f475ea3"
|
||||
"reference": "b159ffe570dffd335e22ef0b91a946eacb182fa1"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/php-http/message/zipball/741f2266a202d59c4ed75436671e1b8e6f475ea3",
|
||||
"reference": "741f2266a202d59c4ed75436671e1b8e6f475ea3",
|
||||
"url": "https://api.github.com/repos/php-http/message/zipball/b159ffe570dffd335e22ef0b91a946eacb182fa1",
|
||||
"reference": "b159ffe570dffd335e22ef0b91a946eacb182fa1",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -2738,7 +2797,7 @@
|
|||
"message",
|
||||
"psr-7"
|
||||
],
|
||||
"time": "2018-08-15T06:37:30+00:00"
|
||||
"time": "2018-11-01T09:32:41+00:00"
|
||||
},
|
||||
{
|
||||
"name": "php-http/message-factory",
|
||||
|
@ -3270,16 +3329,16 @@
|
|||
},
|
||||
{
|
||||
"name": "symfony/console",
|
||||
"version": "v4.1.4",
|
||||
"version": "v4.1.7",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/console.git",
|
||||
"reference": "ca80b8ced97cf07390078b29773dc384c39eee1f"
|
||||
"reference": "432122af37d8cd52fba1b294b11976e0d20df595"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/console/zipball/ca80b8ced97cf07390078b29773dc384c39eee1f",
|
||||
"reference": "ca80b8ced97cf07390078b29773dc384c39eee1f",
|
||||
"url": "https://api.github.com/repos/symfony/console/zipball/432122af37d8cd52fba1b294b11976e0d20df595",
|
||||
"reference": "432122af37d8cd52fba1b294b11976e0d20df595",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -3334,20 +3393,20 @@
|
|||
],
|
||||
"description": "Symfony Console Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2018-07-26T11:24:31+00:00"
|
||||
"time": "2018-10-31T09:30:44+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/event-dispatcher",
|
||||
"version": "v4.1.4",
|
||||
"version": "v4.1.7",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/event-dispatcher.git",
|
||||
"reference": "bfb30c2ad377615a463ebbc875eba64a99f6aa3e"
|
||||
"reference": "552541dad078c85d9414b09c041ede488b456cd5"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/bfb30c2ad377615a463ebbc875eba64a99f6aa3e",
|
||||
"reference": "bfb30c2ad377615a463ebbc875eba64a99f6aa3e",
|
||||
"url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/552541dad078c85d9414b09c041ede488b456cd5",
|
||||
"reference": "552541dad078c85d9414b09c041ede488b456cd5",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -3397,20 +3456,20 @@
|
|||
],
|
||||
"description": "Symfony EventDispatcher Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2018-07-26T09:10:45+00:00"
|
||||
"time": "2018-10-10T13:52:42+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/finder",
|
||||
"version": "v4.1.4",
|
||||
"version": "v4.1.7",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/finder.git",
|
||||
"reference": "e162f1df3102d0b7472805a5a9d5db9fcf0a8068"
|
||||
"reference": "1f17195b44543017a9c9b2d437c670627e96ad06"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/finder/zipball/e162f1df3102d0b7472805a5a9d5db9fcf0a8068",
|
||||
"reference": "e162f1df3102d0b7472805a5a9d5db9fcf0a8068",
|
||||
"url": "https://api.github.com/repos/symfony/finder/zipball/1f17195b44543017a9c9b2d437c670627e96ad06",
|
||||
"reference": "1f17195b44543017a9c9b2d437c670627e96ad06",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -3446,20 +3505,20 @@
|
|||
],
|
||||
"description": "Symfony Finder Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2018-07-26T11:24:31+00:00"
|
||||
"time": "2018-10-03T08:47:56+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/options-resolver",
|
||||
"version": "v4.1.4",
|
||||
"version": "v4.1.7",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/options-resolver.git",
|
||||
"reference": "1913f1962477cdbb13df951f8147d5da1fe2412c"
|
||||
"reference": "40f0e40d37c1c8a762334618dea597d64bbb75ff"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/options-resolver/zipball/1913f1962477cdbb13df951f8147d5da1fe2412c",
|
||||
"reference": "1913f1962477cdbb13df951f8147d5da1fe2412c",
|
||||
"url": "https://api.github.com/repos/symfony/options-resolver/zipball/40f0e40d37c1c8a762334618dea597d64bbb75ff",
|
||||
"reference": "40f0e40d37c1c8a762334618dea597d64bbb75ff",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -3500,20 +3559,20 @@
|
|||
"configuration",
|
||||
"options"
|
||||
],
|
||||
"time": "2018-07-26T08:55:25+00:00"
|
||||
"time": "2018-09-18T12:45:12+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-mbstring",
|
||||
"version": "v1.9.0",
|
||||
"version": "v1.10.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-mbstring.git",
|
||||
"reference": "d0cd638f4634c16d8df4508e847f14e9e43168b8"
|
||||
"reference": "c79c051f5b3a46be09205c73b80b346e4153e494"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/d0cd638f4634c16d8df4508e847f14e9e43168b8",
|
||||
"reference": "d0cd638f4634c16d8df4508e847f14e9e43168b8",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/c79c051f5b3a46be09205c73b80b346e4153e494",
|
||||
"reference": "c79c051f5b3a46be09205c73b80b346e4153e494",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -3559,20 +3618,75 @@
|
|||
"portable",
|
||||
"shim"
|
||||
],
|
||||
"time": "2018-08-06T14:22:27+00:00"
|
||||
"time": "2018-09-21T13:07:52+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/process",
|
||||
"version": "v4.1.6",
|
||||
"name": "symfony/polyfill-php72",
|
||||
"version": "v1.10.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/process.git",
|
||||
"reference": "ee33c0322a8fee0855afcc11fff81e6b1011b529"
|
||||
"url": "https://github.com/symfony/polyfill-php72.git",
|
||||
"reference": "9050816e2ca34a8e916c3a0ae8b9c2fccf68b631"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/process/zipball/ee33c0322a8fee0855afcc11fff81e6b1011b529",
|
||||
"reference": "ee33c0322a8fee0855afcc11fff81e6b1011b529",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/9050816e2ca34a8e916c3a0ae8b9c2fccf68b631",
|
||||
"reference": "9050816e2ca34a8e916c3a0ae8b9c2fccf68b631",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.3"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.9-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Symfony\\Polyfill\\Php72\\": ""
|
||||
},
|
||||
"files": [
|
||||
"bootstrap.php"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Nicolas Grekas",
|
||||
"email": "p@tchwork.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions",
|
||||
"homepage": "https://symfony.com",
|
||||
"keywords": [
|
||||
"compatibility",
|
||||
"polyfill",
|
||||
"portable",
|
||||
"shim"
|
||||
],
|
||||
"time": "2018-09-21T13:07:52+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/process",
|
||||
"version": "v4.1.7",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/process.git",
|
||||
"reference": "3e83acef94d979b1de946599ef86b3a352abcdc9"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/process/zipball/3e83acef94d979b1de946599ef86b3a352abcdc9",
|
||||
"reference": "3e83acef94d979b1de946599ef86b3a352abcdc9",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -3608,7 +3722,82 @@
|
|||
],
|
||||
"description": "Symfony Process Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2018-10-02T12:40:59+00:00"
|
||||
"time": "2018-10-14T20:48:13+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/var-dumper",
|
||||
"version": "v4.1.7",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/var-dumper.git",
|
||||
"reference": "60319b45653580b0cdacca499344577d87732f16"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/var-dumper/zipball/60319b45653580b0cdacca499344577d87732f16",
|
||||
"reference": "60319b45653580b0cdacca499344577d87732f16",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.1.3",
|
||||
"symfony/polyfill-mbstring": "~1.0",
|
||||
"symfony/polyfill-php72": "~1.5"
|
||||
},
|
||||
"conflict": {
|
||||
"phpunit/phpunit": "<4.8.35|<5.4.3,>=5.0",
|
||||
"symfony/console": "<3.4"
|
||||
},
|
||||
"require-dev": {
|
||||
"ext-iconv": "*",
|
||||
"symfony/process": "~3.4|~4.0",
|
||||
"twig/twig": "~1.34|~2.4"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-iconv": "To convert non-UTF-8 strings to UTF-8 (or symfony/polyfill-iconv in case ext-iconv cannot be used).",
|
||||
"ext-intl": "To show region name in time zone dump",
|
||||
"symfony/console": "To use the ServerDumpCommand and/or the bin/var-dump-server script"
|
||||
},
|
||||
"bin": [
|
||||
"Resources/bin/var-dump-server"
|
||||
],
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "4.1-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"files": [
|
||||
"Resources/functions/dump.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"Symfony\\Component\\VarDumper\\": ""
|
||||
},
|
||||
"exclude-from-classmap": [
|
||||
"/Tests/"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Nicolas Grekas",
|
||||
"email": "p@tchwork.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Symfony mechanism for exploring and dumping PHP variables",
|
||||
"homepage": "https://symfony.com",
|
||||
"keywords": [
|
||||
"debug",
|
||||
"dump"
|
||||
],
|
||||
"time": "2018-10-02T16:36:10+00:00"
|
||||
},
|
||||
{
|
||||
"name": "zendframework/zend-code",
|
||||
|
@ -3886,16 +4075,16 @@
|
|||
},
|
||||
{
|
||||
"name": "codeception/codeception",
|
||||
"version": "2.5.0",
|
||||
"version": "2.5.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Codeception/Codeception.git",
|
||||
"reference": "dee493561daf644134c95cf176fd2c25aff59ea9"
|
||||
"reference": "e0a658c64e98811a6fd4f6aa7c3222e0609066a9"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/Codeception/Codeception/zipball/dee493561daf644134c95cf176fd2c25aff59ea9",
|
||||
"reference": "dee493561daf644134c95cf176fd2c25aff59ea9",
|
||||
"url": "https://api.github.com/repos/Codeception/Codeception/zipball/e0a658c64e98811a6fd4f6aa7c3222e0609066a9",
|
||||
"reference": "e0a658c64e98811a6fd4f6aa7c3222e0609066a9",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -3974,20 +4163,20 @@
|
|||
"functional testing",
|
||||
"unit testing"
|
||||
],
|
||||
"time": "2018-09-24T09:33:01+00:00"
|
||||
"time": "2018-10-29T21:23:19+00:00"
|
||||
},
|
||||
{
|
||||
"name": "codeception/phpunit-wrapper",
|
||||
"version": "7.3.1",
|
||||
"version": "7.3.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Codeception/phpunit-wrapper.git",
|
||||
"reference": "1967be130082effb3c30510cf8f8397fbd9d8b84"
|
||||
"reference": "a5633c736e0e0022bc5065b27c63f2d1aa97b69f"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/Codeception/phpunit-wrapper/zipball/1967be130082effb3c30510cf8f8397fbd9d8b84",
|
||||
"reference": "1967be130082effb3c30510cf8f8397fbd9d8b84",
|
||||
"url": "https://api.github.com/repos/Codeception/phpunit-wrapper/zipball/a5633c736e0e0022bc5065b27c63f2d1aa97b69f",
|
||||
"reference": "a5633c736e0e0022bc5065b27c63f2d1aa97b69f",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -4017,7 +4206,7 @@
|
|||
}
|
||||
],
|
||||
"description": "PHPUnit classes used by Codeception",
|
||||
"time": "2018-09-28T15:36:26+00:00"
|
||||
"time": "2018-10-07T21:30:01+00:00"
|
||||
},
|
||||
{
|
||||
"name": "codeception/stub",
|
||||
|
@ -4200,16 +4389,16 @@
|
|||
},
|
||||
{
|
||||
"name": "mockery/mockery",
|
||||
"version": "1.1.0",
|
||||
"version": "1.2.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/mockery/mockery.git",
|
||||
"reference": "99e29d3596b16dabe4982548527d5ddf90232e99"
|
||||
"reference": "100633629bf76d57430b86b7098cd6beb996a35a"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/mockery/mockery/zipball/99e29d3596b16dabe4982548527d5ddf90232e99",
|
||||
"reference": "99e29d3596b16dabe4982548527d5ddf90232e99",
|
||||
"url": "https://api.github.com/repos/mockery/mockery/zipball/100633629bf76d57430b86b7098cd6beb996a35a",
|
||||
"reference": "100633629bf76d57430b86b7098cd6beb996a35a",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -4218,8 +4407,7 @@
|
|||
"php": ">=5.6.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpdocumentor/phpdocumentor": "^2.9",
|
||||
"phpunit/phpunit": "~5.7.10|~6.5"
|
||||
"phpunit/phpunit": "~5.7.10|~6.5|~7.0"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
|
@ -4262,7 +4450,7 @@
|
|||
"test double",
|
||||
"testing"
|
||||
],
|
||||
"time": "2018-05-08T08:54:48+00:00"
|
||||
"time": "2018-10-02T21:52:37+00:00"
|
||||
},
|
||||
{
|
||||
"name": "myclabs/deep-copy",
|
||||
|
@ -4631,16 +4819,16 @@
|
|||
},
|
||||
{
|
||||
"name": "phpunit/php-code-coverage",
|
||||
"version": "6.0.7",
|
||||
"version": "6.1.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/php-code-coverage.git",
|
||||
"reference": "865662550c384bc1db7e51d29aeda1c2c161d69a"
|
||||
"reference": "807e6013b00af69b6c5d9ceb4282d0393dbb9d8d"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/865662550c384bc1db7e51d29aeda1c2c161d69a",
|
||||
"reference": "865662550c384bc1db7e51d29aeda1c2c161d69a",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/807e6013b00af69b6c5d9ceb4282d0393dbb9d8d",
|
||||
"reference": "807e6013b00af69b6c5d9ceb4282d0393dbb9d8d",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -4651,7 +4839,7 @@
|
|||
"phpunit/php-text-template": "^1.2.1",
|
||||
"phpunit/php-token-stream": "^3.0",
|
||||
"sebastian/code-unit-reverse-lookup": "^1.0.1",
|
||||
"sebastian/environment": "^3.1",
|
||||
"sebastian/environment": "^3.1 || ^4.0",
|
||||
"sebastian/version": "^2.0.1",
|
||||
"theseer/tokenizer": "^1.1"
|
||||
},
|
||||
|
@ -4664,7 +4852,7 @@
|
|||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "6.0-dev"
|
||||
"dev-master": "6.1-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
|
@ -4690,7 +4878,7 @@
|
|||
"testing",
|
||||
"xunit"
|
||||
],
|
||||
"time": "2018-06-01T07:51:50+00:00"
|
||||
"time": "2018-10-31T16:06:48+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpunit/php-file-iterator",
|
||||
|
@ -4834,16 +5022,16 @@
|
|||
},
|
||||
{
|
||||
"name": "phpunit/php-token-stream",
|
||||
"version": "3.0.0",
|
||||
"version": "3.0.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/php-token-stream.git",
|
||||
"reference": "21ad88bbba7c3d93530d93994e0a33cd45f02ace"
|
||||
"reference": "c99e3be9d3e85f60646f152f9002d46ed7770d18"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/21ad88bbba7c3d93530d93994e0a33cd45f02ace",
|
||||
"reference": "21ad88bbba7c3d93530d93994e0a33cd45f02ace",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/c99e3be9d3e85f60646f152f9002d46ed7770d18",
|
||||
"reference": "c99e3be9d3e85f60646f152f9002d46ed7770d18",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -4879,7 +5067,7 @@
|
|||
"keywords": [
|
||||
"tokenizer"
|
||||
],
|
||||
"time": "2018-02-01T13:16:43+00:00"
|
||||
"time": "2018-10-30T05:52:18+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpunit/phpunit",
|
||||
|
@ -4971,6 +5159,7 @@
|
|||
"conflict": {
|
||||
"3f/pygmentize": "<1.2",
|
||||
"adodb/adodb-php": "<5.20.12",
|
||||
"alterphp/easyadmin-extension-bundle": ">=1.2,<1.2.11|>=1.3,<1.3.1",
|
||||
"amphp/artax": "<1.0.6|>=2,<2.0.6",
|
||||
"amphp/http": "<1.0.1",
|
||||
"asymmetricrypt/asymmetricrypt": ">=0,<9.9.99",
|
||||
|
@ -4998,12 +5187,14 @@
|
|||
"doctrine/mongodb-odm-bundle": ">=2,<3.0.1",
|
||||
"doctrine/orm": ">=2,<2.4.8|>=2.5,<2.5.1",
|
||||
"dompdf/dompdf": ">=0.6,<0.6.2",
|
||||
"drupal/core": ">=7,<7.59|>=8,<8.4.8|>=8.5,<8.5.3",
|
||||
"drupal/drupal": ">=7,<7.59|>=8,<8.4.8|>=8.5,<8.5.3",
|
||||
"drupal/core": ">=7,<7.60|>=8,<8.5.8|>=8.6,<8.6.2",
|
||||
"drupal/drupal": ">=7,<7.60|>=8,<8.5.8|>=8.6,<8.6.2",
|
||||
"erusev/parsedown": "<1.7",
|
||||
"ezsystems/ezpublish-legacy": ">=5.3,<5.3.12.3|>=5.4,<5.4.11.3|>=2017.8,<2017.8.1.1|>=2017.12,<2017.12.2.1",
|
||||
"ezsystems/ezpublish-legacy": ">=5.3,<5.3.12.5|>=5.4,<5.4.12.2|>=2017.8,<2017.8.1.1|>=2017.12,<2017.12.4.2|>=2018.6,<2018.6.1.3|>=2018.9,<2018.9.1.2",
|
||||
"ezyang/htmlpurifier": "<4.1.1",
|
||||
"firebase/php-jwt": "<2",
|
||||
"fooman/tcpdf": "<6.2.22",
|
||||
"fossar/tcpdf-parser": "<6.2.22",
|
||||
"friendsofsymfony/rest-bundle": ">=1.2,<1.2.2",
|
||||
"friendsofsymfony/user-bundle": ">=1.2,<1.3.5",
|
||||
"fuel/core": "<1.8.1",
|
||||
|
@ -5020,11 +5211,12 @@
|
|||
"jsmitty12/phpwhois": "<5.1",
|
||||
"kazist/phpwhois": "<=4.2.6",
|
||||
"kreait/firebase-php": ">=3.2,<3.8.1",
|
||||
"la-haute-societe/tcpdf": "<6.2.22",
|
||||
"laravel/framework": ">=4,<4.0.99|>=4.1,<=4.1.31|>=4.2,<=4.2.22|>=5,<=5.0.35|>=5.1,<=5.1.46|>=5.2,<=5.2.45|>=5.3,<=5.3.31|>=5.4,<=5.4.36|>=5.5,<5.5.42|>=5.6,<5.6.30",
|
||||
"laravel/socialite": ">=1,<1.0.99|>=2,<2.0.10",
|
||||
"magento/magento1ce": "<1.9.3.9",
|
||||
"magento/magento1ee": ">=1.9,<1.14.3.2",
|
||||
"magento/product-community-edition": ">=2,<2.2.5",
|
||||
"magento/product-community-edition": ">=2,<2.2.6",
|
||||
"monolog/monolog": ">=1.8,<1.12",
|
||||
"namshi/jose": "<2.2",
|
||||
"onelogin/php-saml": "<2.10.4",
|
||||
|
@ -5042,6 +5234,7 @@
|
|||
"propel/propel": ">=2.0.0-alpha1,<=2.0.0-alpha7",
|
||||
"propel/propel1": ">=1,<=1.7.1",
|
||||
"pusher/pusher-php-server": "<2.2.1",
|
||||
"robrichards/xmlseclibs": ">=1,<3.0.2",
|
||||
"sabre/dav": ">=1.6,<1.6.99|>=1.7,<1.7.11|>=1.8,<1.8.9",
|
||||
"sensiolabs/connect": "<4.2.3",
|
||||
"serluck/phpwhois": "<=4.2.6",
|
||||
|
@ -5057,6 +5250,7 @@
|
|||
"slim/slim": "<2.6",
|
||||
"smarty/smarty": "<3.1.33",
|
||||
"socalnick/scn-social-auth": "<1.15.2",
|
||||
"spoonity/tcpdf": "<6.2.22",
|
||||
"squizlabs/php_codesniffer": ">=1,<2.8.1|>=3,<3.0.1",
|
||||
"stormpath/sdk": ">=0,<9.9.99",
|
||||
"swiftmailer/swiftmailer": ">=4,<5.4.5",
|
||||
|
@ -5068,6 +5262,8 @@
|
|||
"symfony/http-foundation": ">=2,<2.7.49|>=2.8,<2.8.44|>=3,<3.3.18|>=3.4,<3.4.14|>=4,<4.0.14|>=4.1,<4.1.3",
|
||||
"symfony/http-kernel": ">=2,<2.3.29|>=2.4,<2.5.12|>=2.6,<2.6.8",
|
||||
"symfony/intl": ">=2.7,<2.7.38|>=2.8,<2.8.31|>=3,<3.2.14|>=3.3,<3.3.13",
|
||||
"symfony/polyfill": ">=1,<1.10",
|
||||
"symfony/polyfill-php55": ">=1,<1.10",
|
||||
"symfony/routing": ">=2,<2.0.19",
|
||||
"symfony/security": ">=2,<2.7.48|>=2.8,<2.8.41|>=3,<3.3.17|>=3.4,<3.4.11|>=4,<4.0.11",
|
||||
"symfony/security-bundle": ">=2,<2.7.48|>=2.8,<2.8.41|>=3,<3.3.17|>=3.4,<3.4.11|>=4,<4.0.11",
|
||||
|
@ -5081,6 +5277,7 @@
|
|||
"symfony/validator": ">=2,<2.0.24|>=2.1,<2.1.12|>=2.2,<2.2.5|>=2.3,<2.3.3",
|
||||
"symfony/web-profiler-bundle": ">=2,<2.3.19|>=2.4,<2.4.9|>=2.5,<2.5.4",
|
||||
"symfony/yaml": ">=2,<2.0.22|>=2.1,<2.1.7",
|
||||
"tecnickcom/tcpdf": "<6.2.22",
|
||||
"thelia/backoffice-default-template": ">=2.1,<2.1.2",
|
||||
"thelia/thelia": ">=2.1.0-beta1,<2.1.3|>=2.1,<2.1.2",
|
||||
"theonedemon/phpwhois": "<=4.2.5",
|
||||
|
@ -5091,6 +5288,7 @@
|
|||
"typo3/cms-core": ">=8,<8.7.17|>=9,<9.3.2",
|
||||
"typo3/flow": ">=1,<1.0.4|>=1.1,<1.1.1|>=2,<2.0.1|>=2.3,<2.3.16|>=3,<3.0.10|>=3.1,<3.1.7|>=3.2,<3.2.7|>=3.3,<3.3.5",
|
||||
"typo3/neos": ">=1.1,<1.1.3|>=1.2,<1.2.13|>=2,<2.0.4",
|
||||
"wallabag/tcpdf": "<6.2.22",
|
||||
"willdurand/js-translation-bundle": "<2.1.1",
|
||||
"yiisoft/yii": ">=1.1.14,<1.1.15",
|
||||
"yiisoft/yii2": "<2.0.15",
|
||||
|
@ -5138,7 +5336,7 @@
|
|||
}
|
||||
],
|
||||
"description": "Prevents installation of composer packages with known security vulnerabilities: no API, simply require it",
|
||||
"time": "2018-09-17T20:20:31+00:00"
|
||||
"time": "2018-11-01T18:39:28+00:00"
|
||||
},
|
||||
{
|
||||
"name": "sebastian/code-unit-reverse-lookup",
|
||||
|
@ -5756,7 +5954,7 @@
|
|||
},
|
||||
{
|
||||
"name": "symfony/browser-kit",
|
||||
"version": "v4.1.4",
|
||||
"version": "v4.1.7",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/browser-kit.git",
|
||||
|
@ -5813,16 +6011,16 @@
|
|||
},
|
||||
{
|
||||
"name": "symfony/css-selector",
|
||||
"version": "v4.1.4",
|
||||
"version": "v4.1.7",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/css-selector.git",
|
||||
"reference": "2a4df7618f869b456f9096781e78c57b509d76c7"
|
||||
"reference": "d67de79a70a27d93c92c47f37ece958bf8de4d8a"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/css-selector/zipball/2a4df7618f869b456f9096781e78c57b509d76c7",
|
||||
"reference": "2a4df7618f869b456f9096781e78c57b509d76c7",
|
||||
"url": "https://api.github.com/repos/symfony/css-selector/zipball/d67de79a70a27d93c92c47f37ece958bf8de4d8a",
|
||||
"reference": "d67de79a70a27d93c92c47f37ece958bf8de4d8a",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -5862,20 +6060,20 @@
|
|||
],
|
||||
"description": "Symfony CssSelector Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2018-07-26T09:10:45+00:00"
|
||||
"time": "2018-10-02T16:36:10+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/dom-crawler",
|
||||
"version": "v4.1.4",
|
||||
"version": "v4.1.7",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/dom-crawler.git",
|
||||
"reference": "1c4519d257e652404c3aa550207ccd8ada66b38e"
|
||||
"reference": "80e60271bb288de2a2259662cff125cff4f93f95"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/dom-crawler/zipball/1c4519d257e652404c3aa550207ccd8ada66b38e",
|
||||
"reference": "1c4519d257e652404c3aa550207ccd8ada66b38e",
|
||||
"url": "https://api.github.com/repos/symfony/dom-crawler/zipball/80e60271bb288de2a2259662cff125cff4f93f95",
|
||||
"reference": "80e60271bb288de2a2259662cff125cff4f93f95",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -5919,11 +6117,11 @@
|
|||
],
|
||||
"description": "Symfony DomCrawler Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2018-07-26T11:00:49+00:00"
|
||||
"time": "2018-10-02T12:40:59+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-ctype",
|
||||
"version": "v1.9.0",
|
||||
"version": "v1.10.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-ctype.git",
|
||||
|
@ -5981,16 +6179,16 @@
|
|||
},
|
||||
{
|
||||
"name": "symfony/yaml",
|
||||
"version": "v4.1.4",
|
||||
"version": "v4.1.7",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/yaml.git",
|
||||
"reference": "b832cc289608b6d305f62149df91529a2ab3c314"
|
||||
"reference": "367e689b2fdc19965be435337b50bc8adf2746c9"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/yaml/zipball/b832cc289608b6d305f62149df91529a2ab3c314",
|
||||
"reference": "b832cc289608b6d305f62149df91529a2ab3c314",
|
||||
"url": "https://api.github.com/repos/symfony/yaml/zipball/367e689b2fdc19965be435337b50bc8adf2746c9",
|
||||
"reference": "367e689b2fdc19965be435337b50bc8adf2746c9",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -6036,7 +6234,7 @@
|
|||
],
|
||||
"description": "Symfony Yaml Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2018-08-18T16:52:46+00:00"
|
||||
"time": "2018-10-02T16:36:10+00:00"
|
||||
},
|
||||
{
|
||||
"name": "theseer/tokenizer",
|
||||
|
@ -6130,16 +6328,16 @@
|
|||
},
|
||||
{
|
||||
"name": "zircote/swagger-php",
|
||||
"version": "3.0.0",
|
||||
"version": "3.0.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/zircote/swagger-php.git",
|
||||
"reference": "67f517375c0c8180bf2c09dbad6f305524cff2ab"
|
||||
"reference": "8fc3bc059a7f71b3f100bcfd84a96b5b8fcf6fcf"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/zircote/swagger-php/zipball/67f517375c0c8180bf2c09dbad6f305524cff2ab",
|
||||
"reference": "67f517375c0c8180bf2c09dbad6f305524cff2ab",
|
||||
"url": "https://api.github.com/repos/zircote/swagger-php/zipball/8fc3bc059a7f71b3f100bcfd84a96b5b8fcf6fcf",
|
||||
"reference": "8fc3bc059a7f71b3f100bcfd84a96b5b8fcf6fcf",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -6189,12 +6387,13 @@
|
|||
"rest",
|
||||
"service discovery"
|
||||
],
|
||||
"time": "2018-08-16T06:06:29+00:00"
|
||||
"time": "2018-09-30T12:19:07+00:00"
|
||||
}
|
||||
],
|
||||
"aliases": [],
|
||||
"minimum-stability": "dev",
|
||||
"stability-flags": {
|
||||
"azuracast/azuracore": 20,
|
||||
"azuracast/azuraforms": 20,
|
||||
"azuracast/nowplaying": 20,
|
||||
"james-heinrich/getid3": 20,
|
||||
|
@ -6207,9 +6406,6 @@
|
|||
"ext-fileinfo": "*",
|
||||
"ext-gd": "*",
|
||||
"ext-intl": "*",
|
||||
"ext-json": "*",
|
||||
"ext-pdo": "*",
|
||||
"ext-redis": "*",
|
||||
"ext-simplexml": "*",
|
||||
"ext-xml": "*",
|
||||
"ext-xmlwriter": "*"
|
||||
|
|
|
@ -1,68 +1,23 @@
|
|||
<?php
|
||||
use App\Event;
|
||||
use App\Middleware;
|
||||
use App\Console\Command;
|
||||
|
||||
return function (\App\EventDispatcher $dispatcher)
|
||||
return function (\Azura\EventDispatcher $dispatcher)
|
||||
{
|
||||
// Build default routes and middleware
|
||||
$dispatcher->addListener(Event\BuildRoutes::NAME, function(Event\BuildRoutes $event) {
|
||||
$dispatcher->addListener(Azura\Event\BuildRoutes::NAME, function(Azura\Event\BuildRoutes $event) {
|
||||
$app = $event->getApp();
|
||||
|
||||
// Get the current user entity object and assign it into the request if it exists.
|
||||
$app->add(Middleware\GetCurrentUser::class);
|
||||
|
||||
// Inject the application router into the request object.
|
||||
$app->add(Middleware\EnableRouter::class);
|
||||
|
||||
// Inject the session manager into the request object.
|
||||
$app->add(Middleware\EnableSession::class);
|
||||
|
||||
// Check HTTPS setting and enforce Content Security Policy accordingly.
|
||||
$app->add(Middleware\EnforceSecurity::class);
|
||||
|
||||
// Remove trailing slash from all URLs when routing.
|
||||
$app->add(Middleware\RemoveSlashes::class);
|
||||
}, 1);
|
||||
|
||||
$dispatcher->addListener(Event\BuildRoutes::NAME, function(Event\BuildRoutes $event) {
|
||||
call_user_func(include(__DIR__.'/routes.php'), $event->getApp());
|
||||
}, 0);
|
||||
}, 2);
|
||||
|
||||
// Build CLI commands
|
||||
$dispatcher->addListener(Event\BuildConsoleCommands::NAME, function(Event\BuildConsoleCommands $event) {
|
||||
$em = $event->getConsole()->getService(\Doctrine\ORM\EntityManager::class);
|
||||
|
||||
// Doctrine ORM/DBAL
|
||||
\Doctrine\ORM\Tools\Console\ConsoleRunner::addCommands($event->getConsole());
|
||||
|
||||
// Doctrine Migrations
|
||||
$migrate_config = new \Doctrine\DBAL\Migrations\Configuration\Configuration($em->getConnection());
|
||||
$migrate_config->setMigrationsTableName('app_migrations');
|
||||
$migrate_config->setMigrationsDirectory(dirname(__DIR__).'/src/Entity/Migration');
|
||||
$migrate_config->setMigrationsNamespace('App\Entity\Migration');
|
||||
|
||||
$output = new \Symfony\Component\Console\Output\ConsoleOutput;
|
||||
$migrate_config->setOutputWriter(new \Doctrine\DBAL\Migrations\OutputWriter(function($message) use ($output) {
|
||||
$output->writeln($message);
|
||||
}));
|
||||
|
||||
$migration_commands = [
|
||||
new \Doctrine\DBAL\Migrations\Tools\Console\Command\DiffCommand,
|
||||
new \Doctrine\DBAL\Migrations\Tools\Console\Command\ExecuteCommand,
|
||||
new \Doctrine\DBAL\Migrations\Tools\Console\Command\GenerateCommand,
|
||||
new \Doctrine\DBAL\Migrations\Tools\Console\Command\MigrateCommand,
|
||||
new \Doctrine\DBAL\Migrations\Tools\Console\Command\StatusCommand,
|
||||
new \Doctrine\DBAL\Migrations\Tools\Console\Command\VersionCommand
|
||||
];
|
||||
|
||||
foreach($migration_commands as $cmd) {
|
||||
$cmd->setMigrationConfiguration($migrate_config);
|
||||
$event->getConsole()->add($cmd);
|
||||
}
|
||||
}, 1);
|
||||
|
||||
$dispatcher->addListener(Event\BuildConsoleCommands::NAME, function(Event\BuildConsoleCommands $event) {
|
||||
$dispatcher->addListener(Azura\Event\BuildConsoleCommands::NAME, function(Azura\Event\BuildConsoleCommands $event) {
|
||||
$event->getConsole()->addCommands([
|
||||
// Liquidsoap Internal CLI Commands
|
||||
new Command\NextSong,
|
||||
|
@ -81,7 +36,6 @@ return function (\App\EventDispatcher $dispatcher)
|
|||
new Command\Setup,
|
||||
|
||||
// Maintenance
|
||||
new Command\ClearCache,
|
||||
new Command\RestartRadio,
|
||||
new Command\Sync,
|
||||
new Command\ReprocessMedia,
|
||||
|
|
|
@ -3,7 +3,7 @@ use \App\Entity\StationPlaylist;
|
|||
|
||||
/** @var \App\Customization $customization */
|
||||
|
||||
$local_time_offset = \App\Timezone::getOffsetMinutes(null);
|
||||
$local_time_offset = \Azura\Timezone::getOffsetMinutes(null);
|
||||
$local_time_hours = floor($local_time_offset / 60);
|
||||
$local_time_mins = $local_time_offset % 60;
|
||||
|
||||
|
|
|
@ -81,7 +81,7 @@ return [
|
|||
'label' => __('Time Zone'),
|
||||
'description' => __('All times displayed on the site will be based on this time zone.') . '<br>' . sprintf(__('Current server time is <b>%s</b>.'),
|
||||
date('g:ia')),
|
||||
'options' => \App\Timezone::fetchSelect(),
|
||||
'options' => \Azura\Timezone::fetchSelect(),
|
||||
'default' => 'UTC',
|
||||
]
|
||||
],
|
||||
|
|
|
@ -31,7 +31,7 @@ return [
|
|||
[
|
||||
'label' => __('System Default Time Zone'),
|
||||
'description' => __('For users who have not customized their time zone, all times displayed on the site will be based on this time zone.'),
|
||||
'options' => \App\Timezone::fetchSelect(),
|
||||
'options' => \Azura\Timezone::fetchSelect(),
|
||||
'default' => 'UTC',
|
||||
],
|
||||
],
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
<?php
|
||||
use App\Controller;
|
||||
use App\Middleware;
|
||||
use Azura\Middleware as AzuraMiddleware;
|
||||
|
||||
return function(\Slim\App $app)
|
||||
{
|
||||
|
@ -115,7 +116,7 @@ return function(\Slim\App $app)
|
|||
|
||||
})
|
||||
->add(Middleware\Module\Admin::class)
|
||||
->add(Middleware\EnableView::class)
|
||||
->add(AzuraMiddleware\EnableView::class)
|
||||
->add([Middleware\Permissions::class, 'view administration'])
|
||||
->add(Middleware\RequireLogin::class);
|
||||
|
||||
|
@ -167,13 +168,13 @@ return function(\Slim\App $app)
|
|||
|
||||
$this->get('/stations', Controller\Api\Stations\IndexController::class.':listAction')
|
||||
->setName('api:stations:list')
|
||||
->add([Middleware\RateLimit::class, 'api', 5, 2]);
|
||||
->add([AzuraMiddleware\RateLimit::class, 'api', 5, 2]);
|
||||
|
||||
$this->group('/station/{station}', function () {
|
||||
|
||||
$this->get('', Controller\Api\Stations\IndexController::class.':indexAction')
|
||||
->setName('api:stations:index')
|
||||
->add([Middleware\RateLimit::class, 'api', 5, 2]);
|
||||
->add([AzuraMiddleware\RateLimit::class, 'api', 5, 2]);
|
||||
|
||||
$this->get('/nowplaying', Controller\Api\NowplayingController::class.':indexAction');
|
||||
|
||||
|
@ -188,7 +189,7 @@ return function(\Slim\App $app)
|
|||
|
||||
$this->map(['GET', 'POST'], '/request/{media_id}', Controller\Api\RequestsController::class.':submitAction')
|
||||
->setName('api:requests:submit')
|
||||
->add([Middleware\RateLimit::class, 'api', 5, 2]);
|
||||
->add([AzuraMiddleware\RateLimit::class, 'api', 5, 2]);
|
||||
|
||||
$this->get('/listeners', Controller\Api\ListenersController::class.':indexAction')
|
||||
->setName('api:listeners:index')
|
||||
|
@ -257,12 +258,12 @@ return function(\Slim\App $app)
|
|||
}
|
||||
|
||||
})
|
||||
->add(Middleware\EnableView::class)
|
||||
->add(AzuraMiddleware\EnableView::class)
|
||||
->add(Middleware\RequireLogin::class);
|
||||
|
||||
$app->map(['GET', 'POST'], '/login', Controller\Frontend\AccountController::class.':loginAction')
|
||||
->setName('account:login')
|
||||
->add(Middleware\EnableView::class);
|
||||
->add(AzuraMiddleware\EnableView::class);
|
||||
|
||||
$app->group('/setup', function () {
|
||||
|
||||
|
@ -282,7 +283,7 @@ return function(\Slim\App $app)
|
|||
->setName('setup:settings');
|
||||
|
||||
})
|
||||
->add(Middleware\EnableView::class);
|
||||
->add(AzuraMiddleware\EnableView::class);
|
||||
|
||||
$app->group('/public/{station}', function () {
|
||||
|
||||
|
@ -300,7 +301,7 @@ return function(\Slim\App $app)
|
|||
|
||||
})
|
||||
->add(Middleware\GetStation::class)
|
||||
->add(Middleware\EnableView::class);
|
||||
->add(AzuraMiddleware\EnableView::class);
|
||||
|
||||
$app->group('/station/{station}', function () {
|
||||
|
||||
|
@ -498,7 +499,7 @@ return function(\Slim\App $app)
|
|||
->add(Middleware\Module\Stations::class)
|
||||
->add([Middleware\Permissions::class, 'view station management', true])
|
||||
->add(Middleware\GetStation::class)
|
||||
->add(Middleware\EnableView::class)
|
||||
->add(AzuraMiddleware\EnableView::class)
|
||||
->add(Middleware\RequireLogin::class);
|
||||
|
||||
};
|
||||
|
|
|
@ -1,148 +1,48 @@
|
|||
<?php
|
||||
return function (\Slim\Container $di, $settings)
|
||||
return function (\Azura\Container $di)
|
||||
{
|
||||
|
||||
$di['app_settings'] = $settings;
|
||||
|
||||
// Override Slim handlers.
|
||||
$di['request'] = function (\Slim\Container $di) {
|
||||
$di['request'] = function (\Azura\Container $di) {
|
||||
return \App\Http\Request::createFromEnvironment($di->get('environment'));
|
||||
};
|
||||
|
||||
$di['response'] = function (\Slim\Container $di) {
|
||||
$di['response'] = function (\Azura\Container $di) {
|
||||
$headers = new \Slim\Http\Headers(['Content-Type' => 'text/html; charset=UTF-8']);
|
||||
$response = new \App\Http\Response(200, $headers, null);
|
||||
|
||||
return $response->withProtocolVersion($di->get('settings')['httpVersion']);
|
||||
};
|
||||
|
||||
$di['router'] = function(\Slim\Container $di) {
|
||||
$routerCacheFile = $di['settings']['routerCacheFile'];
|
||||
$router = (new \App\Http\Router())->setCacheFile($routerCacheFile);
|
||||
$router->setContainer($di);
|
||||
$di['router'] = function(\Azura\Container $container) {
|
||||
$routerCacheFile = $container->get('settings')[\Azura\Settings::SLIM_ROUTER_CACHE_FILE];
|
||||
$router = new \App\Http\Router();
|
||||
$router->setCacheFile($routerCacheFile);
|
||||
$router->setContainer($container);
|
||||
return $router;
|
||||
};
|
||||
|
||||
$di['callableResolver'] = function ($di) {
|
||||
return new \App\Http\Resolver($di);
|
||||
};
|
||||
|
||||
$di['errorHandler'] = function ($di) {
|
||||
return $di[\App\Http\ErrorHandler::class];
|
||||
};
|
||||
|
||||
$di['phpErrorHandler'] = function($di) {
|
||||
return $di[\App\Http\ErrorHandler::class];
|
||||
$di[\App\Http\ErrorHandler::class] = function($di) {
|
||||
return new \App\Http\ErrorHandler(
|
||||
$di[\App\Acl::class],
|
||||
$di[\Monolog\Logger::class],
|
||||
$di['router'],
|
||||
$di[\Azura\Session::class],
|
||||
$di[\Azura\View::class]
|
||||
);
|
||||
};
|
||||
|
||||
$di->addAlias('phpErrorHandler', \App\Http\ErrorHandler::class);
|
||||
$di->addAlias('errorHandler', \App\Http\ErrorHandler::class);
|
||||
|
||||
$di['notFoundHandler'] = function ($di) {
|
||||
return function (\App\Http\Request $request, \App\Http\Response $response) use ($di) {
|
||||
/** @var \App\View $view */
|
||||
$view = $di[App\View::class];
|
||||
/** @var \Azura\View $view */
|
||||
$view = $di[\Azura\View::class];
|
||||
|
||||
return $view->renderToResponse($response->withStatus(404), 'system/error_pagenotfound');
|
||||
};
|
||||
};
|
||||
|
||||
$di['foundHandler'] = function() {
|
||||
return new \Slim\Handlers\Strategies\RequestResponseArgs();
|
||||
};
|
||||
|
||||
$di[\App\Config::class] = function () {
|
||||
return new \App\Config(__DIR__);
|
||||
};
|
||||
|
||||
$di[\Doctrine\ORM\EntityManager::class] = function ($di) {
|
||||
try {
|
||||
$options = [
|
||||
'autoGenerateProxies' => !APP_IN_PRODUCTION,
|
||||
'proxyNamespace' => 'AppProxy',
|
||||
'proxyPath' => APP_INCLUDE_TEMP . '/proxies',
|
||||
'modelPath' => APP_INCLUDE_ROOT . '/src/Entity',
|
||||
'conn' => [
|
||||
'driver' => 'pdo_mysql',
|
||||
'charset' => 'utf8mb4',
|
||||
'defaultTableOptions' => [
|
||||
'charset' => 'utf8mb4',
|
||||
'collate' => 'utf8mb4_general_ci',
|
||||
],
|
||||
'driverOptions' => [
|
||||
\PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8mb4 COLLATE utf8mb4_general_ci',
|
||||
],
|
||||
'platform' => new \Doctrine\DBAL\Platforms\MariaDb1027Platform(),
|
||||
]
|
||||
];
|
||||
|
||||
if (APP_INSIDE_DOCKER) {
|
||||
$options['conn']['host'] = $_ENV['MYSQL_HOST'] ?? 'mariadb';
|
||||
$options['conn']['port'] = $_ENV['MYSQL_PORT'] ?? 3306;
|
||||
$options['conn']['dbname'] = $_ENV['MYSQL_DATABASE'] ?? 'azuracast';
|
||||
$options['conn']['user'] = $_ENV['MYSQL_USER'] ?? 'azuracast';
|
||||
$options['conn']['password'] = $_ENV['MYSQL_PASSWORD'] ?? 'azur4c457';
|
||||
} else {
|
||||
$options['conn']['host'] = $_ENV['db_host'] ?? 'localhost';
|
||||
$options['conn']['port'] = $_ENV['db_port'] ?? '3306';
|
||||
$options['conn']['dbname'] = $_ENV['db_name'] ?? 'azuracast';
|
||||
$options['conn']['user'] = $_ENV['db_username'] ?? 'azuracast';
|
||||
$options['conn']['password'] = $_ENV['db_password'];
|
||||
}
|
||||
|
||||
// Fetch and store entity manager.
|
||||
$config = new \Doctrine\ORM\Configuration;
|
||||
|
||||
$metadata_driver = $config->newDefaultAnnotationDriver($options['modelPath']);
|
||||
$config->setMetadataDriverImpl($metadata_driver);
|
||||
|
||||
$repo_factory = new \App\Doctrine\RepositoryFactory($di);
|
||||
$config->setRepositoryFactory($repo_factory);
|
||||
|
||||
if (APP_IN_PRODUCTION) {
|
||||
/** @var \Redis $redis */
|
||||
$redis = $di[\Redis::class];
|
||||
$redis->select(2);
|
||||
|
||||
$cache = new \App\Doctrine\Cache\Redis;
|
||||
$cache->setRedis($redis);
|
||||
} else {
|
||||
$cache = new \Doctrine\Common\Cache\ArrayCache;
|
||||
}
|
||||
|
||||
$config->setMetadataCacheImpl($cache);
|
||||
$config->setQueryCacheImpl($cache);
|
||||
$config->setResultCacheImpl($cache);
|
||||
|
||||
// Disable second-level cache for unit testing purposes, as it causes data to be out of date on pages.
|
||||
if (APP_TESTING_MODE) {
|
||||
$config->setSecondLevelCacheEnabled(false);
|
||||
}
|
||||
|
||||
$config->setProxyDir($options['proxyPath']);
|
||||
$config->setProxyNamespace($options['proxyNamespace']);
|
||||
$config->setAutoGenerateProxyClasses(\Doctrine\Common\Proxy\AbstractProxyFactory::AUTOGENERATE_FILE_NOT_EXISTS);
|
||||
$config->setDefaultRepositoryClassName(\App\Entity\Repository\BaseRepository::class);
|
||||
|
||||
if (isset($options['conn']['debug']) && $options['conn']['debug']) {
|
||||
$config->setSQLLogger(new \Doctrine\DBAL\Logging\EchoSQLLogger);
|
||||
}
|
||||
|
||||
$config->addCustomNumericFunction('RAND', '\App\Doctrine\Functions\Rand');
|
||||
$config->addCustomStringFunction('FIELD', 'DoctrineExtensions\Query\Mysql\Field');
|
||||
$config->addCustomStringFunction('IF', 'DoctrineExtensions\Query\Mysql\IfElse');
|
||||
|
||||
$em = \Doctrine\ORM\EntityManager::create($options['conn'], $config, new \Doctrine\Common\EventManager);
|
||||
|
||||
return $em;
|
||||
} catch (\Exception $e) {
|
||||
throw new \App\Exception\Bootstrap($e->getMessage());
|
||||
}
|
||||
};
|
||||
|
||||
$di[\Doctrine\DBAL\Connection::class] = function ($di) {
|
||||
/** @var \Doctrine\ORM\EntityManager $em */
|
||||
$em = $di[\Doctrine\ORM\EntityManager::class];
|
||||
return $em->getConnection();
|
||||
};
|
||||
|
||||
$di[\App\Entity\Repository\SettingsRepository::class] = function($di) {
|
||||
/** @var \Doctrine\ORM\EntityManager $em */
|
||||
$em = $di[\Doctrine\ORM\EntityManager::class];
|
||||
|
@ -160,7 +60,7 @@ return function (\Slim\Container $di, $settings)
|
|||
return new \App\Entity\Repository\StationPlaylistMediaRepository(
|
||||
$em,
|
||||
$em->getClassMetadata(\App\Entity\StationPlaylistMedia::class),
|
||||
$di[\App\Cache::class]
|
||||
$di[\Azura\Cache::class]
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -171,7 +71,7 @@ return function (\Slim\Container $di, $settings)
|
|||
/** @var App\Entity\Repository\UserRepository $user_repo */
|
||||
$user_repo = $em->getRepository(App\Entity\User::class);
|
||||
|
||||
return new \App\Auth($di[\App\Session::class], $user_repo);
|
||||
return new \App\Auth($di[\Azura\Session::class], $user_repo);
|
||||
};
|
||||
|
||||
$di[\App\Acl::class] = function ($di) {
|
||||
|
@ -184,36 +84,6 @@ return function (\Slim\Container $di, $settings)
|
|||
return new \App\Acl($permissions_repo);
|
||||
};
|
||||
|
||||
$di[\Redis::class] = $di->factory(function ($di) {
|
||||
$redis_host = (APP_INSIDE_DOCKER) ? 'redis' : 'localhost';
|
||||
|
||||
$redis = new \Redis();
|
||||
$redis->connect($redis_host, 6379, 15);
|
||||
return $redis;
|
||||
});
|
||||
|
||||
$di[\App\Cache::class] = function ($di) {
|
||||
/** @var \Redis $redis */
|
||||
$redis = $di[\Redis::class];
|
||||
$redis->select(0);
|
||||
|
||||
return new \App\Cache($redis);
|
||||
};
|
||||
|
||||
$di[\App\Session::class] = function ($di) {
|
||||
if (!APP_TESTING_MODE) {
|
||||
ini_set('session.gc_maxlifetime', 86400);
|
||||
ini_set('session.gc_probability', 1);
|
||||
ini_set('session.gc_divisor', 100);
|
||||
|
||||
$redis_server = (APP_INSIDE_DOCKER) ? 'redis' : 'localhost';
|
||||
ini_set('session.save_handler', 'redis');
|
||||
ini_set('session.save_path', 'tcp://' . $redis_server . ':6379?database=1');
|
||||
}
|
||||
|
||||
return new \App\Session;
|
||||
};
|
||||
|
||||
$di[\InfluxDB\Database::class] = function ($di) {
|
||||
$opts = [
|
||||
'host' => (APP_INSIDE_DOCKER) ? 'influxdb' : 'localhost',
|
||||
|
@ -239,31 +109,18 @@ return function (\Slim\Container $di, $settings)
|
|||
$supervisor = new \Supervisor\Supervisor($connector);
|
||||
|
||||
if (!$supervisor->isConnected()) {
|
||||
throw new \App\Exception(sprintf('Could not connect to supervisord.'));
|
||||
throw new \Azura\Exception(sprintf('Could not connect to supervisord.'));
|
||||
}
|
||||
|
||||
return $supervisor;
|
||||
};
|
||||
|
||||
$di[\App\View::class] = $di->factory(function(\Slim\Container $di) {
|
||||
$view = new App\View(dirname(__DIR__) . '/resources/templates');
|
||||
$view->setFileExtension('phtml');
|
||||
|
||||
$view->registerFunction('service', function($service) {
|
||||
return $this->di->get($service);
|
||||
});
|
||||
|
||||
$view->registerFunction('escapeJs', function($string) {
|
||||
return json_encode($string);
|
||||
});
|
||||
|
||||
|
||||
$di->extend(\Azura\View::class, function(\Azura\View $view, \Azura\Container $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;
|
||||
|
@ -271,106 +128,37 @@ return function (\Slim\Container $di, $settings)
|
|||
return \Doctrine\Common\Inflector\Inflector::pluralize($word);
|
||||
}
|
||||
});
|
||||
|
||||
$view->registerFunction('truncate', function ($text, $length = 80) {
|
||||
return \App\Utilities::truncate_text($text, $length);
|
||||
});
|
||||
|
||||
/** @var \App\Session $session */
|
||||
$session = $di[\App\Session::class];
|
||||
|
||||
$view->addData([
|
||||
'app_settings' => $di['app_settings'],
|
||||
'router' => $di['router'],
|
||||
'request' => $di['request'],
|
||||
'assets' => $di[\App\Assets::class],
|
||||
'assets' => $di[\Azura\Assets::class],
|
||||
'auth' => $di[\App\Auth::class],
|
||||
'acl' => $di[\App\Acl::class],
|
||||
'flash' => $session->getFlash(),
|
||||
'customization' => $di[\App\Customization::class],
|
||||
'version' => $di[\App\Version::class],
|
||||
]);
|
||||
|
||||
/** @var \App\EventDispatcher $dispatcher */
|
||||
$dispatcher = $di[\App\EventDispatcher::class];
|
||||
$dispatcher->dispatch(\App\Event\BuildView::NAME, new \App\Event\BuildView($view));
|
||||
|
||||
return $view;
|
||||
});
|
||||
|
||||
$di[\App\Http\ErrorHandler::class] = function($di) {
|
||||
return new \App\Http\ErrorHandler(
|
||||
$di[\App\Acl::class],
|
||||
$di[\Monolog\Logger::class],
|
||||
$di['router'],
|
||||
$di[\App\Session::class],
|
||||
$di[\App\View::class]
|
||||
);
|
||||
};
|
||||
|
||||
$di[\Monolog\Logger::class] = function($di) use ($settings) {
|
||||
$logger = new Monolog\Logger($settings['name']);
|
||||
$logging_level = (APP_IN_PRODUCTION) ? \Monolog\Logger::INFO : \Monolog\Logger::DEBUG;
|
||||
|
||||
if (APP_INSIDE_DOCKER || APP_IS_COMMAND_LINE) {
|
||||
$log_stderr = new \Monolog\Handler\StreamHandler('php://stderr', $logging_level, true);
|
||||
$logger->pushHandler($log_stderr);
|
||||
}
|
||||
|
||||
$log_file = new \Monolog\Handler\StreamHandler(APP_INCLUDE_TEMP.'/azuracast.log', $logging_level, true);
|
||||
$logger->pushHandler($log_file);
|
||||
|
||||
return $logger;
|
||||
};
|
||||
|
||||
$di[\MaxMind\Db\Reader::class] = function($di) {
|
||||
$mmdb_path = dirname(APP_INCLUDE_ROOT).'/geoip/GeoLite2-City.mmdb';
|
||||
return new \MaxMind\Db\Reader($mmdb_path);
|
||||
};
|
||||
|
||||
$di[\GuzzleHttp\Client::class] = function($di) {
|
||||
$stack = \GuzzleHttp\HandlerStack::create();
|
||||
$di->extend(\Azura\EventDispatcher::class, function(\Azura\EventDispatcher $dispatcher, \Azura\Container $di) {
|
||||
if (isset($di[\App\Plugins::class])) {
|
||||
/** @var \App\Plugins $plugins */
|
||||
$plugins = $di[\App\Plugins::class];
|
||||
|
||||
$stack->unshift(function (callable $handler) use ($di) {
|
||||
return function (\Psr\Http\Message\RequestInterface $request, array $options) use ($handler, $di) {
|
||||
if ($request->getUri()->getScheme() === 'https') {
|
||||
$fetcher = new \ParagonIE\Certainty\RemoteFetch(APP_INCLUDE_TEMP);
|
||||
$latestCACertBundle = $fetcher->getLatestBundle();
|
||||
|
||||
$options['verify'] = $latestCACertBundle->getFilePath();
|
||||
}
|
||||
|
||||
return $handler($request, $options);
|
||||
};
|
||||
}, 'ssl_verify');
|
||||
|
||||
$stack->push(\GuzzleHttp\Middleware::log(
|
||||
$di[\Monolog\Logger::class],
|
||||
new \GuzzleHttp\MessageFormatter('HTTP client {method} call to {uri} produced response {code}'),
|
||||
\Monolog\Logger::DEBUG
|
||||
));
|
||||
|
||||
return new \GuzzleHttp\Client([
|
||||
'handler' => $stack,
|
||||
'http_errors' => false,
|
||||
'timeout' => 3.0,
|
||||
]);
|
||||
};
|
||||
|
||||
$di[\App\EventDispatcher::class] = function($di) use ($settings) {
|
||||
$dispatcher = new \App\EventDispatcher($di);
|
||||
|
||||
// Register application default events.
|
||||
call_user_func(include(__DIR__.'/events.php'), $dispatcher);
|
||||
|
||||
/** @var \App\Plugins $plugins */
|
||||
$plugins = $di[\App\Plugins::class];
|
||||
|
||||
// Register plugin-provided events.
|
||||
$plugins->registerEvents($dispatcher);
|
||||
// Register plugin-provided events.
|
||||
$plugins->registerEvents($dispatcher);
|
||||
}
|
||||
|
||||
return $dispatcher;
|
||||
};
|
||||
});
|
||||
|
||||
//
|
||||
// AzuraCast-specific dependencies
|
||||
|
@ -384,39 +172,31 @@ return function (\Slim\Container $di, $settings)
|
|||
);
|
||||
};
|
||||
|
||||
$di[\App\Assets::class] = function ($di) {
|
||||
/** @var \App\Config $config */
|
||||
$config = $di[\App\Config::class];
|
||||
$di[\Azura\Assets::class] = function ($di) {
|
||||
/** @var \Azura\Config $config */
|
||||
$config = $di[\Azura\Config::class];
|
||||
|
||||
$libraries = $config->get('assets');
|
||||
|
||||
$versioned_files = [];
|
||||
$assets_file = APP_INCLUDE_STATIC . '/assets.json';
|
||||
$assets_file = APP_INCLUDE_ROOT.'/web/static/assets.json';
|
||||
if (file_exists($assets_file)) {
|
||||
$versioned_files = json_decode(file_get_contents($assets_file), true);
|
||||
}
|
||||
|
||||
return new \App\Assets($libraries, $versioned_files);
|
||||
return new \Azura\Assets($libraries, $versioned_files);
|
||||
};
|
||||
|
||||
$di[\App\Customization::class] = function ($di) {
|
||||
return new \App\Customization(
|
||||
$di['app_settings'],
|
||||
$di['settings'],
|
||||
$di[\App\Entity\Repository\SettingsRepository::class]
|
||||
);
|
||||
};
|
||||
|
||||
$di[\App\RateLimit::class] = function($di) {
|
||||
/** @var \Redis $redis */
|
||||
$redis = $di[\Redis::class];
|
||||
$redis->select(3);
|
||||
|
||||
return new \App\RateLimit($redis);
|
||||
};
|
||||
|
||||
$di[\App\Version::class] = function($di) {
|
||||
return new \App\Version(
|
||||
$di[\App\Cache::class]
|
||||
$di[\Azura\Cache::class]
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -438,18 +218,5 @@ return function (\Slim\Container $di, $settings)
|
|||
$di->register(new \App\Provider\FrontendProvider);
|
||||
$di->register(new \App\Provider\StationsProvider);
|
||||
|
||||
// Main Slim Application
|
||||
$di['app'] = function ($di) {
|
||||
|
||||
$app = new \Slim\App($di);
|
||||
|
||||
/** @var \App\EventDispatcher $dispatcher */
|
||||
$dispatcher = $di[\App\EventDispatcher::class];
|
||||
$dispatcher->dispatch(\App\Event\BuildRoutes::NAME, new \App\Event\BuildRoutes($app));
|
||||
|
||||
return $app;
|
||||
};
|
||||
|
||||
return $di;
|
||||
|
||||
};
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<?php
|
||||
/** @var \App\Assets $assets */
|
||||
/** @var \Azura\Assets $assets */
|
||||
$assets
|
||||
->load('codemirror_css')
|
||||
->addInlineJs($this->fetch('admin/branding/index.js'), 99);
|
||||
|
|
|
@ -12,7 +12,7 @@ $this->layout('minimal', [
|
|||
<?php if ($customization->hideProductName()): ?>
|
||||
<?=__('Welcome!') ?>
|
||||
<?php else: ?>
|
||||
<?=sprintf(__('Welcome to %s!'), $app_settings['name']) ?>
|
||||
<?=sprintf(__('Welcome to %s!'), $settings['name']) ?>
|
||||
<?php endif; ?>
|
||||
<?php if (!empty($customization->getInstanceName())): ?>
|
||||
<small class="text-muted"><?=$this->e($customization->getInstanceName()) ?></small>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
<?php
|
||||
/** @var \App\Customization $customization */
|
||||
/** @var \App\Assets $assets */
|
||||
/** @var \Azura\Assets $assets */
|
||||
$assets
|
||||
->load('vue')
|
||||
->load('radio')
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
$(function () {
|
||||
Highcharts.setOptions({
|
||||
global: {
|
||||
timezoneOffset: <?=\App\Timezone::getOffsetMinutes() ?>,
|
||||
timezoneOffset: <?=\Azura\Timezone::getOffsetMinutes() ?>,
|
||||
useUTC: false
|
||||
}
|
||||
});
|
||||
|
|
|
@ -7,7 +7,7 @@ $this->layout('minimal', [
|
|||
'hide_footer' => true
|
||||
]);
|
||||
|
||||
/** @var \App\Assets $assets */
|
||||
/** @var \Azura\Assets $assets */
|
||||
$assets
|
||||
->load('vue')
|
||||
->load('radio')
|
||||
|
|
|
@ -7,7 +7,7 @@ $this->layout('minimal', [
|
|||
'hide_footer' => true
|
||||
]);
|
||||
|
||||
/** @var \App\Assets $assets */
|
||||
/** @var \Azura\Assets $assets */
|
||||
$assets
|
||||
->load('bootgrid')
|
||||
->addInlineJs($this->fetch('frontend/public/embedrequests.js', ['station' => $station]));
|
||||
|
|
|
@ -6,7 +6,7 @@ $this->layout('minimal', [
|
|||
'title' => $this->e($station->getName()),
|
||||
]);
|
||||
|
||||
/** @var \App\Assets $assets */
|
||||
/** @var \Azura\Assets $assets */
|
||||
$assets
|
||||
->load('vue')
|
||||
->load('radio')
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<?php
|
||||
/** @var \App\Assets $assets */
|
||||
/** @var \Azura\Assets $assets */
|
||||
$assets->addInlineJs($this->fetch('frontend/public/player_component.js'), 95);
|
||||
?>
|
||||
<div class="media media-left" id="station-nowplaying">
|
||||
|
|
|
@ -4,7 +4,7 @@ $this->layout('minimal', [
|
|||
'page_class' => 'login-content'
|
||||
]);
|
||||
|
||||
/** @var \App\Assets $assets */
|
||||
/** @var \Azura\Assets $assets */
|
||||
$assets->load('zxcvbn');
|
||||
?>
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ $this->layout('main', [
|
|||
'manual' => true
|
||||
]);
|
||||
|
||||
/** @var \App\Assets $assets */
|
||||
/** @var \Azura\Assets $assets */
|
||||
$assets
|
||||
->addInlineJs($this->fetch('partials/station_form.js'), 99);
|
||||
?>
|
||||
|
|
|
@ -5,12 +5,15 @@
|
|||
* @var \App\Auth $auth
|
||||
* @var \App\Acl $acl
|
||||
* @var \App\Http\Router $router
|
||||
* @var \App\Session\Flash $flash
|
||||
* @var \Azura\Session\Flash $flash
|
||||
* @var \App\Customization $customization
|
||||
* @var \App\Assets $assets
|
||||
* @var \Azura\Assets $assets
|
||||
* @var \App\Version $version
|
||||
* @var \App\Http\Request $request
|
||||
* @var array $app_settings
|
||||
*/
|
||||
|
||||
$user = $request->getUser();
|
||||
?>
|
||||
<html>
|
||||
<head>
|
||||
|
@ -131,7 +134,7 @@ echo $assets->js();
|
|||
</section>
|
||||
|
||||
<footer id="footer" <?php if (empty($sidebar)): ?>class="footer-alt"<?php endif; ?> role="contentinfo">
|
||||
<?=__('Powered by %s', '<a href="https://www.azuracast.com/" target="_blank">'.$app_settings['name'].'</a> • '.$version->getVersionText().' • '.(APP_INSIDE_DOCKER ? 'Docker' : 'Traditional').' • PHP '.\PHP_MAJOR_VERSION.'.'.\PHP_MINOR_VERSION) ?><br>
|
||||
<?=__('Powered by %s', '<a href="https://www.azuracast.com/" target="_blank">'.$settings['name'].'</a> • '.$version->getVersionText().' • '.(APP_INSIDE_DOCKER ? 'Docker' : 'Traditional').' • PHP '.\PHP_MAJOR_VERSION.'.'.\PHP_MINOR_VERSION) ?><br>
|
||||
<?=__('Like our software? <a href="%s" target="_blank">Donate to support AzuraCast!</a>', 'https://www.azuracast.com/donate.html') ?>
|
||||
</footer>
|
||||
|
||||
|
|
|
@ -5,9 +5,11 @@
|
|||
* @var \App\Auth $auth
|
||||
* @var \App\Acl $acl
|
||||
* @var \App\Http\Router $router
|
||||
* @var \App\Session\Flash $flash
|
||||
* @var \Azura\Session\Flash $flash
|
||||
* @var \App\Customization $customization
|
||||
* @var \App\Assets $assets
|
||||
* @var \Azura\Assets $assets
|
||||
* @var \App\Version $version
|
||||
* @var \App\Http\Request $request
|
||||
* @var array $app_settings
|
||||
*/
|
||||
?>
|
||||
|
@ -40,7 +42,7 @@ echo $assets->js();
|
|||
|
||||
<?php if (!$customization->hideProductName() && !$hide_footer): ?>
|
||||
<footer id="footer" class="footer-alt" role="contentinfo">
|
||||
<?=sprintf(__('Powered by %s'), '<a href="https://azuracast.com/" target="_blank">'.$app_settings['name'].'</a>'.' ') ?><br>
|
||||
<?=sprintf(__('Powered by %s'), '<a href="https://azuracast.com/" target="_blank">'.$settings['name'].'</a>'.' ') ?><br>
|
||||
<?=sprintf(__('Mascot designed by %s'), '<a href="https://tysontan.deviantart.com/" target="_blank">Tyson Tan</a>') ?>
|
||||
</footer>
|
||||
<?php endif; ?>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<?php
|
||||
/** @var \App\Assets $assets */
|
||||
/** @var \Azura\Assets $assets */
|
||||
$assets
|
||||
->addInlineJs($this->fetch('partials/station_form.js'), 99);
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?php $this->layout('main', ['title' => __('Music Files'), 'manual' => true, 'page_class' => 'page-file-manager']) ?>
|
||||
|
||||
<?php
|
||||
/** @var \App\Assets $assets */
|
||||
/** @var \Azura\Assets $assets */
|
||||
$assets
|
||||
->load('vue')
|
||||
->load('radio')
|
||||
|
|
|
@ -4,7 +4,7 @@ $this->layout('main', [
|
|||
'manual' => true
|
||||
]);
|
||||
|
||||
/** @var \App\Assets $assets */
|
||||
/** @var \Azura\Assets $assets */
|
||||
$assets
|
||||
->addInlineJs($this->fetch('stations/logs/index.js'), 99);
|
||||
?>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<?php
|
||||
/** @var \App\Assets $assets */
|
||||
/** @var \Azura\Assets $assets */
|
||||
$assets
|
||||
->addInlineJs($this->fetch('stations/playlists/edit.js'), 99);
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ use App\Entity\StationPlaylist;
|
|||
|
||||
$this->layout('main', ['title' => __('Playlists'), 'manual' => true]);
|
||||
|
||||
/** @var \App\Assets $assets */
|
||||
/** @var \Azura\Assets $assets */
|
||||
$assets->load('fullcalendar')
|
||||
->addInlineJs($this->fetch('stations/playlists/index.js', [
|
||||
'schedule_now' => $schedule_now,
|
||||
|
|
|
@ -3,7 +3,7 @@ use Entity\StationPlaylist;
|
|||
|
||||
$this->layout('main', ['title' => __('Reorder Playlist'), 'manual' => true]);
|
||||
|
||||
/** @var \App\Assets $assets */
|
||||
/** @var \Azura\Assets $assets */
|
||||
$assets->load('jquery-sortable');
|
||||
?>
|
||||
|
||||
|
|
|
@ -7,12 +7,14 @@ $this->layout('main', [
|
|||
'sidebar_tab' => 'profile',
|
||||
]);
|
||||
|
||||
/** @var \App\Assets $assets */
|
||||
/** @var \Azura\Assets $assets */
|
||||
$assets
|
||||
->load('vue')
|
||||
->load('radio')
|
||||
->load('clipboard')
|
||||
->addInlineJs($this->fetch('stations/profile/index.js', ['nowplaying' => $nowplaying]), 99);
|
||||
|
||||
$user = $request->getUser();
|
||||
?>
|
||||
|
||||
<div class="row">
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<?php
|
||||
/** @var \App\Assets $assets */
|
||||
/** @var \Azura\Assets $assets */
|
||||
$assets
|
||||
->addInlineJs($this->fetch('stations/remotes/edit.js'), 99);
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?php $this->layout('main', ['title' => __('Listeners'), 'manual' => true]) ?>
|
||||
|
||||
<?php
|
||||
/** @var \App\Assets $assets */
|
||||
/** @var \Azura\Assets $assets */
|
||||
$assets
|
||||
->load('vue')
|
||||
->load('daterangepicker')
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
$(function () {
|
||||
Highcharts.setOptions({
|
||||
global: {
|
||||
timezoneOffset: <?=\App\Timezone::getOffsetMinutes() ?>,
|
||||
timezoneOffset: <?=\Azura\Timezone::getOffsetMinutes() ?>,
|
||||
useUTC: false
|
||||
}
|
||||
});
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?php $this->layout('main', ['title' => __('Statistics Overview'), 'manual' => true]) ?>
|
||||
|
||||
<?php
|
||||
/** @var \App\Assets $assets */
|
||||
/** @var \Azura\Assets $assets */
|
||||
$assets
|
||||
->load('highcharts')
|
||||
->load('highcharts_theme_'.$customization->getTheme())
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?php $this->layout('main', ['title' => __('Song Listener Impact'), 'manual' => true]) ?>
|
||||
|
||||
<?php
|
||||
/** @var \App\Assets $assets */
|
||||
/** @var \Azura\Assets $assets */
|
||||
$assets
|
||||
->load('bootgrid')
|
||||
->addInlineJs($this->fetch('stations/reports/performance.js'));
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?php $this->layout('main', ['title' => __('Song Requests'), 'manual' => true]) ?>
|
||||
|
||||
<?php
|
||||
/** @var \App\Assets $assets */
|
||||
/** @var \Azura\Assets $assets */
|
||||
$assets
|
||||
->load('bootgrid');
|
||||
?>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?php $this->layout('main', ['title' => __('Song Playback Timeline'), 'manual' => true]) ?>
|
||||
|
||||
<?php
|
||||
/** @var \App\Assets $assets */
|
||||
/** @var \Azura\Assets $assets */
|
||||
$assets
|
||||
->load('daterangepicker')
|
||||
->load('bootgrid')
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
/** @var $assets \App\Assets */
|
||||
|
||||
$assets->addInlineJs($this->fetch('stations/sidebar.js'));
|
||||
|
||||
$user = $request->getUser();
|
||||
?>
|
||||
<div class="navdrawer-header">
|
||||
<a class="navbar-brand px-0" href="<?=$router->fromHere('stations:profile:index') ?>">
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<?php
|
||||
/** @var \App\Assets $assets */
|
||||
/** @var \Azura\Assets $assets */
|
||||
$assets
|
||||
->load('chosen')
|
||||
->load('zxcvbn')
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
<?php
|
||||
namespace App;
|
||||
|
||||
use Azura\Settings;
|
||||
use Azura\Exception;
|
||||
|
||||
class App extends \Azura\App
|
||||
{
|
||||
public static function create(array $values): \Azura\App
|
||||
{
|
||||
$settings = $values['settings'] ?? [];
|
||||
|
||||
if (!isset($settings[Settings::BASE_DIR])) {
|
||||
throw new Exception\Bootstrap('No base directory specified!');
|
||||
}
|
||||
|
||||
$settings[Settings::TEMP_DIR] = dirname($settings[Settings::BASE_DIR]) . '/www_tmp';
|
||||
$settings[Settings::VIEWS_DIR] = $settings[Settings::BASE_DIR] . '/resources/templates';
|
||||
|
||||
// Define the "helper" constants used by AzuraCast.
|
||||
define('APP_IS_COMMAND_LINE', PHP_SAPI === 'cli');
|
||||
|
||||
define('APP_INCLUDE_ROOT', $settings[Settings::BASE_DIR]);
|
||||
define('APP_INCLUDE_TEMP', $settings[Settings::TEMP_DIR]);
|
||||
|
||||
define('APP_INSIDE_DOCKER', file_exists(dirname($settings[Settings::BASE_DIR]) . '/.docker'));
|
||||
define('APP_DOCKER_REVISION', getenv('AZURACAST_DC_REVISION') ?? 1);
|
||||
|
||||
$settings[Settings::IS_DOCKER] = APP_INSIDE_DOCKER;
|
||||
|
||||
define('APP_TESTING_MODE', (isset($settings[Settings::APP_ENV]) && Settings::ENV_TESTING === $settings[Settings::APP_ENV]));
|
||||
|
||||
// Register the plugins engine.
|
||||
if (isset($values['autoloader'])) {
|
||||
$autoloader = $values['autoloader'];
|
||||
|
||||
$plugins = new Plugins($settings[Settings::BASE_DIR] . '/plugins');
|
||||
$plugins->registerAutoloaders($autoloader);
|
||||
|
||||
$values[Plugins::class] = $plugins;
|
||||
} else {
|
||||
$plugins = null;
|
||||
}
|
||||
|
||||
$values['settings'] = $settings;
|
||||
|
||||
$app = \Azura\App::create($values);
|
||||
$di = $app->getContainer();
|
||||
|
||||
/** @var Settings $settings */
|
||||
$settings = $di['settings'];
|
||||
|
||||
define('APP_APPLICATION_ENV', $settings[Settings::APP_ENV]);
|
||||
define('APP_IN_PRODUCTION', $settings->isProduction());
|
||||
|
||||
if (null !== $plugins) {
|
||||
$plugins->registerServices($di);
|
||||
}
|
||||
|
||||
return $app;
|
||||
}
|
||||
}
|
382
src/Assets.php
382
src/Assets.php
|
@ -1,382 +0,0 @@
|
|||
<?php
|
||||
namespace App;
|
||||
|
||||
use App\Http\Request;
|
||||
|
||||
/**
|
||||
* Asset management class for AzuraCast.
|
||||
* 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 = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 library to the collection.
|
||||
*
|
||||
* @param array $data Array with asset data.
|
||||
* @param string|null $library_name
|
||||
* @return $this
|
||||
*/
|
||||
public function addLibrary(array $data, $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'] ?? [],
|
||||
];
|
||||
|
||||
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'] ?? []
|
||||
];
|
||||
} elseif (isset($this->libraries[$data])) {
|
||||
$item = $this->libraries[$data];
|
||||
} else {
|
||||
throw new \InvalidArgumentException(sprintf('Library %s not found!', $data));
|
||||
}
|
||||
|
||||
$name = $item['name'];
|
||||
|
||||
if (!isset($this->loaded[$name])) {
|
||||
if (!empty($item['require'])) {
|
||||
foreach($item['require'] as $require_name) {
|
||||
$this->load($require_name);
|
||||
}
|
||||
}
|
||||
|
||||
$this->loaded[$name] = $item;
|
||||
$this->is_sorted = false;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a single javascript file.
|
||||
*
|
||||
* @param $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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a single javascript inline script.
|
||||
*
|
||||
* @param $js_script
|
||||
* @return $this
|
||||
*/
|
||||
public function addInlineJs($js_script, $order = 100): self
|
||||
{
|
||||
$this->load([
|
||||
'order' => $order,
|
||||
'inline' => [
|
||||
'js' => (is_array($js_script)) ? $js_script : array($js_script),
|
||||
],
|
||||
]);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a single CSS file.
|
||||
*
|
||||
* @param $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 $css_script
|
||||
* @return $this
|
||||
*/
|
||||
public function addInlineCss($css_script): self
|
||||
{
|
||||
$this->load([
|
||||
'order' => 100,
|
||||
'inline' => [
|
||||
'css' => (is_array($css_script)) ? $css_script : array($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 Request $request
|
||||
* @return string
|
||||
*/
|
||||
public function inlineJs(Request $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";
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 = [])
|
||||
{
|
||||
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 $resource_uri
|
||||
* @return string The resolved resource URL.
|
||||
*/
|
||||
protected function _getUrl($resource_uri)
|
||||
{
|
||||
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;
|
||||
} else {
|
||||
return '/static/'.$resource_uri;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the loaded domain to the full list of CSP-approved domains.
|
||||
*
|
||||
* @param $files
|
||||
*/
|
||||
protected function _addDomainToCsp($src)
|
||||
{
|
||||
$src_parts = parse_url($src);
|
||||
|
||||
$domain = $src_parts['scheme'].'://'.$src_parts['host'];
|
||||
|
||||
if (!isset($this->csp_domains[$domain])) {
|
||||
$this->csp_domains[$domain] = $domain;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -3,7 +3,8 @@ namespace App;
|
|||
|
||||
use App\Entity\Repository\UserRepository;
|
||||
use App\Entity\User;
|
||||
use App\Session\NamespaceInterface;
|
||||
use Azura\Session;
|
||||
use Azura\Session\NamespaceInterface;
|
||||
|
||||
class Auth
|
||||
{
|
||||
|
@ -78,7 +79,7 @@ class Auth
|
|||
*
|
||||
* @param bool $real_user_only
|
||||
* @return bool|User|null|object
|
||||
* @throws Exception
|
||||
* @throws \Azura\Exception
|
||||
*/
|
||||
public function getLoggedInUser($real_user_only = false)
|
||||
{
|
||||
|
@ -93,7 +94,7 @@ class Auth
|
|||
* Get the authenticated user entity.
|
||||
*
|
||||
* @return bool|User|null
|
||||
* @throws Exception
|
||||
* @throws \Azura\Exception
|
||||
*/
|
||||
public function getUser()
|
||||
{
|
||||
|
@ -114,7 +115,7 @@ class Auth
|
|||
$this->_user = false;
|
||||
$this->logout();
|
||||
|
||||
throw new Exception('Invalid user!');
|
||||
throw new \Azura\Exception('Invalid user!');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
170
src/Cache.php
170
src/Cache.php
|
@ -1,170 +0,0 @@
|
|||
<?php
|
||||
namespace App;
|
||||
|
||||
class Cache
|
||||
{
|
||||
/** @var \Redis */
|
||||
protected $redis;
|
||||
|
||||
/** @var int Default length of time to keep cached items. */
|
||||
protected $default_ttl = 3600;
|
||||
|
||||
public function __construct(\Redis $redis, $default_ttl = null)
|
||||
{
|
||||
$this->redis = $redis;
|
||||
|
||||
if ($default_ttl !== null) {
|
||||
$this->default_ttl = $default_ttl;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Properly close the connection.
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
if ($this->redis instanceof \Redis) {
|
||||
try {
|
||||
$this->redis->close();
|
||||
} catch (\RedisException $e) {
|
||||
/*
|
||||
* \Redis::close will throw a \RedisException("Redis server went away") exception if
|
||||
* we haven't previously been able to connect to Redis or the connection has severed.
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to load an item from cache, or return default value if not found.
|
||||
*
|
||||
* @param $id
|
||||
* @param null $default
|
||||
* @return mixed|null
|
||||
*/
|
||||
public function load($id, $default = null)
|
||||
{
|
||||
$result = $this->redis->get($this->_filterId($id));
|
||||
|
||||
if ($result === false) {
|
||||
return (is_callable($default)) ? $default() : $default;
|
||||
}
|
||||
|
||||
return unserialize($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Alias of the "load" function.
|
||||
*
|
||||
* @param $id
|
||||
* @param null $default
|
||||
* @return mixed|null
|
||||
*/
|
||||
public function get($id, $default = null)
|
||||
{
|
||||
return $this->load($id, $default);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test whether an ID is present in the cache.
|
||||
*
|
||||
* @param $id
|
||||
* @return bool
|
||||
*/
|
||||
public function test($id)
|
||||
{
|
||||
$result = $this->redis->get($this->_filterId($id));
|
||||
return ($result !== false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Save an item to the cache.
|
||||
*
|
||||
* @param $data
|
||||
* @param $id
|
||||
* @param int|null $ttl
|
||||
*/
|
||||
public function save($data, $id, $ttl = null)
|
||||
{
|
||||
if ($ttl === null || !is_numeric($ttl)) {
|
||||
$ttl = $this->default_ttl;
|
||||
}
|
||||
|
||||
if ($ttl < 0) {
|
||||
$ttl = 0.1;
|
||||
}
|
||||
|
||||
$this->redis->setex($this->_filterId($id), $ttl, serialize($data));
|
||||
}
|
||||
|
||||
/**
|
||||
* Alias for the "save" function.
|
||||
*
|
||||
* @param $data
|
||||
* @param $id
|
||||
* @param int|null $ttl
|
||||
*/
|
||||
public function set($data, $id, $ttl = null)
|
||||
{
|
||||
$this->save($data, $id, $ttl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Combination of the "get" and "set" functions to return an existing cache
|
||||
* item or set it if one doesn't exist.
|
||||
*
|
||||
* @param $id
|
||||
* @param null $default
|
||||
* @param bool|false $ttl
|
||||
* @return mixed|null
|
||||
*/
|
||||
public function getOrSet($id, $default = null, $ttl = false)
|
||||
{
|
||||
$result = $this->redis->get($this->_filterId($id));
|
||||
|
||||
if ($result === false) {
|
||||
|
||||
if ($ttl === null || !is_numeric($ttl)) {
|
||||
$ttl = $this->default_ttl;
|
||||
}
|
||||
|
||||
if ($ttl < 0) {
|
||||
$ttl = 0.1;
|
||||
}
|
||||
|
||||
$data = (is_callable($default)) ? $default() : $default;
|
||||
$this->redis->setex($this->_filterId($id), $ttl, serialize($data));
|
||||
|
||||
return $data;
|
||||
|
||||
}
|
||||
|
||||
return unserialize($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete an item from the cache.
|
||||
*
|
||||
* @param $id
|
||||
* @return void
|
||||
*/
|
||||
public function remove($id)
|
||||
{
|
||||
$this->redis->delete($this->_filterId($id));
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean the cache of all items.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function clean()
|
||||
{
|
||||
return true; // Not used with Redis
|
||||
}
|
||||
|
||||
protected function _filterId($id)
|
||||
{
|
||||
return str_replace('/', ':', ltrim($id, '/'));
|
||||
}
|
||||
}
|
|
@ -1,58 +0,0 @@
|
|||
<?php
|
||||
namespace App;
|
||||
|
||||
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 [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicate whether a given configuration file name exists.
|
||||
*
|
||||
* @param $name
|
||||
* @return bool
|
||||
*/
|
||||
public function has($name): bool
|
||||
{
|
||||
return file_exists($this->_getPath($name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the configuration path resolved by the specified name.
|
||||
*
|
||||
* @param $name
|
||||
* @return string
|
||||
*/
|
||||
public function _getPath($name)
|
||||
{
|
||||
return $this->_base_folder.DIRECTORY_SEPARATOR.str_replace(['.', '..'], ['', ''], $name).'.php';
|
||||
}
|
||||
}
|
|
@ -1,60 +0,0 @@
|
|||
<?php
|
||||
namespace App\Console;
|
||||
|
||||
use App\Event\BuildConsoleCommands;
|
||||
use App\EventDispatcher;
|
||||
use Slim\Container;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
class Application extends \Symfony\Component\Console\Application
|
||||
{
|
||||
/** @var Container */
|
||||
protected $di;
|
||||
|
||||
/**
|
||||
* @param Container $di
|
||||
*/
|
||||
public function setContainer(Container $di)
|
||||
{
|
||||
$this->di = $di;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Container
|
||||
*/
|
||||
public function getContainer(): Container
|
||||
{
|
||||
return $this->di;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $service_name
|
||||
* @return mixed
|
||||
* @throws \App\Exception
|
||||
* @throws \Interop\Container\Exception\ContainerException
|
||||
*/
|
||||
public function getService($service_name)
|
||||
{
|
||||
if ($this->di->has($service_name)) {
|
||||
return $this->di->get($service_name);
|
||||
} else {
|
||||
throw new \App\Exception(sprintf('Service "%s" not found.', $service_name));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function run(InputInterface $input = null, OutputInterface $output = null)
|
||||
{
|
||||
/** @var EventDispatcher $dispatcher */
|
||||
$dispatcher = $this->di[EventDispatcher::class];
|
||||
|
||||
// Trigger an event for the core app and all plugins to build their CLI commands.
|
||||
$event = new BuildConsoleCommands($this);
|
||||
$dispatcher->dispatch(BuildConsoleCommands::NAME, $event);
|
||||
|
||||
return parent::run($input, $output);
|
||||
}
|
||||
}
|
|
@ -1,44 +0,0 @@
|
|||
<?php
|
||||
namespace App\Console\Command;
|
||||
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
class ClearCache extends \App\Console\Command\CommandAbstract
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function configure()
|
||||
{
|
||||
$this->setName('cache:clear')
|
||||
->setDescription('Clear all application caches.');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
// Flush route cache.
|
||||
$app_settings = $this->get('settings');
|
||||
if (!empty($app_settings['routerCacheFile'])) {
|
||||
@unlink($app_settings['routerCacheFile']);
|
||||
}
|
||||
|
||||
$output->writeln('Router cache file cleared.');
|
||||
|
||||
// Flush all Redis databases
|
||||
/** @var \Redis $redis */
|
||||
$redis = $this->get(\Redis::class);
|
||||
|
||||
for($i = 0; $i < 14; $i++) {
|
||||
$redis->select($i);
|
||||
$redis->flushAll();
|
||||
}
|
||||
|
||||
$output->writeln('Local cache flushed.');
|
||||
return 0;
|
||||
}
|
||||
}
|
|
@ -1,42 +0,0 @@
|
|||
<?php
|
||||
namespace App\Console\Command;
|
||||
|
||||
use App\Console\Application;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\ArrayInput;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
abstract class CommandAbstract extends Command
|
||||
{
|
||||
/**
|
||||
* Return a Dependency Injection service.
|
||||
*
|
||||
* @param $service_name
|
||||
* @return mixed
|
||||
* @throws \App\Exception
|
||||
* @throws \Interop\Container\Exception\ContainerException
|
||||
*/
|
||||
public function get($service_name)
|
||||
{
|
||||
/** @var Application $application */
|
||||
$application = self::getApplication();
|
||||
|
||||
return $application->getService($service_name);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param OutputInterface $output
|
||||
* @param $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,6 +3,7 @@ namespace App\Console\Command;
|
|||
|
||||
use App\Radio\Adapters;
|
||||
use App\Radio\Backend\Liquidsoap;
|
||||
use Azura\Console\Command\CommandAbstract;
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use App\Entity;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
|
@ -10,7 +11,7 @@ use Symfony\Component\Console\Input\InputInterface;
|
|||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
class DjAuth extends \App\Console\Command\CommandAbstract
|
||||
class DjAuth extends CommandAbstract
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
|
|
|
@ -3,13 +3,14 @@ namespace App\Console\Command;
|
|||
|
||||
use App\Radio\Adapters;
|
||||
use App\Radio\Backend\Liquidsoap;
|
||||
use Azura\Console\Command\CommandAbstract;
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use App\Entity;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
class DjOff extends \App\Console\Command\CommandAbstract
|
||||
class DjOff extends CommandAbstract
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
|
|
|
@ -3,13 +3,14 @@ namespace App\Console\Command;
|
|||
|
||||
use App\Radio\Adapters;
|
||||
use App\Radio\Backend\Liquidsoap;
|
||||
use Azura\Console\Command\CommandAbstract;
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use App\Entity;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
class DjOn extends \App\Console\Command\CommandAbstract
|
||||
class DjOn extends CommandAbstract
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
|
|
|
@ -3,10 +3,11 @@
|
|||
namespace App\Console\Command;
|
||||
|
||||
use App\Entity;
|
||||
use Azura\Console\Command\CommandAbstract;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
class GenerateApiDocs extends \App\Console\Command\CommandAbstract
|
||||
class GenerateApiDocs extends CommandAbstract
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
|
@ -37,7 +38,7 @@ class GenerateApiDocs extends \App\Console\Command\CommandAbstract
|
|||
],
|
||||
]);
|
||||
|
||||
$yaml_path = APP_INCLUDE_STATIC.'/api/openapi.yml';
|
||||
$yaml_path = APP_INCLUDE_ROOT.'/web/static/api/openapi.yml';
|
||||
$yaml = $oa->toYaml();
|
||||
|
||||
file_put_contents($yaml_path, $yaml);
|
||||
|
|
|
@ -3,13 +3,14 @@ namespace App\Console\Command;
|
|||
|
||||
use App\Entity;
|
||||
use App\Utilities;
|
||||
use Azura\Console\Command\CommandAbstract;
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\Console\Style\SymfonyStyle;
|
||||
|
||||
class ListSettings extends \App\Console\Command\CommandAbstract
|
||||
class ListSettings extends CommandAbstract
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
<?php
|
||||
namespace App\Console\Command;
|
||||
|
||||
use Azura\Console\Command\CommandAbstract;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
<?php
|
||||
namespace App\Console\Command;
|
||||
|
||||
use Azura\Console\Command\CommandAbstract;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
|
@ -20,7 +21,7 @@ class LocaleImport extends CommandAbstract
|
|||
*/
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$app_settings = $this->get('app_settings');
|
||||
$app_settings = $this->get('settings');
|
||||
$locales = $app_settings['locale']['supported'];
|
||||
|
||||
$locale_base = APP_INCLUDE_ROOT.'/resources/locale';
|
||||
|
|
|
@ -2,11 +2,12 @@
|
|||
namespace App\Console\Command;
|
||||
|
||||
use App\Entity;
|
||||
use Azura\Console\Command\CommandAbstract;
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
class MigrateConfig extends \App\Console\Command\CommandAbstract
|
||||
class MigrateConfig extends CommandAbstract
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
|
|
|
@ -4,12 +4,13 @@ namespace App\Console\Command;
|
|||
use App\Radio\Adapters;
|
||||
use App\Radio\Backend\Liquidsoap;
|
||||
use App\Entity;
|
||||
use Azura\Console\Command\CommandAbstract;
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
class NextSong extends \App\Console\Command\CommandAbstract
|
||||
class NextSong extends CommandAbstract
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
<?php
|
||||
namespace App\Console\Command;
|
||||
|
||||
use Azura\Console\Command\CommandAbstract;
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use App\Entity;
|
||||
|
||||
class ReprocessMedia extends \App\Console\Command\CommandAbstract
|
||||
class ReprocessMedia extends CommandAbstract
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
|
|
|
@ -2,13 +2,14 @@
|
|||
namespace App\Console\Command;
|
||||
|
||||
use App\Entity;
|
||||
use Azura\Console\Command\CommandAbstract;
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\Console\Style\SymfonyStyle;
|
||||
|
||||
class ResetPassword extends \App\Console\Command\CommandAbstract
|
||||
class ResetPassword extends CommandAbstract
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
|
|
|
@ -2,12 +2,13 @@
|
|||
namespace App\Console\Command;
|
||||
|
||||
use App\Radio\Configuration;
|
||||
use Azura\Console\Command\CommandAbstract;
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use App\Entity\Station;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
class RestartRadio extends \App\Console\Command\CommandAbstract
|
||||
class RestartRadio extends CommandAbstract
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
|
|
|
@ -2,13 +2,14 @@
|
|||
namespace App\Console\Command;
|
||||
|
||||
use App\Entity;
|
||||
use Azura\Console\Command\CommandAbstract;
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\Console\Style\SymfonyStyle;
|
||||
|
||||
class SetSetting extends \App\Console\Command\CommandAbstract
|
||||
class SetSetting extends CommandAbstract
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
|
|
|
@ -2,12 +2,13 @@
|
|||
namespace App\Console\Command;
|
||||
|
||||
use App\Utilities;
|
||||
use Azura\Console\Command\CommandAbstract;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\Console\Style\SymfonyStyle;
|
||||
|
||||
class Setup extends \App\Console\Command\CommandAbstract
|
||||
class Setup extends CommandAbstract
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
<?php
|
||||
namespace App\Console\Command;
|
||||
|
||||
use Azura\Console\Command\CommandAbstract;
|
||||
use Doctrine\Common\DataFixtures\Executor\ORMExecutor;
|
||||
use Doctrine\Common\DataFixtures\Loader;
|
||||
use Doctrine\Common\DataFixtures\Purger\ORMPurger;
|
||||
|
@ -9,7 +10,7 @@ use Symfony\Component\Console\Input\ArrayInput;
|
|||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
class SetupFixtures extends \App\Console\Command\CommandAbstract
|
||||
class SetupFixtures extends CommandAbstract
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
<?php
|
||||
namespace App\Console\Command;
|
||||
|
||||
use Azura\Console\Command\CommandAbstract;
|
||||
use InfluxDB\Database;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
class SetupInflux extends \App\Console\Command\CommandAbstract
|
||||
class SetupInflux extends CommandAbstract
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
|
|
|
@ -3,11 +3,12 @@ namespace App\Console\Command;
|
|||
|
||||
use App;
|
||||
use App\Sync\Runner;
|
||||
use Azura\Console\Command\CommandAbstract;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
class Sync extends \App\Console\Command\CommandAbstract
|
||||
class Sync extends CommandAbstract
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
|
|
|
@ -2,13 +2,14 @@
|
|||
namespace App\Console\Command;
|
||||
|
||||
use App;
|
||||
use Azura\Console\Command\CommandAbstract;
|
||||
use Doctrine\ORM\EntityManager;
|
||||
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
class UptimeWait extends \App\Console\Command\CommandAbstract
|
||||
class UptimeWait extends CommandAbstract
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
|
|
|
@ -11,7 +11,7 @@ class ApiController
|
|||
/** @var EntityManager */
|
||||
protected $em;
|
||||
|
||||
/** @var Entity\Repository\BaseRepository */
|
||||
/** @var \Azura\Doctrine\Repository */
|
||||
protected $record_repo;
|
||||
|
||||
/** @var array */
|
||||
|
|
|
@ -14,7 +14,7 @@ class CustomFieldsController
|
|||
/** @var array */
|
||||
protected $form_config;
|
||||
|
||||
/** @var Entity\Repository\BaseRepository */
|
||||
/** @var \Azura\Doctrine\Repository */
|
||||
protected $record_repo;
|
||||
|
||||
/** @var string */
|
||||
|
|
|
@ -65,7 +65,7 @@ class PermissionsController
|
|||
|
||||
public function editAction(Request $request, Response $response, $id = null): Response
|
||||
{
|
||||
/** @var Entity\Repository\BaseRepository $role_repo */
|
||||
/** @var \Azura\Doctrine\Repository $role_repo */
|
||||
$role_repo = $this->em->getRepository(Entity\Role::class);
|
||||
|
||||
/** @var Entity\Repository\RolePermissionRepository $permission_repo */
|
||||
|
@ -114,7 +114,7 @@ class PermissionsController
|
|||
{
|
||||
$request->getSession()->getCsrf()->verify($csrf_token, $this->csrf_namespace);
|
||||
|
||||
/** @var Entity\Repository\BaseRepository $role_repo */
|
||||
/** @var \Azura\Doctrine\Repository $role_repo */
|
||||
$role_repo = $this->em->getRepository(Entity\Role::class);
|
||||
|
||||
$record = $role_repo->find((int)$id);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?php
|
||||
namespace App\Controller\Admin;
|
||||
|
||||
use App\Cache;
|
||||
use Azura\Cache;
|
||||
use App\Radio\Adapters;
|
||||
use App\Radio\Configuration;
|
||||
use Doctrine\ORM\EntityManager;
|
||||
|
|
|
@ -46,7 +46,7 @@ class IndexController
|
|||
*/
|
||||
public function timeAction(Request $request, Response $response): Response
|
||||
{
|
||||
$tz_info = \App\Timezone::getInfo();
|
||||
$tz_info = \Azura\Timezone::getInfo();
|
||||
return $response->withJson(new Entity\Api\Time($tz_info));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -93,11 +93,6 @@ class InternalController
|
|||
|
||||
$payload = $request->getBody()->getContents();
|
||||
|
||||
if (!APP_IN_PRODUCTION) {
|
||||
$log = date('Y-m-d g:i:s')."\n".$station->getName()."\n".$payload."\n\n";
|
||||
file_put_contents(APP_INCLUDE_TEMP.'/notify.log', $log, \FILE_APPEND);
|
||||
}
|
||||
|
||||
$this->sync_nowplaying->processStation($station, $payload);
|
||||
|
||||
return $response->write('received');
|
||||
|
@ -105,7 +100,7 @@ class InternalController
|
|||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @throws \App\Exception
|
||||
* @throws \Azura\Exception
|
||||
* @throws \App\Exception\PermissionDenied
|
||||
*/
|
||||
protected function _checkStationAuth(Request $request): void
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?php
|
||||
namespace App\Controller\Api;
|
||||
|
||||
use App\Cache;
|
||||
use Azura\Cache;
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use App\Entity;
|
||||
use App\Http\Request;
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
<?php
|
||||
namespace App\Controller\Api;
|
||||
|
||||
use App\Cache;
|
||||
use Azura\Cache;
|
||||
use App\Event\Radio\LoadNowPlaying;
|
||||
use App\EventDispatcher;
|
||||
use Azura\EventDispatcher;
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use App\Entity;
|
||||
use App\Http\Request;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?php
|
||||
namespace App\Controller\Api;
|
||||
|
||||
use App\Doctrine\Paginator;
|
||||
use Azura\Doctrine\Paginator;
|
||||
use App\Utilities;
|
||||
use App\ApiUtilities;
|
||||
use Doctrine\ORM\EntityManager;
|
||||
|
@ -155,7 +155,7 @@ class RequestsController
|
|||
$request_repo->submit($station, $media_id);
|
||||
|
||||
return $response->withJson('Request submitted successfully.');
|
||||
} catch (\App\Exception $e) {
|
||||
} catch (\Azura\Exception $e) {
|
||||
return $response->withJson($e->getMessage(), 400);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
namespace App\Controller\Api\Stations;
|
||||
|
||||
use App;
|
||||
use App\Doctrine\Paginator;
|
||||
use Azura\Doctrine\Paginator;
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use App\Entity;
|
||||
use App\Http\Request;
|
||||
|
|
|
@ -5,7 +5,7 @@ use App\Acl;
|
|||
use App\Auth;
|
||||
use App\Entity\Repository\SettingsRepository;
|
||||
use App\Entity\User;
|
||||
use App\RateLimit;
|
||||
use Azura\RateLimit;
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use App\Entity\Settings;
|
||||
use App\Http\Request;
|
||||
|
@ -68,7 +68,7 @@ class AccountController
|
|||
if (!empty($_POST['username']) && !empty($_POST['password'])) {
|
||||
try {
|
||||
$this->rate_limit->checkRateLimit('login', 30, 5);
|
||||
} catch(\App\Exception\RateLimitExceeded $e) {
|
||||
} catch(\Azura\Exception\RateLimitExceeded $e) {
|
||||
$session->flash('<b>' . __('Too many login attempts') . '</b><br>' . __('You have attempted to log in too many times. Please wait 30 seconds and try again.'),
|
||||
'red');
|
||||
|
||||
|
|
|
@ -2,9 +2,8 @@
|
|||
namespace App\Controller\Frontend;
|
||||
|
||||
use App\Acl;
|
||||
use App\Cache;
|
||||
use Azura\Cache;
|
||||
use App\Http\Router;
|
||||
use App\Url;
|
||||
use App\Radio\Adapters;
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use App\Entity;
|
||||
|
|
|
@ -40,6 +40,7 @@ class ProfileController
|
|||
$customization_form = new \AzuraForms\Form($this->form_config['groups']['customization'], $user_profile);
|
||||
|
||||
return $request->getView()->renderToResponse($response, 'frontend/profile/index', [
|
||||
'user' => $request->getUser(),
|
||||
'account_info_form' => $account_info_form,
|
||||
'customization_form' => $customization_form,
|
||||
]);
|
||||
|
|
|
@ -34,7 +34,7 @@ class PublicController
|
|||
$station = $request->getStation();
|
||||
|
||||
if (!$station->getEnablePublicPage()) {
|
||||
throw new \App\Exception(__('Station not found!'));
|
||||
throw new \Azura\Exception(__('Station not found!'));
|
||||
}
|
||||
|
||||
$frontend_adapter = $request->getStationFrontend();
|
||||
|
|
|
@ -29,7 +29,7 @@ class EditController extends FilesControllerAbstract
|
|||
|
||||
// Add custom fields to form configuration.
|
||||
|
||||
/** @var Entity\Repository\BaseRepository $custom_fields_repo */
|
||||
/** @var \Azura\Doctrine\Repository $custom_fields_repo */
|
||||
$custom_fields_repo = $this->em->getRepository(Entity\CustomField::class);
|
||||
$custom_fields = $custom_fields_repo->fetchArray();
|
||||
|
||||
|
@ -79,7 +79,7 @@ class EditController extends FilesControllerAbstract
|
|||
$art_resource = imagecreatefromstring($file->getStream()->getContents());
|
||||
$media->setArt($art_resource);
|
||||
} else if ($file->getError() !== UPLOAD_ERR_NO_FILE) {
|
||||
throw new \App\Exception('Error ' . $file->getError() . ' in uploaded file!');
|
||||
throw new \Azura\Exception('Error ' . $file->getError() . ' in uploaded file!');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -130,7 +130,7 @@ class FilesController extends FilesControllerAbstract
|
|||
$search_phrase = trim($request->getParam('searchPhrase') ?? '');
|
||||
|
||||
if (!is_dir($file_path)) {
|
||||
throw new \App\Exception(__('Path "%s" is not a folder.', $file));
|
||||
throw new \Azura\Exception(__('Path "%s" is not a folder.', $file));
|
||||
}
|
||||
|
||||
$media_query = $this->em->createQueryBuilder()
|
||||
|
@ -293,7 +293,7 @@ class FilesController extends FilesControllerAbstract
|
|||
{
|
||||
try {
|
||||
$request->getSession()->getCsrf()->verify($request->getParam('csrf'), $this->csrf_namespace);
|
||||
} catch(\App\Exception\CsrfValidation $e) {
|
||||
} catch(\Azura\Exception\CsrfValidation $e) {
|
||||
return $response->withStatus(403)
|
||||
->withJson(['error' => ['code' => 403, 'msg' => 'CSRF Failure: '.$e->getMessage()]]);
|
||||
}
|
||||
|
@ -449,7 +449,7 @@ class FilesController extends FilesControllerAbstract
|
|||
{
|
||||
try {
|
||||
$request->getSession()->getCsrf()->verify($request->getParam('csrf'), $this->csrf_namespace);
|
||||
} catch(\App\Exception\CsrfValidation $e) {
|
||||
} catch(\Azura\Exception\CsrfValidation $e) {
|
||||
return $response->withStatus(403)
|
||||
->withJson(['error' => ['code' => 403, 'msg' => 'CSRF Failure: '.$e->getMessage()]]);
|
||||
}
|
||||
|
@ -474,7 +474,7 @@ class FilesController extends FilesControllerAbstract
|
|||
{
|
||||
try {
|
||||
$request->getSession()->getCsrf()->verify($request->getParam('csrf'), $this->csrf_namespace);
|
||||
} catch(\App\Exception\CsrfValidation $e) {
|
||||
} catch(\Azura\Exception\CsrfValidation $e) {
|
||||
return $response->withStatus(403)
|
||||
->withJson(['error' => ['code' => 403, 'msg' => 'CSRF Failure: '.$e->getMessage()]]);
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?php
|
||||
namespace App\Controller\Stations\Files;
|
||||
|
||||
use App\Cache;
|
||||
use Azura\Cache;
|
||||
use App\Http\Router;
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use App\Entity;
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
namespace App\Controller\Stations;
|
||||
|
||||
use App\Entity;
|
||||
use App\Exception;
|
||||
use Azura\Exception;
|
||||
use App\Http\Request;
|
||||
use App\Http\Response;
|
||||
use App\Radio\Adapters;
|
||||
|
|
|
@ -35,7 +35,7 @@ class MountsController
|
|||
$frontend = $request->getStationFrontend();
|
||||
|
||||
if (!$frontend::supportsMounts()) {
|
||||
throw new \App\Exception(__('This feature is not currently supported on this station.'));
|
||||
throw new \Azura\Exception(__('This feature is not currently supported on this station.'));
|
||||
}
|
||||
|
||||
return $request->getView()->renderToResponse($response, 'stations/mounts/index', [
|
||||
|
|
|
@ -23,7 +23,7 @@ class PlaylistsController
|
|||
/** @var array */
|
||||
protected $form_config;
|
||||
|
||||
/** @var Entity\Repository\BaseRepository */
|
||||
/** @var \Azura\Doctrine\Repository */
|
||||
protected $playlist_repo;
|
||||
|
||||
/** @var Entity\Repository\StationPlaylistMediaRepository */
|
||||
|
@ -52,7 +52,7 @@ class PlaylistsController
|
|||
$backend = $request->getStationBackend();
|
||||
|
||||
if (!$backend::supportsMedia()) {
|
||||
throw new \App\Exception(__('This feature is not currently supported on this station.'));
|
||||
throw new \Azura\Exception(__('This feature is not currently supported on this station.'));
|
||||
}
|
||||
|
||||
/** @var Entity\StationPlaylist[] $all_playlists */
|
||||
|
@ -167,13 +167,13 @@ class PlaylistsController
|
|||
|
||||
if ($record->getSource() !== Entity\StationPlaylist::SOURCE_SONGS
|
||||
|| $record->getOrder() !== Entity\StationPlaylist::ORDER_SEQUENTIAL) {
|
||||
throw new \App\Exception(__('This playlist is not a sequential playlist.'));
|
||||
throw new \Azura\Exception(__('This playlist is not a sequential playlist.'));
|
||||
}
|
||||
|
||||
if ($request->isPost()) {
|
||||
try {
|
||||
$request->getSession()->getCsrf()->verify($request->getParam('csrf'), $this->csrf_namespace);
|
||||
} catch(\App\Exception\CsrfValidation $e) {
|
||||
} catch(\Azura\Exception\CsrfValidation $e) {
|
||||
return $response->withStatus(403)
|
||||
->withJson(['error' => ['code' => 403, 'msg' => 'CSRF Failure: '.$e->getMessage()]]);
|
||||
}
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
<?php
|
||||
namespace App\Controller\Stations\Profile;
|
||||
|
||||
use App\Cache;
|
||||
use App\Radio\Backend\BackendAbstract;
|
||||
use Azura\Cache;
|
||||
use App\Radio\Configuration;
|
||||
use App\Radio\Frontend\FrontendAbstract;
|
||||
use AzuraForms\Field\AbstractField;
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use App\Entity;
|
||||
|
|
|
@ -42,7 +42,7 @@ class RemotesController
|
|||
{
|
||||
$station = $request->getStation();
|
||||
|
||||
/** @var Entity\Repository\BaseRepository $remote_repo */
|
||||
/** @var \Azura\Doctrine\Repository $remote_repo */
|
||||
$remote_repo = $this->em->getRepository(Entity\StationRemote::class);
|
||||
|
||||
$form = new \AzuraForms\Form($this->form_config);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?php
|
||||
namespace App\Controller\Stations\Reports;
|
||||
|
||||
use App\Cache;
|
||||
use Azura\Cache;
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use App\Entity;
|
||||
use App\Http\Request;
|
||||
|
|
|
@ -40,7 +40,7 @@ class StreamersController
|
|||
$backend = $request->getStationBackend();
|
||||
|
||||
if (!$backend::supportsStreamers()) {
|
||||
throw new \App\Exception(__('This feature is not currently supported on this station.'));
|
||||
throw new \Azura\Exception(__('This feature is not currently supported on this station.'));
|
||||
}
|
||||
|
||||
$view = $request->getView();
|
||||
|
|
|
@ -85,7 +85,7 @@ class WebhooksController
|
|||
if (!empty($_POST) && $form->isValid($_POST)) {
|
||||
$data = $form->getValues();
|
||||
|
||||
/** @var Entity\Repository\BaseRepository $record_repo */
|
||||
/** @var \Azura\Doctrine\Repository $record_repo */
|
||||
$record_repo = $this->em->getRepository(Entity\StationWebhook::class);
|
||||
|
||||
$record = new Entity\StationWebhook($station, $type);
|
||||
|
@ -112,7 +112,7 @@ class WebhooksController
|
|||
{
|
||||
$station = $request->getStation();
|
||||
|
||||
/** @var Entity\Repository\BaseRepository $record_repo */
|
||||
/** @var \Azura\Doctrine\Repository $record_repo */
|
||||
$record_repo = $this->em->getRepository(Entity\StationWebhook::class);
|
||||
|
||||
$record = $record_repo->findOneBy([
|
||||
|
|
|
@ -1,92 +0,0 @@
|
|||
<?php
|
||||
namespace App\Doctrine\Cache;
|
||||
|
||||
/**
|
||||
* Overrider of the Doctrine Redis Cache functionality
|
||||
*
|
||||
* Dev Note: This entire class basically only exists because \Doctrine\Common\Cache\CacheProvider::getNamespacedId
|
||||
* is a private function that can't be overridden. Thus, instead, to remove Doctrine's flavor of namespacing
|
||||
* from Redis caching, one must reimplement *everything* that calls that.
|
||||
*
|
||||
* @package App\Doctrine\Cache
|
||||
*/
|
||||
class Redis extends \Doctrine\Common\Cache\RedisCache
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function fetch($id)
|
||||
{
|
||||
return $this->doFetch($id);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function fetchMultiple(array $keys)
|
||||
{
|
||||
if (empty($keys)) {
|
||||
return array();
|
||||
}
|
||||
|
||||
// note: the array_combine() is in place to keep an association between our $keys and the $namespacedKeys
|
||||
$namespacedKeys = array_combine($keys, $keys);
|
||||
$items = $this->doFetchMultiple($namespacedKeys);
|
||||
$foundItems = array();
|
||||
|
||||
// no internal array function supports this sort of mapping: needs to be iterative
|
||||
// this filters and combines keys in one pass
|
||||
foreach ($namespacedKeys as $requestedKey => $namespacedKey) {
|
||||
if (isset($items[$namespacedKey]) || array_key_exists($namespacedKey, $items)) {
|
||||
$foundItems[$requestedKey] = $items[$namespacedKey];
|
||||
}
|
||||
}
|
||||
|
||||
return $foundItems;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function saveMultiple(array $keysAndValues, $lifetime = 0)
|
||||
{
|
||||
return $this->doSaveMultiple($keysAndValues, $lifetime);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function contains($id)
|
||||
{
|
||||
return $this->doContains($id);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function save($id, $data, $lifeTime = 0)
|
||||
{
|
||||
return $this->doSave($id, $data, $lifeTime);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function delete($id)
|
||||
{
|
||||
return $this->doDelete($id);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function deleteAll()
|
||||
{
|
||||
$this->getRedis()->flushDB();
|
||||
}
|
||||
|
||||
protected function getSerializerValue()
|
||||
{
|
||||
return \Redis::SERIALIZER_PHP;
|
||||
}
|
||||
}
|
|
@ -1,25 +0,0 @@
|
|||
<?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()';
|
||||
}
|
||||
}
|
|
@ -1,68 +0,0 @@
|
|||
<?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;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,187 +0,0 @@
|
|||
<?php
|
||||
namespace App\Doctrine;
|
||||
|
||||
use App\Http\Request;
|
||||
use App\Http\Response;
|
||||
use App\Http\Router;
|
||||
use Doctrine\ORM\Query;
|
||||
use Doctrine\ORM\QueryBuilder;
|
||||
use Doctrine\ORM\Tools\Pagination\Paginator as DoctrinePaginator;
|
||||
|
||||
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;
|
||||
|
||||
/** @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 setCurrentPage(int $current_page): void
|
||||
{
|
||||
$this->current_page = ($current_page > 0) ? $current_page : 1;
|
||||
}
|
||||
|
||||
public function getCurrentPage(): int
|
||||
{
|
||||
return $this->current_page;
|
||||
}
|
||||
|
||||
public function setMaxPerPage(int $max_per_page): void
|
||||
{
|
||||
$this->max_per_page = ($max_per_page > 0) ? $max_per_page : 1;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
public function getPerPage(): int
|
||||
{
|
||||
return $this->per_page;
|
||||
}
|
||||
|
||||
public function setRouter(Router $router): void
|
||||
{
|
||||
$this->router = $router;
|
||||
}
|
||||
|
||||
public function getRouter(): Router
|
||||
{
|
||||
return $this->router;
|
||||
}
|
||||
|
||||
public function isFromBootgrid(): bool
|
||||
{
|
||||
return $this->is_bootgrid;
|
||||
}
|
||||
|
||||
public function setFromRequest(Request $request)
|
||||
{
|
||||
$this->is_bootgrid = $request->hasParam('rowCount') || $request->hasParam('searchPhrase');
|
||||
|
||||
if ($this->is_bootgrid) {
|
||||
$this->setCurrentPage((int)$request->getParam('current'));
|
||||
$this->setPerPage((int)$request->getParam('rowCount'));
|
||||
} else {
|
||||
if ($request->hasParam('page')) {
|
||||
$this->setCurrentPage($request->getParam('page'));
|
||||
}
|
||||
if ($request->hasParam('per_page')) {
|
||||
$this->setPerPage($request->getParam('per_page'));
|
||||
}
|
||||
}
|
||||
|
||||
$this->setRouter($request->getRouter());
|
||||
}
|
||||
|
||||
public function setPostprocessor(callable $postprocessor)
|
||||
{
|
||||
$this->postprocessor = $postprocessor;
|
||||
}
|
||||
|
||||
public function getPaginator()
|
||||
{
|
||||
static $paginator;
|
||||
|
||||
if (!$paginator) {
|
||||
if ($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;
|
||||
}
|
||||
|
||||
public function write(Response $response): Response
|
||||
{
|
||||
$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_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,
|
||||
]);
|
||||
}
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Custom MySQL platform that supports utf8mb4 charset and encoding by default for tables.
|
||||
*/
|
||||
|
||||
namespace App\Doctrine\Platform;
|
||||
|
||||
class MysqlUnicode extends \Doctrine\DBAL\Platforms\MySqlPlatform
|
||||
{
|
||||
protected function _getCreateTableSQL($tableName, array $columns, array $options = [])
|
||||
{
|
||||
if (!isset($options['charset'])) {
|
||||
$options['charset'] = 'utf8mb4';
|
||||
}
|
||||
|
||||
if (!isset($options['collate'])) {
|
||||
$options['collate'] = 'utf8mb4_unicode_ci';
|
||||
}
|
||||
|
||||
return parent::_getCreateTableSQL($tableName, $columns, $options);
|
||||
}
|
||||
}
|
|
@ -1,383 +0,0 @@
|
|||
<?php
|
||||
namespace App\Doctrine;
|
||||
|
||||
use Doctrine\Common\Collections\Collection;
|
||||
use Doctrine\ORM\EntityRepository;
|
||||
|
||||
class Repository extends EntityRepository
|
||||
{
|
||||
/**
|
||||
* Generate an array result of all records.
|
||||
*
|
||||
* @param bool $cached
|
||||
* @param null $order_by
|
||||
* @param string $order_dir
|
||||
* @return array
|
||||
*/
|
||||
public function fetchArray($cached = true, $order_by = null, $order_dir = 'ASC')
|
||||
{
|
||||
$qb = $this->_em->createQueryBuilder()
|
||||
->select('e')
|
||||
->from($this->_entityName, 'e');
|
||||
|
||||
if ($order_by) {
|
||||
$qb->orderBy('e.' . str_replace('e.', '', $order_by), $order_dir);
|
||||
}
|
||||
|
||||
return $qb->getQuery()->getArrayResult();
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic dropdown builder function (can be overridden for specialized use cases).
|
||||
*
|
||||
* @param bool $add_blank
|
||||
* @param \Closure|NULL $display
|
||||
* @param string $pk
|
||||
* @param string $order_by
|
||||
* @return array
|
||||
*/
|
||||
public function fetchSelect($add_blank = false, \Closure $display = null, $pk = 'id', $order_by = 'name')
|
||||
{
|
||||
$select = [];
|
||||
|
||||
// Specify custom text in the $add_blank parameter to override.
|
||||
if ($add_blank !== false) {
|
||||
$select[''] = ($add_blank === true) ? 'Select...' : $add_blank;
|
||||
}
|
||||
|
||||
// Build query for records.
|
||||
$qb = $this->_em->createQueryBuilder()->from($this->_entityName, 'e');
|
||||
|
||||
if ($display === null) {
|
||||
$qb->select('e.' . $pk)->addSelect('e.name')->orderBy('e.' . $order_by, 'ASC');
|
||||
} else {
|
||||
$qb->select('e')->orderBy('e.' . $order_by, 'ASC');
|
||||
}
|
||||
|
||||
$results = $qb->getQuery()->getArrayResult();
|
||||
|
||||
// Assemble select values and, if necessary, call $display callback.
|
||||
foreach ((array)$results as $result) {
|
||||
$key = $result[$pk];
|
||||
$value = ($display === null) ? $result['name'] : $display($result);
|
||||
$select[$key] = $value;
|
||||
}
|
||||
|
||||
return $select;
|
||||
}
|
||||
|
||||
/**
|
||||
* FromArray (A Doctrine 1 Classic)
|
||||
*
|
||||
* @param object|Entity $entity
|
||||
* @param array $source
|
||||
*/
|
||||
public function fromArray($entity, array $source)
|
||||
{
|
||||
$metadata = $this->_getMetadata($entity);
|
||||
|
||||
$meta = $metadata['meta'];
|
||||
$mappings = $metadata['mappings'];
|
||||
|
||||
foreach ((array)$source as $field => $value) {
|
||||
if (isset($mappings[$field])) {
|
||||
$mapping = $mappings[$field];
|
||||
|
||||
switch ($mapping['type']) {
|
||||
case "one_id":
|
||||
$entity_field = $mapping['name'];
|
||||
$entity_id = $mapping['ids'][0];
|
||||
|
||||
if (empty($value)) {
|
||||
$this->_set($entity, $field, null);
|
||||
$this->_set($entity, $entity_field, null);
|
||||
} else {
|
||||
if ($value != $this->_get($entity, $field)) {
|
||||
$obj_class = $mapping['entity'];
|
||||
$obj = $this->_em->find($obj_class, $value);
|
||||
|
||||
if ($obj instanceof $obj_class) {
|
||||
$this->_set($entity, $field, $this->_get($obj, $entity_id));
|
||||
$this->_set($entity, $entity_field, $obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case "one_entity":
|
||||
$entity_id = $mapping['ids'][0];
|
||||
$id_field = $mapping['name'];
|
||||
|
||||
if (empty($value)) {
|
||||
$this->_set($entity, $field, null);
|
||||
$this->_set($entity, $id_field, null);
|
||||
} else {
|
||||
if ($this->_get($value, $entity_id) != $this->_get($entity, $field)) {
|
||||
$this->_set($entity, $field, $value);
|
||||
$this->_set($entity, $id_field, $this->_get($value, $entity_id));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case "many":
|
||||
$obj_class = $mapping['entity'];
|
||||
|
||||
if ($mapping['is_owning_side']) {
|
||||
/** @var Collection $collection */
|
||||
$collection = $this->_get($entity, $field);
|
||||
|
||||
$collection->clear();
|
||||
|
||||
if ($value) {
|
||||
foreach ((array)$value as $field_id) {
|
||||
if (($field_item = $this->_em->find($obj_class, (int)$field_id)) instanceof $obj_class) {
|
||||
$collection->add($field_item);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$foreign_field = $mapping['mappedBy'];
|
||||
|
||||
if (count($this->_get($entity, $field)) > 0) {
|
||||
foreach ($this->_get($entity, $field) as $record) {
|
||||
/** @var Collection $collection */
|
||||
$collection = $this->_get($record, $foreign_field);
|
||||
$collection->removeElement($entity);
|
||||
|
||||
$this->_em->persist($record);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ((array)$value as $field_id) {
|
||||
$record = $this->_em->find($obj_class, (int)$field_id);
|
||||
|
||||
if ($record instanceof $obj_class) {
|
||||
/** @var Collection $collection */
|
||||
$collection = $this->_get($record, $foreign_field);
|
||||
$collection->add($entity);
|
||||
|
||||
$this->_em->persist($record);
|
||||
}
|
||||
}
|
||||
|
||||
$this->_em->flush();
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (!isset($meta->fieldMappings[$field])) {
|
||||
$field_info = [];
|
||||
} else {
|
||||
$field_info = $meta->fieldMappings[$field];
|
||||
}
|
||||
|
||||
switch ($field_info['type']) {
|
||||
case "datetime":
|
||||
case "date":
|
||||
if (!($value instanceof \DateTime)) {
|
||||
if ($value) {
|
||||
if (!is_numeric($value)) {
|
||||
$value = strtotime($value . ' UTC');
|
||||
}
|
||||
|
||||
$value = \DateTime::createFromFormat(\DateTime::ISO8601,
|
||||
gmdate(\DateTime::ISO8601, (int)$value));
|
||||
} else {
|
||||
$value = null;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case "string":
|
||||
if ($field_info['length'] && strlen($value) > $field_info['length']) {
|
||||
$value = substr($value, 0, $field_info['length']);
|
||||
}
|
||||
break;
|
||||
|
||||
case "decimal":
|
||||
case "float":
|
||||
if ($value !== null) {
|
||||
if (is_numeric($value)) {
|
||||
$value = (float)$value;
|
||||
} elseif (empty($value)) {
|
||||
$value = ($field_info['nullable']) ? NULL : 0.0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case "integer":
|
||||
case "smallint":
|
||||
case "bigint":
|
||||
if ($value !== null) {
|
||||
$value = (int)$value;
|
||||
}
|
||||
break;
|
||||
|
||||
case "boolean":
|
||||
if ($value !== null) {
|
||||
$value = (bool)$value;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
$this->_set($entity, $field, $value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* ToArray (A Doctrine 1 Classic)
|
||||
*
|
||||
* @param object|Entity $entity
|
||||
* @param bool $deep Iterate through collections associated with this item.
|
||||
* @param bool $form_mode Return values in a format suitable for ZendForm setDefault function.
|
||||
* @return array
|
||||
*/
|
||||
public function toArray($entity, $deep = false, $form_mode = false)
|
||||
{
|
||||
$return_arr = [];
|
||||
|
||||
$class_meta = $this->_em->getClassMetadata(get_class($entity));
|
||||
|
||||
$reflect = new \ReflectionClass($entity);
|
||||
$props = $reflect->getProperties(\ReflectionProperty::IS_PUBLIC | \ReflectionProperty::IS_PROTECTED);
|
||||
|
||||
if ($props) {
|
||||
foreach ($props as $property) {
|
||||
$property->setAccessible(true);
|
||||
$prop_name = $property->getName();
|
||||
$prop_val = $property->getValue($entity);
|
||||
|
||||
if (isset($class_meta->fieldMappings[$prop_name])) {
|
||||
$prop_info = $class_meta->fieldMappings[$prop_name];
|
||||
} else {
|
||||
$prop_info = [];
|
||||
}
|
||||
|
||||
if (is_array($prop_val)) {
|
||||
$return_arr[$prop_name] = $prop_val;
|
||||
} else {
|
||||
if (!is_object($prop_val)) {
|
||||
if ($prop_info['type'] == "array") {
|
||||
$return_arr[$prop_name] = (array)$prop_val;
|
||||
} else {
|
||||
$return_arr[$prop_name] = (string)$prop_val;
|
||||
}
|
||||
} else {
|
||||
if ($prop_val instanceof \DateTime) {
|
||||
$return_arr[$prop_name] = $prop_val->getTimestamp();
|
||||
} else {
|
||||
if ($deep) {
|
||||
if ($prop_val instanceof \Doctrine\Common\Collections\Collection) {
|
||||
$return_val = [];
|
||||
if (count($prop_val) > 0) {
|
||||
foreach ($prop_val as $val_obj) {
|
||||
if ($form_mode) {
|
||||
$obj_meta = $this->_em->getClassMetadata(get_class($val_obj));
|
||||
$id_field = $obj_meta->identifier;
|
||||
|
||||
if ($id_field && count($id_field) == 1) {
|
||||
$return_val[] = $this->_get($val_obj, $id_field[0]);
|
||||
}
|
||||
} else {
|
||||
$return_val[] = $this->toArray($val_obj, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$return_arr[$prop_name] = $return_val;
|
||||
} else {
|
||||
$return_arr[$prop_name] = $this->toArray($prop_val, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $return_arr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal function for pulling metadata, used in toArray and fromArray
|
||||
*
|
||||
* @param object $source_entity
|
||||
* @return array
|
||||
*/
|
||||
protected function _getMetadata($source_entity)
|
||||
{
|
||||
$class = get_class($source_entity);
|
||||
|
||||
$meta_result = [];
|
||||
$meta_result['em'] = $this->_em;
|
||||
$meta_result['factory'] = $this->_em->getMetadataFactory();
|
||||
$meta_result['meta'] = $meta_result['factory']->getMetadataFor($class);
|
||||
$meta_result['mappings'] = [];
|
||||
|
||||
if ($meta_result['meta']->associationMappings) {
|
||||
foreach ($meta_result['meta']->associationMappings as $mapping_name => $mapping_info) {
|
||||
$entity = $mapping_info['targetEntity'];
|
||||
|
||||
if (isset($mapping_info['joinTable'])) {
|
||||
$meta_result['mappings'][$mapping_info['fieldName']] = [
|
||||
'type' => 'many',
|
||||
'entity' => $entity,
|
||||
'is_owning_side' => ($mapping_info['isOwningSide'] == 1),
|
||||
'mappedBy' => $mapping_info['mappedBy'],
|
||||
];
|
||||
} else {
|
||||
if (isset($mapping_info['joinColumns'])) {
|
||||
foreach ($mapping_info['joinColumns'] as $col) {
|
||||
$join_meta = $meta_result['factory']->getMetadataFor($entity);
|
||||
$join_ids = $join_meta->getIdentifierFieldNames();
|
||||
|
||||
$col_name = $col['name'];
|
||||
$col_name = (isset($meta_result['meta']->fieldNames[$col_name])) ? $meta_result['meta']->fieldNames[$col_name] : $col_name;
|
||||
|
||||
$meta_result['mappings'][$col_name] = [
|
||||
'name' => $mapping_name,
|
||||
'type' => 'one_id',
|
||||
'entity' => $entity,
|
||||
'ids' => $join_ids,
|
||||
];
|
||||
|
||||
$meta_result['mappings'][$mapping_name] = [
|
||||
'name' => $col_name,
|
||||
'type' => 'one_entity',
|
||||
'entity' => $entity,
|
||||
'ids' => $join_ids,
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $meta_result;
|
||||
}
|
||||
|
||||
protected function _get($entity, $key)
|
||||
{
|
||||
$method_name = $this->_getMethodName($key, 'get');
|
||||
|
||||
return (method_exists($entity, $method_name))
|
||||
? $entity->$method_name()
|
||||
: null;
|
||||
}
|
||||
|
||||
protected function _set($entity, $key, $value)
|
||||
{
|
||||
$method_name = $this->_getMethodName($key, 'set');
|
||||
|
||||
return (method_exists($entity, $method_name))
|
||||
? $entity->$method_name($value)
|
||||
: null;
|
||||
}
|
||||
|
||||
// Converts "getvar_name_blah" to "getVarNameBlah".
|
||||
protected function _getMethodName($var, $prefix = '')
|
||||
{
|
||||
return $prefix . str_replace(" ", "", ucwords(strtr($var, "_-", " ")));
|
||||
}
|
||||
}
|
|
@ -1,62 +0,0 @@
|
|||
<?php
|
||||
namespace App\Doctrine;
|
||||
|
||||
use Doctrine\Common\Persistence\ObjectRepository;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Doctrine\ORM\Mapping\ClassMetadata;
|
||||
use Psr\Container\ContainerInterface;
|
||||
|
||||
/**
|
||||
* A dependency-injection aware repository locator.
|
||||
*
|
||||
* @package App\Doctrine
|
||||
*/
|
||||
class RepositoryFactory implements \Doctrine\ORM\Repository\RepositoryFactory
|
||||
{
|
||||
/** @var ObjectRepository[] */
|
||||
protected $repository_list = [];
|
||||
|
||||
/** @var ContainerInterface */
|
||||
protected $di;
|
||||
|
||||
public function __construct(ContainerInterface $di)
|
||||
{
|
||||
$this->di = $di;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getRepository(EntityManagerInterface $em, $entity_name)
|
||||
{
|
||||
$entity_meta = $em->getClassMetadata($entity_name);
|
||||
$repo_name = $entity_meta->getName();
|
||||
|
||||
if (isset($this->repository_list[$repo_name])) {
|
||||
return $this->repository_list[$repo_name];
|
||||
}
|
||||
|
||||
return $this->repository_list[$repo_name] = $this->createRepository($em, $entity_meta);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new repository instance for an entity class.
|
||||
*
|
||||
* @param EntityManagerInterface $entityManager
|
||||
* @param ClassMetadata $entity_meta
|
||||
* @return ObjectRepository
|
||||
*/
|
||||
protected function createRepository(
|
||||
EntityManagerInterface $entityManager,
|
||||
ClassMetadata $entity_meta): ObjectRepository
|
||||
{
|
||||
$repo_class = $entity_meta->customRepositoryClassName
|
||||
?: $entityManager->getConfiguration()->getDefaultRepositoryClassName();
|
||||
|
||||
if ($this->di->has($repo_class)) {
|
||||
return $this->di->get($repo_class);
|
||||
}
|
||||
|
||||
return new $repo_class($entityManager, $entity_meta);
|
||||
}
|
||||
}
|
|
@ -19,21 +19,38 @@ final class Version20161003041904 extends AbstractMigration
|
|||
$this->abortIf($this->connection->getDatabasePlatform()->getName() != 'mysql',
|
||||
'Migration can only be executed safely on \'mysql\'.');
|
||||
|
||||
$db_dump_file = APP_INCLUDE_ROOT.'/util/azuracast_db.sql';
|
||||
$db_dump = file_get_contents($db_dump_file);
|
||||
// Apply the original database schema.
|
||||
$this->addSql([
|
||||
'SET NAMES utf8mb4',
|
||||
'SET FOREIGN_KEY_CHECKS=0',
|
||||
|
||||
foreach(explode("\n", $db_dump) as $db_dump_line) {
|
||||
$this->addSql($db_dump_line);
|
||||
}
|
||||
'CREATE TABLE IF NOT EXISTS `action` (`id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(100) COLLATE utf8_unicode_ci DEFAULT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci',
|
||||
'CREATE TABLE IF NOT EXISTS `analytics` (`id` int(11) NOT NULL AUTO_INCREMENT, `station_id` int(11) DEFAULT NULL, `type` varchar(15) COLLATE utf8_unicode_ci NOT NULL, `timestamp` int(11) NOT NULL, `number_min` int(11) NOT NULL, `number_max` int(11) NOT NULL, `number_avg` int(11) NOT NULL, PRIMARY KEY (`id`), KEY `IDX_EAC2E68821BDB235` (`station_id`), KEY `search_idx` (`type`,`timestamp`), CONSTRAINT `FK_EAC2E68821BDB235` FOREIGN KEY (`station_id`) REFERENCES `station` (`id`) ON DELETE CASCADE) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci',
|
||||
'CREATE TABLE IF NOT EXISTS `api_keys` (`id` varchar(50) COLLATE utf8_unicode_ci NOT NULL, `owner` varchar(150) COLLATE utf8_unicode_ci DEFAULT NULL, `calls_made` int(11) NOT NULL, `created` int(11) NOT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci',
|
||||
'CREATE TABLE IF NOT EXISTS `role` (`id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(100) COLLATE utf8_unicode_ci NOT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci',
|
||||
'CREATE TABLE IF NOT EXISTS `role_has_action` (`role_id` int(11) NOT NULL, `action_id` int(11) NOT NULL, PRIMARY KEY (`role_id`,`action_id`), KEY `IDX_E4DAF125D60322AC` (`role_id`), KEY `IDX_E4DAF1259D32F035` (`action_id`), CONSTRAINT `FK_E4DAF1259D32F035` FOREIGN KEY (`action_id`) REFERENCES `action` (`id`) ON DELETE CASCADE, CONSTRAINT `FK_E4DAF125D60322AC` FOREIGN KEY (`role_id`) REFERENCES `role` (`id`) ON DELETE CASCADE) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci',
|
||||
'CREATE TABLE IF NOT EXISTS `settings` (`setting_key` varchar(64) COLLATE utf8_unicode_ci NOT NULL, `setting_value` longtext COLLATE utf8_unicode_ci COMMENT \'(DC2Type:json)\', PRIMARY KEY (`setting_key`)) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci',
|
||||
'CREATE TABLE IF NOT EXISTS `songs` (`id` varchar(50) COLLATE utf8_unicode_ci NOT NULL, `text` varchar(150) COLLATE utf8_unicode_ci DEFAULT NULL, `artist` varchar(150) COLLATE utf8_unicode_ci DEFAULT NULL, `title` varchar(150) COLLATE utf8_unicode_ci DEFAULT NULL, `created` int(11) NOT NULL, `play_count` int(11) NOT NULL, `last_played` int(11) NOT NULL, PRIMARY KEY (`id`), KEY `search_idx` (`text`,`artist`,`title`)) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci',
|
||||
'CREATE TABLE IF NOT EXISTS `song_history` (`id` int(11) NOT NULL AUTO_INCREMENT, `song_id` varchar(50) COLLATE utf8_unicode_ci NOT NULL, `station_id` int(11) NOT NULL, `timestamp_start` int(11) NOT NULL, `listeners_start` int(11) DEFAULT NULL, `timestamp_end` int(11) NOT NULL, `listeners_end` smallint(6) DEFAULT NULL, `delta_total` smallint(6) NOT NULL, `delta_positive` smallint(6) NOT NULL, `delta_negative` smallint(6) NOT NULL, `delta_points` longtext COLLATE utf8_unicode_ci COMMENT \'(DC2Type:json)\', PRIMARY KEY (`id`), KEY `IDX_2AD16164A0BDB2F3` (`song_id`), KEY `IDX_2AD1616421BDB235` (`station_id`), KEY `sort_idx` (`timestamp_start`), CONSTRAINT `FK_2AD1616421BDB235` FOREIGN KEY (`station_id`) REFERENCES `station` (`id`) ON DELETE CASCADE, CONSTRAINT `FK_2AD16164A0BDB2F3` FOREIGN KEY (`song_id`) REFERENCES `songs` (`id`) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci',
|
||||
'CREATE TABLE IF NOT EXISTS `station` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(100) COLLATE utf8_unicode_ci DEFAULT NULL, `frontend_type` varchar(100) COLLATE utf8_unicode_ci DEFAULT NULL, `frontend_config` longtext COLLATE utf8_unicode_ci COMMENT \'(DC2Type:json)\', `backend_type` varchar(100) COLLATE utf8_unicode_ci DEFAULT NULL, `backend_config` longtext COLLATE utf8_unicode_ci COMMENT \'(DC2Type:json)\', `description` longtext COLLATE utf8_unicode_ci, `radio_base_dir` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL, `nowplaying_data` longtext COLLATE utf8_unicode_ci COMMENT \'(DC2Type:json)\', `automation_settings` longtext COLLATE utf8_unicode_ci COMMENT \'(DC2Type:json)\', `automation_timestamp` int(11) DEFAULT NULL, `enable_requests` tinyint(1) NOT NULL, `request_delay` int(11) DEFAULT NULL, `enable_streamers` tinyint(1) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci',
|
||||
'CREATE TABLE IF NOT EXISTS `station_media` ( `id` int(11) NOT NULL AUTO_INCREMENT, `station_id` int(11) NOT NULL, `song_id` varchar(50) COLLATE utf8_unicode_ci DEFAULT NULL, `title` varchar(200) COLLATE utf8_unicode_ci DEFAULT NULL, `artist` varchar(200) COLLATE utf8_unicode_ci DEFAULT NULL, `album` varchar(200) COLLATE utf8_unicode_ci DEFAULT NULL, `length` smallint(6) NOT NULL, `length_text` varchar(10) COLLATE utf8_unicode_ci DEFAULT NULL, `path` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL, `mtime` int(11) DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `path_unique_idx` (`path`), KEY `IDX_32AADE3A21BDB235` (`station_id`), KEY `IDX_32AADE3AA0BDB2F3` (`song_id`), KEY `search_idx` (`title`,`artist`,`album`), CONSTRAINT `FK_32AADE3A21BDB235` FOREIGN KEY (`station_id`) REFERENCES `station` (`id`) ON DELETE CASCADE, CONSTRAINT `FK_32AADE3AA0BDB2F3` FOREIGN KEY (`song_id`) REFERENCES `songs` (`id`) ON DELETE SET NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci',
|
||||
'CREATE TABLE IF NOT EXISTS `station_playlists` ( `id` int(11) NOT NULL AUTO_INCREMENT, `station_id` int(11) NOT NULL, `name` varchar(200) COLLATE utf8_unicode_ci NOT NULL, `type` varchar(50) COLLATE utf8_unicode_ci NOT NULL, `is_enabled` tinyint(1) NOT NULL, `play_per_songs` smallint(6) NOT NULL, `play_per_minutes` smallint(6) NOT NULL, `schedule_start_time` smallint(6) NOT NULL, `schedule_end_time` smallint(6) NOT NULL, `play_once_time` smallint(6) NOT NULL, `weight` smallint(6) NOT NULL, `include_in_automation` tinyint(1) NOT NULL, PRIMARY KEY (`id`), KEY `IDX_DC827F7421BDB235` (`station_id`), CONSTRAINT `FK_DC827F7421BDB235` FOREIGN KEY (`station_id`) REFERENCES `station` (`id`) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci',
|
||||
'CREATE TABLE IF NOT EXISTS `station_playlist_has_media` ( `media_id` int(11) NOT NULL, `playlists_id` int(11) NOT NULL, PRIMARY KEY (`media_id`,`playlists_id`), KEY `IDX_668E6486EA9FDD75` (`media_id`), KEY `IDX_668E64869F70CF56` (`playlists_id`), CONSTRAINT `FK_668E64869F70CF56` FOREIGN KEY (`playlists_id`) REFERENCES `station_playlists` (`id`) ON DELETE CASCADE, CONSTRAINT `FK_668E6486EA9FDD75` FOREIGN KEY (`media_id`) REFERENCES `station_media` (`id`) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci',
|
||||
'CREATE TABLE IF NOT EXISTS `station_requests` ( `id` int(11) NOT NULL AUTO_INCREMENT, `station_id` int(11) NOT NULL, `track_id` int(11) NOT NULL, `timestamp` int(11) NOT NULL, `played_at` int(11) NOT NULL, `ip` varchar(40) COLLATE utf8_unicode_ci NOT NULL, PRIMARY KEY (`id`), KEY `IDX_F71F0C0721BDB235` (`station_id`), KEY `IDX_F71F0C075ED23C43` (`track_id`), CONSTRAINT `FK_F71F0C0721BDB235` FOREIGN KEY (`station_id`) REFERENCES `station` (`id`) ON DELETE CASCADE, CONSTRAINT `FK_F71F0C075ED23C43` FOREIGN KEY (`track_id`) REFERENCES `station_media` (`id`) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci',
|
||||
'CREATE TABLE IF NOT EXISTS `station_streamers` ( `id` int(11) NOT NULL AUTO_INCREMENT, `station_id` int(11) NOT NULL, `streamer_username` varchar(50) COLLATE utf8_unicode_ci NOT NULL, `streamer_password` varchar(50) COLLATE utf8_unicode_ci NOT NULL, `comments` longtext COLLATE utf8_unicode_ci, `is_active` tinyint(1) NOT NULL, PRIMARY KEY (`id`), KEY `IDX_5170063E21BDB235` (`station_id`), CONSTRAINT `FK_5170063E21BDB235` FOREIGN KEY (`station_id`) REFERENCES `station` (`id`) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci',
|
||||
'CREATE TABLE IF NOT EXISTS `users` ( `uid` int(11) NOT NULL AUTO_INCREMENT, `email` varchar(100) COLLATE utf8_unicode_ci DEFAULT NULL, `auth_password` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL, `auth_last_login_time` int(11) DEFAULT NULL, `auth_recovery_code` varchar(50) COLLATE utf8_unicode_ci DEFAULT NULL, `name` varchar(100) COLLATE utf8_unicode_ci DEFAULT NULL, `gender` varchar(1) COLLATE utf8_unicode_ci DEFAULT NULL, `customization` longtext COLLATE utf8_unicode_ci COMMENT \'(DC2Type:json)\', PRIMARY KEY (`uid`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci',
|
||||
'CREATE TABLE IF NOT EXISTS `user_has_role` ( `user_id` int(11) NOT NULL, `role_id` int(11) NOT NULL, PRIMARY KEY (`user_id`,`role_id`), KEY `IDX_EAB8B535A76ED395` (`user_id`), KEY `IDX_EAB8B535D60322AC` (`role_id`), CONSTRAINT `FK_EAB8B535A76ED395` FOREIGN KEY (`user_id`) REFERENCES `users` (`uid`) ON DELETE CASCADE, CONSTRAINT `FK_EAB8B535D60322AC` FOREIGN KEY (`role_id`) REFERENCES `role` (`id`) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci',
|
||||
'CREATE TABLE IF NOT EXISTS `user_manages_station` ( `user_id` int(11) NOT NULL, `station_id` int(11) NOT NULL, PRIMARY KEY (`user_id`,`station_id`), KEY `IDX_2453B56BA76ED395` (`user_id`), KEY `IDX_2453B56B21BDB235` (`station_id`), CONSTRAINT `FK_2453B56B21BDB235` FOREIGN KEY (`station_id`) REFERENCES `station` (`id`) ON DELETE CASCADE, CONSTRAINT `FK_2453B56BA76ED395` FOREIGN KEY (`user_id`) REFERENCES `users` (`uid`) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci',
|
||||
|
||||
$this->addSql('CREATE TABLE role_has_actions (id INT AUTO_INCREMENT NOT NULL, station_id INT DEFAULT NULL, role_id INT NOT NULL, action_id INT NOT NULL, INDEX IDX_50EEC1BDD60322AC (role_id), INDEX IDX_50EEC1BD21BDB235 (station_id), UNIQUE INDEX role_action_unique_idx (role_id, action_id, station_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB');
|
||||
$this->addSql('ALTER TABLE role_has_actions ADD CONSTRAINT FK_50EEC1BD21BDB235 FOREIGN KEY (station_id) REFERENCES station (id) ON DELETE CASCADE');
|
||||
'CREATE TABLE role_has_actions (id INT AUTO_INCREMENT NOT NULL, station_id INT DEFAULT NULL, role_id INT NOT NULL, action_id INT NOT NULL, INDEX IDX_50EEC1BDD60322AC (role_id), INDEX IDX_50EEC1BD21BDB235 (station_id), UNIQUE INDEX role_action_unique_idx (role_id, action_id, station_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB',
|
||||
'ALTER TABLE role_has_actions ADD CONSTRAINT FK_50EEC1BD21BDB235 FOREIGN KEY (station_id) REFERENCES station (id) ON DELETE CASCADE',
|
||||
'INSERT INTO role_has_actions (role_id, action_id) SELECT role_id, action_id FROM role_has_action',
|
||||
'DROP TABLE role_has_action',
|
||||
'ALTER TABLE action ADD is_global TINYINT(1) NOT NULL',
|
||||
'UPDATE action SET is_global=1',
|
||||
|
||||
$this->addSql('INSERT INTO role_has_actions (role_id, action_id) SELECT role_id, action_id FROM role_has_action');
|
||||
$this->addSql('DROP TABLE role_has_action');
|
||||
|
||||
$this->addSql('ALTER TABLE action ADD is_global TINYINT(1) NOT NULL');
|
||||
$this->addSql('UPDATE action SET is_global=1');
|
||||
'SET FOREIGN_KEY_CHECKS=1',
|
||||
]);
|
||||
|
||||
$actions = [
|
||||
['view administration', 1],
|
||||
|
|
|
@ -2,8 +2,9 @@
|
|||
namespace App\Entity\Repository;
|
||||
|
||||
use App\Entity;
|
||||
use Azura\Doctrine\Repository;
|
||||
|
||||
class ApiKeyRepository extends BaseRepository
|
||||
class ApiKeyRepository extends Repository
|
||||
{
|
||||
/**
|
||||
* Given an API key string in the format `identifier:verifier`, find and authenticate an API key.
|
||||
|
|
|
@ -1,415 +0,0 @@
|
|||
<?php
|
||||
namespace App\Entity\Repository;
|
||||
|
||||
use Doctrine\Common\Collections\Collection;
|
||||
use Doctrine\ORM\EntityRepository;
|
||||
|
||||
class BaseRepository extends EntityRepository
|
||||
{
|
||||
/**
|
||||
* Combination of find() and toArray() helper functions.
|
||||
*
|
||||
* @param $id
|
||||
* @param bool $deep
|
||||
* @param bool $form_mode
|
||||
* @return array|null
|
||||
*/
|
||||
public function findAsArray($id, $deep = false, $form_mode = false)
|
||||
{
|
||||
$record = $this->_em->find($this->_entityName, $id);
|
||||
return ($record === null)
|
||||
? null
|
||||
: $this->toArray($record, $deep, $form_mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate an array result of all records.
|
||||
*
|
||||
* @param bool $cached
|
||||
* @param null $order_by
|
||||
* @param string $order_dir
|
||||
* @return array
|
||||
*/
|
||||
public function fetchArray($cached = true, $order_by = null, $order_dir = 'ASC')
|
||||
{
|
||||
$qb = $this->_em->createQueryBuilder()
|
||||
->select('e')
|
||||
->from($this->_entityName, 'e');
|
||||
|
||||
if ($order_by) {
|
||||
$qb->orderBy('e.' . str_replace('e.', '', $order_by), $order_dir);
|
||||
}
|
||||
|
||||
return $qb->getQuery()->getArrayResult();
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic dropdown builder function (can be overridden for specialized use cases).
|
||||
*
|
||||
* @param bool $add_blank
|
||||
* @param \Closure|NULL $display
|
||||
* @param string $pk
|
||||
* @param string $order_by
|
||||
* @return array
|
||||
*/
|
||||
public function fetchSelect($add_blank = false, \Closure $display = null, $pk = 'id', $order_by = 'name')
|
||||
{
|
||||
$select = [];
|
||||
|
||||
// Specify custom text in the $add_blank parameter to override.
|
||||
if ($add_blank !== false) {
|
||||
$select[''] = ($add_blank === true) ? 'Select...' : $add_blank;
|
||||
}
|
||||
|
||||
// Build query for records.
|
||||
$qb = $this->_em->createQueryBuilder()->from($this->_entityName, 'e');
|
||||
|
||||
if ($display === null) {
|
||||
$qb->select('e.' . $pk)->addSelect('e.name')->orderBy('e.' . $order_by, 'ASC');
|
||||
} else {
|
||||
$qb->select('e')->orderBy('e.' . $order_by, 'ASC');
|
||||
}
|
||||
|
||||
$results = $qb->getQuery()->getArrayResult();
|
||||
|
||||
// Assemble select values and, if necessary, call $display callback.
|
||||
foreach ((array)$results as $result) {
|
||||
$key = $result[$pk];
|
||||
$value = ($display === null) ? $result['name'] : $display($result);
|
||||
$select[$key] = $value;
|
||||
}
|
||||
|
||||
return $select;
|
||||
}
|
||||
|
||||
/**
|
||||
* FromArray (A Doctrine 1 Classic)
|
||||
*
|
||||
* @param object $entity
|
||||
* @param array $source
|
||||
*/
|
||||
public function fromArray($entity, array $source)
|
||||
{
|
||||
$metadata = $this->_getMetadata($entity);
|
||||
|
||||
$meta = $metadata['meta'];
|
||||
$mappings = $metadata['mappings'];
|
||||
|
||||
foreach ((array)$source as $field => $value) {
|
||||
if (isset($mappings[$field])) {
|
||||
$mapping = $mappings[$field];
|
||||
|
||||
switch ($mapping['type']) {
|
||||
case "one_id":
|
||||
$entity_field = $mapping['name'];
|
||||
$entity_id = $mapping['ids'][0];
|
||||
|
||||
if (empty($value)) {
|
||||
$this->_set($entity, $field, null);
|
||||
$this->_set($entity, $entity_field, null);
|
||||
} else {
|
||||
if ($value != $this->_get($entity, $field)) {
|
||||
$obj_class = $mapping['entity'];
|
||||
$obj = $this->_em->find($obj_class, $value);
|
||||
|
||||
if ($obj instanceof $obj_class) {
|
||||
$this->_set($entity, $field, $this->_get($obj, $entity_id));
|
||||
$this->_set($entity, $entity_field, $obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case "one_entity":
|
||||
$entity_id = $mapping['ids'][0];
|
||||
$id_field = $mapping['name'];
|
||||
|
||||
if (empty($value)) {
|
||||
$this->_set($entity, $field, null);
|
||||
$this->_set($entity, $id_field, null);
|
||||
} else {
|
||||
if ($this->_get($value, $entity_id) != $this->_get($entity, $field)) {
|
||||
$this->_set($entity, $field, $value);
|
||||
$this->_set($entity, $id_field, $this->_get($value, $entity_id));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case "many":
|
||||
$obj_class = $mapping['entity'];
|
||||
|
||||
if ($mapping['is_owning_side']) {
|
||||
/** @var Collection $collection */
|
||||
$collection = $this->_get($entity, $field);
|
||||
|
||||
$collection->clear();
|
||||
|
||||
if ($value) {
|
||||
foreach ((array)$value as $field_id) {
|
||||
if (($field_item = $this->_em->find($obj_class, (int)$field_id)) instanceof $obj_class) {
|
||||
$collection->add($field_item);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$foreign_field = $mapping['mappedBy'];
|
||||
|
||||
if (count($this->_get($entity, $field)) > 0) {
|
||||
foreach ($this->_get($entity, $field) as $record) {
|
||||
/** @var Collection $collection */
|
||||
$collection = $this->_get($record, $foreign_field);
|
||||
$collection->removeElement($entity);
|
||||
|
||||
$this->_em->persist($record);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ((array)$value as $field_id) {
|
||||
$record = $this->_em->find($obj_class, (int)$field_id);
|
||||
|
||||
if ($record instanceof $obj_class) {
|
||||
/** @var Collection $collection */
|
||||
$collection = $this->_get($record, $foreign_field);
|
||||
$collection->add($entity);
|
||||
|
||||
$this->_em->persist($record);
|
||||
}
|
||||
}
|
||||
|
||||
$this->_em->flush();
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (!isset($meta->fieldMappings[$field])) {
|
||||
$field_info = [];
|
||||
} else {
|
||||
$field_info = $meta->fieldMappings[$field];
|
||||
}
|
||||
|
||||
switch ($field_info['type']) {
|
||||
case "datetime":
|
||||
case "date":
|
||||
if (!($value instanceof \DateTime)) {
|
||||
if ($value) {
|
||||
if (!is_numeric($value)) {
|
||||
$value = strtotime($value . ' UTC');
|
||||
}
|
||||
|
||||
$value = \DateTime::createFromFormat(\DateTime::ISO8601,
|
||||
gmdate(\DateTime::ISO8601, (int)$value));
|
||||
} else {
|
||||
$value = null;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case "string":
|
||||
if (is_string($value) && $field_info['length'] && strlen($value) > $field_info['length']) {
|
||||
$value = substr($value, 0, $field_info['length']);
|
||||
}
|
||||
break;
|
||||
|
||||
case "decimal":
|
||||
case "float":
|
||||
if ($value !== null) {
|
||||
if (is_numeric($value)) {
|
||||
$value = (float)$value;
|
||||
} elseif (empty($value)) {
|
||||
$value = ($field_info['nullable']) ? NULL : 0.0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case "integer":
|
||||
case "smallint":
|
||||
case "bigint":
|
||||
if ($value !== null) {
|
||||
$value = (int)$value;
|
||||
}
|
||||
break;
|
||||
|
||||
case "boolean":
|
||||
if ($value !== null) {
|
||||
$value = (bool)$value;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
$this->_set($entity, $field, $value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* ToArray (A Doctrine 1 Classic)
|
||||
*
|
||||
* @param object $entity
|
||||
* @param bool $deep Iterate through collections associated with this item.
|
||||
* @param bool $form_mode Return values in a format suitable for ZendForm setDefault function.
|
||||
* @return array
|
||||
*/
|
||||
public function toArray($entity, $deep = false, $form_mode = false)
|
||||
{
|
||||
$return_arr = [];
|
||||
|
||||
$class_meta = $this->_em->getClassMetadata(get_class($entity));
|
||||
|
||||
$reflect = new \ReflectionClass($entity);
|
||||
$props = $reflect->getProperties(\ReflectionProperty::IS_PUBLIC | \ReflectionProperty::IS_PROTECTED);
|
||||
|
||||
if ($props) {
|
||||
foreach ($props as $property) {
|
||||
$property->setAccessible(true);
|
||||
$prop_name = $property->getName();
|
||||
$prop_val = $this->_get($entity, $prop_name) ?? $property->getValue($entity);
|
||||
|
||||
if (isset($class_meta->fieldMappings[$prop_name])) {
|
||||
$prop_info = $class_meta->fieldMappings[$prop_name];
|
||||
} else {
|
||||
$prop_info = [];
|
||||
}
|
||||
|
||||
if (is_array($prop_val)) {
|
||||
$return_arr[$prop_name] = $prop_val;
|
||||
} else {
|
||||
if (!is_object($prop_val)) {
|
||||
if ($prop_info['type'] == "array") {
|
||||
$return_arr[$prop_name] = (array)$prop_val;
|
||||
} else {
|
||||
$return_arr[$prop_name] = (string)$prop_val;
|
||||
}
|
||||
} else {
|
||||
if ($prop_val instanceof \DateTime) {
|
||||
$return_arr[$prop_name] = $prop_val->getTimestamp();
|
||||
} else {
|
||||
if ($deep) {
|
||||
if ($prop_val instanceof \Doctrine\Common\Collections\Collection) {
|
||||
$return_val = [];
|
||||
if (count($prop_val) > 0) {
|
||||
foreach ($prop_val as $val_obj) {
|
||||
if ($form_mode) {
|
||||
$obj_meta = $this->_em->getClassMetadata(get_class($val_obj));
|
||||
$id_field = $obj_meta->identifier;
|
||||
|
||||
if ($id_field && count($id_field) == 1) {
|
||||
$return_val[] = $this->_get($val_obj, $id_field[0]);
|
||||
}
|
||||
} else {
|
||||
$return_val[] = $this->toArray($val_obj, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$return_arr[$prop_name] = $return_val;
|
||||
} else {
|
||||
$return_arr[$prop_name] = $this->toArray($prop_val, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $return_arr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal function for pulling metadata, used in toArray and fromArray
|
||||
*
|
||||
* @param object $source_entity
|
||||
* @return array
|
||||
*/
|
||||
protected function _getMetadata($source_entity)
|
||||
{
|
||||
$class = get_class($source_entity);
|
||||
|
||||
$meta_result = [];
|
||||
$meta_result['em'] = $this->_em;
|
||||
$meta_result['factory'] = $this->_em->getMetadataFactory();
|
||||
$meta_result['meta'] = $meta_result['factory']->getMetadataFor($class);
|
||||
$meta_result['mappings'] = [];
|
||||
|
||||
if ($meta_result['meta']->associationMappings) {
|
||||
foreach ($meta_result['meta']->associationMappings as $mapping_name => $mapping_info) {
|
||||
$entity = $mapping_info['targetEntity'];
|
||||
|
||||
if (isset($mapping_info['joinTable'])) {
|
||||
$meta_result['mappings'][$mapping_info['fieldName']] = [
|
||||
'type' => 'many',
|
||||
'entity' => $entity,
|
||||
'is_owning_side' => ($mapping_info['isOwningSide'] == 1),
|
||||
'mappedBy' => $mapping_info['mappedBy'],
|
||||
];
|
||||
} else {
|
||||
if (isset($mapping_info['joinColumns'])) {
|
||||
foreach ($mapping_info['joinColumns'] as $col) {
|
||||
$join_meta = $meta_result['factory']->getMetadataFor($entity);
|
||||
$join_ids = $join_meta->getIdentifierFieldNames();
|
||||
|
||||
$col_name = $col['name'];
|
||||
$col_name = (isset($meta_result['meta']->fieldNames[$col_name])) ? $meta_result['meta']->fieldNames[$col_name] : $col_name;
|
||||
|
||||
$meta_result['mappings'][$col_name] = [
|
||||
'name' => $mapping_name,
|
||||
'type' => 'one_id',
|
||||
'entity' => $entity,
|
||||
'ids' => $join_ids,
|
||||
];
|
||||
|
||||
$meta_result['mappings'][$mapping_name] = [
|
||||
'name' => $col_name,
|
||||
'type' => 'one_entity',
|
||||
'entity' => $entity,
|
||||
'ids' => $join_ids,
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $meta_result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Shortcut to persist an object and flush the entity manager.
|
||||
*
|
||||
* @param object $entity
|
||||
*/
|
||||
public function save($entity)
|
||||
{
|
||||
$this->_em->persist($entity);
|
||||
$this->_em->flush();
|
||||
}
|
||||
|
||||
protected function _get($entity, $key)
|
||||
{
|
||||
$method_name = $this->_getMethodName($key, '');
|
||||
|
||||
// Default to "getStatus", "getConfig", etc...but also allow "isEnabled" instead of "getIsEnabled"
|
||||
if (method_exists($entity, 'get'.$method_name)) {
|
||||
return $entity->{'get'.$method_name}();
|
||||
}
|
||||
if (method_exists($entity, $method_name)) {
|
||||
return $entity->{$method_name}();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected function _set($entity, $key, $value)
|
||||
{
|
||||
$method_name = $this->_getMethodName($key, 'set');
|
||||
|
||||
return (method_exists($entity, $method_name))
|
||||
? $entity->$method_name($value)
|
||||
: null;
|
||||
}
|
||||
|
||||
// Converts "getvar_name_blah" to "getVarNameBlah".
|
||||
protected function _getMethodName($var, $prefix = '')
|
||||
{
|
||||
return $prefix . str_replace(" ", "", ucwords(strtr($var, "_-", " ")));
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue