Move Entity, Migration and AzuraCast classes into a PSR-friendly "src/" folder, move Entity Repositories into their own classes, and update AzuraCore to reflect this change.

This commit is contained in:
Buster Silver 2017-01-17 02:46:43 -06:00
parent ae566e24af
commit 270e6370d9
61 changed files with 851 additions and 774 deletions

View File

@ -16,15 +16,16 @@ define("APP_INCLUDE_ROOT", realpath(APP_INCLUDE_BASE.'/..'));
define("APP_INCLUDE_WEB", APP_INCLUDE_ROOT.'/web');
define("APP_INCLUDE_STATIC", APP_INCLUDE_WEB.'/static');
define("APP_INCLUDE_MODELS", APP_INCLUDE_BASE.'/models');
define("APP_INCLUDE_VENDOR", APP_INCLUDE_ROOT.'/vendor');
define("APP_INCLUDE_LIB", APP_INCLUDE_ROOT.'/src');
define("APP_INCLUDE_MODELS", APP_INCLUDE_LIB);
define("APP_INCLUDE_MODULES", APP_INCLUDE_BASE.'/modules');
define("APP_INCLUDE_TEMP", APP_INCLUDE_ROOT.'/../www_tmp');
define("APP_INCLUDE_CACHE", APP_INCLUDE_TEMP.'/cache');
define("APP_INCLUDE_LIB", APP_INCLUDE_BASE.'/library');
define("APP_INCLUDE_VENDOR", APP_INCLUDE_ROOT.'/vendor');
define("APP_UPLOAD_FOLDER", APP_INCLUDE_STATIC);
// Application environment.

View File

