Project restructure + lazy loading dependency stuff.
This commit is contained in:
parent
740a957e1a
commit
28b719bead
31 changed files with 339 additions and 191 deletions
composer.lockmince.php
public
src
Clients
AccountLinkInfo.phpAccountLinksData.phpAuthorisationInfo.phpAuthorisationsData.phpClientsContext.phpClientsRoutes.phpVerificationInfo.phpVerificationsData.php
DatabaseContext.phpHomeRoutes.phpMinceContext.phpRoutingContext.phpRoutingErrorHandler.phpRpcRoutes.phpServers
Skins
Users
tools
6
composer.lock
generated
6
composer.lock
generated
|
@ -174,11 +174,11 @@
|
|||
},
|
||||
{
|
||||
"name": "flashwave/index",
|
||||
"version": "v0.2501.220016",
|
||||
"version": "v0.2501.221237",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://patchii.net/flash/index.git",
|
||||
"reference": "94107b7130a95e04c35291bdfcae4daeabc40abd"
|
||||
"reference": "fee9a65e3bca341be7401fe2e21b795630f15f2a"
|
||||
},
|
||||
"require": {
|
||||
"ext-mbstring": "*",
|
||||
|
@ -225,7 +225,7 @@
|
|||
],
|
||||
"description": "Composer package for the common library for my projects.",
|
||||
"homepage": "https://railgun.sh/index",
|
||||
"time": "2025-01-22T00:16:30+00:00"
|
||||
"time": "2025-01-22T12:38:11+00:00"
|
||||
},
|
||||
{
|
||||
"name": "guzzlehttp/psr7",
|
||||
|
|
|
@ -34,5 +34,4 @@ if($cfg->hasValues('sentry:dsn'))
|
|||
});
|
||||
})($cfg->scopeTo('sentry'));
|
||||
|
||||
$db = DbBackends::create($cfg->getString('database:dsn', 'null:'));
|
||||
$db->execute('SET SESSION time_zone = \'+00:00\', sql_mode = \'STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION\';');
|
||||
$mince = new MinceContext($cfg);
|
||||
|
|
|
@ -1,85 +1,6 @@
|
|||
<?php
|
||||
namespace Mince;
|
||||
|
||||
use RuntimeException;
|
||||
use Flashii\{FlashiiClient,FlashiiUrls};
|
||||
use Flashii\Credentials\MisuzuCredentials;
|
||||
use Index\{CsrfToken,Dependencies};
|
||||
use Index\Http\Routing\HttpRouter;
|
||||
use Index\Templating\TplEnvironment;
|
||||
use Index\Urls\{ArrayUrlRegistry,UrlRegistry};
|
||||
|
||||
require_once __DIR__ . '/../mince.php';
|
||||
|
||||
// replace this with id.flashii.net shit
|
||||
$authToken = (string)filter_input(INPUT_COOKIE, 'msz_auth');
|
||||
|
||||
$flashii = new FlashiiClient('Mince', new MisuzuCredentials($authToken), new FlashiiUrls(
|
||||
$cfg->getString('apii:api', FlashiiUrls::PROD_API_URL)
|
||||
));
|
||||
|
||||
$deps = new Dependencies;
|
||||
$deps->register($db);
|
||||
$deps->register(AccountLinks::class);
|
||||
$deps->register(ArrayUrlRegistry::class);
|
||||
$deps->register(Authorisations::class);
|
||||
$deps->register(Capes::class);
|
||||
$deps->register(Servers::class);
|
||||
$deps->register(Skins::class);
|
||||
$deps->register(new TplEnvironment(MCR_DIR_TPL, ['Mince'], debug: MCR_DEBUG));
|
||||
$deps->register(Users::class);
|
||||
$deps->register(Verifications::class);
|
||||
|
||||
$users = $deps->resolve(Users::class);
|
||||
|
||||
try {
|
||||
$authInfo = $flashii->v1()->me();
|
||||
$deps->register($authInfo);
|
||||
$users->syncApiUser($authInfo);
|
||||
$userInfo = $users->getUser($authInfo->getId());
|
||||
} catch(RuntimeException $ex) {
|
||||
$authInfo = $sUserInfo = null;
|
||||
}
|
||||
|
||||
$deps->register($csrfp = new CsrfToken(
|
||||
$cfg->getString('csrfp:secret', 'wowof'),
|
||||
$authInfo === null ? $_SERVER['REMOTE_ADDR'] : $authToken
|
||||
));
|
||||
|
||||
$templating = $deps->resolve(TplEnvironment::class);
|
||||
$templating->addGlobal('globals', [
|
||||
'title' => 'Flashii Minecraft Servers',
|
||||
'is_authed' => $userInfo !== null,
|
||||
'user' => $userInfo,
|
||||
'csrfp' => $csrfp->createToken(),
|
||||
]);
|
||||
|
||||
$accountLinks = $deps->resolve(AccountLinks::class);
|
||||
$authorisations = $deps->resolve(Authorisations::class);
|
||||
$authorisations->prune();
|
||||
$verifications = $deps->resolve(Verifications::class);
|
||||
$verifications->prune();
|
||||
|
||||
$urls = $deps->resolve(UrlRegistry::class);
|
||||
$templating->addFunction('url', $urls->format(...));
|
||||
|
||||
$router = new HttpRouter(errorHandler: new RouterErrorHandler($templating));
|
||||
$router->use('/', function($response, $request) { $response->setPoweredBy('Mince'); });
|
||||
|
||||
$router->register($deps->construct(RpcRoutes::class, secretKey: $cfg->getString('rpc:secret'), clientsUrl: $cfg->getString('urls:clients')));
|
||||
|
||||
$homeRoutes = $deps->construct(HomeRoutes::class, loginUrl: $cfg->getString('site:login'));
|
||||
$router->register($homeRoutes);
|
||||
$urls->register($homeRoutes);
|
||||
|
||||
$clientRoutes = $deps->construct(ClientsRoutes::class);
|
||||
$router->register($clientRoutes);
|
||||
$urls->register($clientRoutes);
|
||||
|
||||
$skinsRoutes = $deps->construct(SkinsRoutes::class, baseUrl: $cfg->getString('urls:skins_base'));
|
||||
$router->register($skinsRoutes);
|
||||
$urls->register($skinsRoutes);
|
||||
|
||||
MojangInterop::registerRoutes($router);
|
||||
|
||||
$router->dispatch();
|
||||
$mince->createRouting()->dispatch();
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<?php
|
||||
namespace Mince;
|
||||
namespace Mince\Clients;
|
||||
|
||||
use Carbon\CarbonImmutable;
|
||||
use Index\Db\DbResult;
|
|
@ -1,12 +1,13 @@
|
|||
<?php
|
||||
namespace Mince;
|
||||
namespace Mince\Clients;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use RuntimeException;
|
||||
use Index\Db\{DbConnection,DbStatementCache};
|
||||
use Mince\Users\UserInfo;
|
||||
use Ramsey\Uuid\UuidInterface;
|
||||
|
||||
class AccountLinks {
|
||||
class AccountLinksData {
|
||||
private DbStatementCache $cache;
|
||||
|
||||
public function __construct(DbConnection $dbConn) {
|
|
@ -1,5 +1,5 @@
|
|||
<?php
|
||||
namespace Mince;
|
||||
namespace Mince\Clients;
|
||||
|
||||
use Carbon\CarbonImmutable;
|
||||
use Index\Db\DbResult;
|
|
@ -1,12 +1,12 @@
|
|||
<?php
|
||||
namespace Mince;
|
||||
namespace Mince\Clients;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use RuntimeException;
|
||||
use Index\Db\{DbConnection,DbStatementCache};
|
||||
use Ramsey\Uuid\UuidInterface;
|
||||
|
||||
class Authorisations {
|
||||
class AuthorisationsData {
|
||||
private DbStatementCache $cache;
|
||||
|
||||
public function __construct(
|
31
src/Clients/ClientsContext.php
Normal file
31
src/Clients/ClientsContext.php
Normal file
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
namespace Mince\Clients;
|
||||
|
||||
use Index\Dependencies;
|
||||
use Index\Http\Routing\{RouteHandler,Router};
|
||||
use Index\Urls\{UrlRegistry,UrlSource};
|
||||
|
||||
class ClientsContext implements RouteHandler, UrlSource {
|
||||
public private(set) AccountLinksData $accountLinks;
|
||||
public private(set) AuthorisationsData $authorisations;
|
||||
public private(set) VerificationsData $verifications;
|
||||
public private(set) ClientsRoutes $routes;
|
||||
|
||||
public function __construct(Dependencies $deps) {
|
||||
// TODO: the prune calls should be in a cron script
|
||||
$this->accountLinks = $deps->constructLazy(AccountLinksData::class);
|
||||
$this->authorisations = $deps->constructLazy(AuthorisationsData::class);
|
||||
$this->authorisations->prune();
|
||||
$this->verifications = $deps->constructLazy(VerificationsData::class);
|
||||
$this->verifications->prune();
|
||||
$this->routes = $deps->constructLazy(ClientsRoutes::class);
|
||||
}
|
||||
|
||||
public function registerRoutes(Router $router): void {
|
||||
$router->register($this->routes);
|
||||
}
|
||||
|
||||
public function registerUrls(UrlRegistry $registry): void {
|
||||
$registry->register($this->routes);
|
||||
}
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
<?php
|
||||
namespace Mince;
|
||||
namespace Mince\Clients;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use RuntimeException;
|
||||
|
@ -17,9 +17,7 @@ class ClientsRoutes implements RouteHandler, UrlSource {
|
|||
public function __construct(
|
||||
private TplEnvironment $templating,
|
||||
private UrlRegistry $urls,
|
||||
private AccountLinks $accountLinks,
|
||||
private Authorisations $authorisations,
|
||||
private Verifications $verifications,
|
||||
private ClientsContext $clientsCtx,
|
||||
private CsrfToken $csrfp,
|
||||
private ?V1User $authInfo
|
||||
) {}
|
||||
|
@ -67,8 +65,8 @@ class ClientsRoutes implements RouteHandler, UrlSource {
|
|||
}
|
||||
|
||||
try {
|
||||
$linkInfo = $this->accountLinks->getLink(userInfo: $this->authInfo->getId());
|
||||
$clients = iterator_to_array($this->authorisations->getAuthorisations($linkInfo), false);
|
||||
$linkInfo = $this->clientsCtx->accountLinks->getLink(userInfo: $this->authInfo->getId());
|
||||
$clients = iterator_to_array($this->clientsCtx->authorisations->getAuthorisations($linkInfo), false);
|
||||
|
||||
$template->setVars([
|
||||
'link' => $linkInfo,
|
||||
|
@ -82,7 +80,7 @@ class ClientsRoutes implements RouteHandler, UrlSource {
|
|||
#[HttpPost('/clients/link')]
|
||||
#[UrlFormat('clients:link', '/clients/link')]
|
||||
public function postLink(HttpResponseBuilder $response, HttpRequest $request) {
|
||||
if($this->accountLinks->checkHasLink($this->authInfo->getId())) {
|
||||
if($this->clientsCtx->accountLinks->checkHasLink($this->authInfo->getId())) {
|
||||
$response->redirect($this->urls->format('clients:index', ['error' => 'link:already']));
|
||||
return;
|
||||
}
|
||||
|
@ -96,15 +94,15 @@ class ClientsRoutes implements RouteHandler, UrlSource {
|
|||
$code = strtr(strtoupper($code), '0189', 'OIBG');
|
||||
|
||||
try {
|
||||
$verifyInfo = $this->verifications->getVerification(code: $code);
|
||||
$verifyInfo = $this->clientsCtx->verifications->getVerification(code: $code);
|
||||
} catch(RuntimeException $ex) {
|
||||
$response->redirect($this->urls->format('clients:index', ['error' => 'link:code']));
|
||||
return;
|
||||
}
|
||||
|
||||
$this->verifications->deleteVerification($verifyInfo);
|
||||
$this->accountLinks->createLink($this->authInfo->getId(), $verifyInfo);
|
||||
$this->authorisations->createAuthorisation($verifyInfo, grant: true);
|
||||
$this->clientsCtx->verifications->deleteVerification($verifyInfo);
|
||||
$this->clientsCtx->accountLinks->createLink($this->authInfo->getId(), $verifyInfo);
|
||||
$this->clientsCtx->authorisations->createAuthorisation($verifyInfo, grant: true);
|
||||
|
||||
$response->redirect($this->urls->format('clients:index'));
|
||||
}
|
||||
|
@ -112,7 +110,7 @@ class ClientsRoutes implements RouteHandler, UrlSource {
|
|||
#[HttpPost('/clients/unlink')]
|
||||
#[UrlFormat('clients:unlink', '/clients/unlink')]
|
||||
public function postUnlink(HttpResponseBuilder $response) {
|
||||
$this->accountLinks->deleteLink(userInfo: $this->authInfo->getId());
|
||||
$this->clientsCtx->accountLinks->deleteLink(userInfo: $this->authInfo->getId());
|
||||
$response->redirect($this->urls->format('clients:index'));
|
||||
}
|
||||
|
||||
|
@ -124,13 +122,13 @@ class ClientsRoutes implements RouteHandler, UrlSource {
|
|||
return 404;
|
||||
|
||||
try {
|
||||
$linkInfo = $this->accountLinks->getLink(userInfo: $this->authInfo->getId());
|
||||
$linkInfo = $this->clientsCtx->accountLinks->getLink(userInfo: $this->authInfo->getId());
|
||||
} catch(RuntimeException $ex) {
|
||||
return 403;
|
||||
}
|
||||
|
||||
try {
|
||||
$authInfo = $this->authorisations->getAuthorisation(authId: $authId);
|
||||
$authInfo = $this->clientsCtx->authorisations->getAuthorisation(authId: $authId);
|
||||
} catch(RuntimeException $ex) {
|
||||
return 403;
|
||||
}
|
||||
|
@ -140,7 +138,7 @@ class ClientsRoutes implements RouteHandler, UrlSource {
|
|||
if($authInfo->granted)
|
||||
return 404;
|
||||
|
||||
$this->authorisations->setAuthorisationGranted($authInfo);
|
||||
$this->clientsCtx->authorisations->setAuthorisationGranted($authInfo);
|
||||
|
||||
$response->redirect($this->urls->format('clients:index'));
|
||||
}
|
||||
|
@ -153,18 +151,18 @@ class ClientsRoutes implements RouteHandler, UrlSource {
|
|||
return 404;
|
||||
|
||||
try {
|
||||
$linkInfo = $this->accountLinks->getLink(userInfo: $this->authInfo->getId());
|
||||
$linkInfo = $this->clientsCtx->accountLinks->getLink(userInfo: $this->authInfo->getId());
|
||||
} catch(RuntimeException $ex) {
|
||||
return 403;
|
||||
}
|
||||
|
||||
if($authId === 'all') {
|
||||
$this->authorisations->deleteAuthorisations(uuid: $linkInfo);
|
||||
$this->clientsCtx->authorisations->deleteAuthorisations(uuid: $linkInfo);
|
||||
} elseif($authId === 'pending') {
|
||||
$this->authorisations->deleteAuthorisations(uuid: $linkInfo, pending: true);
|
||||
$this->clientsCtx->authorisations->deleteAuthorisations(uuid: $linkInfo, pending: true);
|
||||
} else {
|
||||
try {
|
||||
$authInfo = $this->authorisations->getAuthorisation(authId: $authId);
|
||||
$authInfo = $this->clientsCtx->authorisations->getAuthorisation(authId: $authId);
|
||||
} catch(RuntimeException $ex) {
|
||||
return 403;
|
||||
}
|
||||
|
@ -172,7 +170,7 @@ class ClientsRoutes implements RouteHandler, UrlSource {
|
|||
if($authInfo->uuidRaw !== $linkInfo->uuidRaw)
|
||||
return 403;
|
||||
|
||||
$this->authorisations->deleteAuthorisations(authInfo: $authInfo);
|
||||
$this->clientsCtx->authorisations->deleteAuthorisations(authInfo: $authInfo);
|
||||
}
|
||||
|
||||
$response->redirect($this->urls->format('clients:index'));
|
|
@ -1,5 +1,5 @@
|
|||
<?php
|
||||
namespace Mince;
|
||||
namespace Mince\Clients;
|
||||
|
||||
use Carbon\CarbonImmutable;
|
||||
use Index\Db\DbResult;
|
|
@ -1,5 +1,5 @@
|
|||
<?php
|
||||
namespace Mince;
|
||||
namespace Mince\Clients;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use RuntimeException;
|
||||
|
@ -7,7 +7,7 @@ use Index\XString;
|
|||
use Index\Db\{DbConnection,DbStatementCache};
|
||||
use Ramsey\Uuid\UuidInterface;
|
||||
|
||||
class Verifications {
|
||||
class VerificationsData {
|
||||
private const CODE_CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567';
|
||||
|
||||
private DbStatementCache $cache;
|
28
src/DatabaseContext.php
Normal file
28
src/DatabaseContext.php
Normal file
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
namespace Mince;
|
||||
|
||||
use Index\Config\Config;
|
||||
use Index\Db\{DbBackends,DbConnection};
|
||||
use Index\Db\Migration\{DbMigrationManager,DbMigrationRepo,FsDbMigrationRepo};
|
||||
|
||||
class DatabaseContext {
|
||||
public private(set) DbConnection $conn;
|
||||
|
||||
public function __construct(Config $config) {
|
||||
$this->conn = DbBackends::create($config->getString('dsn', 'null:'));
|
||||
$this->conn->execute('SET SESSION time_zone = \'+00:00\', sql_mode = \'STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION\';');
|
||||
}
|
||||
|
||||
public function getQueryCount(): int {
|
||||
$result = $this->conn->query('SHOW SESSION STATUS LIKE "Questions"');
|
||||
return $result->next() ? $result->getInteger(1) : 0;
|
||||
}
|
||||
|
||||
public function createMigrationManager(): DbMigrationManager {
|
||||
return new DbMigrationManager($this->conn);
|
||||
}
|
||||
|
||||
public function createMigrationRepo(): DbMigrationRepo {
|
||||
return new FsDbMigrationRepo(MCR_DIR_MIG);
|
||||
}
|
||||
}
|
|
@ -6,6 +6,7 @@ use Index\Http\HttpResponseBuilder;
|
|||
use Index\Http\Routing\{HttpGet,RouteHandler,RouteHandlerCommon};
|
||||
use Index\Urls\{UrlFormat,UrlRegistry,UrlSource,UrlSourceCommon};
|
||||
use Index\Templating\TplEnvironment;
|
||||
use Mince\Servers\ServersContext;
|
||||
|
||||
class HomeRoutes implements RouteHandler, UrlSource {
|
||||
use RouteHandlerCommon, UrlSourceCommon;
|
||||
|
@ -13,7 +14,7 @@ class HomeRoutes implements RouteHandler, UrlSource {
|
|||
public function __construct(
|
||||
private TplEnvironment $templating,
|
||||
private UrlRegistry $urls,
|
||||
private Servers $servers,
|
||||
private ServersContext $serversCtx,
|
||||
private ?V1User $authInfo,
|
||||
private string $loginUrl
|
||||
) {}
|
||||
|
@ -22,7 +23,7 @@ class HomeRoutes implements RouteHandler, UrlSource {
|
|||
#[UrlFormat('index', '/')]
|
||||
public function getIndex() {
|
||||
return $this->templating->render('index', [
|
||||
'servers' => iterator_to_array($this->servers->getServers(deleted: false), false),
|
||||
'servers' => iterator_to_array($this->serversCtx->servers->getServers(deleted: false), false),
|
||||
]);
|
||||
}
|
||||
|
||||
|
|
89
src/MinceContext.php
Normal file
89
src/MinceContext.php
Normal file
|
@ -0,0 +1,89 @@
|
|||
<?php
|
||||
namespace Mince;
|
||||
|
||||
use Flashii\{FlashiiClient,FlashiiUrls};
|
||||
use Flashii\Credentials\MisuzuCredentials;
|
||||
use Index\{CsrfToken,Dependencies};
|
||||
use Index\Config\Config;
|
||||
use Index\Db\DbConnection;
|
||||
use Index\Http\{HttpResponseBuilder,HttpRequest};
|
||||
use Index\Http\Routing\RouteHandler;
|
||||
use Index\Templating\TplEnvironment;
|
||||
use Index\Urls\UrlSource;
|
||||
|
||||
class MinceContext {
|
||||
public private(set) Dependencies $deps;
|
||||
|
||||
public private(set) DatabaseContext $dbCtx;
|
||||
public private(set) Clients\ClientsContext $clientsCtx;
|
||||
public private(set) Servers\ServersContext $serversCtx;
|
||||
public private(set) Skins\SkinsContext $skinsCtx;
|
||||
public private(set) Users\UsersContext $usersCtx;
|
||||
|
||||
public function __construct(
|
||||
private Config $config
|
||||
) {
|
||||
$this->deps = new Dependencies;
|
||||
$this->deps->register($this->deps);
|
||||
$this->deps->register($config);
|
||||
$this->deps->register($this->dbCtx = $this->deps->construct(DatabaseContext::class, config: $config->scopeTo('database')));
|
||||
$this->deps->register($this->dbCtx->conn);
|
||||
$this->deps->register($this->clientsCtx = $this->deps->constructLazy(Clients\ClientsContext::class));
|
||||
$this->deps->register($this->serversCtx = $this->deps->constructLazy(Servers\ServersContext::class));
|
||||
$this->deps->register($this->skinsCtx = $this->deps->constructLazy(Skins\SkinsContext::class));
|
||||
$this->deps->register($this->usersCtx = $this->deps->constructLazy(Users\UsersContext::class));
|
||||
}
|
||||
|
||||
public function createRouting(): RoutingContext {
|
||||
$this->deps->register($templating = new TplEnvironment(MCR_DIR_TPL, ['Mince'], debug: MCR_DEBUG));
|
||||
|
||||
$routingCtx = $this->deps->construct(RoutingContext::class);
|
||||
$templating->addFunction('url', $routingCtx->urls->format(...));
|
||||
$this->deps->register($routingCtx->router);
|
||||
$this->deps->register($routingCtx->urls);
|
||||
|
||||
$routingCtx->router->use('/', function(HttpResponseBuilder $response, HttpRequest $request) use ($templating) {
|
||||
$authToken = (string)$request->getCookie('msz_auth');
|
||||
if(empty($authToken)) {
|
||||
$csrfSecret = $request->remoteAddress;
|
||||
$userInfo = null;
|
||||
} else {
|
||||
$flashii = new FlashiiClient('Mince', new MisuzuCredentials($authToken), new FlashiiUrls(
|
||||
$this->config->getString('apii:api', FlashiiUrls::PROD_API_URL)
|
||||
));
|
||||
|
||||
try {
|
||||
$authInfo = $flashii->v1()->me();
|
||||
$this->deps->register($authInfo);
|
||||
$this->usersCtx->users->syncApiUser($authInfo);
|
||||
$userInfo = $this->usersCtx->users->getUser($authInfo->getId());
|
||||
$csrfSecret = $authToken;
|
||||
} catch(RuntimeException $ex) {
|
||||
$userInfo = null;
|
||||
}
|
||||
}
|
||||
|
||||
$this->deps->register($csrfToken = new CsrfToken(
|
||||
$this->config->getString('csrfp:secret', 'wowof'), $csrfSecret
|
||||
));
|
||||
|
||||
$templating->addGlobal('globals', [
|
||||
'title' => 'Flashii Minecraft Servers',
|
||||
'is_authed' => $userInfo !== null,
|
||||
'user' => $userInfo,
|
||||
'csrfp' => $csrfToken->createToken(),
|
||||
]);
|
||||
});
|
||||
|
||||
$routingCtx->register($this->deps->construct(RpcRoutes::class, secretKey: $this->config->getString('rpc:secret'), clientsUrl: $this->config->getString('urls:clients')));
|
||||
$routingCtx->register($this->deps->construct(HomeRoutes::class, loginUrl: $this->config->getString('site:login')));
|
||||
|
||||
$handlers = array_unique($this->deps->all(RouteHandler::class) + $this->deps->all(UrlSource::class), SORT_REGULAR);
|
||||
foreach($handlers as $handler)
|
||||
$routingCtx->register($handler);
|
||||
|
||||
MojangInterop::registerRoutes($routingCtx->router);
|
||||
|
||||
return $routingCtx;
|
||||
}
|
||||
}
|
30
src/RoutingContext.php
Normal file
30
src/RoutingContext.php
Normal file
|
@ -0,0 +1,30 @@
|
|||
<?php
|
||||
namespace Mince;
|
||||
|
||||
use Index\Http\{HttpResponseBuilder,HttpRequest};
|
||||
use Index\Http\Routing\{HttpRouter,Router,RouteHandler};
|
||||
use Index\Urls\{ArrayUrlRegistry,UrlRegistry,UrlSource};
|
||||
use Index\Templating\TplEnvironment;
|
||||
|
||||
class RoutingContext {
|
||||
public private(set) UrlRegistry $urls;
|
||||
public private(set) HttpRouter $router;
|
||||
|
||||
public function __construct(TplEnvironment $templating) {
|
||||
$this->urls = new ArrayUrlRegistry;
|
||||
$this->router = new HttpRouter(errorHandler: new RoutingErrorHandler($templating));
|
||||
$this->router->use('/', fn(HttpResponseBuilder $resp) => $resp->setPoweredBy('Mince'));
|
||||
}
|
||||
|
||||
public function register(RouteHandler|UrlSource $handler): void {
|
||||
if($handler instanceof RouteHandler)
|
||||
$this->router->register($handler);
|
||||
if($handler instanceof UrlSource)
|
||||
$this->urls->register($handler);
|
||||
}
|
||||
|
||||
/** @param mixed[] $args */
|
||||
public function dispatch(?HttpRequest $request = null, array $args = []): void {
|
||||
$this->router->dispatch($request, $args);
|
||||
}
|
||||
}
|
|
@ -4,7 +4,7 @@ namespace Mince;
|
|||
use Index\Http\{HttpErrorHandler,HttpResponseBuilder,HttpRequest};
|
||||
use Index\Templating\TplEnvironment;
|
||||
|
||||
class RouterErrorHandler implements HttpErrorHandler {
|
||||
class RoutingErrorHandler implements HttpErrorHandler {
|
||||
public function __construct(
|
||||
private TplEnvironment $templating
|
||||
) {}
|
|
@ -7,16 +7,16 @@ use RuntimeException;
|
|||
use Stringable;
|
||||
use Index\Http\{FormHttpContent,HttpResponseBuilder,HttpRequest};
|
||||
use Index\Http\Routing\{HttpMiddleware,HttpPost,RouteHandler,RouteHandlerCommon};
|
||||
use Mince\Clients\ClientsContext;
|
||||
use Mince\Users\UsersContext;
|
||||
use Ramsey\Uuid\Uuid;
|
||||
|
||||
class RpcRoutes implements RouteHandler {
|
||||
use RouteHandlerCommon;
|
||||
|
||||
public function __construct(
|
||||
private Users $users,
|
||||
private AccountLinks $accountLinks,
|
||||
private Authorisations $authorisations,
|
||||
private Verifications $verifications,
|
||||
private UsersContext $usersCtx,
|
||||
private ClientsContext $clientsCtx,
|
||||
#[\SensitiveParameter] private string $secretKey,
|
||||
private string $clientsUrl
|
||||
) {}
|
||||
|
@ -97,17 +97,17 @@ class RpcRoutes implements RouteHandler {
|
|||
return self::createErrorPayload('auth:uuid', 'Provided UUID isn\'t an offline ID nor a Mojang ID.');
|
||||
|
||||
try {
|
||||
$linkInfo = $this->accountLinks->getLink(uuid: $uuid);
|
||||
$linkInfo = $this->clientsCtx->accountLinks->getLink(uuid: $uuid);
|
||||
} catch(RuntimeException $ex) {
|
||||
$linkInfo = null;
|
||||
}
|
||||
|
||||
if($linkInfo !== null) {
|
||||
try {
|
||||
$authInfo = $this->authorisations->getAuthorisation(uuid: $linkInfo, remoteAddr: $addr);
|
||||
$authInfo = $this->clientsCtx->authorisations->getAuthorisation(uuid: $linkInfo, remoteAddr: $addr);
|
||||
|
||||
if($authInfo->granted) {
|
||||
$this->authorisations->markAuthorisationUsed($authInfo);
|
||||
$this->clientsCtx->authorisations->markAuthorisationUsed($authInfo);
|
||||
return self::createPayload('auth:ok');
|
||||
}
|
||||
} catch(RuntimeException $ex) {
|
||||
|
@ -115,13 +115,13 @@ class RpcRoutes implements RouteHandler {
|
|||
}
|
||||
|
||||
try {
|
||||
$userInfo = $this->users->getUser(userId: $linkInfo->userId);
|
||||
$userInfo = $this->usersCtx->users->getUser(userId: $linkInfo->userId);
|
||||
} catch(RuntimeException $ex) {
|
||||
return 500;
|
||||
}
|
||||
|
||||
if($authInfo === null)
|
||||
$this->authorisations->createAuthorisation($uuid, $addr);
|
||||
$this->clientsCtx->authorisations->createAuthorisation($uuid, $addr);
|
||||
|
||||
return self::createPayload('auth:authorise', [
|
||||
'user_id' => $userInfo->id,
|
||||
|
@ -132,10 +132,10 @@ class RpcRoutes implements RouteHandler {
|
|||
}
|
||||
|
||||
try {
|
||||
$verifyInfo = $this->verifications->getVerification(uuid: $uuid, remoteAddr: $addr);
|
||||
$verifyInfo = $this->clientsCtx->verifications->getVerification(uuid: $uuid, remoteAddr: $addr);
|
||||
$verifyCode = $verifyInfo->code;
|
||||
} catch(RuntimeException $ex) {
|
||||
$verifyCode = $this->verifications->createVerification($uuid, $name, $addr);
|
||||
$verifyCode = $this->clientsCtx->verifications->createVerification($uuid, $name, $addr);
|
||||
}
|
||||
|
||||
return self::createPayload('auth:link', [
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<?php
|
||||
namespace Mince;
|
||||
namespace Mince\Servers;
|
||||
|
||||
use Carbon\CarbonImmutable;
|
||||
use Index\Db\DbResult;
|
12
src/Servers/ServersContext.php
Normal file
12
src/Servers/ServersContext.php
Normal file
|
@ -0,0 +1,12 @@
|
|||
<?php
|
||||
namespace Mince\Servers;
|
||||
|
||||
use Index\Dependencies;
|
||||
|
||||
class ServersContext {
|
||||
public private(set) ServersData $servers;
|
||||
|
||||
public function __construct(Dependencies $deps) {
|
||||
$this->servers = $deps->constructLazy(ServersData::class);
|
||||
}
|
||||
}
|
|
@ -1,9 +1,9 @@
|
|||
<?php
|
||||
namespace Mince;
|
||||
namespace Mince\Servers;
|
||||
|
||||
use Index\Db\{DbConnection,DbStatementCache};
|
||||
|
||||
class Servers {
|
||||
class ServersData {
|
||||
private DbStatementCache $cache;
|
||||
|
||||
public function __construct(DbConnection $dbConn) {
|
|
@ -1,5 +1,5 @@
|
|||
<?php
|
||||
namespace Mince;
|
||||
namespace Mince\Skins;
|
||||
|
||||
use Carbon\CarbonImmutable;
|
||||
use Index\Db\DbResult;
|
|
@ -1,11 +1,13 @@
|
|||
<?php
|
||||
namespace Mince;
|
||||
namespace Mince\Skins;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use RuntimeException;
|
||||
use Index\Db\{DbConnection,DbStatementCache};
|
||||
use Mince\Clients\AccountLinkInfo;
|
||||
use Mince\Users\UserInfo;
|
||||
|
||||
class Capes {
|
||||
class CapesData {
|
||||
private DbStatementCache $cache;
|
||||
|
||||
public function __construct(DbConnection $dbConn) {
|
|
@ -1,5 +1,5 @@
|
|||
<?php
|
||||
namespace Mince;
|
||||
namespace Mince\Skins;
|
||||
|
||||
use Carbon\CarbonImmutable;
|
||||
use Index\Db\DbResult;
|
27
src/Skins/SkinsContext.php
Normal file
27
src/Skins/SkinsContext.php
Normal file
|
@ -0,0 +1,27 @@
|
|||
<?php
|
||||
namespace Mince\Skins;
|
||||
|
||||
use Index\Dependencies;
|
||||
use Index\Config\Config;
|
||||
use Index\Http\Routing\{RouteHandler,Router};
|
||||
use Index\Urls\{UrlRegistry,UrlSource};
|
||||
|
||||
class SkinsContext implements RouteHandler, UrlSource {
|
||||
public private(set) CapesData $capes;
|
||||
public private(set) SkinsData $skins;
|
||||
public private(set) SkinsRoutes $routes;
|
||||
|
||||
public function __construct(Dependencies $deps, Config $config) {
|
||||
$this->capes = $deps->constructLazy(CapesData::class);
|
||||
$this->skins = $deps->constructLazy(SkinsData::class);
|
||||
$this->routes = $deps->constructLazy(SkinsRoutes::class, baseUrl: $config->getString('urls:skins_base'));
|
||||
}
|
||||
|
||||
public function registerRoutes(Router $router): void {
|
||||
$router->register($this->routes);
|
||||
}
|
||||
|
||||
public function registerUrls(UrlRegistry $registry): void {
|
||||
$registry->register($this->routes);
|
||||
}
|
||||
}
|
|
@ -1,11 +1,13 @@
|
|||
<?php
|
||||
namespace Mince;
|
||||
namespace Mince\Skins;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use RuntimeException;
|
||||
use Index\Db\{DbConnection,DbStatementCache};
|
||||
use Mince\Clients\AccountLinkInfo;
|
||||
use Mince\Users\UserInfo;
|
||||
|
||||
class Skins {
|
||||
class SkinsData {
|
||||
public const MODELS = ['classic', 'slim'];
|
||||
|
||||
private DbStatementCache $cache;
|
|
@ -1,5 +1,5 @@
|
|||
<?php
|
||||
namespace Mince;
|
||||
namespace Mince\Skins;
|
||||
|
||||
use Imagick;
|
||||
use ImagickException;
|
||||
|
@ -13,6 +13,8 @@ use Index\Http\Routing\{HttpGet,HttpMiddleware,HttpPost,RouteHandler,RouteHandle
|
|||
use Index\Json\JsonHttpContent;
|
||||
use Index\Templating\TplEnvironment;
|
||||
use Index\Urls\{UrlFormat,UrlRegistry,UrlSource,UrlSourceCommon};
|
||||
use Mince\MojangInterop;
|
||||
use Mince\Clients\{AccountLinkInfo,ClientsContext};
|
||||
use Ramsey\Uuid\{Uuid,UuidInterface};
|
||||
|
||||
class SkinsRoutes implements RouteHandler, UrlSource {
|
||||
|
@ -26,9 +28,8 @@ class SkinsRoutes implements RouteHandler, UrlSource {
|
|||
public function __construct(
|
||||
private TplEnvironment $templating,
|
||||
private UrlRegistry $urls,
|
||||
private AccountLinks $accountLinks,
|
||||
private Skins $skins,
|
||||
private Capes $capes,
|
||||
private SkinsContext $skinsCtx,
|
||||
private ClientsContext $clientsCtx,
|
||||
private CsrfToken $csrfp,
|
||||
private ?V1User $authInfo,
|
||||
private string $baseUrl
|
||||
|
@ -40,8 +41,8 @@ class SkinsRoutes implements RouteHandler, UrlSource {
|
|||
}
|
||||
|
||||
public function checkHash(string $hash): bool {
|
||||
return $this->skins->checkHash($hash)
|
||||
|| $this->capes->checkHash($hash);
|
||||
return $this->skinsCtx->skins->checkHash($hash)
|
||||
|| $this->skinsCtx->capes->checkHash($hash);
|
||||
}
|
||||
|
||||
public function getLocalPath(string $hash): string {
|
||||
|
@ -64,7 +65,7 @@ class SkinsRoutes implements RouteHandler, UrlSource {
|
|||
return 403;
|
||||
|
||||
try {
|
||||
$this->linkInfo = $this->accountLinks->getLink(userInfo: $this->authInfo->getId());
|
||||
$this->linkInfo = $this->clientsCtx->accountLinks->getLink(userInfo: $this->authInfo->getId());
|
||||
} catch(RuntimeException $ex) {
|
||||
$response->redirect($this->urls->format('clients:index'));
|
||||
return true;
|
||||
|
@ -93,9 +94,9 @@ class SkinsRoutes implements RouteHandler, UrlSource {
|
|||
#[HttpGet('/skins')]
|
||||
#[UrlFormat('skins:index', '/skins', ['error' => '<error>'])]
|
||||
public function getSkins(HttpResponseBuilder $response, HttpRequest $request) {
|
||||
$skinInfo = $this->skins->getSkin($this->linkInfo);
|
||||
$skinInfo = $this->skinsCtx->skins->getSkin($this->linkInfo);
|
||||
$skinPath = $skinInfo === null ? null : $this->getRemotePath($skinInfo->hash, false);
|
||||
$capeInfo = $this->capes->getCape($this->linkInfo);
|
||||
$capeInfo = $this->skinsCtx->capes->getCape($this->linkInfo);
|
||||
$capePath = $capeInfo === null ? null : $this->getRemotePath($capeInfo->hash, false);
|
||||
|
||||
$template = $this->templating->load('skins/index', [
|
||||
|
@ -133,7 +134,7 @@ class SkinsRoutes implements RouteHandler, UrlSource {
|
|||
$texture = $request->content->getUploadedFile('texture');
|
||||
$model = (string)$request->content->getParam('model');
|
||||
|
||||
if(!in_array($model, Skins::MODELS)) {
|
||||
if(!in_array($model, SkinsData::MODELS)) {
|
||||
$response->redirect($this->urls->format('skins:index', ['error' => 'skin:model']));
|
||||
return;
|
||||
}
|
||||
|
@ -143,7 +144,7 @@ class SkinsRoutes implements RouteHandler, UrlSource {
|
|||
return;
|
||||
}
|
||||
|
||||
$skinInfo = $this->skins->getSkin($this->linkInfo);
|
||||
$skinInfo = $this->skinsCtx->skins->getSkin($this->linkInfo);
|
||||
$tmpPath = $texture->localFileName;
|
||||
$hasNewFile = is_file($tmpPath);
|
||||
|
||||
|
@ -172,7 +173,7 @@ class SkinsRoutes implements RouteHandler, UrlSource {
|
|||
// apply new skin
|
||||
if($hasNewFile && !is_file($localPath))
|
||||
$texture->moveTo($localPath);
|
||||
$this->skins->updateSkin($this->linkInfo, $hash, $model);
|
||||
$this->skinsCtx->skins->updateSkin($this->linkInfo, $hash, $model);
|
||||
} finally {
|
||||
// see about deleting the old one
|
||||
if($skinInfo !== null)
|
||||
|
@ -190,9 +191,9 @@ class SkinsRoutes implements RouteHandler, UrlSource {
|
|||
#[HttpPost('/skins/delete-skin')]
|
||||
#[UrlFormat('skins:skin:delete', '/skins/delete-skin')]
|
||||
public function postDeleteSkin(HttpResponseBuilder $response) {
|
||||
$skinInfo = $this->skins->getSkin($this->linkInfo);
|
||||
$skinInfo = $this->skinsCtx->skins->getSkin($this->linkInfo);
|
||||
if($skinInfo !== null) {
|
||||
$this->skins->deleteSkin(userInfo: $this->linkInfo);
|
||||
$this->skinsCtx->skins->deleteSkin(userInfo: $this->linkInfo);
|
||||
$this->deleteLocalFileMaybe($skinInfo->hash);
|
||||
}
|
||||
|
||||
|
@ -231,13 +232,13 @@ class SkinsRoutes implements RouteHandler, UrlSource {
|
|||
|
||||
try {
|
||||
// get previous cape
|
||||
$capeInfo = $this->capes->getCape($this->linkInfo);
|
||||
$capeInfo = $this->skinsCtx->capes->getCape($this->linkInfo);
|
||||
|
||||
try {
|
||||
// apply new cape
|
||||
if(!is_file($localPath))
|
||||
$texture->moveTo($localPath);
|
||||
$this->capes->updateCape($this->linkInfo, $hash);
|
||||
$this->skinsCtx->capes->updateCape($this->linkInfo, $hash);
|
||||
} finally {
|
||||
// see about deleting the old one
|
||||
if($capeInfo !== null)
|
||||
|
@ -254,9 +255,9 @@ class SkinsRoutes implements RouteHandler, UrlSource {
|
|||
#[HttpPost('/skins/delete-cape')]
|
||||
#[UrlFormat('skins:cape:delete', '/skins/delete-cape')]
|
||||
public function postDeleteCape(HttpResponseBuilder $response) {
|
||||
$capeInfo = $this->capes->getCape($this->linkInfo);
|
||||
$capeInfo = $this->skinsCtx->capes->getCape($this->linkInfo);
|
||||
if($capeInfo !== null) {
|
||||
$this->capes->deleteCape(userInfo: $this->linkInfo);
|
||||
$this->skinsCtx->capes->deleteCape(userInfo: $this->linkInfo);
|
||||
$this->deleteLocalFileMaybe($capeInfo->hash);
|
||||
}
|
||||
|
||||
|
@ -298,7 +299,7 @@ class SkinsRoutes implements RouteHandler, UrlSource {
|
|||
$hash = hash_file('sha256', $tmpFile);
|
||||
$localPath = $this->getLocalPath($hash);
|
||||
rename($tmpFile, $localPath);
|
||||
$this->skins->updateSkin($this->linkInfo, $hash, $model);
|
||||
$this->skinsCtx->skins->updateSkin($this->linkInfo, $hash, $model);
|
||||
} finally {
|
||||
if(is_file($tmpFile))
|
||||
unlink($tmpFile);
|
||||
|
@ -317,7 +318,7 @@ class SkinsRoutes implements RouteHandler, UrlSource {
|
|||
$hash = hash_file('sha256', $tmpFile);
|
||||
$localPath = $this->getLocalPath($hash);
|
||||
rename($tmpFile, $localPath);
|
||||
$this->capes->updateCape($this->linkInfo, $hash);
|
||||
$this->skinsCtx->capes->updateCape($this->linkInfo, $hash);
|
||||
} finally {
|
||||
if(is_file($tmpFile))
|
||||
unlink($tmpFile);
|
||||
|
@ -338,14 +339,14 @@ class SkinsRoutes implements RouteHandler, UrlSource {
|
|||
return 204;
|
||||
|
||||
try {
|
||||
$linkInfo = $this->accountLinks->getLink(uuid: $uuid);
|
||||
$linkInfo = $this->clientsCtx->accountLinks->getLink(uuid: $uuid);
|
||||
} catch(RuntimeException $ex) {
|
||||
return 204;
|
||||
}
|
||||
|
||||
$textures = [];
|
||||
|
||||
$skinInfo = $this->skins->getSkin($linkInfo);
|
||||
$skinInfo = $this->skinsCtx->skins->getSkin($linkInfo);
|
||||
if($skinInfo !== null) {
|
||||
$texture = ['url' => $this->getRemotePath($skinInfo->hash, true)];
|
||||
if(!$skinInfo->classic)
|
||||
|
@ -353,7 +354,7 @@ class SkinsRoutes implements RouteHandler, UrlSource {
|
|||
$textures['SKIN'] = $texture;
|
||||
}
|
||||
|
||||
$capeInfo = $this->capes->getCape($linkInfo);
|
||||
$capeInfo = $this->skinsCtx->capes->getCape($linkInfo);
|
||||
if($capeInfo !== null)
|
||||
$textures['CAPE'] = ['url' => $this->getRemotePath($capeInfo->hash, true)];
|
||||
|
||||
|
@ -430,7 +431,7 @@ class SkinsRoutes implements RouteHandler, UrlSource {
|
|||
#[HttpGet('/users/profiles/minecraft/([A-Za-z0-9_]+)')]
|
||||
public function getUsersMinecraftProfile(HttpResponseBuilder $response, HttpRequest $request, string $name) {
|
||||
try {
|
||||
$linkInfo = $this->accountLinks->getLink(name: $name);
|
||||
$linkInfo = $this->clientsCtx->accountLinks->getLink(name: $name);
|
||||
} catch(RuntimeException $ex) {
|
||||
$response->statusCode = 404;
|
||||
return [
|
||||
|
@ -450,12 +451,12 @@ class SkinsRoutes implements RouteHandler, UrlSource {
|
|||
#[HttpGet('/s3s3MinecraftSkins/([A-Za-z0-9_]+).png')]
|
||||
public function getS3MinecraftSkin(HttpResponseBuilder $response, HttpRequest $request, string $name) {
|
||||
try {
|
||||
$linkInfo = $this->accountLinks->getLink(name: $name);
|
||||
$linkInfo = $this->clientsCtx->accountLinks->getLink(name: $name);
|
||||
} catch(RuntimeException $ex) {
|
||||
return 404;
|
||||
}
|
||||
|
||||
$skinInfo = $this->skins->getSkin($linkInfo);
|
||||
$skinInfo = $this->skinsCtx->skins->getSkin($linkInfo);
|
||||
if($skinInfo === null)
|
||||
return 404;
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
<?php
|
||||
namespace Mince;
|
||||
namespace Mince\Users;
|
||||
|
||||
use Index\Colour\{Colour,ColourRgb};
|
||||
use Index\Db\DbResult;
|
12
src/Users/UsersContext.php
Normal file
12
src/Users/UsersContext.php
Normal file
|
@ -0,0 +1,12 @@
|
|||
<?php
|
||||
namespace Mince\Users;
|
||||
|
||||
use Index\Dependencies;
|
||||
|
||||
class UsersContext {
|
||||
public private(set) UsersData $users;
|
||||
|
||||
public function __construct(Dependencies $deps) {
|
||||
$this->users = $deps->constructLazy(UsersData::class);
|
||||
}
|
||||
}
|
|
@ -1,11 +1,11 @@
|
|||
<?php
|
||||
namespace Mince;
|
||||
namespace Mince\Users;
|
||||
|
||||
use RuntimeException;
|
||||
use Flashii\V1\Users\V1User;
|
||||
use Index\Db\{DbConnection,DbStatementCache};
|
||||
|
||||
class Users {
|
||||
class UsersData {
|
||||
private DbStatementCache $cache;
|
||||
|
||||
public function __construct(DbConnection $dbConn) {
|
|
@ -4,31 +4,25 @@ use Index\Db\Migration\{DbMigrationManager,FsDbMigrationRepo};
|
|||
|
||||
require_once __DIR__ . '/../mince.php';
|
||||
|
||||
try {
|
||||
touch(MCR_ROOT . '/.migrating');
|
||||
chmod(MCR_ROOT . '/.migrating', 0777);
|
||||
echo 'Creating migration manager...' . PHP_EOL;
|
||||
$manager = $mince->dbCtx->createMigrationManager();
|
||||
|
||||
echo 'Creating migration manager...' . PHP_EOL;
|
||||
$manager = new DbMigrationManager($db);
|
||||
echo 'Preparing to run migrations...' . PHP_EOL;
|
||||
$manager->init();
|
||||
|
||||
echo 'Preparing to run migrations...' . PHP_EOL;
|
||||
$manager->init();
|
||||
echo 'Creating migration repository...' . PHP_EOL;
|
||||
$repo = $mince->dbCtx->createMigrationRepo();
|
||||
|
||||
echo 'Creating migration repository...' . PHP_EOL;
|
||||
$repo = new FsDbMigrationRepo(MCR_DIR_MIG);
|
||||
echo 'Running migrations...' . PHP_EOL;
|
||||
$completed = $manager->processMigrations($repo);
|
||||
|
||||
echo 'Running migrations...' . PHP_EOL;
|
||||
$completed = $manager->processMigrations($repo);
|
||||
|
||||
if(empty($completed)) {
|
||||
echo 'There were no migrations to run!' . PHP_EOL;
|
||||
} else {
|
||||
echo 'The following migrations have been completed:' . PHP_EOL;
|
||||
foreach($completed as $migration)
|
||||
echo ' - ' . $migration . PHP_EOL;
|
||||
}
|
||||
|
||||
echo PHP_EOL;
|
||||
} finally {
|
||||
unlink(MCR_ROOT . '/.migrating');
|
||||
if(empty($completed)) {
|
||||
echo 'There were no migrations to run!' . PHP_EOL;
|
||||
} else {
|
||||
echo 'The following migrations have been completed:' . PHP_EOL;
|
||||
foreach($completed as $migration)
|
||||
echo ' - ' . $migration . PHP_EOL;
|
||||
}
|
||||
|
||||
echo PHP_EOL;
|
||||
|
||||
|
|
|
@ -4,9 +4,9 @@ use Index\Db\Migration\DbMigrationManager;
|
|||
|
||||
require_once __DIR__ . '/../mince.php';
|
||||
|
||||
$repo = new FsDbMigrationRepo(MCR_DIR_MIG);
|
||||
$repo = $mince->dbCtx->createMigrationRepo();
|
||||
$baseName = implode(' ', array_slice($argv, 1));
|
||||
$manager = new DbMigrationManager($db);
|
||||
$manager = $mince->dbCtx->createMigrationManager();
|
||||
|
||||
try {
|
||||
$names = $manager->createNames($baseName);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue