The PHP framework behind SitioYa

Koshkil documentation

Services

Plugins

What a plugin is

A plugin is a self-contained module inside plugins/<name>/: it has its own controllers, models, widgets, API endpoints, templates, translations, permissions, admin menu and rewrite rules. SitioYa ships, among others, noticias, clasificados, mensajes, stock, tablas and multidomain.

Creating one

./app/bin/create-plugin.sh tienda

It creates this structure:

plugins/tienda/
├── config/
│   ├── config.php          'enabled' => true
│   ├── permissions.php     rules, roles and assignments
│   ├── menu.php            admin menu items
│   ├── rewrite.php         rewrite rules
│   ├── domains/            per-domain overrides
│   └── locales/{es,en,pt}/ translations
├── src/
│   ├── Controllers/        (Admin/, Ajax/…)
│   ├── Models/
│   ├── Widgets/
│   ├── Api/                endpoints: plugins.tienda.<class>.<method>
│   ├── Components/  Hooks/  Libraries/
└── webroot/
    ├── css/  js/
    └── templates/          admin/, front/, widgets/

Activation

PluginsManager::getInstalledPlugins() scans plugins/ on every request and activates those with 'enabled' => true in config/config.php. Each domain can change that:

<?php
// plugins/tienda/config/domains/mysite.com/config.php
$CONFIG = ['enabled' => false];

The list of active plugins is in PluginsManager::$installedPlugins. The rest of config.php is read with:

PluginsManager::readPluginConfig('tienda', 'currency', 'ARS');
PluginsManager::writePluginConfig('tienda', 'currency', 'USD');

URLs

The first URL segment (after admin/, if present) selects the plugin:

URL Controller
/tienda/carrito plugins/tienda/src/Controllers/CarritoController.php
/admin/tienda/productos/editar/4 plugins/tienda/src/Controllers/Admin/ProductosController.phpeditar(4)
/tienda/js/carrito.js the file plugins/tienda/webroot/js/carrito.js

Templates are looked up in plugins/tienda/webroot/templates/<front|admin>/, and the plugin's widgets are used with {html_widget type="plugins.tienda.front.carrito"}.

Permissions

<?php
// plugins/tienda/config/permissions.php
$PERMISSIONS = [
    'rules' => [
        'tienda'           => ['name' => 'Shop access',        'attributes' => 15],
        'tienda_productos' => ['name' => 'Product management', 'attributes' => 15],
    ],
    'roles' => [
        'Tienda' => 0,
    ],
    'rules_roles' => [
        'Tienda' => [
            'tienda'           => 8,    // view only
            'tienda_productos' => 15,   // everything
        ],
    ],
];

attributes are the permissions the rule supports (bits for add=1, edit=2, delete=4, view=8; see Security). Rules and roles are created or updated automatically when the file changes.

Admin menu

<?php
// plugins/tienda/config/menu.php
$MENU = [
    'tienda' => [
        'rules'    => 'tienda',
        'text'     => __('main', [], 'menu', 'tienda'),
        'iconmenu' => 'fa fa-shopping-cart',
        'link'     => Koshkil::getLink('admin/tienda/index'),
        'options'  => [
            'productos' => [
                'text'  => __('products', [], 'menu', 'tienda'),
                'rules' => 'tienda&tienda_productos',
                'link'  => Koshkil::getLink('admin/tienda/productos/listado'),
            ],
        ],
    ],
];

Each item is shown only to users who meet its roles or rules.

Rewriting

<?php
// plugins/tienda/config/rewrite.php
$RULES = [
    ['rule' => '^tienda/producto/([0-9]+)$', 'target' => '/tienda/productos/ver/$1', 'flags' => 'L,NC'],
];

There is also a per-domain version: config/domains/<domain>/rewrite.php.

Models and extending users

Koshkil::UsesModel('tienda.productos');     // plugins/tienda/src/Models/productos.php -> TMProductos

If the plugin defines a usuarios behavior (class TiendaUsuariosBehavior in plugins/tienda/src/Models/Behaviors/Usuarios.php), it is attached to the users model automatically: this is how a plugin adds methods such as $usuario->pedidos() without touching the core. In plugins, a behavior's class is prefixed with the plugin name.

Template integration

A theme can include the pieces contributed by every active plugin:

{include_plugins folder="admin/dashboard"}              {* every plugin/webroot/templates/admin/dashboard/*.tpl *}
{include_plugins_scripts file="admin/dashboard.js"}