@ -33,9 +33,7 @@ $config = [
],
'autoload' => [
'psr0' => [
'Entity' => APP_INCLUDE_MODELS,
],
'psr0' => [],
'psr4' => [
'\\Proxy\\' => APP_INCLUDE_TEMP . '/proxies',
],

View File

@ -31,7 +31,9 @@
],
"autoload": {
"psr-4": {
"AzuraCast\\": "app/library/AzuraCast"
"AzuraCast\\": "src/AzuraCast",
"Entity\\": "src/Entity",
"Migration\\": "src/Migration"
}
},
"config": {

225
composer.lock generated
View File

@ -288,16 +288,16 @@
},
{
"name": "doctrine/common",
"version": "v2.7.1",
"version": "v2.7.2",
"source": {
"type": "git",
"url": "https://github.com/doctrine/common.git",
"reference": "5954c297e9d93ff84554906c2fbbc2a133c43941"
"reference": "930297026c8009a567ac051fd545bf6124150347"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/doctrine/common/zipball/5954c297e9d93ff84554906c2fbbc2a133c43941",
"reference": "5954c297e9d93ff84554906c2fbbc2a133c43941",
"url": "https://api.github.com/repos/doctrine/common/zipball/930297026c8009a567ac051fd545bf6124150347",
"reference": "930297026c8009a567ac051fd545bf6124150347",
"shasum": ""
},
"require": {
@ -357,20 +357,20 @@
"persistence",
"spl"
],
"time": "2016-12-03T08:15:01+00:00"
"time": "2017-01-13T14:02:13+00:00"
},
{
"name": "doctrine/dbal",
"version": "2.5.x-dev",
"version": "v2.5.7",
"source": {
"type": "git",
"url": "https://github.com/doctrine/dbal.git",
"reference": "a526d0df58daa8ab6802244bf3227f532e0deb45"
"reference": "3a351369582dade60c750e2cef540eb7b568e6b3"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/doctrine/dbal/zipball/a526d0df58daa8ab6802244bf3227f532e0deb45",
"reference": "a526d0df58daa8ab6802244bf3227f532e0deb45",
"url": "https://api.github.com/repos/doctrine/dbal/zipball/3a351369582dade60c750e2cef540eb7b568e6b3",
"reference": "3a351369582dade60c750e2cef540eb7b568e6b3",
"shasum": ""
},
"require": {
@ -428,7 +428,7 @@
"persistence",
"queryobject"
],
"time": "2016-12-04T05:53:43+00:00"
"time": "2017-01-14T21:05:28+00:00"
},
{
"name": "doctrine/inflector",
@ -1364,16 +1364,16 @@
},
{
"name": "nette/utils",
"version": "v2.4.2",
"version": "v2.4.4",
"source": {
"type": "git",
"url": "https://github.com/nette/utils.git",
"reference": "fd2e67c2ce28da409864507d8d124621780d036d"
"reference": "714afb64d0da07d0da7178cbf5680008e4b0180b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/nette/utils/zipball/fd2e67c2ce28da409864507d8d124621780d036d",
"reference": "fd2e67c2ce28da409864507d8d124621780d036d",
"url": "https://api.github.com/repos/nette/utils/zipball/714afb64d0da07d0da7178cbf5680008e4b0180b",
"reference": "714afb64d0da07d0da7178cbf5680008e4b0180b",
"shasum": ""
},
"require": {
@ -1423,7 +1423,7 @@
],
"description": "Nette Utility Classes",
"homepage": "https://nette.org",
"time": "2016-12-19T22:01:55+00:00"
"time": "2017-01-16T12:30:14+00:00"
},
{
"name": "nibble/nibble-forms",
@ -2326,12 +2326,12 @@
"source": {
"type": "git",
"url": "https://github.com/SlvrEagle23/AzuraCore.git",
"reference": "c7bd91319e1ad0ba6de86336c00770ae63401ff9"
"reference": "0e048095646490c3d860eb30b0c63429a9c06db8"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/SlvrEagle23/AzuraCore/zipball/c7bd91319e1ad0ba6de86336c00770ae63401ff9",
"reference": "c7bd91319e1ad0ba6de86336c00770ae63401ff9",
"url": "https://api.github.com/repos/SlvrEagle23/AzuraCore/zipball/0e048095646490c3d860eb30b0c63429a9c06db8",
"reference": "0e048095646490c3d860eb30b0c63429a9c06db8",
"shasum": ""
},
"require": {
@ -2370,7 +2370,7 @@
}
],
"description": "The common web application framework code powering AzuraCast and other similar MVC PHP web applications.",
"time": "2016-12-16T20:53:11+00:00"
"time": "2017-01-17T08:42:31+00:00"
},
{
"name": "supervisorphp/supervisor",
@ -2434,16 +2434,16 @@
},
{
"name": "symfony/console",
"version": "v3.2.1",
"version": "v3.2.2",
"source": {
"type": "git",
"url": "https://github.com/symfony/console.git",
"reference": "d12aa9ca20f4db83ec58410978dab6afcb9d6aaa"
"reference": "4f9e449e76996adf310498a8ca955c6deebe29dd"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/console/zipball/d12aa9ca20f4db83ec58410978dab6afcb9d6aaa",
"reference": "d12aa9ca20f4db83ec58410978dab6afcb9d6aaa",
"url": "https://api.github.com/repos/symfony/console/zipball/4f9e449e76996adf310498a8ca955c6deebe29dd",
"reference": "4f9e449e76996adf310498a8ca955c6deebe29dd",
"shasum": ""
},
"require": {
@ -2493,20 +2493,20 @@
],
"description": "Symfony Console Component",
"homepage": "https://symfony.com",
"time": "2016-12-11T14:34:22+00:00"
"time": "2017-01-08T20:47:33+00:00"
},
{
"name": "symfony/debug",
"version": "v3.2.1",
"version": "v3.2.2",
"source": {
"type": "git",
"url": "https://github.com/symfony/debug.git",
"reference": "9f923e68d524a3095c5a2ae5fc7220c7cbc12231"
"reference": "810ba5c1c5352a4ddb15d4719e8936751dff0b05"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/debug/zipball/9f923e68d524a3095c5a2ae5fc7220c7cbc12231",
"reference": "9f923e68d524a3095c5a2ae5fc7220c7cbc12231",
"url": "https://api.github.com/repos/symfony/debug/zipball/810ba5c1c5352a4ddb15d4719e8936751dff0b05",
"reference": "810ba5c1c5352a4ddb15d4719e8936751dff0b05",
"shasum": ""
},
"require": {
@ -2550,20 +2550,20 @@
],
"description": "Symfony Debug Component",
"homepage": "https://symfony.com",
"time": "2016-11-16T22:18:16+00:00"
"time": "2017-01-02T20:32:22+00:00"
},
{
"name": "symfony/event-dispatcher",
"version": "v3.2.1",
"version": "v3.2.2",
"source": {
"type": "git",
"url": "https://github.com/symfony/event-dispatcher.git",
"reference": "e8f47a327c2f0fd5aa04fa60af2b693006ed7283"
"reference": "9137eb3a3328e413212826d63eeeb0217836e2b6"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/e8f47a327c2f0fd5aa04fa60af2b693006ed7283",
"reference": "e8f47a327c2f0fd5aa04fa60af2b693006ed7283",
"url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/9137eb3a3328e413212826d63eeeb0217836e2b6",
"reference": "9137eb3a3328e413212826d63eeeb0217836e2b6",
"shasum": ""
},
"require": {
@ -2610,20 +2610,20 @@
],
"description": "Symfony EventDispatcher Component",
"homepage": "https://symfony.com",
"time": "2016-10-13T06:29:04+00:00"
"time": "2017-01-02T20:32:22+00:00"
},
{
"name": "symfony/options-resolver",
"version": "v3.2.1",
"version": "v3.2.2",
"source": {
"type": "git",
"url": "https://github.com/symfony/options-resolver.git",
"reference": "45940bcad6388b3b6058107eca67ced738d205bb"
"reference": "855429e3e9014b9dafee2a667de304c3aaa86fe6"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/options-resolver/zipball/45940bcad6388b3b6058107eca67ced738d205bb",
"reference": "45940bcad6388b3b6058107eca67ced738d205bb",
"url": "https://api.github.com/repos/symfony/options-resolver/zipball/855429e3e9014b9dafee2a667de304c3aaa86fe6",
"reference": "855429e3e9014b9dafee2a667de304c3aaa86fe6",
"shasum": ""
},
"require": {
@ -2664,7 +2664,7 @@
"configuration",
"options"
],
"time": "2016-05-13T18:13:23+00:00"
"time": "2017-01-02T20:32:22+00:00"
},
{
"name": "symfony/polyfill-mbstring",
@ -2727,16 +2727,16 @@
},
{
"name": "symfony/yaml",
"version": "v3.2.1",
"version": "v3.2.2",
"source": {
"type": "git",
"url": "https://github.com/symfony/yaml.git",
"reference": "a7095af4b97a0955f85c8989106c249fa649011f"
"reference": "50eadbd7926e31842893c957eca362b21592a97d"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/yaml/zipball/a7095af4b97a0955f85c8989106c249fa649011f",
"reference": "a7095af4b97a0955f85c8989106c249fa649011f",
"url": "https://api.github.com/repos/symfony/yaml/zipball/50eadbd7926e31842893c957eca362b21592a97d",
"reference": "50eadbd7926e31842893c957eca362b21592a97d",
"shasum": ""
},
"require": {
@ -2778,7 +2778,7 @@
],
"description": "Symfony Yaml Component",
"homepage": "https://symfony.com",
"time": "2016-12-10T10:07:06+00:00"
"time": "2017-01-03T13:51:32+00:00"
},
{
"name": "tedivm/stash",
@ -3325,26 +3325,28 @@
},
{
"name": "facebook/webdriver",
"version": "1.2.0",
"version": "1.3.0",
"source": {
"type": "git",
"url": "https://github.com/facebook/php-webdriver.git",
"reference": "af21de3ae5306a8ca0bcc02a19735dadc43e83f3"
"reference": "77300c4ab2025d4316635f592ec849ca7323bd8c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/facebook/php-webdriver/zipball/af21de3ae5306a8ca0bcc02a19735dadc43e83f3",
"reference": "af21de3ae5306a8ca0bcc02a19735dadc43e83f3",
"url": "https://api.github.com/repos/facebook/php-webdriver/zipball/77300c4ab2025d4316635f592ec849ca7323bd8c",
"reference": "77300c4ab2025d4316635f592ec849ca7323bd8c",
"shasum": ""
},
"require": {
"ext-curl": "*",
"php": "^5.5 || ~7.0"
"php": "^5.5 || ~7.0",
"symfony/process": "^2.8 || ^3.1"
},
"require-dev": {
"friendsofphp/php-cs-fixer": "^1.11",
"php-mock/php-mock-phpunit": "^1.1",
"phpunit/phpunit": "4.6.* || ~5.0",
"satooshi/php-coveralls": "^1.0",
"squizlabs/php_codesniffer": "^2.6"
},
"suggest": {
@ -3368,7 +3370,7 @@
"selenium",
"webdriver"
],
"time": "2016-10-14T15:16:51+00:00"
"time": "2017-01-13T15:48:08+00:00"
},
{
"name": "flow/jsonpath",
@ -4713,16 +4715,16 @@
},
{
"name": "symfony/browser-kit",
"version": "v3.2.1",
"version": "v3.2.2",
"source": {
"type": "git",
"url": "https://github.com/symfony/browser-kit.git",
"reference": "34348c2691ce6254e8e008026f4c5e72c22bb318"
"reference": "548f8230bad9f77463b20b15993a008f03e96db5"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/browser-kit/zipball/34348c2691ce6254e8e008026f4c5e72c22bb318",
"reference": "34348c2691ce6254e8e008026f4c5e72c22bb318",
"url": "https://api.github.com/repos/symfony/browser-kit/zipball/548f8230bad9f77463b20b15993a008f03e96db5",
"reference": "548f8230bad9f77463b20b15993a008f03e96db5",
"shasum": ""
},
"require": {
@ -4766,20 +4768,20 @@
],
"description": "Symfony BrowserKit Component",
"homepage": "https://symfony.com",
"time": "2016-10-13T13:35:11+00:00"
"time": "2017-01-02T20:32:22+00:00"
},
{
"name": "symfony/config",
"version": "v3.2.1",
"version": "v3.2.2",
"source": {
"type": "git",
"url": "https://github.com/symfony/config.git",
"reference": "b4ec9f099599cfc5b7f4d07bb2e910781a2be5e4"
"reference": "c5ea878b5a7f6a01b9a2f182f905831711b9ff3f"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/config/zipball/b4ec9f099599cfc5b7f4d07bb2e910781a2be5e4",
"reference": "b4ec9f099599cfc5b7f4d07bb2e910781a2be5e4",
"url": "https://api.github.com/repos/symfony/config/zipball/c5ea878b5a7f6a01b9a2f182f905831711b9ff3f",
"reference": "c5ea878b5a7f6a01b9a2f182f905831711b9ff3f",
"shasum": ""
},
"require": {
@ -4822,20 +4824,20 @@
],
"description": "Symfony Config Component",
"homepage": "https://symfony.com",
"time": "2016-12-09T07:45:17+00:00"
"time": "2017-01-02T20:32:22+00:00"
},
{
"name": "symfony/css-selector",
"version": "v3.2.1",
"version": "v3.2.2",
"source": {
"type": "git",
"url": "https://github.com/symfony/css-selector.git",
"reference": "e1241f275814827c411d922ba8e64cf2a00b2994"
"reference": "f0e628f04fc055c934b3211cfabdb1c59eefbfaa"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/css-selector/zipball/e1241f275814827c411d922ba8e64cf2a00b2994",
"reference": "e1241f275814827c411d922ba8e64cf2a00b2994",
"url": "https://api.github.com/repos/symfony/css-selector/zipball/f0e628f04fc055c934b3211cfabdb1c59eefbfaa",
"reference": "f0e628f04fc055c934b3211cfabdb1c59eefbfaa",
"shasum": ""
},
"require": {
@ -4875,20 +4877,20 @@
],
"description": "Symfony CssSelector Component",
"homepage": "https://symfony.com",
"time": "2016-11-03T08:11:03+00:00"
"time": "2017-01-02T20:32:22+00:00"
},
{
"name": "symfony/dom-crawler",
"version": "v3.2.1",
"version": "v3.2.2",
"source": {
"type": "git",
"url": "https://github.com/symfony/dom-crawler.git",
"reference": "1638c7534a8a2fa0bf9e979f9aacb6d7e8e9e24e"
"reference": "27d9790840a4efd3b7bb8f5f4f9efc27b36b7024"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/dom-crawler/zipball/1638c7534a8a2fa0bf9e979f9aacb6d7e8e9e24e",
"reference": "1638c7534a8a2fa0bf9e979f9aacb6d7e8e9e24e",
"url": "https://api.github.com/repos/symfony/dom-crawler/zipball/27d9790840a4efd3b7bb8f5f4f9efc27b36b7024",
"reference": "27d9790840a4efd3b7bb8f5f4f9efc27b36b7024",
"shasum": ""
},
"require": {
@ -4931,20 +4933,20 @@
],
"description": "Symfony DomCrawler Component",
"homepage": "https://symfony.com",
"time": "2016-12-10T14:24:53+00:00"
"time": "2017-01-02T20:32:22+00:00"
},
{
"name": "symfony/filesystem",
"version": "v3.2.1",
"version": "v3.2.2",
"source": {
"type": "git",
"url": "https://github.com/symfony/filesystem.git",
"reference": "8d4cf7561a5b17e5eb7a02b80d0b8f014a3796d4"
"reference": "a0c6ef2dc78d33b58d91d3a49f49797a184d06f4"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/filesystem/zipball/8d4cf7561a5b17e5eb7a02b80d0b8f014a3796d4",
"reference": "8d4cf7561a5b17e5eb7a02b80d0b8f014a3796d4",
"url": "https://api.github.com/repos/symfony/filesystem/zipball/a0c6ef2dc78d33b58d91d3a49f49797a184d06f4",
"reference": "a0c6ef2dc78d33b58d91d3a49f49797a184d06f4",
"shasum": ""
},
"require": {
@ -4980,20 +4982,20 @@
],
"description": "Symfony Filesystem Component",
"homepage": "https://symfony.com",
"time": "2016-11-24T00:46:43+00:00"
"time": "2017-01-08T20:47:33+00:00"
},
{
"name": "symfony/finder",
"version": "v3.2.1",
"version": "v3.2.2",
"source": {
"type": "git",
"url": "https://github.com/symfony/finder.git",
"reference": "a69cb5d455b4885ca376dc5bb3e1155cc8c08c4b"
"reference": "8c71141cae8e2957946b403cc71a67213c0380d6"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/finder/zipball/a69cb5d455b4885ca376dc5bb3e1155cc8c08c4b",
"reference": "a69cb5d455b4885ca376dc5bb3e1155cc8c08c4b",
"url": "https://api.github.com/repos/symfony/finder/zipball/8c71141cae8e2957946b403cc71a67213c0380d6",
"reference": "8c71141cae8e2957946b403cc71a67213c0380d6",
"shasum": ""
},
"require": {
@ -5029,20 +5031,69 @@
],
"description": "Symfony Finder Component",
"homepage": "https://symfony.com",
"time": "2016-12-13T09:39:43+00:00"
"time": "2017-01-02T20:32:22+00:00"
},
{
"name": "symfony/stopwatch",
"version": "v3.2.1",
"name": "symfony/process",
"version": "v3.2.2",
"source": {
"type": "git",
"url": "https://github.com/symfony/stopwatch.git",
"reference": "5b139e1c4290e6c7640ba80d9c9b5e49ef22b841"
"url": "https://github.com/symfony/process.git",
"reference": "350e810019fc52dd06ae844b6a6d382f8a0e8893"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/stopwatch/zipball/5b139e1c4290e6c7640ba80d9c9b5e49ef22b841",
"reference": "5b139e1c4290e6c7640ba80d9c9b5e49ef22b841",
"url": "https://api.github.com/repos/symfony/process/zipball/350e810019fc52dd06ae844b6a6d382f8a0e8893",
"reference": "350e810019fc52dd06ae844b6a6d382f8a0e8893",
"shasum": ""
},
"require": {
"php": ">=5.5.9"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "3.2-dev"
}
},
"autoload": {
"psr-4": {
"Symfony\\Component\\Process\\": ""
},
"exclude-from-classmap": [
"/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony Process Component",
"homepage": "https://symfony.com",
"time": "2017-01-02T20:32:22+00:00"
},
{
"name": "symfony/stopwatch",
"version": "v3.2.2",
"source": {
"type": "git",
"url": "https://github.com/symfony/stopwatch.git",
"reference": "9aa0b51889c01bca474853ef76e9394b02264464"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/stopwatch/zipball/9aa0b51889c01bca474853ef76e9394b02264464",
"reference": "9aa0b51889c01bca474853ef76e9394b02264464",
"shasum": ""
},
"require": {
@ -5078,7 +5129,7 @@
],
"description": "Symfony Stopwatch Component",
"homepage": "https://symfony.com",
"time": "2016-06-29T05:43:10+00:00"
"time": "2017-01-02T20:32:22+00:00"
},
{
"name": "webmozart/assert",

View File

@ -1,52 +1,9 @@
<?php
namespace Entity;
namespace Entity\Repository;
use Doctrine\Common\Collections\ArrayCollection;
use Entity;
/**
* @Table(name="role_permissions", uniqueConstraints={
* @UniqueConstraint(name="role_permission_unique_idx", columns={"role_id","action_name","station_id"})
* })
* @Entity(repositoryClass="RolePermissionRepository")
*/
class RolePermission extends \App\Doctrine\Entity
{
/**
* @Column(name="id", type="integer")
* @Id
* @GeneratedValue(strategy="IDENTITY")
*/
protected $id;
/** @Column(name="role_id", type="integer") */
protected $role_id;
/**
* @ManyToOne(targetEntity="Role", inversedBy="permissions")
* @JoinColumns({
* @JoinColumn(name="role_id", referencedColumnName="id", onDelete="CASCADE")
* })
*/
protected $role;
/** @Column(name="action_name", type="string", length=50, nullable=false) */
protected $action_name;
/** @Column(name="station_id", type="integer", nullable=true) */
protected $station_id;
/**
* @ManyToOne(targetEntity="Station")
* @JoinColumns({
* @JoinColumn(name="station_id", referencedColumnName="id", onDelete="CASCADE")
* })
*/
protected $station;
}
use App\Doctrine\Repository;
class RolePermissionRepository extends Repository
class RolePermissionRepository extends \App\Doctrine\Repository
{
public function getActionsForAllRoles()
{
@ -64,7 +21,7 @@ class RolePermissionRepository extends Repository
return $roles;
}
public function getActionsForRole(Role $role)
public function getActionsForRole(Entity\Role $role)
{
$role_has_action = $this->findBy(['role_id' => $role->id]);
@ -80,7 +37,7 @@ class RolePermissionRepository extends Repository
return $result;
}
public function setActionsForRole(Role $role, $post_values)
public function setActionsForRole(Entity\Role $role, $post_values)
{
$this->_em->createQuery('DELETE FROM '.$this->_entityName.' rp WHERE rp.role_id = :role_id')
->setParameter('role_id', $role->id)
@ -103,7 +60,7 @@ class RolePermissionRepository extends Repository
if ($post_key_id !== 'global')
$record_info['station_id'] = $post_key_id;
$record = new RolePermission;
$record = new Entity\RolePermission;
$record->fromArray($this->_em, $record_info);
$this->_em->persist($record);

View File

@ -1,28 +1,9 @@
<?php
namespace Entity;
namespace Entity\Repository;
use \Doctrine\ORM\Mapping as ORM;
use Entity;
/**
* @Table(name="settings")
* @Entity(repositoryClass="SettingsRepository")
*/
class Settings extends \App\Doctrine\Entity
{
/**
* @Column(name="setting_key", type="string", length=64)
* @Id
* @GeneratedValue(strategy="NONE")
*/
protected $setting_key;
/** @Column(name="setting_value", type="json", nullable=true) */
protected $setting_value;
}
use App\Doctrine\Repository;
class SettingsRepository extends Repository
class SettingsRepository extends \App\Doctrine\Repository
{
/**
* @param $settings
@ -44,9 +25,9 @@ class SettingsRepository extends Repository
{
$record = $this->findOneBy(['setting_key' => $key]);
if (!($record instanceof Settings))
if (!($record instanceof Entity\Settings))
{
$record = new Settings;
$record = new Entity\Settings;
$record->setting_key = $key;
}
@ -101,7 +82,7 @@ class SettingsRepository extends Repository
if (!$settings || !$cached)
{
$settings_raw = $this->_em->createQuery('SELECT s FROM Entity\Settings s ORDER BY s.setting_key ASC')
$settings_raw = $this->_em->createQuery('SELECT s FROM '.$this->_entityName.' s ORDER BY s.setting_key ASC')
->getArrayResult();
$settings = array();

View File

@ -1,102 +1,15 @@
<?php
namespace Entity;
namespace Entity\Repository;
use \Doctrine\Common\Collections\ArrayCollection;
use Entity;
/**
* @Table(name="song_history", indexes={
* @index(name="sort_idx", columns={"timestamp_start"}),
* })
* @Entity(repositoryClass="SongHistoryRepository")
*/
class SongHistory extends \App\Doctrine\Entity
{
public function __construct()
{
$this->timestamp_start = time();
$this->listeners_start = 0;
$this->timestamp_end = 0;
$this->listeners_end = 0;
$this->delta_total = 0;
$this->delta_negative = 0;
$this->delta_positive = 0;
}
/**
* @Column(name="id", type="integer")
* @Id
* @GeneratedValue(strategy="AUTO")
*/
protected $id;
/** @Column(name="song_id", type="string", length=50) */
protected $song_id;
/** @Column(name="station_id", type="integer") */
protected $station_id;
/** @Column(name="timestamp_start", type="integer") */
protected $timestamp_start;
public function getTimestamp()
{
return $this->timestamp_start;
}
/** @Column(name="listeners_start", type="integer", nullable=true) */
protected $listeners_start;
public function getListeners()
{
return $this->listeners_start;
}
/** @Column(name="timestamp_end", type="integer") */
protected $timestamp_end;
/** @Column(name="listeners_end", type="smallint", nullable=true) */
protected $listeners_end;
/** @Column(name="delta_total", type="smallint") */
protected $delta_total;
/** @Column(name="delta_positive", type="smallint") */
protected $delta_positive;
/** @Column(name="delta_negative", type="smallint") */
protected $delta_negative;
/** @Column(name="delta_points", type="json", nullable=true) */
protected $delta_points;
/**
* @ManyToOne(targetEntity="Song", inversedBy="history")
* @JoinColumns({
* @JoinColumn(name="song_id", referencedColumnName="id", onDelete="CASCADE")
* })
*/
protected $song;
/**
* @ManyToOne(targetEntity="Station", inversedBy="history")
* @JoinColumns({
* @JoinColumn(name="station_id", referencedColumnName="id", onDelete="CASCADE")
* })
*/
protected $station;
}
use App\Doctrine\Repository;
class SongHistoryRepository extends Repository
class SongHistoryRepository extends \App\Doctrine\Repository
{
/**
* @param int $num_entries
* @return array
*/
public function getHistoryForStation(\Entity\Station $station, $num_entries = 5)
public function getHistoryForStation(Entity\Station $station, $num_entries = 5)
{
$history = $this->_em->createQuery('SELECT sh, s FROM '.$this->_entityName.' sh JOIN sh.song s WHERE sh.station_id = :station_id ORDER BY sh.id DESC')
->setParameter('station_id', $station->id)
@ -108,7 +21,7 @@ class SongHistoryRepository extends Repository
{
$history = array(
'played_at' => $sh['timestamp_start'],
'song' => Song::api($sh['song']),
'song' => Entity\Song::api($sh['song']),
);
$return[] = $history;
}
@ -117,12 +30,12 @@ class SongHistoryRepository extends Repository
}
/**
* @param Song $song
* @param Station $station
* @param Entity\Song $song
* @param Entity\Station $station
* @param $np
* @return SongHistory|null
* @return Entity\SongHistory|null
*/
public function register(Song $song, Station $station, $np)
public function register(Entity\Song $song, Entity\Station $station, $np)
{
// Pull the most recent history item for this station.
$last_sh = $this->_em->createQuery('SELECT sh FROM Entity\SongHistory sh
@ -149,7 +62,7 @@ class SongHistoryRepository extends Repository
else
{
// Wrapping up processing on the previous SongHistory item (if present).
if ($last_sh instanceof SongHistory)
if ($last_sh instanceof Entity\SongHistory)
{
$last_sh->timestamp_end = time();
$last_sh->listeners_end = $listeners;
@ -185,7 +98,7 @@ class SongHistoryRepository extends Repository
}
// Processing a new SongHistory item.
$sh = new SongHistory;
$sh = new Entity\SongHistory;
$sh->song = $song;
$sh->station = $station;

View File

@ -0,0 +1,91 @@
<?php
namespace Entity\Repository;
use Entity;
class SongRepository extends \App\Doctrine\Repository
{
/**
* Return a song by its ID, including resolving merged song IDs.
*
* @param $song_hash
* @return null|object
*/
public function getById($song_hash)
{
$record = $this->find($song_hash);
if ($record instanceof Entity\Song)
{
if (!empty($record->merge_song_id))
return $this->getById($record->merge_song_id);
else
return $record;
}
return null;
}
/**
* Get a list of all song IDs.
*
* @return array
*/
public function getIds()
{
$ids_raw = $this->_em->createQuery('SELECT s.id FROM '.$this->_entityName.' s')
->getArrayResult();
return \Packaged\Helpers\Arrays::ipull($ids_raw, 'id');
}
public function getOrCreate($song_info, $is_radio_play = false)
{
$song_hash = Entity\Song::getSongHash($song_info);
$obj = $this->getById($song_hash);
if ($obj instanceof Entity\Song)
{
if ($is_radio_play)
{
$obj->last_played = time();
$obj->play_count += 1;
}
$this->_em->persist($obj);
$this->_em->flush();
return $obj;
}
else
{
if (!is_array($song_info))
$song_info = array('text' => $song_info);
$obj = new Entity\Song;
$obj->id = $song_hash;
if (empty($song_info['text']))
$song_info['text'] = $song_info['artist'].' - '.$song_info['title'];
$obj->text = $song_info['text'];
$obj->title = $song_info['title'];
$obj->artist = $song_info['artist'];
if (isset($song_info['image_url']))
$obj->image_url = $song_info['image_url'];
if ($is_radio_play)
{
$obj->last_played = time();
$obj->play_count = 1;
}
$this->_em->persist($obj);
$this->_em->flush();
return $obj;
}
}
}

View File

@ -0,0 +1,79 @@
<?php
namespace Entity\Repository;
use Entity;
class StationMediaRepository extends \App\Doctrine\Repository
{
/**
* @param Entity\Station $station
* @return array
*/
public function getRequestable(Entity\Station $station)
{
return $this->_em->createQuery('SELECT sm FROM '.$this->_entityName.' sm WHERE sm.station_id = :station_id ORDER BY sm.artist ASC, sm.title ASC')
->setParameter('station_id', $station->id)
->getArrayResult();
}
/**
* @param Entity\Station $station
* @param $artist_name
* @return array
*/
public function getByArtist(Entity\Station $station, $artist_name)
{
return $this->_em->createQuery('SELECT sm FROM '.$this->_entityName.' sm WHERE sm.station_id = :station_id AND sm.artist LIKE :artist ORDER BY sm.title ASC')
->setParameter('station_id', $station->id)
->setParameter('artist', $artist_name)
->getArrayResult();
}
/**
* @param Entity\Station $station
* @param $query
* @return array
*/
public function search(Entity\Station $station, $query)
{
$db = $this->_em->getConnection();
$table_name = $this->_em->getClassMetadata(__CLASS__)->getTableName();
$stmt = $db->executeQuery('SELECT sm.* FROM '.$db->quoteIdentifier($table_name).' AS sm WHERE sm.station_id = ? AND CONCAT(sm.title, \' \', sm.artist, \' \', sm.album) LIKE ?', array($station->id, '%'.addcslashes($query, "%_").'%'));
$results = $stmt->fetchAll();
return $results;
}
/**
* @param Entity\Station $station
* @param $path
* @return Entity\StationMedia
*/
public function getOrCreate(Entity\Station $station, $path)
{
$short_path = ltrim(str_replace($station->getRadioMediaDir(), '', $path), '/');
$record = $this->findOneBy(['station_id' => $station->id, 'path' => $short_path]);
if (!($record instanceof Entity\StationMedia))
{
$record = new Entity\StationMedia;
$record->station = $station;
$record->path = $short_path;
}
try
{
$song_info = $record->loadFromFile();
if (!empty($song_info))
$record->song = $this->_em->getRepository(Entity\Song::class)->getOrCreate($song_info);
}
catch(\Exception $e)
{
$record->moveToNotProcessed();
throw $e;
}
return $record;
}
}

View File

@ -0,0 +1,16 @@
<?php
namespace Entity\Repository;
use Entity;
class StationMountRepository extends \App\Doctrine\Repository
{
/**
* @param Entity\Station $station
* @return null|object
*/
public function getDefaultMount(Entity\Station $station)
{
return $this->findOneBy(['station_id' => $station->id, 'is_default' => true]);
}
}

View File

@ -0,0 +1,191 @@
<?php
namespace Entity\Repository;
use Entity;
use Interop\Container\ContainerInterface;
class StationRepository extends \App\Doctrine\Repository
{
/**
* @return mixed
*/
public function fetchAll()
{
return $this->_em->createQuery('SELECT s FROM '.$this->_entityName.' s ORDER BY s.name ASC')
->execute();
}
/**
* @param bool $cached
* @param null $order_by
* @param string $order_dir
* @return array
*/
public function fetchArray($cached = true, $order_by = NULL, $order_dir = 'ASC')
{
$stations = parent::fetchArray($cached, $order_by, $order_dir);
foreach($stations as &$station)
$station['short_name'] = Entity\Station::getStationShortName($station['name']);
return $stations;
}
/**
* @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 = array();
// 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.
$results = $this->fetchArray();
// 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;
}
/**
* @param bool $cached
* @return array
*/
public function getShortNameLookup($cached = true)
{
$stations = $this->fetchArray($cached);
$lookup = array();
foreach ($stations as $station)
$lookup[$station['short_name']] = $station;
return $lookup;
}
/**
* @param $short_code
* @return null|object
*/
public function findByShortCode($short_code)
{
$short_names = $this->getShortNameLookup();
if (isset($short_names[$short_code]))
{
$id = $short_names[$short_code]['id'];
return $this->find($id);
}
return NULL;
}
/**
* Create a station based on the specified data.
*
* @param $data
* @param ContainerInterface $di
* @return Entity\Station
*/
public function create($data, ContainerInterface $di)
{
$station = new Entity\Station;
$station->fromArray($this->_em, $data);
// Create path for station.
$station_base_dir = realpath(APP_INCLUDE_ROOT.'/..').'/stations';
$station_dir = $station_base_dir.'/'.$station->getShortName();
$station->setRadioBaseDir($station_dir);
$this->_em->persist($station);
// Generate station ID.
$this->_em->flush();
// Scan directory for any existing files.
$media_sync = new \AzuraCast\Sync\Media($di);
set_time_limit(600);
$media_sync->importMusic($station);
$this->_em->refresh($station);
$media_sync->importPlaylists($station);
$this->_em->refresh($station);
// Load adapters.
$frontend_adapter = $station->getFrontendAdapter($di);
$backend_adapter = $station->getBackendAdapter($di);
// Create default mountpoints if station supports them.
if ($frontend_adapter->supportsMounts())
{
// Create default mount points.
$mount_points = $frontend_adapter->getDefaultMounts();
foreach($mount_points as $mount_point)
{
$mount_point['station'] = $station;
$mount_record = new Entity\StationMount;
$mount_record->fromArray($this->_em, $mount_point);
$this->_em->persist($mount_record);
}
$this->_em->flush();
$this->_em->refresh($station);
}
// Load configuration from adapter to pull source and admin PWs.
$frontend_adapter->read();
// Write the adapter configurations and update supervisord.
$station->writeConfiguration($di);
// Save changes and continue to the last setup step.
$this->_em->persist($station);
$this->_em->flush();
return $station;
}
/**
* @param Entity\Station $station
* @param ContainerInterface $di
*/
public function destroy(Entity\Station $station, ContainerInterface $di)
{
$frontend = $station->getFrontendAdapter($di);
$backend = $station->getBackendAdapter($di);
if ($frontend->hasCommand() || $backend->hasCommand())
{
/** @var \Supervisor\Supervisor */
$supervisor = $di['supervisor'];
$frontend_name = $frontend->getProgramName();
list($frontend_group, $frontend_program) = explode(':', $frontend_name);
$supervisor->stopProcessGroup($frontend_group);
}
// Remove media folders.
$radio_dir = $station->getRadioBaseDir();
\App\Utilities::rmdir_recursive($radio_dir);
// Save changes and continue to the last setup step.
$this->_em->remove($station);
$this->_em->flush();
}
}

View File

@ -1,75 +1,20 @@
<?php
namespace Entity;
namespace Entity\Repository;
use \Doctrine\Common\Collections\ArrayCollection;
use Entity;
/**
* @Table(name="station_requests")
* @Entity(repositoryClass="StationRequestRepository")
*/
class StationRequest extends \App\Doctrine\Entity
{
public function __construct()
{
$this->timestamp = time();
$this->played_at = 0;
$this->ip = $_SERVER['REMOTE_ADDR'];
}
/**
* @Column(name="id", type="integer")
* @Id
* @GeneratedValue(strategy="IDENTITY")
*/
protected $id;
/** @Column(name="station_id", type="integer") */
protected $station_id;
/** @Column(name="track_id", type="integer") */
protected $track_id;
/** @Column(name="timestamp", type="integer") */
protected $timestamp;
/** @Column(name="played_at", type="integer") */
protected $played_at;
/** @Column(name="ip", type="string", length=40) */
protected $ip;
/**
* @ManyToOne(targetEntity="Station", inversedBy="media")
* @JoinColumns({
* @JoinColumn(name="station_id", referencedColumnName="id", onDelete="CASCADE")
* })
*/
protected $station;
/**
* @ManyToOne(targetEntity="StationMedia")
* @JoinColumns({
* @JoinColumn(name="track_id", referencedColumnName="id", onDelete="CASCADE")
* })
*/
protected $track;
}
use App\Doctrine\Repository;
class StationRequestRepository extends Repository
class StationRequestRepository extends \App\Doctrine\Repository
{
/**
* Submit a new request.
*
* @param Station $station
* @param Entity\Station $station
* @param $track_id
* @param bool $is_authenticated
* @return mixed
* @throws \App\Exception
*/
public function submit(Station $station, $track_id, $is_authenticated = false)
public function submit(Entity\Station $station, $track_id, $is_authenticated = false)
{
// Forbid web crawlers from using this feature.
if (\App\Utilities::is_crawler())
@ -80,10 +25,10 @@ class StationRequestRepository extends Repository
throw new \App\Exception('This station does not accept requests currently.');
// Verify that Track ID exists with station.
$media_repo = $this->_em->getRepository(StationMedia::class);
$media_repo = $this->_em->getRepository(Entity\StationMedia::class);
$media_item = $media_repo->findOneBy(array('id' => $track_id, 'station_id' => $station->id));
if (!($media_item instanceof StationMedia))
if (!($media_item instanceof Entity\StationMedia))
throw new \App\Exception('The song ID you specified could not be found in the station.');
// Check if the song is already enqueued as a request.
@ -131,7 +76,7 @@ class StationRequestRepository extends Repository
}
// Save request locally.
$record = new StationRequest;
$record = new Entity\StationRequest;
$record->track = $media_item;
$record->station = $station;

View File

@ -0,0 +1,33 @@
<?php
namespace Entity\Repository;
use Entity;
class StationStreamerRepository extends \App\Doctrine\Repository
{
/**
* Attempt to authenticate a streamer.
*
* @param Entity\Station $station
* @param $username
* @param $password
* @return bool
*/
public function authenticate(Entity\Station $station, $username, $password)
{
// Extra safety check for the station's streamer status.
if (!$station->enable_streamers)
return false;
$streamer = $this->findOneBy([
'station_id' => $station->id,
'streamer_username' => $username,
'is_active' => 1
]);
if (!($streamer instanceof Entity\StationStreamer))
return false;
return (strcmp($streamer->streamer_password, $password) === 0);
}
}

View File

@ -0,0 +1,45 @@
<?php
namespace Entity\Repository;
use Entity;
class UserRepository extends \App\Doctrine\Repository
{
/**
* @param $username
* @param $password
* @return bool|null|object
*/
public function authenticate($username, $password)
{
$login_info = $this->findOneBy(['email' => $username]);
if (!($login_info instanceof Entity\User))
return FALSE;
if ($login_info->verifyPassword($password))
return $login_info;
else
return FALSE;
}
/**
* Creates or returns an existing user with the specified e-mail address.
*
* @param $email
* @return Entity\User
*/
public function getOrCreate($email)
{
$user = $this->findOneBy(['email' => $email]);
if (!($user instanceof Entity\User))
{
$user = new Entity\User;
$user->email = $email;
$user->name = $email;
}
return $user;
}
}

View File

@ -0,0 +1,45 @@
<?php
namespace Entity;
use Doctrine\Common\Collections\ArrayCollection;
/**
* @Table(name="role_permissions", uniqueConstraints={
* @UniqueConstraint(name="role_permission_unique_idx", columns={"role_id","action_name","station_id"})
* })
* @Entity(repositoryClass="Entity\Repository\RolePermissionRepository")
*/
class RolePermission extends \App\Doctrine\Entity
{
/**
* @Column(name="id", type="integer")
* @Id
* @GeneratedValue(strategy="IDENTITY")
*/
protected $id;
/** @Column(name="role_id", type="integer") */
protected $role_id;
/**
* @ManyToOne(targetEntity="Role", inversedBy="permissions")
* @JoinColumns({
* @JoinColumn(name="role_id", referencedColumnName="id", onDelete="CASCADE")
* })
*/
protected $role;
/** @Column(name="action_name", type="string", length=50, nullable=false) */
protected $action_name;
/** @Column(name="station_id", type="integer", nullable=true) */
protected $station_id;
/**
* @ManyToOne(targetEntity="Station")
* @JoinColumns({
* @JoinColumn(name="station_id", referencedColumnName="id", onDelete="CASCADE")
* })
*/
protected $station;
}

21
src/Entity/Settings.php Normal file
View File

@ -0,0 +1,21 @@
<?php
namespace Entity;
use \Doctrine\ORM\Mapping as ORM;
/**
* @Table(name="settings")
* @Entity(repositoryClass="Entity\Repository\SettingsRepository")
*/
class Settings extends \App\Doctrine\Entity
{
/**
* @Column(name="setting_key", type="string", length=64)
* @Id
* @GeneratedValue(strategy="NONE")
*/
protected $setting_key;
/** @Column(name="setting_value", type="json", nullable=true) */
protected $setting_value;
}

View File

@ -7,7 +7,7 @@ use \Doctrine\Common\Collections\ArrayCollection;
* @Table(name="songs", indexes={
* @index(name="search_idx", columns={"text", "artist", "title"})
* })
* @Entity(repositoryClass="SongRepository")
* @Entity(repositoryClass="Entity\Repository\SongRepository")
* @HasLifecycleCallbacks
*/
class Song extends \App\Doctrine\Entity
@ -117,93 +117,4 @@ class Song extends \App\Doctrine\Entity
'last_played' => (int)$row['last_played'],
);
}
}
use App\Doctrine\Repository;
class SongRepository extends Repository
{
/**
* Return a song by its ID, including resolving merged song IDs.
*
* @param $song_hash
* @return null|object
*/
public function getById($song_hash)
{
$record = $this->find($song_hash);
if ($record instanceof Song)
{
if (!empty($record->merge_song_id))
return $this->getById($record->merge_song_id);
else
return $record;
}
return null;
}
/**
* Get a list of all song IDs.
*
* @return array
*/
public function getIds()
{
$ids_raw = $this->_em->createQuery('SELECT s.id FROM '.$this->_entityName.' s')
->getArrayResult();
return \Packaged\Helpers\Arrays::ipull($ids_raw, 'id');
}
public function getOrCreate($song_info, $is_radio_play = false)
{
$song_hash = Song::getSongHash($song_info);
$obj = $this->getById($song_hash);
if ($obj instanceof Song)
{
if ($is_radio_play)
{
$obj->last_played = time();
$obj->play_count += 1;
}
$this->_em->persist($obj);
$this->_em->flush();
return $obj;
}
else
{
if (!is_array($song_info))
$song_info = array('text' => $song_info);
$obj = new Song;
$obj->id = $song_hash;
if (empty($song_info['text']))
$song_info['text'] = $song_info['artist'].' - '.$song_info['title'];
$obj->text = $song_info['text'];
$obj->title = $song_info['title'];
$obj->artist = $song_info['artist'];
if (isset($song_info['image_url']))
$obj->image_url = $song_info['image_url'];
if ($is_radio_play)
{
$obj->last_played = time();
$obj->play_count = 1;
}
$this->_em->persist($obj);
$this->_em->flush();
return $obj;
}
}
}

View File

@ -0,0 +1,89 @@
<?php
namespace Entity;
use \Doctrine\Common\Collections\ArrayCollection;
/**
* @Table(name="song_history", indexes={
* @index(name="sort_idx", columns={"timestamp_start"}),
* })
* @Entity(repositoryClass="Entity\Repository\SongHistoryRepository")
*/
class SongHistory extends \App\Doctrine\Entity
{
public function __construct()
{
$this->timestamp_start = time();
$this->listeners_start = 0;
$this->timestamp_end = 0;
$this->listeners_end = 0;
$this->delta_total = 0;
$this->delta_negative = 0;
$this->delta_positive = 0;
}
/**
* @Column(name="id", type="integer")
* @Id
* @GeneratedValue(strategy="AUTO")
*/
protected $id;
/** @Column(name="song_id", type="string", length=50) */
protected $song_id;
/** @Column(name="station_id", type="integer") */
protected $station_id;
/** @Column(name="timestamp_start", type="integer") */
protected $timestamp_start;
public function getTimestamp()
{
return $this->timestamp_start;
}
/** @Column(name="listeners_start", type="integer", nullable=true) */
protected $listeners_start;
public function getListeners()
{
return $this->listeners_start;
}
/** @Column(name="timestamp_end", type="integer") */
protected $timestamp_end;
/** @Column(name="listeners_end", type="smallint", nullable=true) */
protected $listeners_end;
/** @Column(name="delta_total", type="smallint") */
protected $delta_total;
/** @Column(name="delta_positive", type="smallint") */
protected $delta_positive;
/** @Column(name="delta_negative", type="smallint") */
protected $delta_negative;
/** @Column(name="delta_points", type="json", nullable=true) */
protected $delta_points;
/**
* @ManyToOne(targetEntity="Song", inversedBy="history")
* @JoinColumns({
* @JoinColumn(name="song_id", referencedColumnName="id", onDelete="CASCADE")
* })
*/
protected $song;
/**
* @ManyToOne(targetEntity="Station", inversedBy="history")
* @JoinColumns({
* @JoinColumn(name="station_id", referencedColumnName="id", onDelete="CASCADE")
* })
*/
protected $station;
}

View File

@ -6,7 +6,7 @@ use Interop\Container\ContainerInterface;
/**
* @Table(name="station")
* @Entity(repositoryClass="StationRepository")
* @Entity(repositoryClass="Entity\Repository\StationRepository")
* @HasLifecycleCallbacks
*/
class Station extends \App\Doctrine\Entity
@ -379,192 +379,4 @@ class Station extends \App\Doctrine\Entity
return $api;
}
}
use App\Doctrine\Repository;
class StationRepository extends Repository
{
/**
* @return mixed
*/
public function fetchAll()
{
return $this->_em->createQuery('SELECT s FROM '.$this->_entityName.' s ORDER BY s.name ASC')
->execute();
}
/**
* @param bool $cached
* @param null $order_by
* @param string $order_dir
* @return array
*/
public function fetchArray($cached = true, $order_by = NULL, $order_dir = 'ASC')
{
$stations = parent::fetchArray($cached, $order_by, $order_dir);
foreach($stations as &$station)
$station['short_name'] = Station::getStationShortName($station['name']);
return $stations;
}
/**
* @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 = array();
// 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.
$results = $this->fetchArray();
// 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;
}
/**
* @param bool $cached
* @return array
*/
public function getShortNameLookup($cached = true)
{
$stations = $this->fetchArray($cached);
$lookup = array();
foreach ($stations as $station)
$lookup[$station['short_name']] = $station;
return $lookup;
}
/**
* @param $short_code
* @return null|object
*/
public function findByShortCode($short_code)
{
$short_names = $this->getShortNameLookup();
if (isset($short_names[$short_code]))
{
$id = $short_names[$short_code]['id'];
return $this->find($id);
}
return NULL;
}
/**
* Create a station based on the specified data.
*
* @param $data
* @param ContainerInterface $di
* @return Station
*/
public function create($data, ContainerInterface $di)
{
$station = new Station;
$station->fromArray($this->_em, $data);
// Create path for station.
$station_base_dir = realpath(APP_INCLUDE_ROOT.'/..').'/stations';
$station_dir = $station_base_dir.'/'.$station->getShortName();
$station->setRadioBaseDir($station_dir);
$this->_em->persist($station);
// Generate station ID.
$this->_em->flush();
// Scan directory for any existing files.
$media_sync = new \AzuraCast\Sync\Media($di);
set_time_limit(600);
$media_sync->importMusic($station);
$this->_em->refresh($station);
$media_sync->importPlaylists($station);
$this->_em->refresh($station);
// Load adapters.
$frontend_adapter = $station->getFrontendAdapter($di);
$backend_adapter = $station->getBackendAdapter($di);
// Create default mountpoints if station supports them.
if ($frontend_adapter->supportsMounts())
{
// Create default mount points.
$mount_points = $frontend_adapter->getDefaultMounts();
foreach($mount_points as $mount_point)
{
$mount_point['station'] = $station;
$mount_record = new StationMount;
$mount_record->fromArray($this->_em, $mount_point);
$this->_em->persist($mount_record);
}
$this->_em->flush();
$this->_em->refresh($station);
}
// Load configuration from adapter to pull source and admin PWs.
$frontend_adapter->read();
// Write the adapter configurations and update supervisord.
$station->writeConfiguration($di);
// Save changes and continue to the last setup step.
$this->_em->persist($station);
$this->_em->flush();
return $station;
}
/**
* @param Station $station
* @param ContainerInterface $di
*/
public function destroy(Station $station, ContainerInterface $di)
{
$frontend = $station->getFrontendAdapter($di);
$backend = $station->getBackendAdapter($di);
if ($frontend->hasCommand() || $backend->hasCommand())
{
/** @var \Supervisor\Supervisor */
$supervisor = $di['supervisor'];
$frontend_name = $frontend->getProgramName();
list($frontend_group, $frontend_program) = explode(':', $frontend_name);
$supervisor->stopProcessGroup($frontend_group);
}
// Remove media folders.
$radio_dir = $station->getRadioBaseDir();
\App\Utilities::rmdir_recursive($radio_dir);
// Save changes and continue to the last setup step.
$this->_em->remove($station);
$this->_em->flush();
}
}

View File

@ -10,7 +10,7 @@ use \Doctrine\Common\Collections\ArrayCollection;
* }, uniqueConstraints={
* @UniqueConstraint(name="path_unique_idx", columns={"path", "station_id"})
* })
* @Entity(repositoryClass="StationMediaRepository")
* @Entity(repositoryClass="Entity\Repository\StationMediaRepository")
* @HasLifecycleCallbacks
*/
class StationMedia extends \App\Doctrine\Entity
@ -218,81 +218,4 @@ class StationMedia extends \App\Doctrine\Entity
{
return ['mp3', 'ogg', 'm4a', 'flac'];
}
}
use App\Doctrine\Repository;
class StationMediaRepository extends Repository
{
/**
* @param Station $station
* @return array
*/
public function getRequestable(Station $station)
{
return $this->_em->createQuery('SELECT sm FROM '.$this->_entityName.' sm WHERE sm.station_id = :station_id ORDER BY sm.artist ASC, sm.title ASC')
->setParameter('station_id', $station->id)
->getArrayResult();
}
/**
* @param Station $station
* @param $artist_name
* @return array
*/
public function getByArtist(Station $station, $artist_name)
{
return $this->_em->createQuery('SELECT sm FROM '.$this->_entityName.' sm WHERE sm.station_id = :station_id AND sm.artist LIKE :artist ORDER BY sm.title ASC')
->setParameter('station_id', $station->id)
->setParameter('artist', $artist_name)
->getArrayResult();
}
/**
* @param Station $station
* @param $query
* @return array
*/
public function search(Station $station, $query)
{
$db = $this->_em->getConnection();
$table_name = $this->_em->getClassMetadata(__CLASS__)->getTableName();
$stmt = $db->executeQuery('SELECT sm.* FROM '.$db->quoteIdentifier($table_name).' AS sm WHERE sm.station_id = ? AND CONCAT(sm.title, \' \', sm.artist, \' \', sm.album) LIKE ?', array($station->id, '%'.addcslashes($query, "%_").'%'));
$results = $stmt->fetchAll();
return $results;
}
/**
* @param Station $station
* @param $path
* @return StationMedia
*/
public function getOrCreate(Station $station, $path)
{
$short_path = ltrim(str_replace($station->getRadioMediaDir(), '', $path), '/');
$record = $this->findOneBy(['station_id' => $station->id, 'path' => $short_path]);
if (!($record instanceof StationMedia))
{
$record = new StationMedia;
$record->station = $station;
$record->path = $short_path;
}
try
{
$song_info = $record->loadFromFile();
if (!empty($song_info))
$record->song = $this->_em->getRepository(Song::class)->getOrCreate($song_info);
}
catch(\Exception $e)
{
$record->moveToNotProcessed();
throw $e;
}
return $record;
}
}

View File

@ -5,7 +5,7 @@ use \Doctrine\Common\Collections\ArrayCollection;
/**
* @Table(name="station_mounts")
* @Entity(repositoryClass="StationMountRepository")
* @Entity(repositoryClass="Entity\Repository\StationMountRepository")
* @HasLifecycleCallbacks
*/
class StationMount extends \App\Doctrine\Entity
@ -70,14 +70,4 @@ class StationMount extends \App\Doctrine\Entity
* })
*/
protected $station;
}
use App\Doctrine\Repository;
class StationMountRepository extends Repository
{
public function getDefaultMount(Station $station)
{
return $this->findOneBy(['station_id' => $station->id, 'is_default' => true]);
}
}

