menu_book Navigation menu

Handling Data

Pragma CMS is designed to stay out of your way. We deliberately avoid heavy ORM layers that obscure performance and generate unpredictable database queries. Instead, we provide a clean separation between Context Objects, Static Managers, and Global Helpers that act as a high-performance API for your site.

PHP: The Global Context Objects

Whenever a controller or template is loaded, Pragma CMS automatically injects global objects that represent the current state of the application. You do not need to fetch these; they are simply available.

  • $site: Contains global configurations, the current active language code, and fallback settings (e.g., $site->url$site->langCode$site->settings['admin_email']).
  • $page: Represents the current route's context. It holds the active view data, SEO metadata, breadcrumbs, and dynamic URL parameters (e.g., $page->currentRoute['params']['slug']).

PHP: The Manager Pattern

To actually retrieve data from the database, Pragma uses specialized Static Managers. These classes automatically handle SQL preparation, security filtering, JSON decoding, and multi-language mapping.

Core Managers Cheat Sheet

ManagerPrimary UseExample Methods
ContentTypeManagerManaging schema structures.ContentTypeManager::get($handle)
EntryManagerFetching dynamic content (Articles, Products).EntryManager::getEntryBySlug()EntryManager::getEntries()
PageManagerRetrieving static or builder-based pages.PageManager::getPageBySlug()
MediaManagerAccessing file metadata and variant paths.MediaManager::getMediaById()
TaxonomyManagerFetching categories, tags, and structure.TaxonomyTermManager::getTermsForObject()
UserManagerAccessing profiles and permission checks.UserManager::getUsers(), UserManager::getUserById()
BreadcrumbManagerManaging hierarchical site paths.BreadcrumbManager::renderBreadcrumbs()
FormManagerRendering frontend forms.FormManager::renderForm()
SeoManagerInjecting metadata and JSON-LD.SeoManager::configureForSingleEntry()
info
Note
This cheat sheet covers the most commonly used Core Managers.

Additional specialized managers are available in the PHP API.

See the PHP API Reference section below for the full list.

Common Pattern: Displaying a Portfolio Landing Page

Here is how Context Objects ($page) and Managers (PageManagerEntryManager) work together in a typical controller:

PHP
<?php
/**
 * Custom Controller: /sites/<your-site>/pages/portfolio.php
 */

// 1. Fetch data for the current page using the slug 'portfolio'
// Note: $_SESSION['lang_id'] is automatically handled by the Core Bootstrap.
$slug = $page->currentRoute['params']['slug'] ?? 'portfolio';
$pageData = PageManager::getPageBySlug($slug, $_SESSION["lang_id"]);

if (!$pageData) {
    // If the user deleted the page in the admin, show 404
    displayError(getTranslation("Not Found"), 404);
    exit;
}

// 2. Add your custom business logic
// Example: Fetching 12 projects from the 'projects' collection
$projects = EntryManager::getEntries('projects', ['limit' => 12]);

// 3. Prepare View Data
$page->entry = $pageData;
$page->viewData["title"] = $pageData["title"];
$page->viewData["projects"] = $projects;

// 4. Set SEO & Breadcrumbs (Standard Helpers)
// This automatically sets <title>, meta description, and OpenGraph tags based on Admin data.
$page = SeoManager::configureForSingleEntry($page, $pageData, $site, $page->currentRoute['handle'], $_SESSION["lang_id"]);

// 5. Render
$page->header   = renderHeader($page);
$page->footer   = renderFooter($page);
$page->template = $pageData['template_path'] ?? "portfolio.php"; // Looks in your active theme /templates/
$page->main     = render_template($page->template, $page);

echo render_template("base.php", $page);

PHP: The Database Class (Raw SQL)

When building Custom Extensions or querying custom tables that are not part of the standard CMS content types, you should bypass the Managers and use the Database class directly.

It is a secure, static wrapper around PHP's PDO, ensuring all queries use prepared statements to prevent SQL injection.

Reading Data (Select)

PHP
// Fetch multiple rows (Returns an array of associative arrays)
$activeUsers = Database::fetchAll(
    "SELECT * FROM custom_bookings WHERE status = :status ORDER BY created_at DESC", 
    ['status' => 'confirmed']
);

// Fetch a single row (Returns an associative array or null)
$booking = Database::fetch(
    "SELECT * FROM custom_bookings WHERE booking_id = :id", 
    ['id' => 142]
);

// Fetch a single column value directly (Returns a string/int or false)
$totalRevenue = Database::fetchColumn(
    "SELECT SUM(price) FROM custom_bookings WHERE status = :status", 
    ['status' => 'paid']
);

Writing Data (Insert, Update, Delete)

Use Database::updateTable() for any query that modifies data. It automatically handles the execution and returns a boolean.

