Skip to main content

Scriptable

This module allows you to create and manage scripts that can be executed from the admin panel.

caution

This module is ONLY intended for advanced users and developers. It allows you to execute PHP code and Twig templates, which can be dangerous if not used properly.

Installation

composer require qore/scriptable

Publish:

php artisan vendor:publish --tag=qore.scriptable.db
php artisan vendor:publish --tag=qore.scriptable.frontend

Optionally, publish config:

php artisan vendor:publish --tag=qore.scriptable.config

Migrate:

php artisan tenants:migrate

Generate a policy for the Scriptable model:

<?php

namespace App\Policies;

use App\Models\Central\User;
use Illuminate\Auth\Access\HandlesAuthorization;
use Qore\Scriptable\Models\Tenant\Scriptable;

class ScriptablePolicy
{
use HandlesAuthorization;

public function viewAny(User $user): bool
{
return $user->canViewAny('scriptables');
}

public function view(User $user, Scriptable $model): bool
{
return $user->canView('scriptables', $model) && $this->hasAccessThroughRoles($user, $model);
}

public function create(User $user): bool
{
return $user->canCreate('scriptables');
}

public function update(User $user, Scriptable $model): bool
{
return $user->canUpdate('scriptables', $model) && $this->hasAccessThroughRoles($user, $model);
}

public function delete(User $user, Scriptable $model): bool
{
return $user->canDelete('scriptables', $model) && $this->hasAccessThroughRoles($user, $model);
}

private function hasAccessThroughRoles(User $user, Scriptable $model): bool
{
return $model->roles->isEmpty() || $user->hasAnyRole($model->roles);
}
}

Then register the policy in the AuthServiceProvider:

Scriptable::class => ScriptablePolicy::class,

Then add a menu item in GlobalsController:

$tab->addResourceMenuItem(resource('scriptables'));

Usage

You can write scripts (PHP & Twig) in the admin panel and execute.

Scope

You can use every method from the application. E.g., if you want to retrieve users you can do:

PHP Code:

dd(
resource('users')->model()::select('id', 'name')
->get()->toArray()
);

Database

To get an overview of the database schema:

PHP Code:

$tenantDb = config('database.connections.tenant.database');

$query = "
SELECT
TABLE_NAME,
COLUMN_NAME,
DATA_TYPE
FROM
INFORMATION_SCHEMA.COLUMNS
WHERE
TABLE_SCHEMA = ?
ORDER BY
TABLE_NAME,
ORDINAL_POSITION
";

$results = DB::select($query, [$tenantDb]);

dd($results);

POST requests

You can send POST requests to the script by using the the scriptable.post call:

PHP Code:

if (request()->arg1 === 'testFunction') {
echo "<br>Test function called!<br>";
echo "Arg2 value: " . request()->get('arg2') . "<hr>";
}

Twig Code:

<strong>Hello world</strong>

<button onclick="scriptable.post(event, { arg1: 'testFunction', arg2: 'test' })">Test me</button>

Events

You can listen to the following events:

Event::listen(ScriptableBeforeRender::class, function (ScriptableBeforeRender $event) {
dd($event->getScriptable());
});

Event::listen(ScriptableAfterRender::class, function (ScriptableAfterRender $event) {
activity()
->causedBy(auth()->user() ?? null)
->performedOn($scriptable)
->withProperties([
'attributes' => [
'php_code' => $scriptable->php_code,
'twig_code' => $scriptable->twig_code,
]
])
->log('rendered');

dd($event->getScriptable(), $event->getOutput());
});

Event::listen(ScriptableRenderOnError::class, function (ScriptableRenderOnError $event) {
dd($event->getScriptable(), $event->getError());
});

AI Integration

You can make use of the qore/openai plugin to integrate AI into your scripts.

Go to the docs for more information: OpenAI plugin