View File

@ -0,0 +1,57 @@
<?php
namespace Entity;
use \Doctrine\Common\Collections\ArrayCollection;
/**
* @Table(name="station_requests")
* @Entity(repositoryClass="Entity\Repository\StationRequestRepository")
*/
class StationRequest extends \App\Doctrine\Entity
{
public function __construct()
{
$this->timestamp = time();
$this->played_at = 0;
$this->ip = $_SERVER['REMOTE_ADDR'];
}
/**
* @Column(name="id", type="integer")
* @Id
* @GeneratedValue(strategy="IDENTITY")
*/
protected $id;
/** @Column(name="station_id", type="integer") */
protected $station_id;
/** @Column(name="track_id", type="integer") */
protected $track_id;
/** @Column(name="timestamp", type="integer") */
protected $timestamp;
/** @Column(name="played_at", type="integer") */
protected $played_at;
/** @Column(name="ip", type="string", length=40) */
protected $ip;
/**
* @ManyToOne(targetEntity="Station", inversedBy="media")
* @JoinColumns({
* @JoinColumn(name="station_id", referencedColumnName="id", onDelete="CASCADE")
* })
*/
protected $station;
/**
* @ManyToOne(targetEntity="StationMedia")
* @JoinColumns({
* @JoinColumn(name="track_id", referencedColumnName="id", onDelete="CASCADE")
* })
*/
protected $track;
}

