Skip to content

Commit

Permalink
Begin adding interactivity to dashboard controller
Browse files Browse the repository at this point in the history
  • Loading branch information
caendesilva committed Oct 20, 2023
1 parent 7726bd1 commit c452ae1
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 0 deletions.
1 change: 1 addition & 0 deletions config/hyde.php
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,7 @@
'host' => env('SERVER_HOST', 'localhost'),
'dashboard' => env('SERVER_DASHBOARD', true),
'save_preview' => true,
'editor' => true,
'tips' => true,
],

Expand Down
1 change: 1 addition & 0 deletions packages/framework/config/hyde.php
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,7 @@
'host' => env('SERVER_HOST', 'localhost'),
'dashboard' => env('SERVER_DASHBOARD', true),
'save_preview' => true,
'editor' => true,
'tips' => true,
],

Expand Down
7 changes: 7 additions & 0 deletions packages/realtime-compiler/resources/dashboard.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,13 @@
{{ $route->getPageIdentifier() }}
</td>
<td class="text-end">
@if($dashboard->enableEditor())
<form action="" method="POST">
<input type="hidden" name="action" value="openInEditor">
<input type="hidden" name="routeKey" value="{{ $route->getRouteKey() }}">
<button type="submit" class="btn btn-outline-primary btn-sm">Edit</button>
</form>
@endif
<a href="{{ $route->getLink() }}" class="btn btn-outline-primary btn-sm">View</a>
</td>
</tr>
Expand Down
56 changes: 56 additions & 0 deletions packages/realtime-compiler/src/Http/DashboardController.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,18 @@
use Illuminate\Support\Arr;
use Hyde\Pages\Concerns\HydePage;
use Illuminate\Support\HtmlString;
use Hyde\Foundation\Facades\Routes;
use Illuminate\Support\Facades\Process;
use Hyde\Framework\Actions\StaticPageBuilder;
use Hyde\Framework\Actions\AnonymousViewCompiler;
use Desilva\Microserve\Request;
use Composer\InstalledVersions;
use Symfony\Component\HttpKernel\Exception\HttpException;

use function abort;
use function basename;
use function array_combine;
use function escapeshellarg;
use function file_get_contents;
use function str_starts_with;
use function str_replace;
Expand All @@ -34,12 +41,37 @@ class DashboardController
'Got stuck? Ask for help on [GitHub](https://github.com/hydephp/hyde)!',
'Found a bug stuck? Please report it on [GitHub](https://github.com/hydephp/hyde)!',
'You can disable tips using by setting `server.tips` to `false` in `config/hyde.php`.',
'By default this dashboard can make changes to your project files. You can disable this by setting `server.editor` to `false` in `config/hyde.php`.',
];

public function __construct()
{
$this->title = config('hyde.name').' - Dashboard';
$this->request = Request::capture();

if ($this->request->method === 'POST') {
if (! $this->enableEditor()) {
abort(403, 'Enable `server.editor` in `config/hyde.php` to use interactive dashboard features.');
}

$this->handlePostRequest();
}
}

protected function handlePostRequest(): void
{
$actions = array_combine($actions = [
'openInEditor',
], $actions);

$action = $this->request->data['action'] ?? abort(400, 'Must provide action');
$action = $actions[$action] ?? abort(403, 'Invalid action');

if ($action === 'openInEditor') {
$routeKey = $this->request->data['routeKey'] ?? abort(400, 'Must provide routeKey');
$page = Routes::getOrFail($routeKey)->getPage();
$this->openInEditor($page);
}
}

public function show(): string
Expand Down Expand Up @@ -118,6 +150,30 @@ public static function renderIndexPage(HydePage $page): string
return $contents;
}

public function enableEditor(): bool
{
return config('hyde.server.editor', true);
}

protected function openInEditor(HydePage $page): void
{
if ($this->enableEditor()) {
$binary = match (PHP_OS_FAMILY) {
'Windows' => 'powershell Start-Process', // Using PowerShell allows us to open the file in the background
'Darwin' => 'open',
'Linux' => 'xdg-open',
default => throw new HttpException(500, sprintf("Unable to find a matching binary for OS family '%s'", PHP_OS_FAMILY))
};
$path = Hyde::path($page->getSourcePath());

if (! (str_ends_with($path, '.md') || str_ends_with($path, '.blade.php'))) {
abort(403, sprintf("Refusing to open unsafe file '%s'", basename($path)));
}

Process::run(sprintf('%s %s', $binary, escapeshellarg($path)))->throw();
}
}

protected static function injectDashboardButton(string $contents): string
{
return str_replace('</body>', sprintf('%s</body>', self::button()), $contents);
Expand Down

0 comments on commit c452ae1

Please sign in to comment.