PHP
$success = Database::updateTable(
    "INSERT INTO custom_bookings (user_id, total, status) VALUES (:user, :total, :status)",
    [
        'user' => 12,
        'total' => 250.00,
        'status' => 'pending'
    ]
);

if ($success) {
    $newId = Database::lastInsertId();
} else {
    $error = Database::getError(); // Returns PDO error info [SQLSTATE, Code, Message]
}

Transactions

For complex operations requiring atomicity, wrap your queries in a transaction:

PHP
Database::beginTransaction();

$insert1 = Database::updateTable("...");
$insert2 = Database::updateTable("...");

if ($insert1 && $insert2) {
    Database::commit();
} else {
    Database::rollBack();
    logError("Transaction failed.");
}

PHP Global Functions

To accelerate development, Pragma CMS exposes a set of globally available helper functions (functions.php) accessible from any controller, extension, or template.

Routing & URLs

  • getLink(string $routeHandle, array $params = [])

    Dynamically generates a translated URL based on the route handle. It automatically handles the active language prefix.
PHP
// Returns: https://domain.com/en/blog/my-article
echo getLink('front.articles.show', ['slug' => 'my-article']);
  • getAssetsPath(string $path, bool $isTheme = false, ?string $extension = null)

    Resolves the correct public URL for CSS/JS assets, handling the fallback priority (Theme > Site > Core).

Templating & UI

  • render_template(string $templateRelativePath, array|object $data = [])

    Automatically detects and renders either a .twig or native .php template, following the CMS hierarchy override rules.
  • renderImage(int|array $mediaData, string $sizeSuffix = 'large', array $attributes = [])

    Outputs a fully optimized <picture> HTML tag, automatically serving AVIF/WebP formats with the correct srcset attributes for Core Web Vitals optimization.
  • renderIcon(string $library, string $name)

    Generates the SVG or Font icon HTML based on the library (e.g., material-symbols-outlinedfa-solid).

Utilities & API

  • getTranslation(string $key, array $params = [])

    Fetches the localized string from the dictionary. Supports variables injection (['name' => 'John']) and pluralization.
  • generate_slug(string $text, ?array $uniquenessCheck = null)

    Generates a clean, URL-friendly string. Can automatically query the database to guarantee uniqueness by appending a numerical suffix if a collision occurs.
  • sendJsonResponse(bool $success, ?string $message = null, $data = null, int $httpCode = 200)

    The universal exit point for API endpoints. It cleans the output buffer, sets the correct application/json headers, and enforces a standard JSON schema structure.

JavaScript Global Functions

In modern web development, many front-end features (infinite scroll, live filters, dynamic modals, headless interactions) require fetching data without reloading the page. Pragma CMS includes native, lightweight wrappers around the JS Fetch API.

The apiRequest Utility

apiRequest is the universal engine for all AJAX calls in the CMS.

Why use apiRequest instead of native fetch()?

  1. Error Handling: It natively parses JSON, catches HTTP errors (4xx, 5xx), and automatically triggers UI popups (displayErrorPopup()) if something goes wrong.
  2. Multiple Formats: It seamlessly handles "json""html" (for DOM injection), and "blob" (for file downloads).
  3. Smart Headers: Automatically injects the X-Requested-With: XMLHttpRequest header.
  4. Loader Integration: Connects to showLoader() to provide visual feedback.

Usage Example: Submitting data or loading HTML

JAVASCRIPT
// Example 1: Fetching JSON data
const response = await apiRequest('/api/custom-endpoint', {
    method: 'POST',
    body: JSON.stringify({ action: 'update_status' })
});

if (response && response.success) {
    console.log(response.data);
}

// Example 2: Fetching an HTML fragment for a modal
const htmlFragment = await apiRequest('/api/modals/user-card?id=1', {}, null, 'html');
if (htmlFragment) {
    document.getElementById('modal-container').innerHTML = htmlFragment;
}

The apiFetch Utility

For strictly querying CMS content (Entries, Taxonomies, Users), Pragma provides apiFetch. It is built on top of apiRequest and specifically formats URLs with search parameters, language context, and extra filters.

Usage Example: Loading categories with a live search

JAVASCRIPT
// apiFetch(endpoint, searchTerm, langId, extraParams)
const searchInput = "tech";
const langId = 1; // e.g., English

const response = await apiFetch("taxonomies/blog_category/terms", searchInput, langId, {
    root_term_id: 12,
    limit: 10
});

if (response) {
    // response.data is guaranteed to be present if the call succeeds
    renderDropdown(response.data); 
}

API Reference

menu_book
Deep Dive
Need a complete list of every method, parameter, and return type?

Explore the PHP API Reference

Explore the JS API Reference