diff --git a/.dockerignore b/.dockerignore index f51c422df..352b0672c 100644 --- a/.dockerignore +++ b/.dockerignore @@ -5,5 +5,6 @@ !/config/ !/external/ !/src/ +!/templates/ !/vendor/ !/webroot/ diff --git a/Dockerfile b/Dockerfile index 279873cfa..ede5fcbcb 100644 --- a/Dockerfile +++ b/Dockerfile @@ -89,6 +89,7 @@ RUN composer install $COMPOSER_FLAGS --no-scripts --no-autoloader # copy rest of the project. copy in order that is least to most changed COPY --from=source /app/webroot ./webroot COPY --from=source /app/external ./external +COPY --from=source /app/templates ./templates COPY --from=source /app/src ./src COPY --from=source /app/config ./config diff --git a/composer.json b/composer.json index 582f2df77..37b383d41 100644 --- a/composer.json +++ b/composer.json @@ -4,7 +4,7 @@ "license": "MIT", "autoload": { "psr-4": { - "XHGui\\": "src/Xhgui/" + "XHGui\\": "src/" } }, "autoload-dev": { diff --git a/external/import.php b/external/import.php index 8690d623c..674f614e5 100644 --- a/external/import.php +++ b/external/import.php @@ -3,9 +3,7 @@ use XHGui\Saver\SaverInterface; use XHGui\ServiceContainer; -if (!defined('XHGUI_ROOT_DIR')) { - require dirname(__DIR__) . '/src/bootstrap.php'; -} +require __DIR__ . '/../vendor/autoload.php'; $options = getopt('f:'); diff --git a/src/Xhgui/AbstractController.php b/src/AbstractController.php similarity index 100% rename from src/Xhgui/AbstractController.php rename to src/AbstractController.php diff --git a/src/Config.php b/src/Config.php new file mode 100644 index 000000000..8e996e0fc --- /dev/null +++ b/src/Config.php @@ -0,0 +1,31 @@ +boot(); } return static::$_instance; @@ -39,6 +42,8 @@ public static function instance() public function __construct() { parent::__construct(); + $this->setupPaths($this); + $this->register(new ConfigProvider()); $this->_slimApp(); $this->_services(); $this->storageDriverPdo($this); @@ -46,19 +51,34 @@ public function __construct() $this->_controllers(); } + public function boot() + { + $this->register(new RouteProvider()); + } + + private function setupPaths(self $app) + { + $app['app.dir'] = dirname(__DIR__); + $app['app.template_dir'] = dirname(__DIR__) . '/templates'; + $app['app.config_dir'] = dirname(__DIR__) . '/config'; + $app['app.cache_dir'] = static function ($c) { + return $c['config']['cache'] ?? dirname(__DIR__) . '/cache'; + }; + } + // Create the Slim app. protected function _slimApp() { $this['view'] = static function ($c) { - $cacheDir = $c['config']['cache'] ?? XHGUI_ROOT_DIR . '/cache'; - // Configure Twig view for slim $view = new Twig(); - $view->twigTemplateDirs = [dirname(__DIR__) . '/templates']; + $view->twigTemplateDirs = [ + $c['app.template_dir'], + ]; $view->parserOptions = [ 'charset' => 'utf-8', - 'cache' => $cacheDir, + 'cache' => $c['app.cache_dir'], 'auto_reload' => true, 'strict_variables' => false, 'autoescape' => true, @@ -97,8 +117,6 @@ protected function _slimApp() */ protected function _services() { - $this['config'] = Config::all(); - $this['searcher'] = static function ($c) { $saver = $c['config']['save.handler']; diff --git a/src/ServiceProvider/ConfigProvider.php b/src/ServiceProvider/ConfigProvider.php new file mode 100644 index 000000000..76f67d744 --- /dev/null +++ b/src/ServiceProvider/ConfigProvider.php @@ -0,0 +1,29 @@ +registerRoutes($di, $di['app']); + } + + private function registerRoutes(Container $di, App $app) + { + $app->error(static function (Exception $e) use ($di, $app) { + /** @var Twig $view */ + $view = $di['view']; + $view->parserOptions['cache'] = false; + $view->parserExtensions = [ + new TwigExtension($app), + ]; + + // Remove the controller so we don't render it. + unset($app->controller); + + $app->view($view); + $app->render('error/view.twig', [ + 'message' => $e->getMessage(), + 'stack_trace' => $e->getTraceAsString(), + ]); + }); + + // Profile Runs routes + $app->get('/', static function () use ($di, $app) { + /** @var Controller\RunController $controller */ + $controller = $app->controller = $di['runController']; + $request = $app->request(); + $response = $app->response(); + + $controller->index($request, $response); + })->setName('home'); + + $app->get('/run/view', static function () use ($di, $app) { + /** @var Controller\RunController $controller */ + $controller = $app->controller = $di['runController']; + $request = $app->request(); + $response = $app->response(); + + $controller->view($request, $response); + })->setName('run.view'); + + $app->get('/run/delete', static function () use ($di, $app) { + /** @var Controller\RunController $controller */ + $controller = $app->controller = $di['runController']; + $request = $app->request(); + + $controller->deleteForm($request); + })->setName('run.delete.form'); + + $app->post('/run/delete', static function () use ($di, $app) { + /** @var Controller\RunController $controller */ + $controller = $di['runController']; + $request = $app->request(); + + $controller->deleteSubmit($request); + })->setName('run.delete.submit'); + + $app->get('/run/delete_all', static function () use ($di, $app) { + /** @var Controller\RunController $controller */ + $controller = $app->controller = $di['runController']; + $controller->deleteAllForm(); + })->setName('run.deleteAll.form'); + + $app->post('/run/delete_all', static function () use ($di) { + /** @var Controller\RunController $controller */ + $controller = $di['runController']; + $controller->deleteAllSubmit(); + })->setName('run.deleteAll.submit'); + + $app->get('/url/view', static function () use ($di, $app) { + /** @var Controller\RunController $controller */ + $controller = $app->controller = $di['runController']; + $request = $app->request(); + + $controller->url($request); + })->setName('url.view'); + + $app->get('/run/compare', static function () use ($di, $app) { + /** @var Controller\RunController $controller */ + $controller = $app->controller = $di['runController']; + $request = $app->request(); + + $controller->compare($request); + })->setName('run.compare'); + + $app->get('/run/symbol', static function () use ($di, $app) { + /** @var Controller\RunController $controller */ + $controller = $app->controller = $di['runController']; + $request = $app->request(); + + $controller->symbol($request); + })->setName('run.symbol'); + + $app->get('/run/symbol/short', static function () use ($di, $app) { + /** @var Controller\RunController $controller */ + $controller = $app->controller = $di['runController']; + $request = $app->request(); + + $controller->symbolShort($request); + })->setName('run.symbol-short'); + + $app->get('/run/callgraph', static function () use ($di, $app) { + /** @var Controller\RunController $controller */ + $controller = $app->controller = $di['runController']; + $request = $app->request(); + + $controller->callgraph($request); + })->setName('run.callgraph'); + + $app->get('/run/callgraph/data', static function () use ($di, $app) { + /** @var Controller\RunController $controller */ + $controller = $di['runController']; + $request = $app->request(); + $response = $app->response(); + + $controller->callgraphData($request, $response); + })->setName('run.callgraph.data'); + + $app->get('/run/callgraph/dot', static function () use ($di, $app) { + /** @var Controller\RunController $controller */ + $controller = $di['runController']; + $request = $app->request(); + $response = $app->response(); + + $controller->callgraphDataDot($request, $response); + })->setName('run.callgraph.dot'); + + // Import route + $app->post('/run/import', static function () use ($di, $app) { + /** @var Controller\ImportController $controller */ + $controller = $di['importController']; + $request = $app->request(); + $response = $app->response(); + + $controller->import($request, $response); + })->setName('run.import'); + + // Watch function routes. + $app->get('/watch', static function () use ($di, $app) { + /** @var Controller\WatchController $controller */ + $controller = $app->controller = $di['watchController']; + $controller->get(); + })->setName('watch.list'); + + $app->post('/watch', static function () use ($di, $app) { + /** @var Controller\WatchController $controller */ + $controller = $di['watchController']; + $request = $app->request(); + + $controller->post($request); + })->setName('watch.save'); + + // Custom report routes. + $app->get('/custom', static function () use ($di, $app) { + /** @var Controller\CustomController $controller */ + $controller = $app->controller = $di['customController']; + $controller->get(); + })->setName('custom.view'); + + $app->get('/custom/help', static function () use ($di, $app) { + /** @var Controller\CustomController $controller */ + $controller = $app->controller = $di['customController']; + $request = $app->request(); + + $controller->help($request); + })->setName('custom.help'); + + $app->post('/custom/query', static function () use ($di, $app) { + /** @var Controller\CustomController $controller */ + $controller = $di['customController']; + $request = $app->request(); + $response = $app->response(); + + $controller->query($request, $response); + })->setName('custom.query'); + + // Waterfall routes + $app->get('/waterfall', static function () use ($di, $app) { + /** @var Controller\WaterfallController $controller */ + $controller = $app->controller = $di['waterfallController']; + $controller->index(); + })->setName('waterfall.list'); + + $app->get('/waterfall/data', static function () use ($di, $app) { + /** @var Controller\WaterfallController $controller */ + $controller = $di['waterfallController']; + $request = $app->request(); + $response = $app->response(); + + $controller->query($request, $response); + })->setName('waterfall.data'); + + // Metrics + $app->get('/metrics', static function () use ($di, $app) { + /** @var Controller\MetricsController $controller */ + $controller = $di['metricsController']; + $response = $app->response(); + + $controller->metrics($response); + })->setName('metrics'); + } +} diff --git a/src/Xhgui/Twig/TwigExtension.php b/src/Twig/TwigExtension.php similarity index 100% rename from src/Xhgui/Twig/TwigExtension.php rename to src/Twig/TwigExtension.php diff --git a/src/Xhgui/Util.php b/src/Util.php similarity index 100% rename from src/Xhgui/Util.php rename to src/Util.php diff --git a/src/Xhgui/Config.php b/src/Xhgui/Config.php deleted file mode 100644 index 178aa2c38..000000000 --- a/src/Xhgui/Config.php +++ /dev/null @@ -1,65 +0,0 @@ -error(static function (Exception $e) use ($di, $app) { - /** @var Twig $view */ - $view = $di['view']; - $view->parserOptions['cache'] = false; - $view->parserExtensions = [ - new TwigExtension($app), - ]; - - // Remove the controller so we don't render it. - unset($app->controller); - - $app->view($view); - $app->render('error/view.twig', [ - 'message' => $e->getMessage(), - 'stack_trace' => $e->getTraceAsString(), - ]); -}); - -// Profile Runs routes -$app->get('/', static function () use ($di, $app) { - /** @var RunController $controller */ - $controller = $app->controller = $di['runController']; - $request = $app->request(); - $response = $app->response(); - - $controller->index($request, $response); -})->setName('home'); - -$app->get('/run/view', static function () use ($di, $app) { - /** @var RunController $controller */ - $controller = $app->controller = $di['runController']; - $request = $app->request(); - $response = $app->response(); - - $controller->view($request, $response); -})->setName('run.view'); - -$app->get('/run/delete', static function () use ($di, $app) { - /** @var RunController $controller */ - $controller = $app->controller = $di['runController']; - $request = $app->request(); - - $controller->deleteForm($request); -})->setName('run.delete.form'); - -$app->post('/run/delete', static function () use ($di, $app) { - /** @var RunController $controller */ - $controller = $di['runController']; - $request = $app->request(); - - $controller->deleteSubmit($request); -})->setName('run.delete.submit'); - -$app->get('/run/delete_all', static function () use ($di, $app) { - /** @var RunController $controller */ - $controller = $app->controller = $di['runController']; - $controller->deleteAllForm(); -})->setName('run.deleteAll.form'); - -$app->post('/run/delete_all', static function () use ($di) { - /** @var RunController $controller */ - $controller = $di['runController']; - $controller->deleteAllSubmit(); -})->setName('run.deleteAll.submit'); - -$app->get('/url/view', static function () use ($di, $app) { - /** @var RunController $controller */ - $controller = $app->controller = $di['runController']; - $request = $app->request(); - - $controller->url($request); -})->setName('url.view'); - -$app->get('/run/compare', static function () use ($di, $app) { - /** @var RunController $controller */ - $controller = $app->controller = $di['runController']; - $request = $app->request(); - - $controller->compare($request); -})->setName('run.compare'); - -$app->get('/run/symbol', static function () use ($di, $app) { - /** @var RunController $controller */ - $controller = $app->controller = $di['runController']; - $request = $app->request(); - - $controller->symbol($request); -})->setName('run.symbol'); - -$app->get('/run/symbol/short', static function () use ($di, $app) { - /** @var RunController $controller */ - $controller = $app->controller = $di['runController']; - $request = $app->request(); - - $controller->symbolShort($request); -})->setName('run.symbol-short'); - -$app->get('/run/callgraph', static function () use ($di, $app) { - /** @var RunController $controller */ - $controller = $app->controller = $di['runController']; - $request = $app->request(); - - $controller->callgraph($request); -})->setName('run.callgraph'); - -$app->get('/run/callgraph/data', static function () use ($di, $app) { - /** @var RunController $controller */ - $controller = $di['runController']; - $request = $app->request(); - $response = $app->response(); - - $controller->callgraphData($request, $response); -})->setName('run.callgraph.data'); - -$app->get('/run/callgraph/dot', static function () use ($di, $app) { - /** @var RunController $controller */ - $controller = $di['runController']; - $request = $app->request(); - $response = $app->response(); - - $controller->callgraphDataDot($request, $response); -})->setName('run.callgraph.dot'); - -// Import route -$app->post('/run/import', static function () use ($di, $app) { - /** @var ImportController $controller */ - $controller = $di['importController']; - $request = $app->request(); - $response = $app->response(); - - $controller->import($request, $response); -})->setName('run.import'); - -// Watch function routes. -$app->get('/watch', static function () use ($di, $app) { - /** @var WatchController $controller */ - $controller = $app->controller = $di['watchController']; - $controller->get(); -})->setName('watch.list'); - -$app->post('/watch', static function () use ($di, $app) { - /** @var WatchController $controller */ - $controller = $di['watchController']; - $request = $app->request(); - - $controller->post($request); -})->setName('watch.save'); - -// Custom report routes. -$app->get('/custom', static function () use ($di, $app) { - /** @var CustomController $controller */ - $controller = $app->controller = $di['customController']; - $controller->get(); -})->setName('custom.view'); - -$app->get('/custom/help', static function () use ($di, $app) { - /** @var CustomController $controller */ - $controller = $app->controller = $di['customController']; - $request = $app->request(); - - $controller->help($request); -})->setName('custom.help'); - -$app->post('/custom/query', static function () use ($di, $app) { - /** @var CustomController $controller */ - $controller = $di['customController']; - $request = $app->request(); - $response = $app->response(); - - $controller->query($request, $response); -})->setName('custom.query'); - -// Waterfall routes -$app->get('/waterfall', static function () use ($di, $app) { - /** @var WaterfallController $controller */ - $controller = $app->controller = $di['waterfallController']; - $controller->index(); -})->setName('waterfall.list'); - -$app->get('/waterfall/data', static function () use ($di, $app) { - /** @var WaterfallController $controller */ - $controller = $di['waterfallController']; - $request = $app->request(); - $response = $app->response(); - - $controller->query($request, $response); -})->setName('waterfall.data'); - -// Metrics -$app->get('/metrics', static function () use ($di, $app) { - /** @var MetricsController $controller */ - $controller = $di['metricsController']; - $response = $app->response(); - - $controller->metrics($response); -})->setName('metrics'); diff --git a/src/templates/custom/create.twig b/templates/custom/create.twig similarity index 100% rename from src/templates/custom/create.twig rename to templates/custom/create.twig diff --git a/src/templates/custom/help.twig b/templates/custom/help.twig similarity index 100% rename from src/templates/custom/help.twig rename to templates/custom/help.twig diff --git a/src/templates/error/view.twig b/templates/error/view.twig similarity index 100% rename from src/templates/error/view.twig rename to templates/error/view.twig diff --git a/src/templates/layout/base.twig b/templates/layout/base.twig similarity index 100% rename from src/templates/layout/base.twig rename to templates/layout/base.twig diff --git a/src/templates/macros/helpers.twig b/templates/macros/helpers.twig similarity index 100% rename from src/templates/macros/helpers.twig rename to templates/macros/helpers.twig diff --git a/src/templates/runs/callgraph.twig b/templates/runs/callgraph.twig similarity index 100% rename from src/templates/runs/callgraph.twig rename to templates/runs/callgraph.twig diff --git a/src/templates/runs/compare-details.twig b/templates/runs/compare-details.twig similarity index 100% rename from src/templates/runs/compare-details.twig rename to templates/runs/compare-details.twig diff --git a/src/templates/runs/compare.twig b/templates/runs/compare.twig similarity index 100% rename from src/templates/runs/compare.twig rename to templates/runs/compare.twig diff --git a/src/templates/runs/delete-all-form.twig b/templates/runs/delete-all-form.twig similarity index 100% rename from src/templates/runs/delete-all-form.twig rename to templates/runs/delete-all-form.twig diff --git a/src/templates/runs/delete-form.twig b/templates/runs/delete-form.twig similarity index 100% rename from src/templates/runs/delete-form.twig rename to templates/runs/delete-form.twig diff --git a/src/templates/runs/list.twig b/templates/runs/list.twig similarity index 100% rename from src/templates/runs/list.twig rename to templates/runs/list.twig diff --git a/src/templates/runs/paginated-list.twig b/templates/runs/paginated-list.twig similarity index 100% rename from src/templates/runs/paginated-list.twig rename to templates/runs/paginated-list.twig diff --git a/src/templates/runs/symbol-short.twig b/templates/runs/symbol-short.twig similarity index 100% rename from src/templates/runs/symbol-short.twig rename to templates/runs/symbol-short.twig diff --git a/src/templates/runs/symbol.twig b/templates/runs/symbol.twig similarity index 100% rename from src/templates/runs/symbol.twig rename to templates/runs/symbol.twig diff --git a/src/templates/runs/url.twig b/templates/runs/url.twig similarity index 100% rename from src/templates/runs/url.twig rename to templates/runs/url.twig diff --git a/src/templates/runs/view.twig b/templates/runs/view.twig similarity index 100% rename from src/templates/runs/view.twig rename to templates/runs/view.twig diff --git a/src/templates/watch/list.twig b/templates/watch/list.twig similarity index 100% rename from src/templates/watch/list.twig rename to templates/watch/list.twig diff --git a/src/templates/waterfall/list.twig b/templates/waterfall/list.twig similarity index 100% rename from src/templates/waterfall/list.twig rename to templates/waterfall/list.twig diff --git a/tests/ConfigTest.php b/tests/ConfigTest.php deleted file mode 100644 index 4df7c12d1..000000000 --- a/tests/ConfigTest.php +++ /dev/null @@ -1,40 +0,0 @@ -assertNull($result); - - $result = Config::read('test'); - $this->assertEquals('value', $result); - - $result = Config::read('not there'); - $this->assertNull($result); - } - - public function testReadWriteWithDots() - { - $result = Config::write('test.name', 'value'); - $this->assertNull(Config::read('test')); - $this->assertEquals('value', Config::read('test.name')); - } - - public function testClear() - { - Config::write('test', 'value'); - $this->assertNull(Config::clear()); - $this->assertNull(Config::read('test')); - } -} diff --git a/tests/LazyContainerProperties.php b/tests/LazyContainerProperties.php index 937c1769e..1963e35a2 100644 --- a/tests/LazyContainerProperties.php +++ b/tests/LazyContainerProperties.php @@ -49,11 +49,13 @@ protected function setupProperties() protected function getDi() { - $di = ServiceContainer::instance(); - $di['app'] = $this->getMockBuilder(App::class) + $di = new ServiceContainer(); + $app = $this->getMockBuilder(App::class) ->setMethods(['redirect', 'render', 'urlFor']) ->setConstructorArgs([$di['config']]) ->getMock(); + $di['app'] = $app; + $di->boot(); return $di; } diff --git a/tests/ProfileTest.php b/tests/ProfileTest.php index fbef069c8..ea0b6be5e 100644 --- a/tests/ProfileTest.php +++ b/tests/ProfileTest.php @@ -12,7 +12,7 @@ class ProfileTest extends TestCase public function setUp() { parent::setUp(); - $contents = file_get_contents(XHGUI_ROOT_DIR . '/tests/fixtures/results.json'); + $contents = file_get_contents(dirname(__DIR__) . '/tests/fixtures/results.json'); $this->fixture = json_decode($contents, true); } diff --git a/tests/Saver/MongoTest.php b/tests/Saver/MongoTest.php index 76e31409d..b98f34c5e 100644 --- a/tests/Saver/MongoTest.php +++ b/tests/Saver/MongoTest.php @@ -10,7 +10,7 @@ class MongoTest extends TestCase { public function testSave() { - $data = json_decode(file_get_contents(XHGUI_ROOT_DIR . '/tests/fixtures/results.json'), true); + $data = json_decode(file_get_contents(__DIR__ . '/../../tests/fixtures/results.json'), true); $collection = $this->getMockBuilder(MongoCollection::class) ->disableOriginalConstructor() diff --git a/tests/bootstrap.php b/tests/bootstrap.php index e11dad129..9d7dc2399 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -5,7 +5,7 @@ use XHGui\ServiceContainer; -require dirname(__DIR__) . '/src/bootstrap.php'; +require __DIR__ . '/../vendor/autoload.php'; $di = ServiceContainer::instance(); diff --git a/webroot/index.php b/webroot/index.php index 828f93ea3..9a0f670e3 100644 --- a/webroot/index.php +++ b/webroot/index.php @@ -1,13 +1,11 @@ run();