mirror of
https://github.com/usetrmnl/byos_laravel.git
synced 2026-01-14 15:37:53 +00:00
Compare commits
6 commits
6d7968a7b0
...
770b511290
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
770b511290 | ||
|
|
4bb5723767 | ||
|
|
40ceba267a | ||
|
|
aa8d3d1428 | ||
|
|
d999b5157f | ||
|
|
d3690c9e10 |
7 changed files with 101 additions and 23 deletions
20
app/Liquid/Filters/StandardFilters.php
Normal file
20
app/Liquid/Filters/StandardFilters.php
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Liquid\Filters;
|
||||||
|
|
||||||
|
class StandardFilters extends \Keepsuit\Liquid\Filters\StandardFilters
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Converts any URL-unsafe characters in a string to the
|
||||||
|
* [percent-encoded](https://developer.mozilla.org/en-US/docs/Glossary/percent-encoding) equivalent.
|
||||||
|
*/
|
||||||
|
public function urlEncode(string|int|float|array|null $input): string
|
||||||
|
{
|
||||||
|
|
||||||
|
if (is_array($input)) {
|
||||||
|
$input = json_encode($input);
|
||||||
|
}
|
||||||
|
|
||||||
|
return parent::urlEncode($input);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -7,6 +7,7 @@ use App\Liquid\Filters\Data;
|
||||||
use App\Liquid\Filters\Date;
|
use App\Liquid\Filters\Date;
|
||||||
use App\Liquid\Filters\Localization;
|
use App\Liquid\Filters\Localization;
|
||||||
use App\Liquid\Filters\Numbers;
|
use App\Liquid\Filters\Numbers;
|
||||||
|
use App\Liquid\Filters\StandardFilters;
|
||||||
use App\Liquid\Filters\StringMarkup;
|
use App\Liquid\Filters\StringMarkup;
|
||||||
use App\Liquid\Filters\Uniqueness;
|
use App\Liquid\Filters\Uniqueness;
|
||||||
use App\Liquid\Tags\TemplateTag;
|
use App\Liquid\Tags\TemplateTag;
|
||||||
|
|
@ -18,6 +19,7 @@ use Illuminate\Support\Facades\Blade;
|
||||||
use Illuminate\Support\Facades\Http;
|
use Illuminate\Support\Facades\Http;
|
||||||
use Illuminate\Support\Facades\Log;
|
use Illuminate\Support\Facades\Log;
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
|
use Keepsuit\LaravelLiquid\LaravelLiquidExtension;
|
||||||
use Keepsuit\Liquid\Exceptions\LiquidException;
|
use Keepsuit\Liquid\Exceptions\LiquidException;
|
||||||
use Keepsuit\Liquid\Extensions\StandardExtension;
|
use Keepsuit\Liquid\Extensions\StandardExtension;
|
||||||
|
|
||||||
|
|
@ -264,6 +266,7 @@ class Plugin extends Model
|
||||||
|
|
||||||
// Use the Liquid template engine to resolve variables
|
// Use the Liquid template engine to resolve variables
|
||||||
$environment = App::make('liquid.environment');
|
$environment = App::make('liquid.environment');
|
||||||
|
$environment->filterRegistry->register(StandardFilters::class);
|
||||||
$liquidTemplate = $environment->parseString($template);
|
$liquidTemplate = $environment->parseString($template);
|
||||||
$context = $environment->newRenderContext(data: $variables);
|
$context = $environment->newRenderContext(data: $variables);
|
||||||
|
|
||||||
|
|
@ -285,7 +288,7 @@ class Plugin extends Model
|
||||||
$inlineFileSystem = new InlineTemplatesFileSystem();
|
$inlineFileSystem = new InlineTemplatesFileSystem();
|
||||||
$environment = new \Keepsuit\Liquid\Environment(
|
$environment = new \Keepsuit\Liquid\Environment(
|
||||||
fileSystem: $inlineFileSystem,
|
fileSystem: $inlineFileSystem,
|
||||||
extensions: [new StandardExtension()]
|
extensions: [new StandardExtension(), new LaravelLiquidExtension()]
|
||||||
);
|
);
|
||||||
|
|
||||||
// Register all custom filters
|
// Register all custom filters
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
use App\Services\PluginImportService;
|
use App\Services\PluginImportService;
|
||||||
use Livewire\Volt\Component;
|
use Livewire\Volt\Component;
|
||||||
|
use Illuminate\Support\Arr;
|
||||||
use Illuminate\Support\Facades\Cache;
|
use Illuminate\Support\Facades\Cache;
|
||||||
use Illuminate\Support\Facades\Http;
|
use Illuminate\Support\Facades\Http;
|
||||||
use Illuminate\Support\Facades\Log;
|
use Illuminate\Support\Facades\Log;
|
||||||
|
|
@ -26,21 +27,40 @@ new class extends Component {
|
||||||
$catalogContent = $response->body();
|
$catalogContent = $response->body();
|
||||||
$catalog = Yaml::parse($catalogContent);
|
$catalog = Yaml::parse($catalogContent);
|
||||||
|
|
||||||
return collect($catalog)->map(function ($plugin, $key) {
|
$currentVersion = config('app.version');
|
||||||
|
|
||||||
|
return collect($catalog)
|
||||||
|
->filter(function ($plugin) use ($currentVersion) {
|
||||||
|
// Check if Laravel compatibility is true
|
||||||
|
if (!Arr::get($plugin, 'byos.byos_laravel.compatibility', false)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check minimum version if specified
|
||||||
|
$minVersion = Arr::get($plugin, 'byos.byos_laravel.min_version');
|
||||||
|
if ($minVersion && $currentVersion && version_compare($currentVersion, $minVersion, '<')) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
})
|
||||||
|
->map(function ($plugin, $key) {
|
||||||
return [
|
return [
|
||||||
'id' => $key,
|
'id' => $key,
|
||||||
'name' => $plugin['name'] ?? 'Unknown Plugin',
|
'name' => Arr::get($plugin, 'name', 'Unknown Plugin'),
|
||||||
'description' => $plugin['author_bio']['description'] ?? '',
|
'description' => Arr::get($plugin, 'author_bio.description', ''),
|
||||||
'author' => $plugin['author']['name'] ?? 'Unknown Author',
|
'author' => Arr::get($plugin, 'author.name', 'Unknown Author'),
|
||||||
'github' => $plugin['author']['github'] ?? null,
|
'github' => Arr::get($plugin, 'author.github'),
|
||||||
'license' => $plugin['license'] ?? null,
|
'license' => Arr::get($plugin, 'license'),
|
||||||
'zip_url' => $plugin['trmnlp']['zip_url'] ?? null,
|
'zip_url' => Arr::get($plugin, 'trmnlp.zip_url'),
|
||||||
'repo_url' => $plugin['trmnlp']['repo'] ?? null,
|
'repo_url' => Arr::get($plugin, 'trmnlp.repo'),
|
||||||
'logo_url' => $plugin['logo_url'] ?? null,
|
'logo_url' => Arr::get($plugin, 'logo_url'),
|
||||||
'screenshot_url' => $plugin['screenshot_url'] ?? null,
|
'screenshot_url' => Arr::get($plugin, 'screenshot_url'),
|
||||||
'learn_more_url' => $plugin['author_bio']['learn_more_url'] ?? null,
|
'learn_more_url' => Arr::get($plugin, 'author_bio.learn_more_url'),
|
||||||
];
|
];
|
||||||
})->toArray();
|
})
|
||||||
|
->sortBy('name')
|
||||||
|
->toArray();
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
Log::error('Failed to load catalog from URL: ' . $e->getMessage());
|
Log::error('Failed to load catalog from URL: ' . $e->getMessage());
|
||||||
return [];
|
return [];
|
||||||
|
|
|
||||||
|
|
@ -38,10 +38,7 @@ new class extends Component {
|
||||||
|
|
||||||
public function refreshPlugins(): void
|
public function refreshPlugins(): void
|
||||||
{
|
{
|
||||||
$userPlugins = auth()->user()?->plugins?->map(function ($plugin) {
|
$userPlugins = auth()->user()?->plugins?->makeHidden(['render_markup', 'data_payload'])->toArray();
|
||||||
return $plugin->toArray();
|
|
||||||
})->toArray();
|
|
||||||
|
|
||||||
$this->plugins = array_merge($this->native_plugins, $userPlugins ?? []);
|
$this->plugins = array_merge($this->native_plugins, $userPlugins ?? []);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -133,7 +133,7 @@ new class extends Component {
|
||||||
$this->addError('polling_url', 'The polling URL must be a valid URL after resolving configuration variables.');
|
$this->addError('polling_url', 'The polling URL must be a valid URL after resolving configuration variables.');
|
||||||
}
|
}
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
$this->addError('polling_url', 'Error resolving Liquid variables: ' . $e->getMessage());
|
$this->addError('polling_url', 'Error resolving Liquid variables: ' . $e->getMessage() . $e->getPrevious()?->getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -148,7 +148,7 @@ new class extends Component {
|
||||||
$this->data_payload_updated_at = $this->plugin->data_payload_updated_at;
|
$this->data_payload_updated_at = $this->plugin->data_payload_updated_at;
|
||||||
|
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
$this->dispatch('data-update-error', message: $e->getMessage());
|
$this->dispatch('data-update-error', message: $e->getMessage() . $e->getPrevious()?->getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -690,7 +690,10 @@ HTML;
|
||||||
<flux:checkbox label="{{ $label }}" value="{{ $value }}"/>
|
<flux:checkbox label="{{ $label }}" value="{{ $value }}"/>
|
||||||
@endforeach
|
@endforeach
|
||||||
@else
|
@else
|
||||||
<flux:checkbox label="{{ $option }}" value="{{ $option }}"/>
|
@php
|
||||||
|
$key = mb_strtolower(str_replace(' ', '_', $option));
|
||||||
|
@endphp
|
||||||
|
<flux:checkbox label="{{ $option }}" value="{{ $key }}"/>
|
||||||
@endif
|
@endif
|
||||||
@endforeach
|
@endforeach
|
||||||
@endif
|
@endif
|
||||||
|
|
|
||||||
|
|
@ -38,6 +38,11 @@ it('loads plugins from catalog URL', function () {
|
||||||
'trmnlp' => [
|
'trmnlp' => [
|
||||||
'zip_url' => 'https://example.com/plugin.zip',
|
'zip_url' => 'https://example.com/plugin.zip',
|
||||||
],
|
],
|
||||||
|
'byos' => [
|
||||||
|
'byos_laravel' => [
|
||||||
|
'compatibility' => true,
|
||||||
|
]
|
||||||
|
],
|
||||||
'logo_url' => 'https://example.com/logo.png',
|
'logo_url' => 'https://example.com/logo.png',
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,9 @@
|
||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
use App\Liquid\Filters\StandardFilters;
|
||||||
use App\Models\Plugin;
|
use App\Models\Plugin;
|
||||||
|
use Keepsuit\Liquid\Environment;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests for the Liquid where filter functionality
|
* Tests for the Liquid where filter functionality
|
||||||
|
|
@ -92,3 +94,31 @@ LIQUID
|
||||||
// Should not contain the low tide data
|
// Should not contain the low tide data
|
||||||
$this->assertStringNotContainsString('"type":"L"', $result);
|
$this->assertStringNotContainsString('"type":"L"', $result);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('encodes arrays for url_encode as JSON with spaces after commas and then percent-encodes', function () {
|
||||||
|
/** @var Environment $env */
|
||||||
|
$env = app('liquid.environment');
|
||||||
|
$env->filterRegistry->register(StandardFilters::class);
|
||||||
|
|
||||||
|
$template = $env->parseString('{{ categories | url_encode }}');
|
||||||
|
|
||||||
|
$output = $template->render($env->newRenderContext([
|
||||||
|
'categories' => ['common', 'obscure'],
|
||||||
|
]));
|
||||||
|
|
||||||
|
expect($output)->toBe('%5B%22common%22%2C%22obscure%22%5D');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('keeps scalar url_encode behavior intact', function () {
|
||||||
|
/** @var Environment $env */
|
||||||
|
$env = app('liquid.environment');
|
||||||
|
$env->filterRegistry->register(StandardFilters::class);
|
||||||
|
|
||||||
|
$template = $env->parseString('{{ text | url_encode }}');
|
||||||
|
|
||||||
|
$output = $template->render($env->newRenderContext([
|
||||||
|
'text' => 'hello world',
|
||||||
|
]));
|
||||||
|
|
||||||
|
expect($output)->toBe('hello+world');
|
||||||
|
});
|
||||||
Loading…
Add table
Add a link
Reference in a new issue