View File

@ -7,7 +7,7 @@ use \Doctrine\Common\Collections\ArrayCollection;
* Station streamers (DJ accounts) allowed to broadcast to a station.
*
* @Table(name="station_streamers")
* @Entity(repositoryClass="StationStreamerRepository")
* @Entity(repositoryClass="Entity\Repository\StationStreamerRepository")
* @HasLifecycleCallbacks
*/
class StationStreamer extends \App\Doctrine\Entity
@ -46,35 +46,4 @@ class StationStreamer extends \App\Doctrine\Entity
* })
*/
protected $station;
}
use App\Doctrine\Repository;
class StationStreamerRepository extends Repository
{
/**
* Attempt to authenticate a streamer.
*
* @param Station $station
* @param $username
* @param $password
* @return bool
*/
public function authenticate(Station $station, $username, $password)
{
// Extra safety check for the station's streamer status.
if (!$station->enable_streamers)
return false;
$streamer = $this->findOneBy([
'station_id' => $station->id,
'streamer_username' => $username,
'is_active' => 1
]);
if (!($streamer instanceof StationStreamer))
return false;
return (strcmp($streamer->streamer_password, $password) === 0);
}
}

View File

@ -6,7 +6,7 @@ use \Doctrine\Common\Collections\ArrayCollection;
/**
* @Table(name="users")
* @Entity(repositoryClass="UserRepository")
* @Entity(repositoryClass="Entity\Repository\UserRepository")
* @HasLifecycleCallbacks
*/
class User extends \App\Doctrine\Entity
@ -94,47 +94,4 @@ class User extends \App\Doctrine\Entity
* )
*/
protected $roles;
}
use App\Doctrine\Repository;
class UserRepository extends Repository
{
/**
* @param $username
* @param $password
* @return bool|null|object
*/
public function authenticate($username, $password)
{
$login_info = $this->findOneBy(['email' => $username]);
if (!($login_info instanceof User))
return FALSE;
if ($login_info->verifyPassword($password))
return $login_info;
else
return FALSE;
}
/**
* Creates or returns an existing user with the specified e-mail address.
*
* @param $email
* @return User
*/
public function getOrCreate($email)
{
$user = $this->findOneBy(['email' => $email]);
if (!($user instanceof User))
{
$user = new User;
$user->email = $email;
$user->name = $email;
}
return $user;
}
}