The PHP framework behind SitioYa

Koshkil documentation

Getting started

Introduction

Koshkil is a lightweight MVC-style PHP framework, and the foundation SitioYa is built on. It covers what almost every site needs (routing, controllers, templates, database access, users and permissions, translations, an API and caching) with very little configuration and without forcing a rigid structure.

What it includes

Area What it does Where it lives
Routing Turns the URL into a controller, action and arguments. Regular-expression rewrite rules. core/http/Route.php, core/http/RewriteManager.php
Controllers Lifecycle with hooks, access control, HTML, JSON or JavaScript responses. core/web/, src/Controllers/
Views Smarty 4 templates organized in themes, reusable widgets and custom Smarty plugins. core/web/View.php, webroot/themes/
Models Active record with a chainable query builder, relations, events and behaviors. The schema is created and updated automatically. core/db/
Security Sessions (files or database), users, roles and rules with bitwise permissions. core/http/Session.php, core/models/
Internationalization JSON translations per language and domain, __() helpers and {t} tags. core/tools/I18n.php, config/locales/
REST API A single entry point, class.method actions, batch calls and in-process use without HTTP. core/web/Rest/, src/api/
Cache File, Redis and null engines, configured per usage domain. core/cache/
Plugins Self-contained modules with their own controllers, models, templates, permissions and menu. plugins/

Key concepts

  • Convention over configuration. The URL /productos/ver/15 runs ProductosController::ver(15) and renders the productos/ver.tpl template without registering anything.
  • Per-domain configuration. One codebase serves several sites. Each domain can override any file in config/ from config/domains/<domain>/, including the theme.
  • Everything goes through Koshkil. The static Koshkil class loads files (Koshkil::Uses()) and models (Koshkil::UsesModel()), builds links (Koshkil::getLink()) and holds the current controller (Koshkil::$controller).
  • Declarative schema. Each model describes its table in code. With Database.AutoUpdateSchema enabled, Koshkil creates the table and keeps it in sync with that definition (see Models).

A quick look

A controller and its template:

<?php
// src/Controllers/SaludoController.php  ->  /saludo  and  /saludo/hola/Daniel
Koshkil::Uses('com.SuperController');

class SaludoController extends SuperController {

    public function index() {
        $this->set(['mensaje' => 'Welcome']);
    }

    public function hola($nombre = 'world') {
        $this->set(['nombre' => $nombre]);
    }
}
{* webroot/themes/<theme>/templates/front/saludo/hola.tpl *}
<h1>Hello, {$nombre|escape}</h1>

A model and its table:

<?php
// src/Models/productos.php  ->  Koshkil::UsesModel('productos')  ->  TMProductos
class TModelProductos extends TModel {
    protected $tableName = 'tbl_productos';
    public $primaryKeyColumn = 'prd_codigo';
    protected $fillable = ['prd_nombre', 'prd_precio'];

    protected function setupTableStructure() {
        $this->table->id('prd_codigo')
            ->varchar('prd_nombre', 120, false, '')
            ->decimal('prd_precio', 10, 2, false, 0);
    }
}

$cheap = TMProductos::where('prd_precio', '<', 1000)->order('prd_nombre')->get();

How to read this documentation

  1. Start with Installation and Project structure.
  2. Request lifecycle explains how all the pieces fit together.
  3. After that, each chapter can be read on its own, depending on what you need.

Conventions

File paths are relative to the project root. <theme> is the value of Templates.Theme and <domain> is the server name ($_SERVER['SERVER_NAME']). SitioYa's own code uses Spanish names (usuarios, productos…); the examples keep them so they match the real code.