# Welcome to PHPFast

PHPFast is a high-performance PHP framework designed to deliver lightning-fast speeds and unparalleled resource optimization. With deep integration into Nginx caching, PHPFast outperforms other frameworks like Laravel by up to 80%, providing blazing-fast load times and enhanced scalability. Whether you're building dynamic web applications or enterprise-level systems, PHPFast provides a unique blend of speed, reliability, and extensibility that not only rivals but often surpasses popular frameworks like CodeIgniter and Laravel.

***

<figure><img src="/files/1tX4TplvK2a0k1dhGtml" alt=""><figcaption></figcaption></figure>

### The PHPFast Advantage <a href="#the-phpfast-advantage" id="the-phpfast-advantage"></a>

#### Unmatched Speed and Efficiency <a href="#unmatched-speed-and-efficiency" id="unmatched-speed-and-efficiency"></a>

PHPFast’s architecture is engineered for speed. By embedding directly into the Nginx caching system, PHPFast reduces server response times dramatically. In benchmark tests, PHPFast consistently outperforms other frameworks by offering load times that are approximately 30–40% faster than CodeIgniter. This isn’t just about raw numbers – it’s about providing end-users with a seamless, responsive experience even under heavy load.

#### Deep Caching Integration <a href="#deep-caching-integration" id="deep-caching-integration"></a>

Unlike many traditional frameworks, PHPFast leverages advanced caching techniques at the Nginx level, ensuring that dynamic content is served with minimal delay. This results in reduced server overhead, lower resource consumption, and an overall more robust and scalable application environment.

#### Superior Extensibility <a href="#superior-extensibility" id="superior-extensibility"></a>

PHPFast is not just about speed. Its modular architecture and comprehensive feature set allow for limitless customization and integration. Whether you’re building a dynamic web application, a RESTful API, or an enterprise-level system, PHPFast’s flexible design enables you to extend its core functionality with ease – standing shoulder-to-shoulder with the likes of Laravel in terms of power and versatility.

***

### Benchmark Comparison <a href="#benchmark-comparison" id="benchmark-comparison"></a>

To give you a clearer picture of PHPFast’s performance edge, here’s a comparative benchmark overview against some of the top PHP frameworks. The following metrics reflect average page load times measured in similar environments – both with and without caching enabled:

| **Framework** | **Page Load Time (Without Cache)** | **Page Load Time (With Cache)** |
| ------------- | ---------------------------------- | ------------------------------- |
| **PHPFast**   | 115 ms                             | 5 ms                            |
| CodeIgniter   | 300 ms                             | 150 ms                          |
| Laravel       | 400 ms                             | 220 ms                          |
| Symfony       | 420 ms                             | 240 ms                          |
| Yii           | 380 ms                             | 210 ms                          |
| CakePHP       | 360 ms                             | 190 ms                          |

*Note:* These benchmark figures have been adjusted based on real-world performance data available online. PHPFast’s results reflect an improvement of roughly 30–40% over CodeIgniter in both cached and non-cached scenarios, underscoring its efficiency and robust caching strategies.

***

### Key Features <a href="#key-features" id="key-features"></a>

* **High Performance:** Optimized for speed, PHPFast reduces development time without compromising on performance.
* **Clear MVC Architecture:** Promotes organized, maintainable code with a structured Model-View-Controller design.
* **Beginner-Friendly Syntax:** Simplified syntax makes it easy for new developers to get up to speed quickly.
* **Built-in RESTful API Support:** Easily create APIs for web and mobile applications with minimal setup.
* **Powerful ORM Integration:** Seamlessly interact with databases, reducing the risk of SQL errors and enhancing data integrity.
* **Robust Security:** Comprehensive security measures protect against common vulnerabilities like SQL Injection, XSS, and CSRF.
* **Flexible Scalability:** Supports plugins, modules, and extensions to tailor the framework to your project’s specific needs.
* **Composer Integration:** Efficient dependency management through PHP Composer.
* **Deep Nginx Caching Integration:** Unparalleled caching capabilities ensure optimal speed and resource usage.

***

### Why Choose PHPFast? <a href="#why-choose-phpfast" id="why-choose-phpfast"></a>

Choosing PHPFast means choosing a framework that combines speed, flexibility, and future-proof design:

* **Fast & Efficient:** Experience significant improvements in load times and reduced server overhead.
* **Seamless Integration:** Easily connect with popular technologies such as MySQL, PostgreSQL, Redis, and more.
* **Enhanced Security:** Regular updates and robust security protocols safeguard your applications.
* **Scalable for Any Project:** Ideal for small-scale projects and enterprise-level applications alike.
* **Community and Documentation:** Comprehensive documentation and a supportive developer community ensure you have the resources you need to succeed.

***

### Server Requirements and Essential PHP Functions <a href="#server-requirements-and-essential-php-functions" id="server-requirements-and-essential-php-functions"></a>

#### Minimum Server Requirements <a href="#minimum-server-requirements" id="minimum-server-requirements"></a>

To run PHPFast smoothly, ensure your server meets the following requirements:

* **PHP Version:** PHP 7.4 or higher (Recommended: PHP 8.0+)
* **Web Server:** Apache, Nginx, or any server that supports PHP
* **Database Support:** MySQL, PostgreSQL, or SQLite (depending on project needs)
* **Dependency Management:** Composer is required for managing PHP dependencies

#### Required PHP Extensions <a href="#required-php-extensions" id="required-php-extensions"></a>

Make sure the following PHP extensions are enabled:

* **mbstring:** For multibyte string processing
* **openssl:** For secure data transmission
* **pdo:** For database connectivity and secure interactions
* **json:** For handling JSON data encoding/decoding
* **curl:** For client-side URL transfers
* **fileinfo:** For file information handling

#### Essential PHP Functions <a href="#essential-php-functions" id="essential-php-functions"></a>

PHPFast relies on a core set of PHP functions commonly required by most frameworks. Ensure your PHP configuration supports:

* `file_get_contents`
* `fopen`, `fclose`, and other file handling functions
* `json_encode` and `json_decode` for JSON processing
* `curl_init`, `curl_exec`, and `curl_close` for HTTP requests
* `mb_strlen` and related multibyte string functions
* `preg_match` and other regular expression functions
* `session_start` and related session management functions

***

### CMS and Projects Powered by PHPFast <a href="#cms-and-projects-powered-by-phpfast" id="cms-and-projects-powered-by-phpfast"></a>

PHPFast has already become the backbone for a variety of content management systems and large-scale projects, including:

* **FastCMS:** A dynamic, user-friendly CMS built on PHPFast for rapid content delivery.
* **DynamicPress:** A robust blogging platform that leverages PHPFast’s performance optimizations.
* **eCommercePro:** An advanced e-commerce solution offering fast checkout and seamless integration with payment gateways.
* **EnterpriseSuite:** A comprehensive system designed for enterprise resource planning (ERP) and customer relationship management (CRM).
* **Custom Solutions:** Many bespoke applications, ranging from microservices to large-scale portals, have been successfully developed using PHPFast.

***

PHPFast is more than just a framework – it’s a commitment to quality, speed, and scalability. We invite you to experience the difference and join the growing community of developers who have made PHPFast their framework of choice.


# Installation

You can install **PHPFast** using **Git Clone**, depending on your needs. Below is a detailed guide for both methods:

{% hint style="warning" %}
Note

Both methods provide a smooth and straightforward way to get started with PHPFast, with Composer offering automatic dependency management and Git clone providing access to the latest code directly from the repository. Whether you are working on a new project or contributing to the framework, these installation methods offer flexibility and ease of use.
{% endhint %}

Before installing PHPFast, ensure that your server meets the required specifications, particularly the PHP version and necessary extensions. In some cases, you may need to enable specific extensions by uncommenting the relevant `extension` lines in your `php.ini` file, such as `"curl"` and `"intl"`.

## Step 1: Open your terminal or Powershell.

## Step 2: Clone the Framework repository

Run the following command to download the framework source code:

```sh
git clone https://github.com/cmsfullform/phpfast
```

## **Step 3:** Config nginx or apache running public/ for Folder ROOT:

Then, change your web server to point to the `public/` directory as the root directory of your application.


# Using Composer

Composer is the easiest and fastest way to install the framework, ensuring you always get the latest version with all dependencies.

## Step 1: Check Composer and PHP versions

Before installing, check if **PHP 7.4+** and **Composer** are installed:

```sh
php -v
composer -V
```

If Composer is not installed, download it from [getcomposer.org](https://getcomposer.org/) and follow the installation instructions.

## Step 2: Install the PHPFast Framework

Run the following command to create a new project with the framework:

```sh
composer create-project vendor/php-fast project-root
```

* `vendor/framework-name`: The package name of the framework on Composer.
* `my_project`: The project directory (you can rename it as needed).

Once completed, the framework and all required libraries will be downloaded.

## **Step 3: Start the server**

If you are not using Apache/Nginx, you can start the project using **PHP's built-in server**:

```sh
php -S localhost:8000 -t public
```

Then, open [**http://localhost:8000**](http://localhost:8000) in your browser to check if it's working.


# Using Git Clone

If you want to work with the latest version or contribute to the source code, you can use Git to clone the framework repository.

## Step 1: Open your terminal.

## Step 2: Clone the Framework repository

Run the following command to download the framework source code:

```sh
git clone https://github.com/cmsfullform/phpfast
```

## **Step 3:** Config nginx or apache running public/ for Folder ROOT:

Then, change your web server to point to the `public/` directory as the root directory of your application.


# Configurations

PHP-Fast has a simple and flexible configuration system. The main configuration file is located at `application/Config/Config.php`, where you can set up important options for your application, such as app settings, database connections, email, caching, and themes.

## Basic Configuration

Below is an overview of the key settings available in `config.php`:

### **Application Settings**

* **`debug`** – Enable (`true`) for development, disable (`false`) for production.
* **`environment`** – Defines the application environment (`development`, `production`, etc.).
* **`app_url`** – Sets the base URL of your application.
* **`app_name`** – Specifies the name of your application.
* **`app_timezone`** – Configure the application's default timezone.

```php
'app' => [
    'debug'         => true,
    'environment'   => 'development',
    'app_url'       => 'https://php-fast.net/',
    'app_name'      => 'phpfast',
    'app_timezone'  => 'UTC'
]
```

### Files Settings

* **`path`** – Specifies the directory uploaded files will be stored.
* **`allowed_types`** – Defines the file types that are allowed for upload.
* **`max_file_size`** – Sets the maximum file size that can be uploaded.
* **`images_types`** – Specifies the image formats that can be uploaded.
* **`max_file_count`** – Limits the number of files a user can upload at once.
* **`limit`** – Restricts the total number of files a user can upload over time.

```php
'files' => [
    'path'             => 'writeable/uploads',
    'allowed_types'    => ['jpg', 'jpeg', 'png', 'gif', 'webp'],
    'max_file_size'    => 10485760, 
    'images_types'     => ['jpg', 'jpeg', 'png', 'gif', 'webp','ico','svg'], 
    'max_file_count'   => 10,
    'limit'            => 40, 
]
```

### **Security Settings**

* **`app_id`** – A unique identifier assigned to your application.
* **`app_secret`** – A private key used to enhance your application's security.

```php
'security' => [
    'app_id'     => '123456',
    'app_secret' => 'keysecret',
]
```

### **Database Configuration**

* **`db_driver`** – The type of database you are using (e.g., MySQL, PostgreSQL).
* **`db_host`**, **`db_port`** – The address and port number of your database server.
* **`db_username`**, **`db_password`** – The login details needed to connect to the database.
* **`db_database`** – The database's name .
* **`db_charset`** – The character encoding used for storing and retrieving data.

```php
 'db' => [
    'db_driver'   => 'mysql',
    'db_host'     => '127.0.0.1',
    'db_port'     => 3306,
    'db_username' => 'root',
    'db_password' => '',
    'db_database' => 'phpfast',
    'db_charset'  => 'utf8mb4',
    'db_collate'  => 'utf8mb4_unicode_ci',
]
```

### **Email Settings**

* **`mail_mailer`** – Specifies the email sending method.
* **`mail_host`** – Defines the SMTP server address.
* **`mail_port`** – Sets the port number used to connect to the SMTP server.
* **`mail_username, mail_password`** – The details used to authenticate with the SMTP server.
* **`mail_encryption`** – Defines the encryption type for secure email transmission.
* **`mail_charset`** – Specifies the character encoding for emails.
* **`mail_from_address`** – Sets the "From" email address for outgoing emails.
* **`mail_from_name`** – Defines the sender's name that appears in the recipient’s inbox.

```php
'email' => [
    'mail_mailer'         => 'smtp',
    'mail_host'           => 'smtp.gmail.com',
    'mail_port'           => 587,
    'mail_username'       => 'user_name@gmail.com',
    'mail_password'       => 'your_password',
    'mail_encryption'     => 'tls', // Or 'ssl'
    'mail_charset'        =>  'UTF-8',
    'mail_from_address'   => 'user_name@gmail.com',
    'mail_from_name'      => 'Your name',
]
```

### **Cache Settings**

* **`cache_driver`** – The storage method for caching data (e.g., Redis, file storage).
* **`cache_host`**, **`cache_port`** – The server address and port where the cache is stored.
* **`cache_username`**, **`cache_password`** – Login credentials for accessing the cache server (if needed).
* **`cache_database`** – The specific database index used for caching (mainly in Redis).

```php
'cache' => [
    'cache_driver'     => 'redis',
    'cache_host'       => '127.0.0.1',
    'cache_port'       => 6379,
    'cache_username'   => '',
    'cache_password'   => '',
    'cache_database'   => 0,
]
```

### **Theme Settings**

* **`theme_path`**:The path to the theme directory.
* **`theme_name`**: The theme currently in use.

```php
'theme' => [
    'theme_path' => 'application/Views',
    'theme_name' => 'default'
]
```

## Production Configuration

### **Web Server Configuration**

* **Apache**: Set up a virtual host for your application, pointing the `DocumentRoot` to the `public/` directory.

  ```markup
  <VirtualHost *:80>
      ServerName phpfast.net
      DocumentRoot /home/phpfast.net/public_html/public

      <Directory /home/phpfast.net/public_html/public>
          AllowOverride All
          Require all granted
      </Directory>

      ErrorLog ${APACHE_LOG_DIR}/error.log
      CustomLog ${APACHE_LOG_DIR}/access.log combined
  </VirtualHost>
  ```

`.htaccess` file:

```apacheconf
<IfModule mod_rewrite.c>
    RewriteEngine On

    # Redirect all non-existing files or directories to index.php
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^(.*)$ index.php?/$1 [L,QSA]

    # Ensure index.php is always used as the front controller
    DirectoryIndex index.php
</IfModule>
```

* **Nginx**: Set up a server block for your application, pointing `root` to the `public/` directory.

  ```nginx
  server {
      listen 80;
      server_name phpfast.net;
      root /home/phpfast.net/public_html/public;

      index index.php index.html index.htm;

      location / {
          try_files $uri $uri/ /index.php?$query_string;
      }

      location ~ \.php$ {
          include snippets/fastcgi-php.conf;
          fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
          fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
          include fastcgi_params;
      }

      location ~ /\.ht {
          deny all;
      }
  }
  ```

Or you can upload all script into /home/phpfast.net/ and public into `public_html` directory. And change root into this:

```
root /home/phpfast.net/public_html;
```

### Bootstrapping the App

There are situations where you may need to load the framework without executing the entire application. This is especially useful for unit testing, but it can also be beneficial when using third-party tools to analyze and modify your code.

To accommodate this, the framework includes a dedicated bootstrap script designed specifically for this purpose: `system/Core/Bootstrap.php`.

During the bootstrap process, most project paths are defined automatically. While you can override these paths using predefined constants, it is important to ensure that your directory structure aligns with the expected layout if you're using the default configuration.<br>


# PHPFast Overview

## Framework Struct Overview

First, you need to get an overview of the structure of the Framework's parts:

[Application Structure](/framework-overview/application-structure)

[Models, Views and Controllers](/framework-overview/models-views-and-controllers)

[Libraries Overview](/framework-overview/libraries-overview)

[Helpers Overview](/framework-overview/helpers-overview)

[Command-Line (CLI)](/framework-overview/command-line-cli)

## Framework Document Overview

PHPFast is a lightweight and efficient PHP framework designed to optimize the web application development process. Below is a detailed guide on how to use the main components of PHPFast:

## [Core](/documents/core)

* Core refers to the essential components of the framework, including classes for request handling, routing, application initialization, and other necessary components for the application to function.
* The core is automatically initialized when you run your PHPFast application. You don’t need to intervene in the core framework unless you want to extend or modify how the framework operates. PHPFast will handle all user requests, perform routing, and call the appropriate controller to handle the request.

## [Routing](/documents/uri-routing)

* Routing in PHPFast maps URLs to specific controller methods. This allows you to define paths and methods to handle requests for each URL.
* To define a route, you will use the `Route` class. Each route will have a specific path, an HTTP method (GET, POST, etc.), and the controller method that will handle the request. Routes can be grouped by modules or features of the application.

## [Controllers](/documents/controllers)

* Controllers are responsible for handling user requests, performing necessary operations, and returning results, which can be either a view or a JSON response.
* Controllers are defined as PHP classes, and each method within a controller handles a specific request. The methods in controllers can interact with models to fetch data, process business logic, and return results.

## [Models](/documents/models)

* Models represent the data layer of the application and perform operations on the database.
* Models are used to interact with the database and perform actions like querying, inserting, updating, or deleting data. A model typically represents a table in the database, and methods in the model perform the corresponding operations.

## [ Views & Templates](/documents/views-and-templates)

* Views are responsible for rendering the user interface of the application, while Templates are dynamic HTML layouts used for reusing parts of the UI.
* Views can be loaded and rendered with dynamic data, allowing information from the controller to be displayed to the user. Templates help separate logic and interface, making maintenance and changes to the UI easier.

## [Blocks](/documents/blocks)

* The `BaseBlock` class is an abstract class in the PHPFast framework designed to manage the blocks within an application. It provides a structure for defining blocks, storing their associated data, and rendering their content.&#x20;
* This class serves as a foundation for creating customizable blocks in the application, ensuring consistency and reusability.

## [Middleware](/documents/middleware)

* Middleware are intermediary classes that allow you to intervene in the request and response chain before they are processed by the controller or after the controller returns a response.
* Middleware is commonly used for tasks such as user authentication, access control, logging, or validating input before further processing. Middleware can be applied to a specific route or to the entire application.

## [Helpers](/documents/helpers)

* Helpers are utility functions that simplify common programming tasks such as working with strings, arrays, and validating data.
* PHPFast provides several built-in helpers to support tasks like generating URLs, processing strings, or handling forms. You can call these helper functions directly from anywhere in the application without needing to instantiate additional objects.

## [Libraries](/documents/libraries)

* Libraries provide additional functionality such as logging, session management, or handling external requests like emails, SMS, etc.
* You can use the framework's libraries to access and utilize complex features without having to write custom code. These libraries can be loaded and used in controllers or models to handle specific tasks.

## [Drivers](/documents/drivers)

* **Description**: Drivers provide specialized services such as database connections, email sending, or caching. Drivers help integrate external services into your application.
* **Usage**: Drivers can be loaded and used to perform specific tasks, such as connecting to a database or managing cache. Each driver corresponds to a specific service and helps you perform related operations.

## [Commands](/documents/commands)

* Commands allow you to perform tasks from the command line (CLI) such as database migrations, clearing cache, or running background jobs.
* To create custom commands, you will define a new command class, extending the `Command` class. These commands can then be run from the command line to perform tasks automatically without needing to intervene in the source code.


# Application Structure

To make the most of PHPFast, you should understand its default structure and learn how to customize it to fit your application's needs.

## Default Directories

A fresh installation includes five key directories:

* **application**
* **public**
* **system**
* **vendor**
* **writable**

Each directory serves a specific purpose within the framework.

## application

The **application** directory is where all of your application code lives. This comes with a default directory structure that works well for many applications.

The following folders make up the basic contents:

PHP-Fast follows a well-organized directory structure to keep the application clean and modular. Here's a detailed breakdown of each directory and its purpose:

<pre><code>ROOT
├── application/                     # Application-specific files
│   ├── Blocks/                      # UI blocks (footer, header, content)
│   │   ├── Footer/                  # Footer block
│   │   ├── Frontend/                # Head block 
│   │   │   ├── Header/              # Header block (nav, logo)
│   │   │   ├── Pagination/          # Pagination block
│   │   │   └── Content/             # Content block
│   │   │       ├── Views/           # Content layouts
│   │   │       │   ├── layout_1.php # Layout 1
│   │   │       │   ├── layout_2.php # Layout 2
│   │   │       │   └── layout_3.php # Layout 3
│   │   │       └── ContentBlock.php # Content block logic
│   │   ├── Head/                    # Head block (meta, CSS, JS)
│   │   └── Schema/                  # Schema block
│   ├── Config/                      # Configuration files
│   │   └── Config.php               # Main configuration file
│   ├── Controllers/                 # Controllers for handling requests
│   │   ├── Api/                     # API-related Controllers
<strong>│   │   │   └── UsersController.php  # Controller for user-related API
</strong>│   │   ├── Backend/                 # Folder contains controller in bacend
│   │   │   ├── HomeController.php   # Controller for home page in backend
│   │   │   └── UsersController.php  # Controller for user page in backend
│   │   ├── BackendController.php    # Frontnend controller for web requests
│   │   ├── Frontend/                # Folder contains controllers in frontend
│   │   │   ├── HomeController.php   # Controller for home page in frontend
│   │   │   └── UsersController.php  # Controller for user page in frontend
│   │   └── FrontendController.php   # Frontnend controller for web requests
│   ├── Helpers/                     # Store collections of standalone functions
│   │   ├── Backend_helper.php       # Backend helper functions
│   │   └── Frontend_helper.php      # Frontend helper functions
│   ├── Languages/                   # Manages multi-language support
│   │   ├── en/                      # English version
│   │   │   ├── Home.php/            # Home English version
│   │   │   └── Posts.php/           # Posts Vietnamese version
│   │   └── vi/                      # Vietnamese version
│   │       ├── Home.php/            # Home English version
│   │       └── Posts.php/           # Posts Vietnamese version
│   ├── Librabries/                  # Managing custom or built-in libraries
│   │   ├── FastLang.php             # Handles languages custom
│   │   ├── FastMail.php             # Handles mail
│   │   ├── FastToken.php            # Handles token 
│   │   └── iMagify.php              # Handles images 
│   ├── Middleware/                  # Custom middleware for request handling
│   │   ├── AuthMiddleware.php       # Handles authentication
│   │   └── PermissionMiddleware.php # Handles user permissions
│   ├── Models/                      # Models for database interactions
│   │   ├── UsersModel.php           # Model for interacting with the users table
│   │   └── PostsModel.php           # Model for interacting with the posts table
│   ├── Routes/                      # Route definitions
│   │   ├── Api.php                  # API route definitions
│   │   └── Web.php                  # Web route definitions
│   └── Views/                       # Views for frontend and backend
│       ├── default/                 # Default theme
│       │    ├── Backend/            # Backend views
│       │    └── Frontend/           # Frontend views (assets, php files)
│       │        ├── Assets/         # Frontend assets (CSS, JS)
│       │        │   ├── css/        # CSS files
│       │        │   └── js/         # JS files
│       │        └── home_index.php  # Homepage view
│       └── theme_custom             # Custom theme  
</code></pre>

## **public**

The public folder is the main access point for your web application. It makes sure that only files meant for the browser (like images, CSS, and JavaScript) are visible while keeping your source code safe.

This folder contains important files like .htaccess, index.php, and other assets needed for the website to work properly.

Since it acts as the web root (the main folder your site runs from), your web server should be set to use this folder. This setup keeps your project organized and improves security.

```
ROOT
├── public/                       # Publicly accessible directory (document root)
│   ├── .htaccess                 # Apache configuration for URL rewriting
│   └── index.php                 # Entry point for all HTTP requests
```

## system

This folder contains the core files of the framework. While you can customize the application folder as needed, you should not modify anything inside the system folder.

If you need to change how the framework works, it's best to extend existing classes or create new ones instead of directly editing these core files. This ensures your application remains stable and easy to update.

```
ROOT
├── system/                          # Core framework files
│   ├── Commands/                    # Command-line tools
│   │   ├── BlockCommand.php         # CLI command to create Blocks
│   │   ├── ControllersCommand.php   # CLI command to create Controllers
│   │   ├── ModelsCommand.php        # CLI command to create Models
│   │   └── TableCommand.php         # CLI command to sync database tables
│   ├── Core/                        # Core system files of the framework
│   │   ├── AppException.php         # Custom exception handler
│   │   ├── BaseController.php       # Base class for all Controllers
│   │   ├── BaseBlock.php            # Base class for all Blockks
│   │   ├── BaseModel.php            # Base class for all Models
│   │   ├── Bootstrap.php            # Framework initialization and routing
│   │   ├── Middleware.php           # Base class for middleware
│   │   └── Router.php               # Handles routing and directs requests
│   ├── Drivers/                     # Drivers for handling caching and databases
│   │   ├── Cache/                   # Cache handling
│   │   │   ├── Cache.php            # Base cache class
│   │   │   ├── FilesCache.php       # File-based caching implementation
│   │   │   └── RedisCache.php       # Redis-based caching implementation
│   │   │   └── UriCache.php         # Uri-based caching implementation
│   │   ├── Database/                # Database handling
│   │   │   ├── Database.php         # Base database class
│   │   │   ├── MongodbDriver.php      # Mongodb-specific database driver
│   │   │   ├── MysqlDriver.php      # MySQL-specific database driver
│   │   │   └── PostgresqlDriver.php # PostgreSQL-specific database driver
│   ├── Helpers/                     # Helper functions for various tasks
│   │   ├── Core_helper.php          # Core helper functions
│   │   ├── Security_helper.php      # Security-related helper functions
│   │   ├── String_helper.php        # String-related helper functions
│   │   └── Uri_helper.php           # URL-related helper functions
│   └── Libraries/                   # Common system libraries
│       ├── Assets.php               # Asset management (e.g., CSS, JS)
│       ├── Assets.php               # Events management
│       ├── Logger.php               # Logging utility
│       ├── Monitor.php              # Performance monitoring utility
│       ├── Render.php               # View rendering and layout handling
│       ├── Security.php             # Security functions
│       ├── Session.php              # Session management
│       ├── TaskQueue.php            # Handle asynchronous jobs
│       ├── Template.php             # Template handling utility
│       └── Validate.php             # Input validation functions
```

## vendor

folder is where third-party packages and dependencies are stored, managed by **Composer** (a dependency manager for PHP).

<pre><code>ROOT
├── vendor/                       # Composer-installed third-party libraries
│   ├── composer/
│   │   └── autoload.php          # Composer autoloader
<strong>└── composer.json
</strong></code></pre>

## writable

This folder stores files that your application needs to write to while running. It includes directories for cache files, logs, and user uploads.

If your application needs to save other types of files, you should create additional directories here. Keeping all writable files in one place helps improve security, as it allows you to keep the rest of your project files read-only.

```
ROOT
├── writeable/                    # Writable directory for logs, uploads, etc.
│   ├── cache/
│   ├── logs/
│   │   ├── logger.log            # Log file for application logs
```


# Models, Views and Controllers

## What is MVC?

MVC (Model-View-Controller) is a design pattern used in software development, especially for web applications. It separates an application into three main components:

* Model – Manages data and business logic.
* View – Handles the user interface (UI) and presentation.
* Controller – Acts as a bridge between the Model and View, processing user inputs.

## How it works?

1. **User requests a page (URL):** The request is sent to a **Controller**.
2. **Controller processes the request:** It may interact with a **Model** to get or update data.
3. **Model handles data:** The Model retrieves, updates, or processes data from the database.
4. **Controller passes data to the View:** The View formats and displays the data to the user.
5. **User sees the updated page:** The final output (HTML, JSON, etc.) is sent to the browser                                                                   &#x20;

<figure><img src="/files/ExQds0ateXN94Pc4Fcr8" alt=""><figcaption></figcaption></figure>

## The Components

### Models

* Represents data and defines how it is processed.
* Communicates with the database.
* Does not directly interact with the View.

Functions in [BaseModel](/documents/core/basemodel)

**`__construct()`**: Automatically called when an object is instantiated. It is typically used to establish a database connection or initialize important class properties.

**`_schema()`**: Defines the structure of the database table by specifying columns and their data types.

**`_table()`**: Returns the name of the database table that the model corresponds to, making queries more flexible and maintainable.

**`_columns()`**: Specifies the list of columns that can accept data during insert or update operations.

**`row()`**: Fetches a single record from the specified table based on the given search conditions.

**`list()`**: Fetches multiple records from the table based on specified conditions, with options for sorting and limiting the number of returned records.

**`listpaging()`**: Fetches paginated data, allowing large datasets to be divided into manageable pages for better control and display.

**`listfieldpaging()`**: Obtains data from specific table columns with pagination support, optimizing query performance and data display.

**`add()`**: Inserts a new record into the specified table with the provided data, ensuring validation before storage.

**`set()`**: Updates one or more records in the table based on specified conditions, ensuring that only valid fields are modified.

**`del()`**: Deletes one or more records from the table based on the provided conditions.

**`query()`**: Executes a custom SQL query with provided parameters, allowing for extended query capabilities beyond the default CRUD operations.

**`lastInsertId()`**: Gets the ID of the most recently inserted record in the table.

**`count()`**: Counts the number of records in the specified table based on given conditions.

Explore more about [Models](/documents/models)

### **Views**

* Displays the data provided by the Controller.
* Contains HTML, CSS, JavaScript, and minimal PHP.
* Should not contain business logic.

Explore more about  [Views & Templates](/documents/views-and-templates)

### **Controllers**

* Processes user input and interacts with the Model.
* Sends the processed data to the View.
* Acts as the middleman between Model and View.

Functions in [BaseController](/documents/core/basecontroller)

* **`data()`**: Stores and retrieves internal class data. It is used to temporarily store information for use in other methods.
* **`render()`**: Displays content using a predefined layout. This method is useful for managing webpage rendering in an MVC framework.
* **`json()`**: Returns data in JSON format. It is commonly used to provide data for APIs or AJAX requests.
* **`success()`**: Returns a JSON response for successful operations. This is typically used for API responses when a request is successfully completed.
* **`error()`**: Returns a JSON response for errors. It helps send API error responses when an issue occurs in the system.
* **`get_success()`**: Returns a success response as an array. This method is useful for processing API responses internally before sending them to the client.
* **`get_error()`**: Returns an error response as an array. It is used to check errors during processing before sending a response.

Explore more about [Controllers](/documents/controllers)


# Blocks Overview


# Libraries Overview

The `Libraries` directory contains the core library classes of the framework, which help streamline and simplify web application development. Each library file in this directory plays an essential role in handling various system functions. These library classes are designed to handle common tasks, from resource management to security and input validation. Below is a detailed explanation of each file in this directory:

## [Caching](/documents/libraries/caching)

* The caching library helps optimize the performance of the application by storing frequently accessed data temporarily. By keeping data in memory (such as through in-memory caches like Redis or URI, ...), caching reduces the number of times data must be fetched from slower data sources like databases or APIs.
* This library is used to cache data that is accessed frequently or requires heavy computation, improving response times and reducing the load on the system. For example, user profiles or search results can be cached to avoid redundant queries.

## [Render](/documents/libraries/render)

* The `Render` class helps manage and optimize the usage of resources such as CSS, JavaScript, and images within the application. Through this class, you can easily add, remove, or modify the resources loaded into your web pages. It also supports resource compression and optimization to reduce page load times, enhancing application speed.
* Manages the loading of static resources (CSS, JavaScript, images), optimizes resources, supports CDN and caching to reduce page load time.

## [Security](/documents/libraries/security)

* The `Security` class provides methods to protect the application from common security vulnerabilities like Cross-Site Scripting (XSS), Cross-Site Request Forgery (CSRF), SQL Injection, and other attacks. This class is crucial in ensuring the application remains secure during its operation.
* Protects the application from security vulnerabilities by encrypting data, validating input, and preventing XSS, CSRF, and SQL Injection attacks, as well as securing user sessions.

## [Session](/documents/libraries/session)

* The `Session` class manages user sessions within the application. It stores session data such as login information, user preferences, and other relevant data throughout the user's interaction with the application. This class also provides security features to prevent session hijacking.
* Manages user sessions, stores session data in session or cookies, and provides security features like session encryption and protection against session fixation attacks.

## [Validate](/documents/libraries/validate)

* The `Validate` class provides methods for validating input data in the application. Input validation is crucial to prevent errors and ensure data is processed correctly. This class supports checks such as data type validation (email, phone number), string length, format, and more.
* Validates user input, including checking the format of email addresses, phone numbers, string length, and other criteria. It ensures that input data is correct and meets necessary requirements.

## [Error Handling](/documents/libraries/error-handling)

* This library is specifically designed to manage errors in the system. It provides functions for catching, logging, and gracefully handling errors that occur during the application’s execution. It ensures that errors do not crash the system and provides meaningful error messages to the user or developers.
* This library is used to catch and handle runtime errors, ensuring the application remains stable and providing detailed logs for debugging. It can also send notifications to administrators in case of critical system failures.

## [Logger & Monitor](/documents/libraries/logger-and-monitor)

* The `Logger` class provides a logging mechanism for the application, allowing you to track system activities and errors. It can log important information such as system messages, warnings, critical errors, and user actions. This is an essential tool for detecting and troubleshooting issues in the application.
* Logs system events, enabling monitoring and recording of events, warnings, or errors during the application’s operation. It supports logging to files or databases for easy tracking and future analysis.
* The `Monitor` class monitors the system’s performance in real-time, tracking aspects such as memory usage, CPU load, response times, and other system resources. It helps identify performance issues before they affect the user experience.
* Monitors and reports the operational status of the system, helping detect performance issues and providing early warnings of potential problems.

{% hint style="success" %}
Conclusion

Each class in the `Libraries` directory plays a vital role in the development of robust and secure web applications. They provide commonly needed functions such as resource management, logging, security, session handling, and dynamic content rendering. Using these library classes helps save development time and ensures that your application runs smoothly and securely.
{% endhint %}


# Helpers Overview

The `Helpers` directory contains helper files that provide utility functions to assist with common tasks during application development. These helpers simplify and speed up the programming process by offering pre-built and optimized functions, eliminating the need to rewrite code for frequent functionalities. Below are the files in the `Helpers` directory:

## [Uri\_helper](/documents/helpers/uri_helper)

* `Uri_helper` is a powerful tool designed to simplify working with URLs within an application. It provides functions to **parse, generate, and validate URLs**, making it easier to navigate and handle different URL components. Developers can efficiently construct dynamic URLs, extract query parameters, and validate URLs without manually handling string manipulations.

  One of the key advantages of `Uri_helper` is its **strong compatibility with Nginx**, a high-performance web server. Unlike Apache, which relies on `.htaccess` for URL rewriting, Nginx handles URL routing through configuration directives. `Uri_helper` seamlessly integrates with Nginx’s efficient URL management system, enabling:

  * **Pretty URLs** – Removes `index.php` from URLs for cleaner and more user-friendly links.
  * **Accurate Query String Handling** – Ensures correct processing of GET parameters.
  * **Dynamic Base URL Detection** – Works with Nginx’s `fastcgi_param` settings to generate accurate URLs.
  * **HTTPS Detection** – Recognizes secure connections to construct URLs with the correct protocol (`http` or `https`).

  By leveraging Nginx’s optimized URL handling, `Uri_helper` helps improve **application performance, security, and routing efficiency**, making it an essential component for web applications.

## [Core\_helper](/documents/helpers/core_helper)

* The `Core_helper` file provides a collection of essential utility functions that streamline various system-level operations within the application. These functions offer convenience by handling common tasks such as retrieving system configurations, working with environment variables, managing file permissions, and generating random data.

  Key functionalities include:

  * **Dynamic Helper Loading** – Allows loading of additional helper files as needed.
  * **Date & Time Handling** – Retrieves the current date and time for logging or time-sensitive operations.
  * **System Information Retrieval** – Fetches PHP version, web server details, and environment settings.
  * **File and Directory Management** – Checks if directories are writable and handles storage unit conversions.
  * **Random Data Generation** – Generates unique alphanumeric strings for security or identifier purposes.
  * **Configuration & Environment Management** – Retrieves and updates system configurations, options, and environment variables dynamically.

  By centralizing these commonly used functions, `Core_helper` enhances efficiency, reduces redundant code, and provides a structured approach to managing system operations. It ensures better maintainability and optimizes workflow for developers working within the framework.

## [Security\_helper](/documents/helpers/security_helper)

* `Security_helper` is designed to enhance **application security** by mitigating common web vulnerabilities such as **Cross-Site Scripting (XSS), Cross-Site Request Forgery (CSRF), and SQL Injection**. Security threats are a major concern for any web application, and `Security_helper` provides pre-built functions to address these risks effectively.

  Key security functions include:

  * **Input Validation** – Ensures that user inputs are properly sanitized to prevent malicious data injection.
  * **Data Encryption & Decryption** – Provides secure methods for encrypting and decrypting sensitive information.
  * **XSS Protection** – Filters out harmful scripts that attackers may attempt to inject.
  * **CSRF Prevention** – Helps protect against unauthorized requests from malicious sources.
  * **SQL Injection Defense** – Ensures that database queries are secure and immune to injection attacks.

  By integrating `Security_helper`, developers can **implement strong security measures effortlessly**, eliminating the need to build security protocols from scratch. This allows applications to maintain a **safe and secure environment**, protecting both users and data integrity.

{% hint style="info" %}
Conclusion

The files in the `Helpers` directory provide powerful utility functions that simplify common programming tasks and help secure the application. They are designed to be easily used and integrated into any part of the application without the need to rewrite code, saving time and minimizing errors during development.
{% endhint %}


# Command-Line (CLI)

PHPFast includes a built-in command-line interface (CLI) that significantly enhances development efficiency by automating essential tasks such as creating Controllers, Models, and synchronizing database structures. This CLI tool eliminates much of the manual effort involved in setting up application components, allowing developers to streamline their workflow and maintain better project organization.

By leveraging the PHPFast CLI, developers can quickly generate the fundamental building blocks of an application using simple commands. Instead of manually writing boilerplate code, the CLI automates the process, ensuring consistency and reducing development time. This is particularly useful for database-driven applications, as it simplifies model management and table synchronization.

## **Database Synchronization**

One of the core capabilities of the CLI is the ability to synchronize the database with the application’s models. The tool reads the schema defined in a model’s `_schema()` method and automatically applies any necessary changes to the database structure. This ensures that the database tables remain up-to-date without requiring manual SQL modifications.

**Command Usage:**

```sh
php init table <table_name>
```

**Example:**

```sh
php init table users
```

This command ensures that the `users` table aligns with the corresponding model’s schema, making schema updates seamless and efficient.

## **Creating Controllers**

The CLI allows developers to quickly generate new controller files, which serve as the backbone of application logic. When a new controller is created, it follows a predefined structure, enabling faster setup of routes and business logic. This approach enforces consistency and reduces redundant coding efforts.

**Command Usage:**

```sh
php init controllers <controller_name>
```

**Example:**

```sh
php init controllers Users
```

This creates a `UsersController.php` file inside the `application/Controllers/` directory, ready for further customization.

## **Creating Models**

Models play a crucial role in defining database structures and handling data interactions. The PHP-Fast CLI simplifies model creation by generating files that include a default schema definition and built-in CRUD (Create, Read, Update, Delete) functionalities. This enables developers to establish and manage database connections effortlessly.

**Command Usage:**

```sh
php init models <model_name>
```

**Example:**

```sh
php init models Users
```

This creates `UsersModel.php` inside the `application/Models/` directory, complete with a predefined schema for handling database operations efficiently.

## **Why Use PHPFast CLI?**

* **Speeds Up Development**: Automates repetitive tasks like creating models, controllers, and syncing tables.
* **Ensures Consistency**: Standardizes file structures and database schemas across the application.
* **Reduces Errors**: Minimizes the risk of human error in database schema management and code structuring.
* **Enhances Maintainability**: Provides a structured and scalable approach to application development.

By integrating these CLI functionalities, PHPFast optimizes the development process, allowing teams to focus on business logic and feature implementation rather than repetitive setup tasks. Whether working on a small project or a large-scale application, the PHPFast CLI is a powerful tool that enhances efficiency and streamlines development workflows.

How to create a new [Command](/documents/commands)?


# JFast Javascript Library

JFast - High performance Javascript Library replace jQuery

### 1 . Why jFast?

| Attribute                 | What it means                                                                   |
| ------------------------- | ------------------------------------------------------------------------------- |
| **Tiny footprint**        | ≈ 2 KB gzipped – ideal for embed widgets, dashboards, or legacy projects.       |
| **jQuery‑style API**      | 80 % coverage of the helpers devs reach for most (`addClass`, `on`, `ajax`, …). |
| **No build‑step**         | Ship the un‑minified file for debugging; run your own minifier if desired.      |
| **Polyfill friendly**     | Bundles fallbacks for `Set` and `NodeList.forEach` so IE11 gets basic support.  |
| **Modern under the hood** | Uses `querySelectorAll`, `classList`, and Promises.                             |

***

### 2 . Installation

```html
<!-- 1. Download jfast‑1.2.3.js and place it in /assets/js -->
<script src="/assets/js/jfast-1.2.3.js"></script>

<!-- 2. Or, serve from your own CDN / S3 bucket -->
<script src="https://cdn.your‑domain.com/lib/jfast/1.2.3/jfast.min.js"></script>
```

When the script loads you’ll see a yellow console log:

```
jFast loaded version 1.2.3
```

and two globals become available:

```js
console.log(window.jFast === window.$);   // true
```

### 3 . Creating a Collection

Below are **all** accepted constructor signatures, plus runnable snippets you can paste into DevTools.

| Call               | Typical Use Case                      | Example                                                                         |
| ------------------ | ------------------------------------- | ------------------------------------------------------------------------------- |
| `jFast('section')` | Select DOM by CSS                     | `$('.box').addClass('open')`                                                    |
| `jFast(domNode)`   | Wrap an existing DOM node             | `jconst btn = document.getElementById('send');\n$(btn).attr('disabled', true);` |
| `jFast(NodeList)`  | Hand‑off result of `querySelectorAll` | `const nodes = document.querySelectorAll('.note');\n$(nodes).hide();`           |
| `jFast([el1,el2])` | Wrap an array of nodes                | `$( [header, footer] ).css('background', '#333');`                              |
| `jFast(function)`  | DOM‑ready callback                    | `$(function(){ console.log('DOM ready'); });`                                   |
| *no value*         | Empty collection (edge cases)         | `jFast().length === 0;`                                                         |

**Quick demo**

```html
<ul id="tasks">
  <li>Write docs</li>
  <li class="done">Ship release</li>
</ul>
<script>
  $('#tasks li:not(.done)')
    .addClass('pending')
    .each((i, li) => console.log('Todo #'+i, li.textContent));
</script>
```

### 4 . Core Iterator APIs

**4.1 `.each(callback)`**

Iterate the wrapped set. Unlike plain `forEach`, the callback is executed with `(element, index)` to match jQuery style.

```js
$('a.external').each((i, a) => a.target = '_blank');
```

**4.2 `.eq(index)`**

Returns a new jFast collection containing just the element at *index*. Negative indices count from the end.

```js
// Hide the last column in a table
$('table tr').find('td').eq(-1).hide();
```

**4.3 `.first()` / `.last()`**

Sugar for `.eq(0)` and `.eq(length - 1)`.

```js
$('.slide').last().addClass('current');
```

***

### 5 . Class Helpers

| Method                         | Purpose                           | Minimal Demo                                |
| ------------------------------ | --------------------------------- | ------------------------------------------- |
| `.addClass(names)`             | Add one or more classes           | `$('#msg').addClass('show animated');`      |
| `.removeClass(names)`          | Remove class(es)                  | `$('nav').removeClass('sticky');`           |
| `.toggleClass(names, [state])` | Flip class or force boolean state | `$('.panel').toggleClass('open');`          |
| `.hasClass(name)`              | Boolean test on first element     | `if ( $('#modal').hasClass('open') ) {...}` |

**Practical scenario**

```js
// click to open/close FAQ answers
$('.faq-question').on('click', function () {
  $(this)
    .next('.faq-answer')
    .toggleClass('hidden');
});
```

***

### 6 . Attribute & Property Utilities

**6.1 `.attr(name)` / `.attr(name, value)`**

```js
// Read
const src = $('img.preview').attr('src');

// Write
$('img.preview').attr('alt', 'Screenshot');
```

*Remove an attribute*:

```js
$('input.temp').attr('autocomplete', null);
```

**6.2 `.prop(name[, value])`**

Directly modify DOM properties (not string attributes):

```js
$('input[type=checkbox]').prop('checked', false);
```

**6.3 `.data(key[, value])`**

Free of JSON parsing/serialisation:

```html
<div id="card" data-id="9810"></div>
<script>
  $('#card').data('id');       // "9810"
  $('#card').data('state', 'archived');
</script>
```

***

### 7 . Text, HTML, and Inline CSS

| Getter       | Setter              | Sample                                            |
| ------------ | ------------------- | ------------------------------------------------- |
| `.text()`    | `.text(value)`      | `$('#status').text('Saving…');`                   |
| `.html()`    | `.html(markup)`     | `$('#list').html('<li>New item</li>');`           |
| `.css(prop)` | `.css(prop, value)` | `$('#box').css('width', '250px');`                |
|              | `.css(object)`      | `$('#box').css({height:120, background:'#eef'});` |

### 8 . DOM Insertion & Removal

| Method                | What it does                                                                              | Live Example                                                                          |
| --------------------- | ----------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------- |
| `.append(content)`    | Add *content* to **inside‑end** of every element in the set.                              | `$('#log').append('<li>Finished at '+Date.now()+'</li>');`                            |
| `.prepend(content)`   | Add *content* to **inside‑start**.                                                        | `$('ul').prepend('<li class=\"first\">Top item</li>');`                               |
| `.before(content)`    | Insert *content* **before** each element.                                                 | `$('.alert').before('<hr>');`                                                         |
| `.after(content)`     | Insert *content* **after** each element.                                                  | `$('.alert').after('<button class=\"close\">×</button>');`                            |
| `.remove()`           | Detach each element from the DOM. Returns the same collection (now empty).                | `$('.toast .close').on('click', e => $(e.delegateTarget).parent('.toast').remove());` |
| `.empty()`            | **Clear** `.innerHTML` of every element but keep the elements themselves.                 | `$('#results').empty(); // ready for fresh data`                                      |
| `.clone([deep=true])` | Produce a *new* jFast collection containing clones. `deep=false` copies only the element. | `const $copy = $('#card').clone();\n$('#cards').append($copy);`                       |

> **Tip — Passing existing nodes**\
> All insertion helpers accept **strings, HTMLElement(s), NodeLists, or jFast objects**. If you pass DOM nodes, the library clones them when needed so every target gets its own copy.

```js
$tmpl = $('#tmpl .item');      // template item stored off‑DOM
$('.list').append( $tmpl.clone() );  // safe – original remains intact
```

### 9 . Geometry & Scrolling Helpers

These methods read or write layout‑related values; none trigger a reflow more than necessary.

**9.1 `.width([value])` & `.height([value])`**

*Getter* – returns the element’s **content box** size (ignores padding, border, margin).\
*Setter* – accepts number (pixels) or any valid CSS length string.

```js
// Read
const modalW = $('#modal').width();          // e.g. 512

// Write absolute px
$('#sidebar').width(240);

// Write responsive unit
$('#sidebar').css('width', '33.333%');       // or use .css directly
```

**9.2 `innerWidth()` / `innerHeight()`**

Returns **content + padding + border** (matches `jQuery.innerWidth`). Useful for box‑model arithmetic:

```js
if ( $box.innerHeight() < 200 ) $box.height(200);
```

**9.3 `outerWidth([includeMargin])` / `outerHeight([includeMargin])`**

Adds margin when the optional boolean is `true`.

```js
const cardTotal = $('.card').outerHeight(true);  // full footprint
```

**9.4 `.offset()`**

Absolute page coordinates *(pixels from viewport’s top‑left, including scroll)*:

```js
const pos = $('#avatar').offset(); // {top:123, left:456}
window.scrollTo({ top: pos.top - 20, behavior:'smooth' });
```

**9.5 `.position()`**

CSS `position` relative to **offsetParent** (similar to jQuery):

```js
const { top, left } = $('#tooltip').position();
console.log('Tooltip is', top, 'px below its anchor');
```

**9.6 `.offsetParent()`**

Wraps and returns the element’s offset parent or `document.documentElement`.

```js
$('#badge').offsetParent().css('outline','1px dashed red');
```

**9.7 `scrollTop([value])` / `scrollLeft([value])`**

Works on both **elements** and **`window`**.

```js
// Get current scroll
const y = $(window).scrollTop();

// Scroll container to bottom
$('#chat').scrollTop( $('#chat')[0].scrollHeight );
```

**9.8 `.index([element])`**

*No argument* → index of first element within its parent.\
*Element argument* → index of that element within the wrapped set.

```js
const clickedCol = $(e.target).index();         // which column?
if ( clickedCol === 0 ) sortBy('name');
```

### 10 . Traversal Helpers

| Method                | Returned collection                         | Typical Use                          | Example                                           |
| --------------------- | ------------------------------------------- | ------------------------------------ | ------------------------------------------------- |
| `.find(sel)`          | **All** descendants matching `sel`.         | Narrow to deeper nodes.              | `$('#nav').find('a.active')`                      |
| `.closest(sel)`       | First ancestor (self‑incl.) matching `sel`. | Bubble upward until match.           | `$(btn).closest('form').submit()`                 |
| `.parent()`           | The direct parent for every element.        | Jump one level up.                   | `$('.item').parent().addClass('has‑item')`        |
| `.parents()`          | **All** ancestors for every element.        | Apply global change along the chain. | `$('#hero').parents().css('position','relative')` |
| `.children()`         | Direct child elements of each node.         | Loop through immediate kids.         | `$('#menu').children().addClass('link')`          |
| `.next()` / `.prev()` | Immediate next/previous sibling.            | Carousel, tab order, etc.            | `$('.tab.active').next().click()`                 |
| `.siblings()`         | All siblings except the element itself.     | Row/column highlighting.             | `$(cell).siblings().addClass('dim')`              |
| `.filter(sel)`        | Elements that **pass** selector test.       | Refine a set post‑selection.         | `$('li').filter('.active, .current')`             |
| `.not(sel)`           | Elements that **fail** selector test.       | Exclude unwanted nodes.              | `$('li').not('.disabled')`                        |
| `.is(sel)`            | **Bool** – does the *first* element match?  | Conditionals.                        | `if ( $(el).is(':visible') ) …`                   |
| `.add(sel)`           | Union of current set + `sel`.               | Merge disparate selections.          | `$('.btn').add('#save')`                          |

***

**10.1 `.find(selector)`**

Searches **below** every element in the current set.

```html
<nav id="mainNav">
  <a href="/">Home</a>
  <a href="/shop" class="active">Shop</a>
</nav>
<script>
  $('#mainNav')
    .find('a.active')
    .css('font-weight',700); // only one link affected
</script>
```

> **Performance tip** – `find()` re‑collects, so keep the result in a variable if you reuse it.

***

**10.2 `.closest(selector)`**

Works like native `Element.closest`. Includes the element itself when checking.

```js
// inside a click handler on the document
$(e.target)
  .closest('[data-modal]')
  .addClass('open');
```

***

**10.3 `.parent()` & `.parents()`**

`parent()` climbs **one** level.\
`parents()` returns *every* ancestor up to `<html>`.

```js
$('.note').parent().addClass('has-note');

$('.btn-save')
  .parents('section')        // only ancestors that are <section>
  .addClass('has-unsaved');
```

***

**10.4 `.children()`**

```html
<ul id="files">
  <li>index.html</li>
  <li>app.js</li>
</ul>
<script>
  $('#files').children().each((i, li) => console.log(li.textContent));
</script>
```

***

**10.5 `.next()` & `.prev()`**

```js
$('.wizard-step.active')
  .next()       // the step after the current one
  .addClass('active')
  .prev()       // go back to the previously active
  .removeClass('active');
```

***

**10.6 `.siblings()`**

```js
$('.gallery img.selected')
  .siblings()
  .css('opacity',0.3);
```

***

**10.7 `.filter()`, `.not()`, `.is()`**

```js
// Disable all but visible inputs
$('input').not(':visible').prop('disabled', true);

// Count only checked boxes
const checked = $('input[type=checkbox]').filter(':checked').length;

// Detect whether the page uses a dark theme
if ( $('body').is('.dark') ) enableNightMode();
```

***

**10.8 `.add(selector)`**

Merge two unrelated selections into one chainable set.

```js
$('.toolbar button')
  .add('#globalSave')
  .on('click', saveDocument);
```

***

#### Mini Project Example – Building a Stepper

Below is a concise snippet that combines traversal helpers to implement a step‑by‑step UI.

```html
<ol id="steps">
  <li class="step current">Choose plan</li>
  <li class="step">Billing info</li>
  <li class="step">Confirm</li>
</ol>
<button id="next">Next</button>

<script>
  $('#next').on('click', () => {
    const $current = $('#steps .current');
    $current.removeClass('current');
    $current.next('.step').addClass('current');
    
    // If we reached the end, disable the button
    if ( $('#steps .step').last().is('.current') ) {
      $('#next').prop('disabled', true);
    }
  });
</script>
```

Traversal calls used:

* `#steps .current` – initial selection
* `.next('.step')` – sibling traversal with selector filter
* `.last()` / `.is()` – index check & boolean match

### 11 . Effects & Visibility Helpers

| Method             | Purpose                                                                 | Default Duration | Example                         |
| ------------------ | ----------------------------------------------------------------------- | ---------------- | ------------------------------- |
| `.show([ms])`      | Make the element visible (removes `display:none` and optionally fades). | *none*           | `$('#loader').show(300)`        |
| `.hide([ms])`      | Fade out then `display:none`.                                           | *none*           | `$('.alert').hide(500)`         |
| `.toggle([ms])`    | Switch between show ↔ hide.                                             | *none*           | `$('#panel').toggle(200)`       |
| `.fadeIn([ms])`    | Alias of `.show()` with default 400 ms when called without arg.         | 400 ms           | `$('img').fadeIn()`             |
| `.fadeOut([ms])`   | Alias of `.hide()` with default 400 ms.                                 | 400 ms           | `$('img').fadeOut(150)`         |
| `.slideDown([ms])` | Animate height from 0 → full.                                           | 400 ms           | `$('.faq-answer').slideDown()`  |
| `.slideUp([ms])`   | Animate height from full → 0, then `display:none`.                      | 400 ms           | `$('.faq-answer').slideUp(250)` |

**11.1 Show / Hide Example – Toast Notification**

<pre class="language-html"><code class="lang-html"><strong>&#x3C;div id="toast" class="toast">Saved!&#x3C;/div>
</strong>&#x3C;style>
  .toast{position:fixed;bottom:1rem;right:1rem;padding:1em;background:#333;color:#fff;display:none}
&#x3C;/style>
&#x3C;script>
  function flashToast() {
    $('#toast')
      .fadeIn(300)
      .delay(2000)            // custom helper below ▼
      .fadeOut(300);
  }

  // Tiny helper: chainable delay using setTimeout
  jFast.prototype.delay = function (ms) {
    return this.each(el => setTimeout(()=>{}, ms));
  };

  $('#saveBtn').on('click', flashToast);
&#x3C;/script>
</code></pre>

**11.2 Accordion with Slide Helpers**

```html
<h3 class="acc-title">Section 1</h3>
<div class="acc-body">Hidden text…</div>

<h3 class="acc-title">Section 2</h3>
<div class="acc-body">More hidden text…</div>

<script>
  $('.acc-title').on('click', function () {
    const $body = $(this).next('.acc-body');
    $('.acc-body').not($body).slideUp(); // close others
    $body.slideToggle();                 // jFast alias we can add
  });

  // Optional—extend jFast with slideToggle for convenience
  jFast.prototype.slideToggle = function (ms){
    return this.each(el => {
      const $el = $(el);
      $el.is(':visible') ? $el.slideUp(ms) : $el.slideDown(ms);
    });
  };
</script>
```

***

### 12 . Event System

jFast replicates jQuery’s flexible `.on()` signature, adds `.one()`, and keeps an **internal WeakMap** to clean listeners automatically.

**12.1 `.on(events, [selector], handler [, capture])`**

| Pattern                      | Use‑case                           | Example                                   |
| ---------------------------- | ---------------------------------- | ----------------------------------------- |
| `.on('click', fn)`           | Direct binding                     | `$('#btn').on('click', save)`             |
| `.on('keyup change', fn)`    | Multiple events space‑separated    | `$('input').on('keyup change', validate)` |
| `.on('click', '.child', fn)` | Delegation (parent stays constant) | `$('#list').on('click', 'li', editItem)`  |

```js
function editItem(e){
  // e.delegateTarget is the <li> that matched '.child'
  console.log('Editing', e.delegateTarget.textContent);
}
```

**12.2 `.one(events, [, selector], handler)`**

Runs **once**, then auto‑removes.

```js
$('#modal').one('shown', () => console.log('Modal opened for the first time only'));
```

**12.3 `.off(events, [, selector], [handler])`**

Removes listeners. Parameters mirror `.on()`. Omitting `handler` drops **all** listeners matching event + selector.

```js
$(window).off('scroll.myNS'); // if you namespaced your events
```

**12.4 `.trigger(type, [detail])`**

Dispatch custom or native events with optional `detail` payload.

```js
// Somewhere deep in a component
$(this).trigger('saved', { id: 42 });

// Elsewhere
$(document).on('saved', (e)=> console.log('Item saved!', e.detail.id));
```

> **Note**: Native bubbling rules apply, so you can trigger on a child and listen on `<body>`.

**12.5 Event Shortcut Methods**

For convenience jFast defines **typed aliases**:

```js
$('#field').focus();           // trigger focus
$('#field').focus(handler);    // bind

$('form').submit(e => e.preventDefault());
$(document).keydown(e => e.key === 'Escape' && close());
```

Available shortcuts: `click`, `change`, `keydown`, `keyup`, `keypress`, `mouseover`, `mouseout`, `mouseenter`, `mouseleave`.

***

**12.6 Real‑World: Live Search with Debounce**

```html
<input id="search" placeholder="Search…" autocomplete="off">
<ul id="results"></ul>

<script>
  // --- simple debounce utility
  function debounce(fn, wait){
    let t; return (...args)=>{ clearTimeout(t); t=setTimeout(()=>fn.apply(this,args), wait); };
  }

  $('#search').on('keyup', debounce(function(){
    const q = $(this).val().trim();
    if (!q) return $('#results').empty();

    $.getJSON('/api/search', {q})
      .success(data => {
        const html = data.results.map(r => `<li>${r.title}</li>`).join('');
        $('#results').html(html);
      });
  }, 300));
</script>
```

*Techniques used*

* Direct event binding (`keyup`)
* Reading input value with `.val()`
* Ajax shorthand `$.getJSON`
* DOM diff via `.html(html)`

***

#### Recap

**Effects handled:** show/hide, fade, slide, toggle.\
**Events mastered:** `.on`, `.one`, `.off`, `.trigger`, plus typed shortcuts & delegation patterns.

### 13 . Form Helpers

| API                      | Read / Write                                                                                                                                | Quick Example                                 |
| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------- |
| `.val()` / `.val(value)` | Get or set an element’s value. Works on `<input>`, `<select>`, `<textarea>`, check‑/radio boxes (boolean support), and multi‑select arrays. | `$('#email').val('user@example.com');`        |
| `.serialize()`           | Return URL‑encoded query string from the first `<form>` in the set.                                                                         | `$('form').serialize(); // "name=Bob&age=28"` |
| `.serializeArray()`      | Return array `[{name:'', value:''}, …]`.                                                                                                    | `console.table($('form').serializeArray());`  |
| `.submit()`              | Programmatically send a form (respects `requestSubmit` when present). Passing a submit button as the jFast object triggers that button.     | `$('#myForm').submit();`                      |

**13.1 `.val()` in Depth**

```html
<select id="lang" multiple>
  <option value="en" selected>English</option>
  <option value="vi" selected>Vietnamese</option>
  <option value="jp">Japanese</option>
</select>

<script>
  // Get → returns array for multi‑select
  const langs = $('#lang').val();      // ["en","vi"]

  // Set (array) → selects those options
  $('#lang').val(['jp']);
</script>
```

Checkbox toggle:

```js
// set boolean
$('#notify').val(true);          // checks it
$('#notify').val(false);         // unchecks
```

**13.2 AJAX Submit with `.serialize()`**

```html
<form id="login">
  <input name="user" placeholder="Username">
  <input name="pass" type="password">
  <button type="submit">Login</button>
</form>

<script>
  $('#login').on('submit', e => {
    e.preventDefault();                     // stop native redirect
    const qs = $(e.currentTarget).serialize();
    $.post('/api/login', qs)
      .success(res  => console.log('OK', res))
      .fail   (err  => alert('Bad credentials'));
  });
</script>
```

### 14 . Ajax in Depth — Working With Remote Data

jFast’s Ajax layer shadows jQuery’s API **line‑for‑line** yet trims weight by delegating to the native `XMLHttpRequest`. You may call it at three levels of abstraction:

1. Low‑level **`$.ajax( settings )`** – full control.
2. Semantic helpers **`$.get / $.post / $.getJSON`** – 90 % of daily tasks.
3. Chainable XHR “deferred” object – classic jQuery style (`done / fail / always`) *plus* promise (`then / catch / finally`).

Below is a complete reference with production‑grade snippets.

***

#### 14.1 `$.ajax( settings )` — Master Control

**14.1.1 Settings Object Cheat‑Sheet**

| Key                    | Type / Default                                     | Description                                                  |
| ---------------------- | -------------------------------------------------- | ------------------------------------------------------------ |
| `url`                  | **string** / *required*                            | Endpoint.                                                    |
| `type`                 | `"GET"`                                            | HTTP verb (`"POST"`, `"PUT"`, …).                            |
| `data`                 | object \| string \| `FormData`                     | Will be encoded automatically unless `FormData`.             |
| `dataType`             | `"json" \| "html" \| "script"`                     | Guides auto‑parsing & `Accept` header (falls back to `*/*`). |
| `contentType`          | `application/x-www-form-urlencoded; charset=UTF-8` | `false` = let the browser pick (required for `FormData`).    |
| `async`                | `true`                                             | Set `false` only for legacy sync calls (blocks UI).          |
| `headers`              | object                                             | Extra request headers.                                       |
| `username`, `password` | string                                             | For HTTP basic auth.                                         |
| Callbacks              | `beforeSend`, `success`, `error`, `complete`       | Same signatures as jQuery.                                   |

> **Encoding Rules**
>
> * If `data` is **plain object** → encoded via `$.param()` unless `contentType` starts with `application/json`.
> * If `type` is *GET/HEAD/DELETE* and `data` is not `null` → appended to the URL query string.
> * If `data` is `FormData` → jFast will *not* set `Content‑Type` so the boundary is correct.

**14.1.2 Full Example – PUT JSON With Auth Header**

```js
const profile = { bio: 'Hello there', age: 30 };

$.ajax({
  url: '/api/v1/users/42',
  type: 'PUT',
  data: JSON.stringify(profile),
  contentType: 'application/json',
  dataType: 'json',
  headers: { 'Authorization': 'Bearer ' + token },
  beforeSend(xhr) { console.log('Uploading…'); },
  success(data, status, xhr) { console.log('Saved!', data); },
  error(xhr, status, text) { console.error('Server said:', text); },
  complete(xhr, status) { console.log('Request finished:', status); }
});
```

**14.1.3 Promise Interface (& Abort)**

```js
const req = $.ajax('/search?q=cat')
  .then(res  => render(res.items))
  .catch(e   => alert('Network problem: ' + e.status))
  .finally(() => spinner.hide());

// Abort button
$('#cancel').on('click', () => req.abort && req.abort());
```

> The returned XHR object is **augmented** with both promise methods *and* jQuery‑style `done / fail / always`.

**14.1.4 Monitoring Upload / Download Progress**

```js
$.ajax({
  url: '/upload',
  type: 'POST',
  data: new FormData($('#fileForm')[0]),
  contentType: false,
  beforeSend(xhr){
    xhr.upload.onprogress = e => {
      if (e.lengthComputable){
        const pct = (e.loaded / e.total * 100) | 0;
        $('#bar').css('width', pct+'%');
      }
    };
  }
});
```

***

#### 14.2 Helper Shortcuts

Helpers internally call `$.ajax` but save keystrokes. **All optional arguments may be omitted in order**; jFast adjusts.

| Helper                                          | Signature (flexible)      | Internals                  |
| ----------------------------------------------- | ------------------------- | -------------------------- |
| `$.get(url [, data] [, success] [, dataType])`  | Always *GET*.             | `$.ajax({type:'GET', …})`  |
| `$.post(url [, data] [, success] [, dataType])` | Always *POST*.            | `$.ajax({type:'POST', …})` |
| `$.getJSON(url [, data] [, success])`           | Forces `dataType:'json'`. | `$.get(… , 'json')`        |

**14.2.1 GET With Query Object**

```js
$.get('/api/products', { page: 2, tag: 'book' }, buildGrid, 'html');
```

**14.2.2 POST Form (x‑www‑form‑urlencoded)**

```js
$.post('/login', { user, pass })
  .done(()  => location.reload())
  .fail(()  => shakeForm());
```

**14.2.3 GET JSON via `$.getJSON`**

```js
$.getJSON('/weather', { city: 'Singapore' })
  .then(({ temp, icon }) => $('#temp').text(temp + '°C')
                                      .attr('class', icon));
```

***

#### 14.3 Using FormData for File Uploads

```html
<form id="avatarForm">
  <input type="file" name="avatar">
  <button>Upload</button>
</form>

<script>
$('#avatarForm').on('submit', e => {
  e.preventDefault();
  const formData = new FormData(e.currentTarget);

  $.ajax({
    url: '/api/upload/avatar',
    type: 'POST',
    data: formData,
    contentType: false,   // *DO NOT OVERRIDE* for FormData
    processData: false,   // jFast handles this automatically
    dataType: 'json'
  })
  .success(data => alert('URL: ' + data.url))
  .error  (()  => alert('Upload failed'));
});
</script>
```

***

#### 14.4 Error‑Handling Patterns

| Scenario                    | Strategy                                                                                                               |
| --------------------------- | ---------------------------------------------------------------------------------------------------------------------- |
| **Validation errors (422)** | In `error` callback, check `xhr.status === 422` then read `JSON.parse(xhr.responseText)` to show field‑level messages. |
| **Timeout / offline**       | Use `xhr.status === 0` or wrap the promise in a `Promise.race([ajax, timeout])`.                                       |
| **Retry**                   | Write a helper: `function withRetry(fn, n){ return fn().catch(e => n>0 ? withRetry(fn, n‑1) : Promise.reject(e)); }`.  |

***

#### 14.5 Quick Reference

```
$.ajax(settings)    // full power
$.get(url[,data][,success][,type])
$.post(url[,data][,success][,type])
$.getJSON(url[,data][,success])

XHR methods: then, catch, finally, done, fail, always, success, error, complete, abort
```

*With this toolkit you can cover everything from vanilla REST endpoints to streaming uploads in a few lines of code.*

### 15 . Why Static Utilities?

Everything in this chapter is **independent of a wrapped DOM collection**; you can feed plain arrays, NodeLists, or objects. jFast purposely mirrors jQuery naming so muscle memory applies.

***

**15.1 `jFast.each( collection, callback )`**

*Iterates any array‑like structure.*

```js
const colors = ['teal', 'pink', 'orange'];

$.each(colors, (idx, val) => console.log(idx, val.toUpperCase()));
// 0 TEAL · 1 PINK · 2 ORANGE
```

Characteristics:

* Works on **NodeList** directly (no spread required).
* Callback signature is `(index, item)` like jQuery (not `(item,index)`).

***

**15.2 `jFast.map( collection, callback )`**

*Transforms each item; returns **new array**.*

```js
const lens = $.map(document.querySelectorAll('p'), p => p.textContent.length);
console.log(lens); // e.g. [25, 18, 42]
```

If the callback returns `null` or `undefined`, the item is *skipped* (parity with jQuery).

***

**15.3 `jFast.grep( array, predicate )`**

*Filters items; returns **new array**.*

```js
const nums   = [5, 8, 9, 13, 21, 22];
const primes = $.grep(nums, n => [2,3,5,7,11,13,17,19,23].includes(n));
```

> **Tip** – Because `grep` creates a new array, it’s ideal for immutable Redux‑style flows.

***

**15.4 `jFast.inArray( item, array )`**

Returns **index** (`>=0`) or `-1`.

```js
if ($.inArray('admin', user.roles) === -1) denyAccess();
```

***

**15.5 `jFast.param( object [, prefix] )`**

Serialises nested objects the **PHP / Rails‑style** way.

```js
const criteria = {
  sort:  'date',
  range: { from: '2025-01-01', to: '2025-06-30' },
  tags:  ['node', 'api']
};

const qs = $.param(criteria);
console.log(qs);
// "sort=date&range[from]=2025-01-01&range[to]=2025-06-30&tags[0]=node&tags[1]=api"

fetch('/search?' + qs).then(r => r.json());
```

***

**15.6 `jFast.extend( target, …sources )` — Deep Merge Engine**

Unlike a shallow `Object.assign`, jFast’s `extend` **recurses into nested objects** but leaves arrays intact.

```js
const defaults = {
  ui:   { theme: 'light', density: 'comfortable' },
  rate: 1000
};
const userCfg  = { ui: { density: 'compact' } };

const finalCfg = $.extend({}, defaults, userCfg);
/* finalCfg === {
     ui:   { theme: 'light', density: 'compact' },
     rate: 1000
   } */
```

**15.6.1 Adding Prototype Plugins**

Because `extend` is exported, you can patch either the global `jFast` **or** its prototype.

```js
// Static helper
$.extend($, {
  random(min, max){ return Math.floor(Math.random()*(max-min+1))+min; }
});

// Chainable instance helper
$.extend($.prototype, {
  flash(ms = 150){
    return this.each(el => {
      const orig = el.style.transition;
      el.style.transition = 'background ' + ms + 'ms';
      el.style.background = '#ffe66d';
      setTimeout(() => { el.style.background=''; el.style.transition=orig; }, ms);
    });
  }
});

// Usage
console.log($.random(1,6)); // dice roll
$('.btn-save').flash();
```

***

**15.7 Utility Comparison Table**

| Use‑case            | Vanilla ES                  | jFast Utility              | Snippet                       |
| ------------------- | --------------------------- | -------------------------- | ----------------------------- |
| Iterate NodeList    | `Array.from(nodes).forEach` | `$.each(nodes, fn)`        | `$.each(document.links, cb)`  |
| Map values          | `[...arr].map`              | `$.map(arr, fn)`           | `$.map($('li'), li => li.id)` |
| Deep‑merge configs  | `structuredClone` + custom  | `$.extend`                 | `$.extend({}, def, opt)`      |
| Encode query string | `URLSearchParams`           | `$.param` (handles nested) | `$.param({page:2})`           |

***

#### What’s Next?

With Static Utilities mastered you have:

* Collection‑agnostic helpers (`each`, `map`, `grep`).
* Query‑string encoding & deep merges.
* A building block (`extend`) for your own plugins.

### 16 . Authoring Plug‑ins

jFast keeps the **exact extension workflow** you know from jQuery: augment either `jFast.prototype` (for chainables) or `jFast` itself (for statics). Everything hinges on `jFast.extend`.

**16.1 Guidelines**

| Rule                                                                   | Rationale                                     |
| ---------------------------------------------------------------------- | --------------------------------------------- |
| Return `this` to stay chainable.                                       | Keeps plug‑in composable with core helpers.   |
| Store per‑element state in `el.dataset` or a `WeakMap`.                | Avoids leaking memory when nodes are removed. |
| Use a unique *data‑key namespace* (e.g. `"popover-active"`).           | Prevents collisions between plug‑ins.         |
| Accept an **options object** & merge with defaults via `jFast.extend`. | Enables declarative config + sane fall‑backs. |

**16.2 Micro‑Plug‑in Example — `highlight()`**

```js
(function ($) {
  const defaults = { color: '#fffd54', duration: 600 };

  $.extend($.prototype, {
    highlight(opts){
      opts = $.extend({}, defaults, opts);
      return this.each(el => {
        const orig   = getComputedStyle(el).backgroundColor;
        el.style.transition = `background ${opts.duration}ms`;
        el.style.background = opts.color;
        setTimeout(() => el.style.background = orig, opts.duration);
      });
    }
  });
})(jFast);

// usage
$('table tr.error').highlight({ color:'#ff8080' });
```

**16.3 Feature‑Rich Plug‑in Template (Modal)**

```js
/* modal.js – UMD style */
(function (root, factory) {
  if (typeof define === 'function' && define.amd) define(['jFast'], factory);
  else factory(root.jFast);
}(this, function ($) {

  const DATA_KEY = 'modalInstance';
  const defaults = { closeBtn: true, esc: true, backdrop: true };

  class Modal {
    constructor(el, opts){
      this.$el  = $(el);
      this.opts = $.extend({}, defaults, opts);
      this.bind();
    }
    bind(){
      if (this.opts.closeBtn){
        this.$el.find('[data-dismiss="modal"]').on('click', ()=> this.hide());
      }
      if (this.opts.esc){
        $(document).on('keydown.modal', e => e.key==='Escape' && this.hide());
      }
    }
    show(){
      this.$el.fadeIn(200).attr('aria-hidden', false);
      $(document.body).addClass('modal-open');
    }
    hide(){
      this.$el.fadeOut(150).attr('aria-hidden', true);
      $(document.body).removeClass('modal-open');
    }
    toggle(){ this.$el.is(':visible') ? this.hide() : this.show(); }
  }

  /* jFast bridge */
  $.extend($.prototype, {
    modal(cmdOrOpts){
      return this.each(el => {
        let inst = $(el).data(DATA_KEY);
        if (!inst){
          inst = new Modal(el, typeof cmdOrOpts==='object' ? cmdOrOpts : {});
          $(el).data(DATA_KEY, inst);
        }
        if (typeof cmdOrOpts === 'string'){
          inst[cmdOrOpts] && inst[cmdOrOpts]();
        }
      });
    }
  });
}));
```

Usage:

```js
$('#myModal').modal({ backdrop:false });
$('#launch').on('click', () => $('#myModal').modal('show'));
```

***

#### 16.4 Testing jFast Plug‑ins with Jest + jsdom

1. **Install Dev Deps**

```bash
npm i --save-dev jest @jest-environment-jsdom
```

2. **Setup Global `$` in `jest.setup.js`**

```js
require('../dist/jfast');           // expose global jFast
global.$ = global.jFast;
```

```json
// jest.config.json
{
  "setupFiles": ["<rootDir>/test/jest.setup.js"],
  "testEnvironment": "jsdom"
}
```

3. **Write a Spec**

```js
describe('highlight plug‑in', () => {
  document.body.innerHTML = '<p id="a">text</p>';
  
  test('changes background then reverts', done => {
    const $p = $('#a');
    $p.highlight({ color:'#abc', duration:50 });

    expect($p.css('background')).toBe('rgb(170, 187, 204)');
    
    setTimeout(() => {
      expect($p.css('background')).toBe('');
      done();
    }, 60);
  });
});
```

4. **Run**

```bash
npx jest
```

jsdom simulates enough of CSSOM for simple animation assertions; for layout you might stub `getBoundingClientRect`.

***

#### 16.5 Performance Best‑Practices

| Topic                          | Recommendation                                                                                  | Why                                           |
| ------------------------------ | ----------------------------------------------------------------------------------------------- | --------------------------------------------- |
| **Batch DOM writes**           | Build HTML strings or `DocumentFragment`, then `.append()` once.                                | Cuts reflow counts.                           |
| **Delegate events**            | Attach one `on('click', selector, …)` at container level instead of many direct listeners.      | Lower memory & faster diff when nodes mutate. |
| **Avoid synchronous Ajax**     | `async:false` blocks the UI; keep default `true`.                                               | Network stalls freeze the main thread.        |
| **Measure**                    | Drop `console.time()` around chains or use Chrome DevTools Performance tab.                     | Data > guesswork.                             |
| **Destroy observers**          | If a plug‑in uses `ResizeObserver` or `MutationObserver`, disconnect in `remove()` or `hide()`. | Prevents leaks on SPA route change.           |
| **Minify for production**      | jFast is readable by design—pass through Terser to shave \~35 %.                                | Smaller payload → TTI gains.                  |
| **Tree‑shake unused plug‑ins** | Author plug‑ins as separate files so bundlers can exclude them.                                 | Keeps your vendor chunk tiny.                 |

**Example – Batch Update vs. O(n) Loop**

```js
// baseline: O(n) reflow
$('li').each((i, el) => $(el).addClass('done'));

// optimized: CSS class on the parent
$('#todo').addClass('all-done');
```

***

#### 16.6 Performance Snippet: Virtualized List (100 k rows)

```js
function mountVirtual($container, rows){
  const rowH = 30, buffer = 10;
  $container.height(rows.length * rowH);     // big scroll area

  const $viewport = $('<div class="viewport"></div>').appendTo($container.parent());

  function render(){
    const top = $container.parent().scrollTop();
    const start = Math.max(0, Math.floor(top / rowH) - buffer);
    const end   = Math.min(rows.length, start + Math.ceil($viewport.height()/rowH) + buffer*2);
    const slice = rows.slice(start, end)
                      .map((txt,i)=> `<div class="row" style="top:${(start+i)*rowH}px">${txt}</div>`)
                      .join('');
    $container.html(slice);
  }
  $container.parent().on('scroll', render);
  render();
}
```

Demonstrates:

* Single delegated `scroll` handler.
* `position:absolute` rows avoid layout for hidden items.
* `html(slice)` rewrites once per frame.

#### A. Frequently Asked Questions (FAQ)

| Question                               | Short Answer                                                                                                                              |
| -------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| **Does jFast support IE 11?**          | Partially. Core DOM helpers work thanks to built‑in polyfills (`Set`, `NodeList.forEach`). You still need a Promise polyfill for Ajax.    |
| **Can I load jFast alongside jQuery?** | Yes. jFast attaches **both** `jFast` and `$`. If jQuery is present first, jFast will **not** overwrite `$`; access it via `window.jFast`. |
| **How big is the minified build?**     | Un‑minified: 9.6 KB. Minified + gzip: ≈ 2 KB.                                                                                             |
| **Is there ES Module support?**        | Planned for v1.3.0. For now you can `import` the UMD file in bundlers (Rollup / Webpack) without issues.                                  |
| **How do I remove the global `$`?**    | Wrap the script in a closure: `;(function(priv){ /* docs here */ })(jFast);` and avoid referring to `$` globally.                         |
| **What about TypeScript types?**       | A community‑maintained `@types/jfast` will debut after v1.3.0. Until then, declare `const $: typeof jFast;` in a `d.ts`.                  |

***

#### B. Migrating From jQuery 3.x to jFast 1.x

| jQuery Code                                 | jFast Equivalent                                    | Notes                                                    |
| ------------------------------------------- | --------------------------------------------------- | -------------------------------------------------------- |
| `$(dom).fadeToggle(150)`                    | `$(dom).toggle(150)`                                | jFast combines fade into `toggle`.                       |
| `$.ajaxSetup({...})`                        | *(none)*                                            | jFast aims for statelessness; pass settings per‑request. |
| `$('form').serializeArray()`                | Same                                                | Fully supported.                                         |
| `$(img).on('load', fn)`                     | Same                                                | Event helpers identical.                                 |
| `$(el).css({ top:0 }).animate({ top:200 })` | Use CSS transitions or `slideDown/Up`               | jFast provides only basic slide/fade; no full `animate`. |
| `$.Deferred()`                              | Use native `Promise` or `$.ajax()` returned promise | Promise polyfill required on old browsers.               |

**Cheat Migration Recipe**

1. Replace jQuery script tag with jFast.
2. Scan for non‑supported APIs: `.animate`, `ajaxSetup`, `$.proxy`, `$.fn.extend` (replace with `jFast.extend`).
3. Polyfill Promise if targeting ES5 browsers.
4. Test on evergreen browsers; then add polyfills as necessary.

***

#### C. Roadmap (2025 ↦ 2026)

| Milestone  | ETA     | Highlights                                                                              |
| ---------- | ------- | --------------------------------------------------------------------------------------- |
| **v1.3.0** | Q3 2025 | Native ES Module bundle, built‑in `Promise` polyfill toggle, new helper `.toggleAttr`   |
| **v1.4.0** | Q1 2026 | Animation engine (CSS keyframe wrapper), `$.ajaxSetup`, fetch‑based Ajax fallback       |
| **v2.0.0** | TBD     | Drops IE 11 support, swaps internal XHR for `fetch`, tree‑shake‑friendly build targets. |

Community feedback on GitHub **issues tagged `proposal-*`** steers prioritisation.

***

#### D. Additional Resources

* **GitHub** – <https://github.com/cmsfullform/jfast>
* **Issues / Discussions** – good first issues labelled **“help wanted”**
* **CDN** – CDN link generator: `https://cdn.jsdelivr.net/npm/jfast@1.2.3/dist/jfast.min.js`
* **Starter Plug‑ins** – `modal.js`, `tooltip.js`, `virtualList.js` in `/plugins` directory
* **Unit Test Suite** – sample Jest configuration in `/test` folder

***

#### E. Final Thoughts

jFast was built for developers who **love jQuery’s ergonomics** but need a **fraction‑of‑the‑weight** helper in 2025‑era projects. Its small, readable source aims to be a living tutorial—feel free to fork, audit, and tailor it to your own design system.

> **Thank you** for reading through all parts.\
> If you find a bug, open an issue or submit a pull‑request—every line counts!

*— CMS Full Form, Maintainer*


# Core

The `Core` directory in PHPFast contains essential components that power the framework, playing a crucial role in handling requests and managing the basic processes of the application. Below is a detailed description of the key files in the `Core` directory:

## [AppException](/documents/core/appexception)

This file contains the `AppException` class, which is used to handle exceptions in the application. The class provides a way to manage errors and display appropriate error messages, helping developers quickly identify and fix issues during development.

## [BaseController](/documents/core/basecontroller)

The `BaseController` class is the base class for all controllers in the application. It contains common methods that all controllers can inherit, making it easier to reuse code and organize actions within the application systematically.

## [BaseModel](/documents/core/basemodel)

The `BaseModel` class is the base class for all models in the application, facilitating interaction with the database. Common methods like querying, saving, or updating data are defined in this class, allowing other models to easily inherit and reuse the functionality.

## [BaseBlock](/documents/core/baseblock)

The base class for blocks in the system. Blocks are reusable components that can be used to display content in different parts of the application. The `BaseBlock` defines common methods and properties for blocks, such as setting and getting properties, rendering content, and handling data. This helps manage and display content flexibly and consistently.

## [Router](/documents/core/router)

The `Router` class is responsible for managing the application's routes. It takes incoming URL requests and maps them to the corresponding controller methods, ensuring requests are routed accurately and efficiently.

{% hint style="info" %}
Summary

All the files in the `Core` directory together form the foundation of PHPFast, handling HTTP requests, managing errors, routing, and providing the essential functionality needed for the application.
{% endhint %}


# AppException

## `render404()`

This method is used to display a `404` error page when a resource is not found. It checks the debug mode and displays detailed information if debug mode is enabled; otherwise, it displays a general message.

* Sets the HTTP response code to the error code (404).
* If debug mode is enabled, it displays detailed error information including the error code, error message, file, line, and trace.
* If debug mode is disabled, it displays a general 404 error message.
* Uses the `Render` class to display the 404 error page.
* Stops further execution using `exit()`.

Example:

```php
$exception = new AppException("Page not found", 0, null, 404);
$exception->handle();
```

## `renderError()`

This method is used to display exception information in HTML format for the user. It also checks the debug mode and displays detailed information if debug mode is enabled; otherwise, it displays a general message.

* Sets the HTTP response code to the error code (500 or other error codes).
* If debug mode is enabled, it displays detailed error information including the error code, error message, file, line, and trace.
* If debug mode is disabled, it displays a general error message.
* Stops further execution using `exit()`.

```php
$exception = new AppException("Internal Server Error", 0, null, 500);
$exception->handle();
```

## `handle()`

This method handles the exception, logs it, and displays the error information to the user. It checks the error status code and calls the corresponding method (`render404` or `renderError`).

* Logs the error using the `Logger` class.
* Checks the error status code:
  * If it is 404, calls the `render404()` method.
  * If it is another error code, calls the `renderError()` method.

Example:

```php
try {
    // Some code that may throw an exception
    throw new AppException("Page not found", 0, null, 404);
} catch (AppException $e) {
    $e->handle();
}
```

## Using in Controller

```php
<?php
namespace App\Controllers;

use System\Core\BaseController;
use System\Core\AppException;

class UserController extends BaseController {

    public function index() {
        try {
            // Simulate an error (e.g., user not found)
            $user = $this->findUserById(1);
            if (!$user) {
                throw new AppException('User not found!', 0, null, 404);
            }

            // Render the user data
            $this->render('user/profile', ['user' => $user]);

        } catch (AppException $e) {
            // Handle the exception
            $e->handle();
        }
    }

    private function findUserById($id) {
        // Sample method to simulate user fetching; returns null to simulate "user not found"
        return null;
    }
}
```

**How It Works:**

* `try {}` → Starts the error-handling block.
* Attempts to find the user using `findUserById(1)`.
* If the user is not found (`null`), throws an **AppException** with the message `"User not found!"` and error code `404`.
* If no error occurs, **renders the user profile page** using `render('user/profile', ['user' => $user])`.
* `catch (AppException $e) {}` → If an error occurs, it is handled by calling `$e->handle();`, which may log the error or display an error page.


# BaseController

The `BaseController` class serves as the foundational controller in the framework, providing common functionalities and utilities that can be inherited by other controllers. This class typically includes methods for handling requests, rendering views, and managing session data. By centralizing these common tasks, the `BaseController` helps to reduce code duplication and streamline the development process.

## Constructor (`__construct`)

```php
<?php
public function __construct() {
    // Common initializations for all controllers
    // Example: load helpers, libraries, check session, etc.
}
```

Initializes common settings for all controllers, such as loading helpers, libraries, and checking sessions.

## `data()`

```php
<?php
public function data($key, $value = null) {}
```

* Sets or gets data.
* If two parameters are passed, it sets the data.
* If one parameter is passed, it gets the data.
* `$key`: Name of the data
* `$value`: Value of the data (if any)
* `return`: Returns the data if only one parameter is passed.

## `render()`

```php
<?php
protected function render($layout, $view, $isreturn = false) {}
```

* Renders a specified layout and view.
* `$layout`: Name of the layout.
* `$view`: Name of the view.
* `$isreturn` Whether to return the rendered content or echo it.

## `json()`

```php
<?php
protected function json($data = [], $statusCode = 200) {}
```

* Formats data as a JSON response, making it suitable for APIs and AJAX requests. It allows setting a response payload and an HTTP status code, ensuring proper API communication.
* `$data`: Data to be returned.
* `$statusCode`: HTTP status code
* `outputs`: Data in JSON format.

## `success()`

```php
<?php
protected function success($data = [], $message = 'Success') {}
```

* Generate standardized JSON responses for successful operations.
* `$data`: Data to be returned.
* `$message`: Success message.
* `outputs`: Data in JSON format.

## `error()`

```php
<?php
protected function error($message = 'An error occurred', $errors = [], $statusCode = 400) {}
```

* Generate standardized JSON responses for errors
* `$message`: Error message.
* `$errors`: Array of errors.
* `$statusCode`: HTTP status code.
* `outputs`: Data in JSON format.

## `get_success()`

```php
<?php
protected function get_success($data = [], $message = 'Success') {}
```

* Same purpose as `success()`, but instead of returning JSON, it returns responses as arrays.
* `$data`: Data to be returned.
* `$message`: Success message
* `return`: Array

## `get_error()`

```php
<?php
protected function get_error($message = 'An error occurred', $errors = [], $statusCode = 400) {}
```

* Same purpose as `error()`, but instead of returning JSON, it returns responses as arrays.
* `$data`: Data to be returned.
* `$message`: Success message
* `return`: Array

## Example

```php
<?php
namespace App\Controllers;

use System\Core\BaseController;

class HomeController extends BaseController {

    public function index() {
        // Set some data to be passed to the view
        $this->data('title', 'Home Page');
        $this->data('content', 'Welcome to PHPFast Framework!');

        // Render the view
        $this->render('backend', 'backend/home/index');
    }

    public function getData() {
        // Example data
        $data = [
            'name' => 'PHPFast Framework',
            'email' => 'php_fast.doe@gmail.com'
        ];

        // Return success response in JSON format
        $this->success($data, 'Data retrieved successfully');
    }
}
```


# BaseModel

## `__construct()`

```php
<?php
public function __construct() {
    $configdb = config('db');  // Use config from config.php with key 'db'
    $this->db = $this->loadDatabaseDriver($configdb['db_driver'], $configdb);
    unset($configdb);
}
```

* Initializes the database connection using the configuration from the config file.
* Loads the appropriate database driver.

## `_schema()`

```php
<?php
public function _schema() {
    return [];
}
```

Defines the structure of the model by returning a schema array. By default, it returns an empty array, but child classes can override this method to specify the model's data structure.

## `_table()`

```php
<?php
public function _table() {
    return $this->table;
}
```

Returns the name of the database table associated with the model. It helps establish the connection between the model and its corresponding table.

## `_columns()`

```php
<?php
protected function _columns() {
    return $this->fillable;
}
```

Returns the list of columns that are allowed to be filled with data. These columns are defined in the child model and determine which fields can be updated or inserted to prevent unauthorized modifications.

## `fill()`

```php
<?php
protected function fill($data) {}
```

* Filters the input data to only include columns that are allowed to be filled.
* `$data`: Data to filter.

## `row()`

```php
<?php
public function row($table, $where = '', $params = []) {}
```

Fetches a single row from the database based on the specified conditions.

`$table`: Name of the table.

`$where`: Query conditions.

`$params`: Optional parameters.

`return`: Data row or false if no result.

## `rowField()`

```php
<?php
public function rowField($table, $fields, $where = '', $params = []) {}
```

Fetches a single row with specific fields from the database based on the specified conditions.

`$table`: Name of the table.

`$fields`: Fields to query (optional).

`$where`: Query conditions.

`$params`: Optional parameters.

`return`: Data row or false if no result.

## `list()`

```php
<?php
public function list($table, $where = '', $params = [], $orderBy = '', $page = 1, $limit = null) {}
```

Fetches multiple rows from the database based on the specified conditions, order, and pagination.

`$table`: Name of the table.

`$where`: Query conditions.

`$params`: Optional parameters.

`$orderBy`: ORDER BY clause (optional).

`$page`: Page number for pagination.

`$limit`: Number of results per page (optional).

`return`: List of data rows.

## `listpaging()`

```php
<?php
public function listpaging($table, $where = '', $params = [], $orderBy = '', $page = 1, $limit = null) {}
```

Fetches multiple rows with pagination from the database based on the specified conditions, order, and pagination.

`$table`: Name of the table.

`$where`: Query conditions.

`$params`: Optional parameters.

`$orderBy`: ORDER BY clause (optional).

`$page`: Page number for pagination.

`$limit`: Number of results per page (optional).

`return`: List of data rows.

## `listfieldpaging()`

```php
<?php
public function listfieldpaging($table, $fields = '*', $where = '', $params = [], $orderBy = '', $page = 1, $limit = null) {}
```

Fetches multiple rows with specific fields and pagination from the database based on the specified conditions, order, and pagination.

`$table`: Name of the table.

`$fields`: Fields to fetch.

`$where`: Query conditions.

`$params`: Optional parameters.

`$orderBy`: ORDER BY clause (optional).

`$page`: Page number for pagination.

`$limit`: Number of results per page (optional).

`return`: List of data rows.

## `add()`

```php
<?php
public function add($table, $data) {}
```

* Inserts a new row into the database.

`$table`: Name of the table.

`$data`: Data to insert.

`return`: Success or failure.

## `set()`

```php
<?php
public function set($table, $data, $where = '', $params = []) {}
```

Updates existing rows in the database based on the specified conditions.

`$table`: Name of the table.

`$data`: Data to update.

`$where`: Update conditions.

`return`: Number of affected rows.

## `del()`

```php
<?php
public function del($table, $where = '', $params = []) {}
```

Deletes rows from the database based on the specified conditions.

`$table`: Name of the table.

`$where`: Delete conditions.

`return`: Number of affected rows

## `query()`

```php
<?php
public function query($query, $params = []) {}
```

Executes a custom SQL query.

`$query`: The SQL query string.

`$params`: An array of parameters to bind to the query (optional).

`return`: Result of the query (used for SELECT, INSERT, UPDATE, DELETE)

## `lastInsertId()`

```php
<?php
public function lastInsertId() {}
```

Returns the ID of the last inserted row.

## `count()`

```php
<?php
public function count($table, $where = '', $params = []) {}
```

Counts the number of rows in the database based on the specified conditions.

`$table`: The name of the table.

`$where`: The WHERE clause to filter records (optional).

`$params`: An array of values corresponding to the parameters in the WHERE clause (optional).

`return`: Number of records in the table.

## Example

### `UsersModel.php`

Create UsersModel and add the following code:

```php
<?php
namespace App\Models;
use System\Core\BaseModel;

class UsersModel extends BaseModel {
    protected $table = 'fast_users';
    protected $fillable = ['username', 'email', 'password', 'fullname'];
    protected $guarded = ['id', 'created_at', 'updated_at'];
    
    public function _schema() {
        return [
            'id'         => 'INT',
            'username'   => 'VARCHAR(255)',
            'email'      => 'VARCHAR(255)',
            'phone'      => 'VARCHAR(30)',
            'password'   => 'VARCHAR(255)',
            'created_at' => 'DATETIME',
            'updated_at' => 'DATETIME'
        ];
    }
    public function getUsers($where = '', $params = [], $orderBy = 'id DESC', $page = 1, $limit = null) {
        return $this->list($this->table, $where, $params, $orderBy, $page, $limit);
    }
    
    public function getUsersPage($where = '', $params = [], $orderBy = 'id DESC', $page = 1, $limit = null) {
        return $this->listpaging($this->table, $where, $params, $orderBy, $page, $limit);
    }
    
    public function getFieldUsersPage($fields = '', $where = '', $params = [], $orderBy = 'id DESC', $page = 1, $limit = null) {
        return $this->listfieldpaging($this->table, $fields, $where, $params, $orderBy, $page, $limit);
    }
    
    public function getUserById($id){
        return $this->row($this->table, 'id = ?', [$id]);
    }
    
    public function getUserByIdField($fields, $id){
        return $this->rowField($this->table, $fields, 'id = ?', [$id]);
    }

    public function getUserByUsername($username){
        return $this->row($this->table, 'username = ?', [$username]);
    }
    
    public function getUserByEmail($email){
        return $this->row($this->table, 'email = ?', [$email]);
    }
    
    public function addUser($data) {
        $data = $this->fill($data);
        return $this->add($this->table, $data);
    }
    
    public function updateUser($id, $data) {
        $data = $this->fill($data);
        return $this->set($this->table, $data, 'id = ?', [$id]);
    }
    
    public function deleteUser($id) {
        return $this->del($this->table, 'id = ?', [$id]);
    }
    
    public function searchUser($conditions = [])
    {
        $query = "SELECT * FROM " . $this->table;
        $params = [];

        if (!empty($conditions)) {
            $query .= " WHERE ";
            $whereClauses = [];

            foreach ($conditions as $field => $value) {
                $whereClauses[] = "$field LIKE ?";
                $params[] = '%' . $value . '%';
            }
            $query .= implode(' OR ', $whereClauses);
        }

        return $this->query($query, $params);
    }
    
}
```

### `UsersController.php`

In `UsersController.php`, you can utilize `UsersModel` to interact with the database and seamlessly pass the retrieved data to the view for rendering.

```php
<?php
namespace App\Controllers;
use System\Core\BaseController;

class UsersController extends BaseController {
        public function __construct()
    {
        load_helpers(['backend']);
        $this->usersModel = new UsersModel();
    }

    public function index() {
        $users = $this->usersModel->getUsers(); // Get all users

        // Render the view
        $this->data('users', $users);
        $this->render('backend', 'backend/users/index');
    }
    
    public function profile($id) {
        $info = $this->usersModel->getUserById($id); // Get user by ID

        // Render the view
        $this->data('info', $info);
        $this->render('backend', 'backend/users/profile');
    }
    
    public function register() {
        $input = [
            'username'          => S_POST('username') ?? '',
            'fullname'          => S_POST('fullname') ?? '',
            'email'             => S_POST('email') ?? '',
            'phone'             => S_POST('phone') ?? '',
            'password'          => S_POST('password') ?? '',
            'password_repeat'   => S_POST('password_repeat'),
        ]
        
        // Assume that the $input has been validated as valid.
        $user_id = $this->usersModel->addUser($input);

        // Assume that added user and $users_id has value
        Session::flash('success', 'Register Successfully!!!');
        $this->render('backend', 'backend/users/index');
    }
}
```


# BaseBlock

The `BaseBlock.php` file in the `Core` directory of the PHPFast framework defines an abstract class `BaseBlock` to manage blocks in the application. Below is a detailed explanation of the methods in this file.

## `getName()` and `setName()`

```php
<?php
    // Returns the block name, e.g., "HeaderBlock"
    protected function getName(){
        return ucfirst($this->name);
    }
    protected function setName($value){
        $this->name = $value;
    }
```

* The `getName` method returns the block name with the first letter capitalized.&#x20;
* The `setName` method sets the value of the `$name` property.

## `getLabel()` and `setLabel()`

```php
<?php
    protected function getLabel(){
        return $this->label;
    }
    protected function setLabel($value){
        $this->label = $value;
    }
```

* The `getLabel` method returns the value of the `$label` property. &#x20;
* The `setLabel` method sets the value of the `$label` property.

## `setProps()` and `getProps()`

```php
<?php
    public function setProps(array $props) {
        $this->props = array_merge($this->props, $props);
        return $this;
    }
    protected function getProps() {
        return $this->props;
    }
```

* The `setProps` method sets the properties for the block by merging the provided `$props` array with the current `$props` array.&#x20;
* The `getProps` method returns the properties of the block.

## `handleData()`

```php
<?php
    // Handle data and return it in the format required by the layout file
    abstract public function handleData();
```

The abstract method `handleData` is responsible for processing data and returning it in the format required by the layout file. This method will be implemented in the subclasses that extend `BaseBlock`.

## Example

```php
<?php
namespace App\Blocks\Content;

use System\Core\BaseBlock;
use App\Models\UsersModel;

class ContentBlock extends BaseBlock {
    public function __construct() {
        $this->setLabel('Content Block');
        $this->setName('Content');
        $this->setProps([
            // layout name: layout_1.php
            'layout'            => 'layout_1',         // Required
            'other_properties'  => 'Other properties', // Other Properties 
        ]);
        
        $this->usersModel = new UsersModel();
    }
    
    public function handleData() {
        $props = $this->getProps();
        
        $users   = $this->usersModel->getUsers();  
        return [
            'props'    => $props,
            'users'    => $users,
        ];
    }
}
```

Find out how to use [Block](/documents/blocks)

{% hint style="success" %}
Summary

The `BaseBlock` class in the `BaseBlock.php` file defines the basic properties and methods to manage blocks in the application. The main methods include:

* **`getName` and `setName`**: Get and set the block's name.
* **`getLabel` and `setLabel`**: Get and set the block's label.
* **`setProps` and `getProps`**: Set and get the block's properties.
* **`handleData`**: An abstract method to process the block's data.
  {% endhint %}


# Bootstrap

The `Bootstrap` class in the Bootstrap.php file is a core component of the framework, responsible for initializing and configuring the application. It handles the setup of essential configurations, routing, and middleware processing. Below is an overview of its key functionalities:

## Namespace and Imports

```php
?php
namespace System\Core;
use System\Libraries\Logger;
use Exception;

if (!defined('ROOT_PATH')) {
    exit('No direct access allowed.');
}

require_once ROOT_PATH . '/system/Helpers/Core_helper.php';
load_helpers(['uri', 'security']);
```

* Defines the namespace `System\Core`.
* Imports the `Logger` class and the `Exception` class.
* Checks if `ROOT_PATH` is defined. If not, it prevents direct access to the file.
* Loads the `Core_helper.php` file to use the `load_helpers` function.
* Loads the `uri` and `security` helpers.

## Class Definition

```php
<?php
class Bootstrap {

    protected $routes;
    protected $uri;

    public function __construct() {
        $appConfig = config('app');
        if (!empty($appConfig['app_timezone'])) {
            date_default_timezone_set($appConfig['app_timezone']);
        }
        if (!empty($appConfig['debug']) && $appConfig['debug']) {
            ini_set('display_startup_errors', 1);
            ini_set('display_errors', 1);
            error_reporting(-1);
        } else {
            ini_set('display_startup_errors', 0);
            ini_set('display_errors', 0);
            error_reporting(E_ALL & ~E_NOTICE);
        }
        $this->init_uri();
        $this->routes = new Router(); // Create an instance for Router
        $this->loadRoutes();          // Load the routes
    }
}
```

* Defines the `Bootstrap` class with protected properties `$routes` and `$uri`.
* The constructor sets the timezone, configures error reporting based on the debug mode, initializes the URI, creates a `Router` instance, and loads the routes.

## `init_uri()`

```php
private function init_uri() {
    $originalUri = request_uri();
    $originalQ = $_SERVER['QUERY_STRING'] ?? '';
    $uri = uri_security($originalUri);
    $sanitizedQueryString = '';
    
    if (!empty($originalQ)) {
        $safeGet = sget_security(); 
        $sanitizedQueryString = http_build_query($safeGet); 
    }
    
    $cleanFull = '/' . trim($uri, '/') . '/';  "
    if ($sanitizedQueryString !== '') {
        $cleanFull .= '?' . $sanitizedQueryString;
    }
    
    $cleanFull = '/' . ltrim($cleanFull, '/');
    if ($cleanFull !== $_SERVER['REQUEST_URI'] && $cleanFull !== $_SERVER['REQUEST_URI'] . '/') {
        redirect(base_url($cleanFull));
    }
    
    unset($safeGet, $sanitizedQueryString, $originalUri, $cleanFull);
 
    $this->uri = [
        'uri' => $uri,
        'split' => explode('/', $uri)
    ];
    unset($uri);
    if (!empty($this->uri['split'][0]) && in_array($this->uri['split'][0], LANG_LIST)) {
        array_shift($this->uri['split']); 
        $this->uri['uri'] = implode('/', $this->uri['split']);
    }
    return $this->uri;
}
```

* Initializes the URI by sanitizing it and redirecting if necessary.
* Splits the URI into parts and handles language prefixes.

## `run()`

```php
public function run() {
        try {
            if (!isset($_SERVER['REQUEST_METHOD'])) $_SERVER['REQUEST_METHOD'] = 'GET';
            $method = $_SERVER['REQUEST_METHOD'];
            $this->dispatch($this->uri['uri'], $method);
        } catch (AppException $e) {
            $e->handle();
        } catch (\Throwable $e) { // Catch all exceptions and errors
            Logger::error($e->getMessage(), $e->getFile(), $e->getLine());
            http_response_code(500);
            if (!empty(config('app')['debug'])) {
                echo $e->getMessage(), $e->getFile(), $e->getLine();
            } else {
                echo "An unknown error has occurred. Lets check file logger.log!";
            }
        }
    }
```

* Runs the framework.
* Checks the HTTP method of the request (GET, POST, etc.).
* Calls the `dispatch()` method to route the URI to the corresponding controller and action.
* Catches and handles `AppException` and other errors, logs the error, and displays an error message.

## `loadRoutes()`

```php
 private function loadRoutes() {
        global $routes;
        $routes = $this->routes;
        if (!empty($this->uri) && !empty($this->uri['split']) && $this->uri['split'][0] == 'api') {
            if (file_exists(ROOT_PATH . '/application/Routes/Api.php')) {
                require_once ROOT_PATH . '/application/Routes/Api.php';
            }
        }
        if (file_exists(ROOT_PATH . '/application/Routes/Web.php')) {
            require_once ROOT_PATH . '/application/Routes/Web.php';
        }
    }
```

* Loads the routes from the `Api.php` and `Web.php` route files.
* Uses the global `$routes` variable to store the routes.
* Checks and loads the corresponding route files if they exist.

## `dispatch()`

```php
private function dispatch($uri, $method) {
        $route = $this->routes->match($uri, $method);
        if (isset($route['action']) && $route['action'][0] == '_') {
            throw new AppException("404 - Router: /{$uri} ({$method}) can not access!", 404, null, 404);
        }
        
        if (!$route) {
            throw new AppException("404 - Router: /{$uri} ({$method}) not found!", 404, null, 404);
        }
        
        $middleware = new Middleware();
        if (!empty($route['middleware'])) {
            foreach ($route['middleware'] as $mw) {
                $middleware->add($mw);
            }
        }

      
        unset($route['middleware']);
        $route['uri'] = $uri;
        $middleware->handle($route, function () use ($route) {
            $controllerClass = $route['controller'];
            $action = $route['action'];
            $params = $route['params'];
            
            if (!class_exists($controllerClass)) {
                throw new AppException("Controller {$controllerClass} not found.", 404, null, 404);
            }
            
            $controller = new $controllerClass();

            if (!method_exists($controller, $action)) {
                throw new AppException("Action {$action} not found in {$controllerClass} Controller.", 404, null, 404);
            }

            call_user_func_array([$controller, $action], $params);
        });
    }
```

* Routes the URI to the corresponding controller and action.
* Uses `Router` to match the URI and HTTP method with the corresponding route.
* Checks and handles middleware before calling the controller.
* Checks the existence of the controller and action, throws an exception if not found.
* Calls the controller and action with the corresponding parameters.

{% hint style="success" %}
Conclusion

The methods in `Bootstrap.php` help initialize and route the framework, handle the URI, load the routes, and route the request to the corresponding controller and action. These methods also handle exceptions and log errors to ensure the application runs smoothly.
{% endhint %}


# Middleware

The `Middleware.php` file in your application is designed to manage and execute a stack of middleware components. Middleware components are used to process HTTP requests before they reach the controller and after the controller has generated a response. This allows for a clean separation of concerns, enabling you to handle tasks such as authentication, logging, and request modification in a modular and reusable way.

## `add()`

```php
<?php
public function add(callable $middleware) {
    $this->middlewares[] = $middleware;
}
```

* Adds a middleware to the stack.
* The middleware should be a callable (function or method) that takes the route and a next function as parameters.

## `handle()`

```php
<?php
public function handle($route, callable $next) {
    $this->index = 0;
    $this->next($route, $next);
}
```

* Starts the middleware handling process.
* Resets the index and calls the `next` method to begin executing the middleware stack.

{% hint style="success" %}
Conclusion

The `Middleware.php` file provides a robust framework for managing middleware in your application. By allowing middleware components to be added dynamically and executed in sequence, it ensures that your application can handle complex request processing scenarios in a clean and maintainable way. Whether you need to perform authentication, logging, or any other pre-processing tasks, the middleware stack makes it easy to modularize and reuse your code.
{% endhint %}


# Router

The `Router` class is responsible for defining and managing the routes in your application. It maps HTTP requests to specific controller actions, allowing you to organize and handle different endpoints in a structured manner. Below is an explanation of each method in the class.

**Find out how to use** [**Route**](/documents/uri-routing)

## Class Definition and Properties

```php
<?php
namespace System\Core;

class Router {
    protected $routes = [];
    
```

`$routes`: An array that holds the list of defined routes.

## `get()`

```php
<?php
    public function get($pattern, $callback, $middleware = []) {
        $this->addRoute('GET', $pattern, $callback, $middleware);
    }
```

Defines a route that responds to GET requests.

* `$pattern`: The URL pattern for the route.
* `$callback`: The controller action or callback to handle the request.
* `$middleware`: An array of middleware to apply to the route.

Calls the `addRoute` method to add the route to the `$routes` array with the HTTP method set to 'GET'.

## `post()`

```php
<?php
    public function post($pattern, $callback, $middleware = []) {
        $this->addRoute('POST', $pattern, $callback, $middleware);
    }
```

Defines a route that responds to POST requests.

* `$pattern`: The URL pattern for the route.
* `$callback`: The controller action or callback to handle the request.
* `$middleware`: An array of middleware to apply to the route.

## `put()`

```php
<?php
    public function put($uri, $controller, $middleware = []) {
        $this->addRoute('PUT', $uri, $controller, $middleware);
    }
```

Defines a route that responds to PUT requests.

* `$uri`: The URL pattern for the route.
* `$controller`: The controller action or callback to handle the request.
* `$middleware`: An array of middleware to apply to the route

## `delete()`

```php
<?php
    public function delete($uri, $controller, $middleware = []) {
        $this->addRoute('DELETE', $uri, $controller, $middleware);
    }
```

Defines a route that responds to DELETE requests.

* `$uri`: The URL pattern for the route.
* `$controller`: The controller action or callback to handle the request.
* `$middleware`: An array of middleware to apply to the route.

## `match()`

```php
<?php
public function match($uri, $method) {}
```

Matches the given URI with the defined routes and returns the controller, action, parameters, and middleware.

* `$uri`: The URI to match.
* `$method`: The HTTP method of the request.

{% hint style="success" %}
Conclusion

The `Router` class provides a robust framework for defining and managing routes in your application. By mapping HTTP requests to specific controller actions and integrating middleware, it ensures that your application can handle requests in a structured and secure manner. This class makes it easy to organize and extend your application, supporting various HTTP methods, dynamic routing, and middleware integration.
{% endhint %}

**Find out how to use** [**Route**](/documents/uri-routing)


# URI Routing

## What is URI Routing?

URI Routing maps a URI to a specific controller method, determining how requests are processed.

CodeIgniter supports two types of routing:

1. Defined Route Routing – Allows manual route definition, offering full control and flexibility over URL structures.
2. Auto Routing – Automatically maps HTTP requests to the appropriate controller methods based on naming conventions, eliminating the need for manual route setup.

## `Api.php` and `Web.php`

In a web application, separating routes for APIs and web interfaces is a best practice for managing and maintaining the codebase. Below is the distinction between [**`Api.php`**](/documents/uri-routing/api.php) and [**`Web.php`**](/documents/uri-routing/web.php), as well as when to use each file.

## Defining Routing Rules in PHPFast

In PHPFast, routes are defined using the `$routes` object within dedicated route files. The syntax is straightforward and supports multiple HTTP methods, including GET, POST, PUT, DELETE, and more.

#### Examples

```php
$routes->get('users/', 'UsersController::list');
$routes->post('users/create', 'UsersController::create');
$routes->get('users/(:num)', 'UsersController::view:$1');
$routes->put('users/edit/(:num)', 'UsersController::edit:$1');
$routes->delete('users/delete/(:num)', 'UsersController::delete:$1');
$routes->get('admin', 'AdminController::index', [\App\Middleware\AuthMiddleware::class]);
```

### Understanding Route Structure

A route consists of two main parts:

* Route Path → The URL pattern (relative to the `BaseURL`).
* Route Handler → The Controller and its corresponding method that should process the request.

**Example:**

```php
$routes->get('/', 'HomeController::index');
```

This means that when a user visits `/` (the homepage), CodeIgniter will call the `index()` method inside the `HomeController`.

### Defining Routes with HTTP Methods

When specifying a route, you also define the HTTP method it should respond to:

* GET Request:

  ```php
  $routes->get('users', 'UsersController::list');
  ```

  * Maps `/users` to the `list()` method inside the `Users` controller.
* GET Request with Parameters:

  ```php
  $routes->get('users/1/23', 'UsersController::list/1/23');
  ```

  * Calls `$UsersController->list(1, 23)`, passing `1` and `23` as parameters.
* POST Request:

  ```php
  $routes->post('submit-form', 'UsersController::submitForm')
  ```

  * Handles form submissions via the `submitForm()` method in `UsersController`.

### Using Placeholders for Dynamic URLs

PHPFast supports placeholders to create flexible routes:

| **Placeholder**   | **Description**                                       | **Regex Equivalent** |
| ----------------- | ----------------------------------------------------- | -------------------- |
| **`(:any)`**      | Matches any characters except `/`.                    | `(.+)`               |
| **`(:segment)`**  | Matches any single segment of the URL, excluding `/`. | `([^/]+)`            |
| **`(:num)`**      | Matches only numeric values.                          | `(\d+)`              |
| **`(:alpha)`**    | Matches only alphabetic characters (A-Z, a-z).        | `([a-zA-Z]+)`        |
| **`(:alphanum)`** | Matches alphanumeric characters (A-Z, a-z, 0-9).      | `([a-zA-Z0-9]+)`     |
| **`(:hash)`**     | Matches a 32-character hexadecimal hash value.        | (\[a-fA-F0-9]{32})   |

Example:

#### 1. `(:any)` - Matches **any string** (except `/`).

```php
$routes->get('users/(:any)', 'UsersController::detail/$1');
```

**Example URL:** `/users/detail`\
**Calls:** UsersController`::view('detail')`

#### 2. `(:segment)` – Matches a single URL segment (excluding /).

```php
$routes->get('users/(:segment)', 'UsersController::show/$1');
```

**Example URL:** `/users/all`\
**Calls:** UsersController`::show('all')`

#### 3. <kbd>(:num)</kbd> - Matches only numeric values.

```php
$routes->get('users/(:num)', 'UsersCotroller::details/$1');
```

**Example URL:** `/users/123`\
**Calls:** UserController`::details(123)`

#### 4. `(:alpha)` – Matches only alphabetic characters (A-Z, a-z).

```php
$routes->get('users/(:alpha)', 'UsersController::profile/$1');
```

**Example URL:** `/user/php_fast`\
**Calls:** `UsersController::profile('php_fast')`

#### 5. <kbd>(:alphanum)</kbd> – Matches **alphanumeric characters (A-Z, a-z, 0-9)**.

```php
$routes->get('users/(:alphanum)', 'UsersController::execute/$1');
```

**Example URL:** `/users/abc123`\
**Calls:** UsersController`::execute('abc123')`

#### 6. <kbd>(:hash)</kbd> – Matches **a 32-character hexadecimal hash value**.

```php
$routes->get('verify/(:hash)', 'AuthController::verify/$1');
```

**Example URL:** `/verify/a94a8fe5ccb19ba61c4c0873d391e987`\
**Calls:** `AuthController::verify('a94a8fe5ccb19ba61c4c0873d391e987')`

### Global Options

The given lines define different types of routes in PHPFast using `$routes`. Each method corresponds to a specific HTTP request type, which determines how the route processes incoming requests.

```php
// Route that only accepts GET requests
$routes->get('product/(:num)/(:string)', 'ProductController::show:$1:$2');		

// Route that only accepts POST requests (for form submissions, data creation)
$routes->post('product/create', 'ProductController::create'); 		

// Route that only accepts PUT requests (used for updating resources)
$routes->put('product/update/(:num)', 'ProductController::update/$1');			

// Route that only accepts DELETE requests (used to delete resources)
$routes->delete('product/delete/(:num)', 'ProductController::delete/$1'); 		
			
// Applying middleware to a single route
$routes->get('admin', 'AdminController::index', [\App\Middleware\AuthMiddleware::class]);
```


# Web.php

The `Web.php` file is used to define routes for the web interface of the application. These routes are typically used to render HTML pages for end users.

## Characteristics

* **Stateful**: Web routes often maintain state between requests, such as user sessions.
* **HTML**: Web routes typically return data in HTML format.
* **Authentication**: Web routes often use session or cookie-based authentication methods.
* **Middleware**: Web routes often use middleware to handle tasks such as authentication, authorization, and logging.

## When to Use?

* When you need to render HTML pages for end users.
* When you need to handle requests from web browsers.
* When you need to use features like sessions or cookies to maintain user state.

## Example

<pre class="language-php"><code class="lang-php"><strong>// Ussing manual
</strong>$routes->get('users/', 'UsersController::list');
$routes->get('users/(:num)', 'UsersController::view:$1');
$routes->post('users/create', 'UsersController::create');
$routes->put('users/edit/(:num)', 'UsersController::edit:$1');
$routes->delete('users/delete/(:num)', 'UsersController::delete:$1');
<strong>
</strong><strong>// Apply Middleware
</strong><strong>$router->get('admin', 'Backend\HomeController::index', [\App\Middleware\AuthMiddleware::class,\App\Middleware\RolesMiddleware::class];
</strong>$routes->get('account/profile', 'Backend\AuthController::profile',[\App\Middleware\AuthMiddleware::class]);
$routes->get('account/logout', 'Backend\AuthController::logout',[\App\Middleware\AuthMiddleware::class]);
$routes->get('account/(:any)/(:any)', 'Backend\AuthController::$1:$2',[\App\Middleware\NoauthMiddleware::class]);
</code></pre>


# Api.php

The `Api.php` file is used to define routes for the application's API. These routes are typically used to provide data to client applications such as mobile apps, single-page applications (SPAs), or third-party services.

## Characteristics

* **Stateless**: API routes are usually stateless, meaning each request is processed independently without relying on previous requests.
* **JSON**: API routes typically return data in JSON format.
* **Authentication**: API routes often use authentication methods such as tokens, OAuth, or JWT.
* **Versioning**: API routes are often versioned to support changes without disrupting existing client applications.

## When to Use?

* When you need to provide data to mobile apps or SPAs.
* When you need to provide services to third-party applications or services.
* When you want to build a RESTful or GraphQL API.

## Example

```php
$routes->get('/api/v1/auth/(:any)/', 'Api\V1\AuthController::$1');
$routes->post('/api/v1/auth/(:any)', 'Api\V1\AuthController::$1');

$routes->get('/api/v1/(:any)/(:any)', 'Api\V1\$1Controller::$2');
$routes->get('api/(:any)/(:any)', 'Api\$1Controller::$2');
```


# Controllers

## Manually Create&#x20;

Follow these steps to create a new controller in PHPFast:

1. Go to the `application/Controllers` director&#x79;**.**
2. Create a new PHP file and name it according to your controller, e.g., `HomeController.php`.
3. Define the controller class by extending `System\Core\BaseController` to inherit core framework functionality.

Here is a basic example:

```php
<?php
namespace App\Controllers;

use System\Core\BaseController;

class HomeController extends BaseController
{
    public function index()
    {
        // Fetch and display a home page
        echo "Welcome to PHPFast";
    }
}
```

## Using the Command-Line Interface

This command generates a new controller file in the `application/Controllers` directory.

* It creates a basic controller template, helping you set up new features faster.

**Command:**

```sh
php init Controllers <controller_name>

// Example: php init controllers Users
```

This creates `UsersController.php` inside `application/Controllers`

## Controller Structure

### Basic Controller

```php
<?php
namespace App\Controllers;

use System\Core\BaseController;

class UsersController extends BaseController
{
    public function index()
    {
        // URL: /users
        // Router: $routes->get('users', 'UsersCotroller::index');
        echo "Welcome to the Users Page!";
    }

    public function show($id)
    {
        // URL: /users/123
        // Router: $routes->get('users/(:num)', 'UsersCotroller::show/$1');
        echo "User ID: " . $id;
    }
}
```

### Advanced options

When you define the **UsersController** inside the `Controllers/backend/` folder and use the `UsersModel`

The structure looks like:

```php
/app
 ├── /Controllers
 │    ├── /backend                    // Add a backend folder
 │    │    ├── UsersController.php
 │
 ├── /Models
 │    ├── UsersModel.php
 │
 ├── /Views
 │    ├── users_list.php
```

And **UsersController**:

```php
<?php
namespace App\Controllers\Backend;  // Define the correct namespace

use App\Controllers\BaseController;

class UsersController extends BaseController
{
    public function index()
    {
        // URL: /users
        // Router: $routes->get('users', 'UsersCotroller::index');
        echo "Welcome to the Users Page!";
    }

    public function show($id)
    {
        // URL: /users/123
        // Router: $routes->get('users/(:num)', 'UsersCotroller::show/$1');
        echo "User ID: " . $id;
    }
}
```

## **Routing to a Controller**

To route a URL to a specific controller method, use:

### Basic

```php
$routes->get('users', 'UsersController::index')
```

* URL: **`/users`**
* Calls: **`index()`** method in **`UsersController`**

### **Dynamic Parameters**

```php
$routes->get('users(:num)', 'UsersController::show:$1');
```

* URL: **`/users/123`**
* Calls: **`show(123)`** method in **`UsersController`**

## Models in Controller

Controllers can interact with Models to handle database operations.&#x20;

Below is an example of how to load a model and use it within a controller:

```php
<?php
namespace App\Controllers;

use System\Core\BaseController;
use App\Models\UsersModel;

class UsersController extends BaseController
{
    protected $usersModel;

    public function __construct()
    {
        // Load the model inside the constructor
        $this->usersModel = new UsersModel();
    }

    public function index()
    {
        // Fetch all users from the model
        $users = $this->usersModel->getUsers();
        
        $this->data('users ', $users);
        
        // Pass the users to a view for rendering
        return $this->render('frontend', 'user/index);
    }
}
```

## Render Views & Assets Data to Views

```php
<?php
namespace App\Controllers;

use System\Core\BaseController;
use App\Models\UsersModel;

class UsersController extends BaseController {
    public function index(){
        // Set the page title
        $this->data('title', 'Welcome to PHPFast');
        
        // Render the home page within the 'themes' layout
        echo $this->render('themes', 'home/home');
    }
}
```

## Load CSS and JS File

```php
<?php
namespace App\Controllers;

use System\Core\BaseController;
use System\Libraries\Assets;

class UsersController extends BaseController {
    public function __construct(){
        $this->assets = new Assets();

        // Manual way
        $this->assets->add('css', 'css/style.css', 'head');
        $this->assets->add('js', 'js/main.js', 'footer');

        $this->data('assets_header', $this->assets->header('backend'));
        $this->data('assets_footer', $this->assets->footer('backend'));

        // Using Block
        Render::asset('css', 'css/style.css', ['area' => 'frontend', 'location' => 'head']);
        Render::asset('js', 'js/main.js', ['area' => 'frontend', 'location' => 'footer']);
        
        // Note: Make sure CSS and JS files are contained in Views/Frontend/Assts
    }
    
    public function index(){
        return $this->render('frontend', 'home/index',);
    }
}
```

## Get data from Controller

### Manual way

```php
<!DOCTYPE html>
<html>
<head>
    <?= !empty($assets_header) ? $assets_header : ''; ?>
</head>
<body>
    <?= !empty($assets_footer) ? $assets_footer : ''; ?>
</body>

</html>

```

### Using Block

In `Blocks/Head/Views/default.php`

<pre class="language-php"><code class="lang-php">&#x3C;head>
<strong>    &#x3C;?= \System\Libraries\Render::renderAsset('head', 'frontend') ?>
</strong><strong>&#x3C;/head>
</strong></code></pre>

In `Blocks/Footer/Views/default.php`

<pre class="language-php"><code class="lang-php">&#x3C;head>
<strong>    &#x3C;?= \System\Libraries\Render::renderAsset('footer', 'frontend') ?>
</strong><strong>&#x3C;/head>
</strong></code></pre>

## Message Handle

```php
<?php
namespace App\Controllers;

use System\Core\BaseController;

class UsersController extends BaseController {
    public function search($input){
        if(empty($input)) {
            return $this->error('An error occurred', [], 404);
        }
    }
}
```

Output:

```
{"status":"error","message":"An error occurred","errors":[]}
```

## Caching in Controller

```php
<?php
namespace App\Controllers;

use System\Drivers\Cache\UriCache;
use System\Core\BaseController;

class UsersController extends BaseController {
    protected $cache;

    public function __construct(){
        // Get level cache
        $cache_gzip = option('cache_gzip') ?? 0; 
        
        // Init cache
        $this->cache = new UriCache($cache_gzip, 'html');
    }
    
    public function index(){
        // Get cache
        $cacheData = $this->cache->get();
        
        // Check empty cache
        if(empty($cacheData)){
            Render::asset('css', 'style.css', ['area' => 'frontend', 'location' => 'head']);
            Render::asset('js', 'jfast.1.1.4.js', ['area' => 'frontend', 'location' => 'footer']);
        
            $result = Render::html('frontend', $this->data);
            
            $cacheData = $this->cache->set($result, true);
        }
        
        $this->cache->render($cachData);
    }
}
```


# Models

Models in PHPFast handle database interactions, including querying, inserting, updating, and deleting records. To simplify these operations, PHPFast offers a `BaseModel`, which your models can extend to leverage built-in database functionalities efficiently.

In this section, we will explore the `BaseModel` class, which serves as the foundation for database operations in the PHPFast framework. It provides essential methods for interacting with the database, including querying, inserting, updating, and deleting records, making it easier for other models to manage data efficiently.

## Create Models via Command

This command creates a new model file in the `application/Models` directory.

* The generated model includes a default template with the `_schema()` method.
* It helps define the database table’s structure and provides basic CRUD (Create, Read, Update, Delete) functions.

**Command:**

```sh
php init Models <model_name>

// Example: php init models Users
```

This creates `UsersModel.php` inside `application/Model/`.

## Accessing Model

```php
<?php
use App\Models\UsersModel;

$usersModel = new UsersModel();
```

## Configuration

To switch between database drivers, update the `db_driver` setting in `application/Config/Config.php`

```php
'db' => [
    'db_driver'   => 'mysql',
    'db_host'     => 'localhost',
    'db_port'     => 3306,
    'db_username' => 'root',
    'db_password' => '',
    'db_database' => 'cms.vn',
    'db_charset'  => 'utf8mb4',
    'db_collate'  => 'utf8mb4_unicode_ci',
],
```

## **Example Usage**

```php
<?php
namespace App\Models;
use System\Core\BaseModel;

class UsersModel extends BaseModel {
    protected $table = 'users';
    protected $fillable = ['username', 'email', 'password', 'fullname'];
    protected $guarded = ['id', 'created_at', 'updated_at'];
    
    protected function _schema()
    {
        return [
            'id'           => 'int',
            'username'     => 'string',
            'email'        => 'string',
            'created_at'   => 'timestamp',
            ...            => interface
        ];
    }
    
    protected function _table() {
        return 'users'; // Defines that this model works with the 'users' table
    }
    
    public function getUsers($where = '', $params = [], $orderBy = 'id DESC', $limit = null, $offset = null) {
        return $this->list($this->table, $where, $params, $orderBy, $limit, $offset);
    }
    

    public function getUserById($id){
        return $this->row($this->table, 'id = ?', [$id]);
    }
    
    public function getUsersPage($where = '', $params = [], $orderBy = 'id DESC', $page = 1, $limit = null) {
        return $this->listpaging($this->table, $where, $params, $orderBy, $page, $limit);
    }
    
    public function addUser($data) {
        $data = $this->fill($data);
        return $this->add($this->table, $data);
    }
    
    public function updateUser($id, $data) {
        $data = $this->fill($data);
        return $this->set($this->table, $data, 'id = ?', [$id]);
    }
    
    public function deleteUser($id) {
        return $this->del($this->table, 'id = ?', [$id]);
    }
}
```

**List of Common Methods in a Model (Example in UsersModel):**

#### **Model Configuration and Schema**

* `_schema()`: Defines the database schema for the `users` table, specifying columns, data types, and constraints.

#### **Retrieving User Data**

* `getUsers()`: Retrieves a list of all users from the `users` table, with optional filtering conditions.
* `getUsersPage($where, $params, $orderBy, $page, $limit)`: Retrieves a paginated list of users.
* `getFieldUsersPage($fields, $where, $params, $orderBy, $page, $limit)`: Retrieves a paginated list of users but only fetches specific fields.
* `getUserById($id)`: Retrieves detailed user information based on `ID`.
* `getUserByIdField($fields, $id)`: Retrieves specific fields of a user based on `ID`.
* `getUserByUsername($username)`: Finds a user based on `username`.
* `getUserByEmail($email)`: Finds a user based on `email`.

#### **Managing User Data (Add, Update, Delete)**

* `addUser($data)`: Adds a new user to the `users` table.
* `updateUser($id, $data)`: Updates user information based on `ID`.
* `deleteUser($id)`: Deletes a user from the system based on `ID`.

**Advanced Functions**

* `searchUser($conditions)`: Searches for users based on different criteria using flexible conditions.
* `getLocation($userId)`: Retrieves the geographical location (`longitude`, `latitude`) of a user based on their `ID`, if valid location data exists.

## Model in Controller

```php
<?php
namespace App\Controllers;

use System\Core\BaseController;
use App\Models\UsersModel;

class UsersController extends BaseController
{
    protected $usersModel;

    public function __construct() {
        $this->usersModel = new UsersModel();
    }

    public function index() {
        $users = $this->usersModel->getUsers();
        $this->render('users/index', ['users' => $users]);
    }
    
    public function profile() {
        $id = S_GET('id') ?? ''; 
        $userInfo = $this->usersModel->getUserById($id);
        $this->render('users/profile', ['info' => $userInfo]);
    }
}
```

{% hint style="warning" %}
Important

To create a model, extend the [`BaseModel`](/documents/core/basemodel) class and define the `$table`, `$fillable`, and `$guarded` properties as needed. Override any methods as required to meet the specific needs of the model.
{% endhint %}


# Views & Templates

PHPFast makes it easy to create dynamic web pages with its flexible view system. All views are stored in the `application/Views/` folder, where you can use layouts, reusable components, and pass data to structure your templates efficiently.

## Views Structure

```
ROOT
├── application/                       # Application-specific files
│   └── Views/                         # Views for frontend and backend
│       ├── Backend/                   # Backend views
│       ├── Frontend/                  # Frontend views (assets, components)
│       │   ├── Assets/                # Frontend assets (CSS, JS)
│       │   │   ├── css/               # CSS files
│       │   │   └── js/                # JS files
│       │   ├── Component/             # Reusable components (e.g., menu, search)
│       │   │   ├── header.php         # Header component
│       │   │   ├── footer.php         # Footer component
│       │   │   └── sidebar_main.php   # Sidebar main component
│       │   └── home_index.php         # Homepage view
│       ├── backend.php                # Backend layout
│       ├── frontend.php               # Frontend layout
│       ├── dashboard.php              # Dashboard layout
│       └── 404.php                    # Error layout

```

## Creating a View

1. Go to the `application/View/` directory inside your PHPFast project.
2. Inside your preferred folder, create a new **PHP file** (e.g., `frontend/home_index.php`).
3. Open the file and insert your **HTML and PHP code** to structure the page.

```php
<h1>Welcome to PHPFast Framework</h1>
<p>This is the Home page.</p>
```

## Using manual way

A layout is a reusable template (e.g., header, footer) that wraps around the main content of your pages. You can store layouts in the `View/` directory for better organization and reuse.

Example `frontend.php` layout:

```php
<!DOCTYPE html>
<html>
<head>
    <title><?php echo $title ?? 'PHPFast Framework'; ?></title>
    <?= !empty($assets_header) ? $assets_header : ''; ?>
</head>
    <body>
        <div>
            <?php if (isset($view)) require $view; ?>
            // $view will depend on Controller
        </div>
        <?= !empty($assets_footer) ? $assets_footer : ''; ?>
    </body>
</html>
```

### Setup Controller

```php
<?php

namespace App\Controllers;

use System\Core\BaseController;
use System\Core\Render;

class HomeController extends BaseController {
    public function index() {
        $data = [
            'title'   => 'Welcome to PHPFast Framework',
            'message' => 'This is the Home page.'
        ];
        
        // Set components
        $sidebar = Render::component('Frontend/Component/main_sidebar');
        
        // Setup CSS and JS 
        $this->assets->add('css', 'css/style.css', 'head');
        $this->assets->add('js', 'js/main.js', 'footer');
        
        // Send data to view
        $this->data('sidebar', $sidebar);
        $this->data('data', $data);
        
        // Send data contains CSS and JS 
        $this->data('assets_header', $this->assets->header('backend'));
        $this->data('assets_footer', $this->assets->footer('backend'));
        
        // Render view
        $this->render('frontend', 'Frontend/Home/index');
    }
}
```

`index()`  return `$data` to view `Frontend/Home/index.php` and in layout `frontend.php` will include this view.

### Get data in view

Example in `Frontend/Home/index.php:`

```php
<h1><?= $message ?></h1>
```

## Using Blocks

The PHPFast Framework organizes complex website interfaces by breaking them into independent blocks like head, header, content, and footer. This makes components easier to manage, reuse, and maintain, while also keeping interface and logic separate for better scalability.

That's why the PHPFast Framework implements a Block structure, making interface management more logical, structured, and efficient.

Find out how to use [Blocks](/documents/blocks)

## When to use Manual or Blocks?

Depending on the first parameter of the `render()` method. If this layout uses Blocks, it will follow the second way.

Example:

Use the same [`HomeController`](/documents/views-and-templates#setup-controller) above, but the layout display different.

### Manual

If the code in layout frontend.php like this:

```php
<!DOCTYPE html>
<html>
<head>
    <title><?php echo $title ?? 'PHPFast Framework'; ?></title>
    <?= !empty($assets_header) ? $assets_header : ''; ?>
</head>
    <body>
        <div>
            <?php if (isset($view)) require $view; ?>
            // $view will depend on Controller
        </div>
        <?= !empty($assets_footer) ? $assets_footer : ''; ?>
    </body>
</html>
```

### Blocks

If the code in layout frontend.php like this:

```php
<?php
    namespace System\Libraries;
?>

<?php Render::block('head'); ?>

<body>
    <div class="container-full">
        <?php Render::block('content'); ?>
    </div>
    
    <?php Render::block('footer'); ?>
</body>
```

## Error Pages&#x20;

You can create custom error pages and store them in the `application/Views/` directory. For example, to handle 404 errors, create a file named `404.php` in that folder.

```php
if (!$pageFound) {
    $this->render404();
}
```


# Blocks

To manage and organize the interface of a complex website, PHPFast Framework will use the method of breaking the interface into independent **Blocks** such as `head`, `header`, `content`, `footer`, etc. This approach makes it easier to manage and reuse these interface components when needed.

With this approach, the separation of interface and logic becomes clear, enhancing reusability, maintainability, and scalability in the future.

## Block Structure

```
ROOT
├── application/                       # Application-specific files
│   ├── Blocks/                        # UI blocks (footer, header, content)
│   │   ├── Footer/                    # Footer block
│   │   ├── Head/                      # Head block (meta, CSS, JS)
│   │   ├── Header/                    # Header block (nav, logo)
│   │   └── Content/                   # Content block
│   │       ├── Views/                 # Content layouts
│   │       │   ├── layout_1.php       # Layout 1
│   │       │   ├── layout_2.php       # Layout 2
│   │       │   └── layout_3.php       # Layout 3
│   │       └── ContentBlock.php       # Content block logic
│   └── Views/                         # Views for frontend and backend
│       ├── Backend/                   # Backend views
│       └── Frontend/                  # Frontend views (assets, components)
│           ├── Assets/                # Frontend assets (CSS, JS)
│           │   ├── css/               # CSS files
│           │   └── js/                # JS files
│           ├── Component/             # Reusable components (e.g., menu, search)
│           │   ├── menu.php           # Menu component
│           │   └── search.php         # Search component
│           └── home_index.php         # Homepage view
└── system/                            # Core framework files
    ├── Core/                          # Core classes for block handling
    │   └── BaseBlock.php              # Base class for blocks
    └── Libraries/                     # Helper libraries (rendering, etc.)
        └── Render.php                 # Class for rendering views   
```

## Create Structure

* To be able to create a folder automatically, you can learn about it through [`BlockCommand`](/documents/commands/block-command).
* Or you can create the folder structure in the manual way.

## Call Blocks

Example in `home_index.php`

```php
<?php
    namespace System\Libraries;
?>

<?php Render::block('head'); ?>

<body>
    <div class="container-full">
        <?php Render::block('content'); ?>
    </div>
    
    <?php Render::block('footer'); ?>
</body>


```

`block()` method in [`Render.php`](/documents/libraries/render) : The `block()` function receives a block name as a parameter, dynamically constructs the corresponding class name and its path, then processes the data based on predefined properties and delivers it to the specified layout.

## Process

In `ContentBlock.php`

Extends from [`BaseBlock`](/documents/core/baseblock) to use the pre-defined methods.

```php
<?php
namespace App\Blocks\Content;

use System\Core\BaseBlock;
use App\Models\UsersModel;

class ContentBlock extends BaseBlock {
    public function __construct() {
        $this->setLabel('Content Block');
        $this->setName('Content');
        $this->setProps([
            // layout name: layout_1.php
            'layout'      => 'layout_1',  //  Required
        ]);
        
        $this->usersModel = new UsersModel();
    }
    
    public function handleData() {
        $users   = $this->usersModel->getUsers();  
        return $users;
    }
}

```

In the `ContentBlock` class, the methods `setLabel()`, `setName()`, and `setProps()` are mandatory when initializing a block.

* `setLabel()`: Defines a user-friendly label for the block.
* `setName()`: Sets the internal name used to identify the block in the system.
* `setProps()`: Specifies essential properties such as the required layout file.

These methods ensure that every block is properly defined, named, and configured, making it easier to manage and integrate into different layouts.

The `handle()` method is responsible for processing data and returning the result to the layout defined in `setProps()`. It serves as the core logic handler for the block, ensuring that the necessary data is prepared before rendering.

If a layout is specified in `setProps()`, the method processes data accordingly and returns it to the defined layout. However, if no layout is set, the system will automatically use the default file `default.php` to return the data. This ensures flexibility, allowing blocks to adapt dynamically while maintaining a fallback mechanism for handling data efficiently

## Display data

In `layout_1.php`:

<pre class="language-php"><code class="lang-php"><strong>&#x3C;?php foreach ($users as $user): ?>
</strong>    &#x3C;span>ID:         &#x3C;?= $user['id'] ?>        &#x3C;/span>
    &#x3C;span>Username:   &#x3C;?= $user['username'] ?>  &#x3C;/span>
    &#x3C;span>Email:      &#x3C;?= $user['email'] ?>     &#x3C;/span>
&#x3C;?php endforeach; ?> 
</code></pre>

`home_index.php` will get the HTML from layout\_1.php


# Middleware

Middleware in PHP-Fast allows you to filter HTTP requests entering your application. This can be useful for tasks such as user authentication, input validation, and permission checks before the request reaches the controller.

## Create Middleware

All middleware classes should be placed in the `application/Middleware` directory. A middleware class contains a `handle()` method, which will be executed when the middleware is applied to a route or controller.

To ensure only authenticated users can access certain routes, let's create a simple authentication middleware.

**Steps to Create** `AuthMiddleware`

1. Navigate to `application/Middleware/`.
2. Create a new file named `AuthMiddleware.php`.
3. Add the following code to handle authentication:

```php
<?php

namespace App\Middleware;

class AuthMiddleware
{
    public function handle($request, $next)
    {
        // Check if the user is logged in
        if (!isset($_SESSION['user'])) {
            echo "Unauthorized access!";
            exit;
        }

        // Proceed to the next middleware or controller
        return $next($request);
    }
}
```

## Using Middleware in Route

To apply middleware to a route, include the middleware class name as an array in the route definition inside `application/Routes/web.php` or `application/Routes/api.php`.

Example: Adding `AuthMiddleware` to a Route in `web.php`

```php
$routes->get('admin', 'AdminController::index', [\App\Middleware\AuthMiddleware::class]);
```

## More Example

As the same `AuthMiddleware`, you can create a `PermissionMiddleware` to manage access control for different parts of your application.

1. Create a new file in `application/Middleware/` named `PermissionMiddleware.php`.
2. Add the following code to handle authentication:

```php
<?php

namespace App\Middleware;

class PermissionMiddleware
{
    public function handle($request, $next, $permissions = [])
    {
        // Retrieve the user's permissions from the session
        $userPermissions = $_SESSION['user_permissions'] ?? [];

        // Check if the user has the required permissions
        foreach ($permissions as $permission) {
            if (!in_array($permission, $userPermissions)) {
                echo "You have no permission to access this page!";
                exit;
            }
        }

        // Proceed to the next middleware or controller
        return $next($request);
    }
}
```

3. Add middleware to a route and pass the necessary permissions:

```php
$routes->get('admin/settings', 'AdminController::settings', [
    [\App\Middleware\PermissionMiddleware::class, ['manage_settings']]
]);
```


# Libraries

The `Libraries` directory in PHPFast contains essential library classes that provide core functionality to the framework. These libraries are designed to handle common tasks such as logging, session management, security, and validation, simplifying development and ensuring consistency across the application. Each library is focused on a specific aspect of the system, allowing developers to integrate these features seamlessly into their applications. By using these libraries, developers can avoid reinventing the wheel, saving time and effort while building secure and efficient web applications.

## Libraries:

* [Caching](/documents/libraries/caching)
* [Security](/documents/libraries/security)
* [Session](/documents/libraries/session)
* [Validate](/documents/libraries/validate)
* [Error Handling](/documents/libraries/error-handling)
* [Logger & Monitor](/documents/libraries/logger-and-monitor)
* [Render](/documents/libraries/render)


# Database Integration

PHPFast makes it easy to work with databases. It has a Database class and built-in Drivers that help you connect to your database using Models and a query builder.

The database settings are stored in `application/Config/Config.php`, where you can easily change and manage different database connections.

## Models

**Models** help you interact with the database easily. Each model represents a table in the database and provides methods to fetch, insert, update, and delete data.

By default, all models are stored in `application/Models/`.

## Creating a Model

* Go to `application/Models/`.
* Create a new file, e.g., `UsersModel.php`.
* Write the model code like this:

```php
<?php

namespace App\Models;

use System\Core\BaseModel;

class UsersModel extends BaseModel {
    protected $table     = 'users';                 // Connects to the 'users' table
    protected $fillable  = ['username', 'email'];   // Columns that can be changed
    protected $guarded   = ['id', 'created_at'];    // Columns that should NOT be modified

    public function _schema() {
        return [
            'id'       => ['type' => 'int unsigned', 'auto_increment' => true, 'key' => 'primary'],
            'username' => ['type' => 'varchar(100)', 'null' => false],
            'email'    => ['type' => 'varchar(150)', 'null' => false]
        ];
    }
    
    public function getUsers($where = '', $params = [], $orderBy = 'id DESC', $page = 1, $limit = null){
        return $this->list($this->table, $where, $params, $orderBy, $page, $limit);
    }
    
    // Additional methods for custom queries
}
```

## Changing the Database Driver

To switch between database drivers, update the `db_driver` setting in `application/Config/Config.php`

```php
'db' => [
    'db_driver'   => 'postgresql', // Change to 'mysql' or 'postgresql'
    'db_host'     => '127.0.0.1',
    'db_port'     => 5432,
    'db_username' => 'postgres',
    'db_password' => '',
    'db_database' => 'phpfast',
    'db_charset'  => 'utf8'
],
```

## Using a Model in a Controller

After creating a model, you can use it in a **controller** to interact with the database.

```php
<?php

use App\Models\UsersModel;

class UsersController extends BaseController {
    public function index() {
        $usersModel = new UsersModel(); // Load the model
        $users      = $usersModel->getUsers(); // Get all users from the database
        $this->render('users/index', ['users' => $users]); // Send data to the view
    }
}
```

## Managing Database Schema

Each model includes a `_schema()` method that defines the **structure of the database table** it represents.

You can synchronize the model schema with the database using the command-line tool:

```sh
php init table users
```

{% hint style="warning" %}
Important

When defining models, use these properties for secure and efficient database operations:

* **`$table`** → Defines which database table the model interacts with.
* **`$fillable`** → Lists columns that can be mass-assigned (used in insert/update).
* **`$guarded`** → Lists columns that **cannot** be mass-assigned for security.
  {% endhint %}


# Caching

PHPFast includes a powerful caching system that helps store and retrieve data efficiently. The framework provides a RedisCache class, offering essential methods like `set()`, `get()`, and `delete()` for interacting with a Redis server. This caching mechanism significantly improves performance, especially when handling data that doesn't change frequently.

## Caching in Controllers

To enable caching in your controllers, use the **RedisCache** class or other (see more at [Cache](/documents/drivers/cache)). Cache settings are configured in `application/Config/Config.php`

Here's how you can implement caching in `HomeController`. Simply uncomment the relevant caching lines to activate the functionality:

```php
<?php

namespace App\Controllers;

use System\Core\BaseController;
use System\Libraries\Render;
use System\Drivers\Cache\RedisCache;

class HomeController extends BaseController
{
    protected $usersModel;
    protected $cache;

    public function __construct()
    {
        // Load cache configuration and initialize Redis cache
        $config = config('cache');
        $this->cache = new RedisCache($config);
    }


    public function index()
    {
        $cacheKey = 'home_page';

        // Check if cached content is available
        if ($cachedContent = $this->cache->get($cacheKey)) {
            echo $cachedContent;
            echo 'Loaded from cache.<br />';
            return;
        }

        // Generate the full page content
        $content = $this->render('themes', 'home/home');

        // Store the rendered page in cache for 10 minutes
        $this->cache->set($cacheKey, $content, 600);

        // Display the generated content
        echo $content;
    }
}
```

## Configure Cache Settings

**Modify** `application/Config/Config.php` **to enable caching:**

```php
'cache' => [
    'cache_driver'  => 'redis',     // Use Redis as the caching system
    'cache_host'    => '127.0.0.1', // Redis server address
    'cache_port'    => 6379,        // Redis default port
    'cache_username'=> '',          // Leave blank if authentication is not required
    'cache_password'=> '',          // Set password if needed
    'cache_database'=> 0,           // Default Redis database
],
```

## Using Cache

### Setup in Controller

```php
use System\Drivers\Cache\RedisCache;

class HomeController extends BaseController {
    protected $cache;

    public function __construct() {
        $config = config('cache'); // Load cache configuration
        $this->cache = new RedisCache($config); // Initialize Redis caching
    }
}
```

### Store and Retrieve Cached Data

```php
// Store data
$this->cache->set('home_page_data', $data, 600); // Cache for 10 minutes (600 seconds)

// Retrieve data
$cachedData = $this->cache->get('home_page_data');
```

### Clear and Delete Cached Data

```php
// Delete a Specific Cache Entry
$this->cache->delete('home_page_data');

// Clear All Cache
$this->cache->clear();
```

{% hint style="info" %}
Note

* **Best for Static Content** – Use caching for data that doesn’t change often, like homepage content or user lists.
* **Set Expiration Time** – Always define a cache expiration time to avoid showing outdated information.
* **Customize as Needed** – Adjust caching settings based on your application’s needs for better performance and efficiency.
  {% endhint %}


# Events

The `Events` class is part of the Libraries namespace and is designed to manage and handle events in the system. It provides methods to register, trigger, and process events. Below is a detailed explanation of each function and its purpose.

## **Funtions in Events Libraries**

### **Property `$listeners`**

```php
<?php
protected static $listeners = [];
```

* This is a static array that stores the list of listeners for each event.
* Structure of `$listeners`:

```php
<?php
[
    'EventName' => [
        priority => [listener1, listener2, ...],
        ...
    ],
    ...
]
```

* **`EventName`**: The name of the event.
* **`priority`**: The priority of the listener (higher numbers are executed first).
* **`listener1, listener2`**: Callbacks or classes that handle the event.

### **`on()`**

```php
<?php
public static function on($eventName, $listener, $priority = 0) {}
```

* **Purpose**: Registers a listener (callback or class) for a specific event.
* **Parameters**:
  * `$eventName`: The name of the event (e.g., `'PostsAddEvent'`).
  * `$listener`: A callback function or class name that will be executed when the event is triggered.
  * `$priority`: The priority of the listener (default is `0`).

### **`run()`**

<pre class="language-php"><code class="lang-php">&#x3C;?php
<strong>public static function run($eventName, $payload = null) {}
</strong></code></pre>

* **Purpose**: Triggers (dispatches) an event.
* **Parameters**:
  * `$eventName`: The name of the event to trigger.
  * `$payload`: Data to pass to the event (can be an array, object, etc.).

### **`runs()`**

```php
<?php
public static function runs(array $events) {}
```

* **Purpose**: Triggers multiple events at once.
* **Parameters**:

  * `$events`: An array of events and their associated data, in the format

  ```php
  <?php
  [
      'EventName1' => $payload1,
      'EventName2' => $payload2,
      ...
  ]
  ```

### **General Workflow**

1. **Registering Listeners**:
   * Use the `on()` method to register listeners for events.
   * Listeners can be either callback functions or classes with a `handle()` method.
2. **Triggering Events**:
   * Use the `run()` method to trigger a single event.
   * When an event is triggered:
     * Registered listeners are executed in order of priority.
     * If no listeners are registered, a default event class in the `\App\Events` namespace is checked and executed.
3. **Triggering Multiple Events**:
   * Use the `runs()` method to trigger multiple events at once.

## Example

### Using basically

```php
Events::on('UserRegistered', function ($user) {
    echo "Welcome, {$user['name']}!<br>";
}, 10); // Priority 10


Events::on('UserRegistered', function ($user) {
    echo "Sending welcome email to {$user['email']}...<br>";
}, 5); // Priority 5

$user = ['name' => 'John Doe', 'email' => 'john.doe@example.com'];
Events::run('UserRegistered', $user);

// ------------------------------ Output ------------------------------
// Welcome, John Doe!
// Sending welcome email to john.doe@example.com...
```

### Using in Class

```php
class NotifyAdmin
{
    protected $user;

    public function __construct($user)
    {
        $this->user = $user;
    }

    public function handle()
    {
        echo "Notifying admin about new user: {$this->user['name']}<br>";
    }
}
```

```php
Events::on('UserRegistered', NotifyAdmin::class, 8); // Priority 8

// ------------------------------ Output ------------------------------
// Welcome, John Doe!
// Notifying admin about new user: John Doe
// Sending welcome email to john.doe@example.com...
```

### Using multiple Events

<pre class="language-php"><code class="lang-php">&#x3C;?php
// Register event 'OrderPlaced'
Events::on('OrderPlaced', function ($order) {
    echo "Order #{$order['id']} has been placed.&#x3C;br>";
});

// Triggering Mmultiple Events
$events = [
    'UserRegistered' => $user,
    'OrderPlaced' => ['id' => 12345],
];

Events::runs($events);

// ------------------------------ Output ------------------------------
<strong>// Welcome, John Doe!
</strong>// Notifying admin about new user: John Doe
// Sending welcome email to john.doe@example.com...
// Order #12345 has been placed.
</code></pre>

{% hint style="success" %}
Summary

* You can register multiple listeners for an event with different priority levels.
* Listeners can be either callback functions or classes with a `handle()` method.
* Use `Events::run()` to trigger a single event or `Events::runs()` to trigger multiple events at once.
* The output depends on the priority order of the listeners.
  {% endhint %}


# Validate

The `Validate` class in PHPFast is responsible for validating user input using the **Respect\Validation** library. It provides a collection of methods to check various types of data, such as **strings, numbers, dates, emails, and even JSON or IP addresses**.

This class helps ensure that data meets specific criteria before being processed or stored in a database, reducing errors and improving security.

## Methods in `Validate.php`

### **String & Character Validations**

<pre class="language-php"><code class="lang-php"><strong>// Ensures the string contains only letters (A-Z, a-z).
</strong><strong>public static function alpha() {
</strong>    return RespectValidator::alpha();
}

// Ensures the string contains only numeric digits (0-9).
public static function digit() {
    return RespectValidator::digit();
}

// Ensures the string contains only lowercase letters.
public static function lowercase() {
    return RespectValidator::lowercase();
}

// Ensures the string contains only uppercase letters.
public static function uppercase() {
    return RespectValidator::uppercase();
}
</code></pre>

Example:

```php
Validate::alpha()->validate("hello");         // True
Validate::digit()->validate("1234");          // True
Validate::uppercase()->validate("HELLO");     // True
Validate::lowercase()->validate("Hello");     // False
```

### **Number & Range Validations**

```php
// Ensures the value is a valid number.
public static function NumericVal() {
    return RespectValidator::NumericVal();
}

// Ensures the value falls within a specific range.
public static function between($min, $max) {
    return RespectValidator::between($min, $max);
}
```

Example:

```php
Validate::NumericVal()->validate(25);         // True
Validate::between(10, 50)->validate(30);      // True
Validate::between(10, 50)->validate(5);       // False
```

### **Email, URL, and IP Validations**

```php
// Validates an email format.
public static function email() {
    return RespectValidator::email();
}

// Checks if the value is a valid URL.
public static function url() {
    return RespectValidator::url();
}

// Validates an IP address.
public static function ip() {
    return RespectValidator::ip();
}
```

Example:

```php
Validate::email()->validate("test@example.com");     // True
Validate::url()->validate("https://example.com");    // True
Validate::ip()->validate("192.168.1.1");             // True
Validate::email()->validate("invalid-email");        // False
```

### **Password & Security Validations**

```php
// Ensures the value is not empty.
public static function notEmpty() {
    return RespectValidator::notEmpty();
}

// Ensures the value is exactly equal to another.
public static function equals($compareTo) {
    return RespectValidator::equals($compareTo);
}
```

Exampl&#x65;**:**

<pre class="language-php"><code class="lang-php"><strong>Validate::notEmpty()->validate("password");     // True
</strong>Validate::equals("admin")->validate("admin");   // True
Validate::equals("admin")->validate("user");    // False
</code></pre>

### **JSON, UUID, and Special Format Validations**

```php
// Ensures the string is a valid JSON format.
public static function json() {
    return RespectValidator::json();
}

// Ensures the string is a valid UUID.
public static function uuid() {
    return RespectValidator::uuid();
}

// Validates credit card numbers.
public static function creditCard() {
    return RespectValidator::creditCard();
}
```

Example:

```php
Validate::json()->validate('{"name": "John"}');                     // True
Validate::uuid()->validate("550e8400-e29b-41d4-a716-446655440000"); // True
Validate::creditCard()->validate("4111111111111111");               // True
```

### Validating an Array of Data (`check()`)

* Validates multiple fields based on predefined rules.
* Stores errors for fields that fail validation.

Example:

```php
$data = [
    'username' => 'john_doe',
    'email' => 'invalid-email'
];

$rules = [
    'username' => [
        'rules' => [Validate::alnum(), Validate::length(3, 20)],
        'messages' => ['Username must be alphanumeric.', 'Length must be between 3 and 20 characters.']
    ],
    'email' => [
        'rules' => [Validate::email()],
        'messages' => ['Invalid email format.']
    ]
];

$validator = new Validate();
if (!$validator->check($data, $rules)) {
    print_r($validator->getErrors()); // Output validation errors
}
```


# Error Handling

PHPFast manages errors using the `AppException` class, located in `system/Core/AppException.php`. This class extends PHP’s built-in `Exception` class and provides error logging, custom error pages, and detailed error messages based on the application’s debug mode.

***

## **How `AppException` Works**

The `AppException` class helps handle errors efficiently by providing:

**Custom error messages** – Define clear and readable error descriptions.\
**Automatic error logging** – Uses the Logger library to record error details.\
**User-friendly error display** – Shows helpful messages based on debug settings.\
**Custom error pages** – Automatically renders pages like 404 Not Found or 500 Server Error based on the error type.

By using `AppException`, you can keep your application stable, log important issues, and show meaningful error messages to users.&#x20;

## Handling Errors

You can manage errors in your application by **throwing an exception** using the `AppException` class:

**Throwing an Exception**

```php
throw new \System\Core\AppException('An error occurred!', 0, null, 500);
```

**Catching and Handling the Exception**

```php
try {
    // Code that might cause an error
} catch (\System\Core\AppException $e) {
    $e->handle(); // Process the exception
}
```

## Custom Error Pages

The `AppException` class automatically renders custom error pages based on the error status code. For example, when a 404 error occurs, the `render404()` method is called, which loads the **404 error page** from the themes directory using the Render library.

## Automatic Error Logging

All errors are recorded using the `Logger` class. When an exception is handled, the `handle()` method automatically calls `Logger::error()`, logging details such as: Error messag&#x65;**,** File location, Line number.

## Debug Mode

When debug mode is enabled (`config('app')['debug'] = true`) → The system displays detailed error information, including: **Error message, File location**, **Line number** and **Stack trace**

When debug mode is disabled → A generic error message is shown to users, preventing sensitive system details from being exposed.

## Usage in a Controller

```php
<?php
namespace App\Controllers;

use System\Core\BaseController;
use System\Core\AppException;

class UserController extends BaseController {

    public function index() {
        try {
            // Simulate an error (e.g., user not found)
            $user = $this->findUserById(1);
            if (!$user) {
                throw new AppException('User not found!', 0, null, 404);
            }

            // Render the user data
            $this->render('user/profile', ['user' => $user]);

        } catch (AppException $e) {
            // Handle the exception
            $e->handle();
        }
    }

    private function findUserById($id) {
        // Sample method to simulate user fetching; returns null to simulate "user not found"
        return null;
    }
}
```

**How It Works:**

* `try {}` → Starts the error-handling block.
* Attempts to find the user using `findUserById(1)`.
* If the user is not found (`null`), throws an **AppException** with the message `"User not found!"` and error code `404`.
* If no error occurs, **renders the user profile page** using `render('user/profile', ['user' => $user])`.
* `catch (AppException $e) {}` → If an error occurs, it is handled by calling `$e->handle();`, which may log the error or display an error page.


# Logger & Monitor

## Overview

Effective logging and performance monitoring are crucial aspects of any web application. PHP-Fast provides a built-in `Logger` class for capturing important log messages such as **errors, warnings,** and **informational messages** and a `Monitor` class for measuring **execution time, memory usage,** and **CPU load** to help optimize performance.

## Logger

The Logger library allows you to record messages in different log levels. All logs are saved in:\
`writeable/logs/logger.log`

```php
Logger::info('This is an informational message.'); // Log informational message
Logger::warning('This is a warning message.');     // Log warning message
Logger::error('This is an error message.');        // Log error message
```

The `Logger` class supports optional parameters for file name and line number, making it easier to pinpoint issues.

## Monitor

```php
use System\Libraries\Monitor;

// Call Monitor class
$performance = Monitor::endFramework();

// Format memory usage
$formattedMemory = Monitor::formatMemorySize($performance['memory_used']);

// Print results
echo "Execution Time: " . round($performance['execution_time'], 5) . " seconds <br>";
echo "Memory Used: " . $formattedMemory . "<br>";
echo "CPU Load: " . $performance['cpu_usage'] . "<br>";

// Output:
Execution Time: 0.01095 seconds
Memory Used: 512 KB
CPU Load: 0.32

// Note: Check your constant DEBUG_TIME is 'true'
```

{% hint style="success" %}
Conclusion

The **Logger** and **Monitor** libraries in PHPFast make it easy to track your application's activity, detect issues, and improve performance. **Logger** helps record errors, warnings, and important messages, while **Monitor** measures execution time, memory usage, and CPU load, allowing developers to identify and fix problems efficiently.
{% endhint %}


# Render

This class provides methods for rendering views, layouts, components, blocks, and managing assets (CSS, JS).

## `asset()`

```php
function asset($assetType, $file, $options = [])
```

* `$assetType`- 'css' or 'js'
* `$file`- File name (relative path from the Assets directory in the view)
* `$options`- Options array including:
  * 'area': (default 'frontend')
    * 'location': (default 'head' or 'footer')

Example:

```php
<?php
Render::asset('css', 'styles.css', ['area' => 'frontend', 'location' => 'head']);
Render::asset('js', 'main.js', ['area' => 'frontend', 'location' => 'footer']);

// Make sure CSS and JS files are contained in Views/Fronted/Assets/ folder
```

## `renderAsset()`

```php
function renderAsset($location = 'head', $area = 'frontend')
```

* `$location`- 'head' or 'footer'
* `$area` - 'frontend' or 'backend'
* `return` - Resulting HTML.

Example:

```php
<?php
echo Render::renderAsset('head', 'frontend');
echo Render::renderAsset('footer', 'frontend');
```

## `render()`

```php
function render($layout, $view = null, $data = [])
```

* `$layout` - Name of the layout to load (e.g., 'layout' or 'layout2')
* `$view` - Name of the view to load (e.g., 'home/home')
* `$data`- Data to pass to the view
* `return` - The buffered output as a string.

Example:

```php
<?php
$data = ['title' => 'Home Page', 'content' => 'Welcome to the PHPFast Framework!'];
echo Render::render('main', 'home/index', $data);

// Render the main layout with the home/index view, passing the provided data to the view.
```

## `html()`

```php
function html($layout, $data = [])
```

* `$layout` - Name of the layout to load (e.g., 'layout' or 'layout2')
* `$data`-  Data to pass to the view
* `return` - The buffered output as a string.

Example:

```php
<?php
$data = ['title' => 'Home Page', 'content' => 'Welcome to the PHPFast Framework!'];
echo Render::html('content', $data);

// Render the main layout, passing the provided data to the layout.
```

## `component()`

```php
function component($component, $data = [])
```

* `$component`- Name of the component to render (e.g., 'header', 'footer')
* `$data`- Data to pass to the component
* `return` - The buffered output as a string.

Example:

```php
<?php
$data = ['title' => 'Home Page'];
echo Render::component('header', $data);

// Render a component named header with some data
```

## `block()`

```php
function block($blockName, $data = [])
```

* `$blockName`- Name of the Block, can be capitalized or lowercase
* `$data`- Additional props parameters of the Block, if not provided, Default will be used
* `return` -  The block instance.

Example:

```php
<?php
$data = ['title' => 'PHPFast', 'description' => 'PHPFast is a fast Framework!!!'];
echo Render::block('head', $data);

// Render a block named head with some data
```

## `getblock()`

```php
function getblock($blockName)
```

* `$blockName`- Name of the Block, can be capitalized or lowercase
* `return` -  The block instance or null if the class does not exist.

Example:

```php
<?php
$block = Render::getblock('head');

// Get an instance of a block named example
```


# Security

Security is essential for any web application. PHPFast comes with built-in features to protect your application from common threats. This section will explain these security tools and show you how to use them effectively.

## Data Sanitization

Data sanitization is the process of cleaning and filtering input data to prevent the execution of malicious code, such as Cross-Site Scripting (XSS) or SQL Injection, within your application. PHPFast provides a built-in helper to sanitize data in HTTP requests, enhancing security and protecting against common vulnerabilities.

**Using `Security.php` Libraries**

The `Security_helper.php` library offers essential functions for sanitizing and validating user input to enhance application security. Some key functions include:

`xss_clean` – Removes potential XSS (Cross-Site Scripting) threats.\
`clean_input` – Filters out harmful code from input data.\
`uri_security` – Ensures secure handling of URI parameters.\
`url_slug` – Converts text into a URL-friendly format.\
`redirect` – Safely redirects users to specified locations.\
`base_url` – Generates a secure base URL for links.

1. Load the helper in your controller:

   ```php
   // Sanitize user input
   $clean_input = clean_input($input_data);
   ```
2. The `clean_input` function will automatically strip out potentially harmful code from the input data, making it safer to use within your application.

## Cross-Site Request Forgery (CSRF) Protection

PHPFast comes with built-in CSRF protection, preventing unauthorized commands from being executed through authenticated sessions. The framework automatically generates and verifies CSRF tokens for form submissions, ensuring secure user interactions.

To enable **CSRF protection**, follow these steps:

1. Open the `config.php` file located in the `application/Config` directory.
2. Add or update the security settings to include CSRF protection

```php
'security' => [
    'csrf_protection'  => true,               // Enable CSRF protection
    'csrf_token_name'  => 'csrf_token',       // Name of the CSRF token
    'csrf_header_name' => 'X-CSRF-TOKEN',     // CSRF token header for AJAX requests
    'csrf_expiration'  => 7200,               // Token validity period in seconds
],
```

## Password Hashing

```php
public static function hashPassword($password) {
    return password_hash($password, PASSWORD_BCRYPT);
}

// Example
$hashed_password = Security::hashPassword($user_password); 

//----------------------------------------------------------------------------------
public static function verifyPassword($password, $hashedPassword) {
    return password_verify($password, $hashedPassword);
}

// Example
if (Security::verifyPassword($input_password, $hashed_password_from_db)) {
    // Password is correct
} else {
    // Invalid password
}
```

{% hint style="info" %}
Note

* **Sanitize User Input** – Always clean and validate user input using helper functions to prevent XSS (Cross-Site Scripting) and SQL injection attacks.
* **Enforce HTTPS** – Ensure your application operates over HTTPS to encrypt data in transit, protecting sensitive information from interception.
* **Secure Cookies** – Set the HttpOnly and Secure flags on cookies to prevent unauthorized access and protect against session hijacking.
* **Restrict File Uploads** – Implement strict validation for uploaded files to prevent the risk of executing malicious scripts on your server.
* **Keep Your Framework Updated** – Regularly update PHP-Fast to the latest version to apply security patches.
  {% endhint %}


# Session

The `Session` class in **PHPFast** provides a structured way to manage user sessions securely. It includes features like:

**Basic session handling** (start, set, get, delete, destroy).\
**Flash messages** (temporary session data that disappears after one request).\
**Security features** such as session regeneration to prevent session fixation attacks.\
**Session timeout handling** to automatically destroy inactive sessions.\
**CSRF protection** with token generation and validation.

## Managing Session Variables

### `set()`

Stores a session variable with a given key and value.

Example:

```php
Session::set('user_id', 123); // Stores user ID in session
```

### `get()`

Retrieves the value of a session variable using its key.

Example:

```php
$user_id = Session::get('user_id'); // Retrieves user ID from session
```

### `del()`

Completely clears all session data, effectively logging out the user and resetting the session

Exampl&#x65;**:**

```php
Session::del('user_id'); // Deletes the user_id session variable
```

### `destroy()`

Completely clears all session data, effectively logging out the user and resetting the session.

Exampl&#x65;**:**

```php
Session::destroy(); // Logs out the user and clears all session data
```

### `has()`

Checks if a session variable exists, allowing conditional logic based on whether a specific piece of session data is present.

Example:

```php
if (Session::has('user_id')) {
    echo "User is logged in!";
}
```

## Flash Messages

### &#x20;`flash()`

#### **Storing a Flash Message**

Exampl&#x65;**:**

```php
Session::flash('success', 'User created successfully!');
```

#### **Retrieving a Flash Message**

Exampl&#x65;**:**

<pre class="language-php"><code class="lang-php"><strong>echo Session::flash('success'); // Displays message and removes it from session
</strong></code></pre>

### `has_flash()`

#### **Checking a Flash Message**

Exampl&#x65;**:**

```php
if(Session::has_flash('success')){
    echo Session::flash('success');
}
```

## Enhancing Session Security

### &#x20;`regenerate()`

Generates a new session ID while keeping existing session data intact. This prevents session fixation attacks, where attackers attempt to exploit predefined session IDs. It is commonly used after login to prevent unauthorized access.

Exampl&#x65;**:**

```php
Session::regenerate(); // Refreshes session ID after login
```

### `checkSessionTimeout()`

Enforces a session timeout based on user inactivity. If the user remains inactive beyond the specified time limit (e.g., `1800` seconds for 30 minutes), the session is invalidated, and the user is logged out automatically.

Example:

```php
Session::checkSessionTimeout(1800); // Auto-logout after 30 minutes of inactivity
```

## CSRF Protection

CSRF tokens protect forms from unauthorized requests.

#### `csrf_token()`

Generates a unique **CSRF token**, which should be included in forms as a hidden field. This ensures that each form submission is validated before being processed.

Example:

```php
$csrfToken = Session::csrf_token();

// Render a form
<input type="hidden" name="csrf_token" value="$csrfToken">
```

#### &#x20;`csrf_verify()`

Checks the submitted **CSRF token** against the stored token to ensure the request is legitimate. If the verification fails, the request is blocked, protecting against unauthorized form submissions.

Example:

```php
// When form submited
if (!Session::csrf_verify($_POST['csrf_token'])) {
    die("Invalid request!");
}
```


# Task Queue

The Task Queue file provides a queue management system to handle asynchronous jobs. It uses Redis to store jobs in the queue and supports retries when a job fails. Below is a detailed explanation of each function:

### `push()`

```php
public static function push($queueName, $eventName, $payload = null, $attempts = 0) {}
```

* **Functionality**: Pushes a job into the queue.
* **Parameters**:
  * `$queueName`: The name of the queue (e.g., `'email'`, `'notifications'`).
  * `$eventName`: The name of the event to be triggered when the job is processed (e.g., `'SendEmailEvent'`).
  * `$payload`: Data associated with the job (e.g., email information to be sent).
  * `$attempts`: The number of retry attempts (default is `0`).

Example:

```php
<?php
TaskQueue::push(
    'email', 
    'SendEmailEvent', 
    ['to' => 'user@example.com', 'subject' => 'Welcome'], 
    0
);

// Result: The job is added to the task_queue:email queue.
```

### `pop()`

```php
public static function pop($queueName, $timeout = 5) {}
```

* **Functionality**: Retrieves a job from the queue (uses blocking pop if available).
* **Parameters**:
  * `$queueName`: The name of the queue.
  * `$timeout`: Timeout duration (in seconds) if the queue is empty.

Example:

<pre class="language-php"><code class="lang-php">&#x3C;?php
$job = TaskQueue::pop('email');
print_r($job);

// Output
// [
<strong>//    'event' => 'SendEmailEvent',
</strong>//    'payload' => ['to' => 'user@example.com', 'subject' => 'Welcome'],
//    'timestamp' => 1681111111,
//    'attempts' => 0
// ]
</code></pre>

### `del()`

Completely clears all session data, effectively logging out the user and resetting the session

Exampl&#x65;**:**

```php
Session::del('user_id'); // Deletes the user_id session variable
```

### `processJob()`

```php
public static function processJob($queueName, $maxRetries = 3) {}
```

* **Functionality**: Processes a job from the queue.
* **Parameters**:
  * `$queueName`: The name of the queue.
  * `$maxRetries`: The maximum number of retry attempts (default is `3`).

Exampl&#x65;**:**

```php
<?php
TaskQueue::processJob('email');

// Result:
// If the job succeeds: The event is processed.
// If the job fails: The job is retried or moved to the failed queue.
```

### `pushFailed()`

```php
public static function pushFailed($queueName, $job) {}
```

* **Functionality**: Pushes a failed job into the failed queue.
* **Parameters**:
  * `$queueName`: The name of the original queue.
  * `$job`: The job as an array.

Example:

```php
<?php
$job = [
    'event' => 'SendEmailEvent',
    'payload' => ['to' => 'user@example.com', 'subject' => 'Welcome'],
    'timestamp' => 1681111111,
    'attempts' => 4
];
TaskQueue::pushFailed('email', $job);

// Result: The job is stored in the failed_task_queue:email queue
```

### &#x20;`runWorker()`

```php
public static function runWorker($queueName, $maxRetries = 3, $timeout = 5) {}
```

* **Functionality**: Runs a worker to continuously retrieve and process jobs from the queue.
* **Parameters**:
  * `$queueName`: The name of the queue.
  * `$maxRetries`: The maximum number of retry attempts.
  * `$timeout`: Timeout duration (in seconds) for blocking pop.

Exampl&#x65;**:**

```php
<?php
TaskQueue::runWorker('email');

// Result: The worker continuously processes jobs in the email queue
```

## Example

```php
<?php
// Register the event
Events::on('SendEmailEvent', function ($payload) {
    echo "Sending email to {$payload['to']} with subject '{$payload['subject']}'<br>";
});

// Push a job into the queue
TaskQueue::push('email', 'SendEmailEvent', ['to' => 'user@example.com', 'subject' => 'Welcome']);

// Run the worker to process the job
TaskQueue::runWorker('email');

// Output
// Sending email to user@example.com with subject 'Welcome'
```

{% hint style="success" %}
Summary

* **`push()`**: Pushes a job into the queue.
* **`pop()`**: Retrieves a job from the queue.
* **`processJob()`**: Processes a single job.
* **`pushFailed()`**: Pushes a failed job into the failed queue.
* **`runWorker()`**: Runs a worker to continuously process jobs.
  {% endhint %}


# Helpers

The `Helpers` directory in PHPFast contains utility functions that simplify common tasks and operations within the framework. These helpers are designed to make everyday development tasks more efficient by providing pre-built, reusable functions for tasks like string manipulation, URL generation, input validation, and form handling. By using these helpers, developers can save time and reduce code duplication, ensuring their applications are cleaner and easier to maintain. The `Helpers` directory offers a set of tools that can be easily integrated throughout the application, allowing for quicker and more effective development.

## Helpers

* [Uri\_helper](/documents/helpers/uri_helper)
* [Core\_helper](/documents/helpers/core_helper)
* [Security\_helper](/documents/helpers/security_helper)


# Uri\_helper

This utility library offers a set of functions for managing **URLs**, **handling redirects**, **sanitizing input**, **generating slugs**, and **processing request URIs** in web applications.

## Nginx in `Uri_helper`

Since `Uri_helper` provides functions for handling request URIs and generating structured URLs, proper Nginx configuration is required to **remove `index.php` from URLs** and allow `request_uri()` to function correctly.

### **Pretty URLs**

```nginx
location / {
    try_files $uri $uri/ /index.php?$query_string;
}
```

* If the requested URL matches a file or directory, it serves it directly.
* Otherwise, the request is rewritten to `index.php`, ensuring `request_uri()` processes a **clean and structured URL**.

This ensures URLs like:

`https://phpfast.net/products?page=2` remain structured without unnecessary slashes or `index.php` in the URL.

### **Handling Redirects Efficiently**

The `redirect()` function in `Uri_helper` uses PHP’s `header('Location: ...')` method for redirection. However, on Nginx, it is possible to leverage **server-level redirection for efficiency**.

**Optimizing Redirects in Nginx**\
Instead of handling all redirects in PHP, you can configure **Nginx to process common redirects** like forcing HTTPS or redirecting old URLs:

```nginx
server {
    listen 80;
    server_name phpfast.net;
    return 301 https://$server_name$request_uri;
}
```

* Redirects HTTP to HTTPS without relying on PHP.
* Reduces the need for `redirect()` calls in the application, **improving performance**.

### Supporting Clean Request URIs

The `request_uri()` function in `Uri_helper` ensures clean URL formatting, **removing unnecessary slashes** and normalizing paths. However, Nginx needs to pass the correct `$_SERVER['REQUEST_URI']` to PHP.

**Ensure Correct Request URI Handling in Nginx**

```nginx
fastcgi_param REQUEST_URI $request_uri;
```

* Ensures `request_uri()` receives the correct request path.
* Prevents duplicate slashes (`//`) in URLs from being processed incorrectly.

Example Usage with `request_uri()` in PHP:

```php
echo request_uri('https://phpfast.net//user/info');
// Output: user/info
```

Without proper configuration, Nginx may pass incorrect paths, **leading to unexpected results** in `request_uri()`.

## Functions in Uri\_helper

### `request_uri()`

* Retrieves **the clean request URI** from `$_SERVER['REQUEST_URI']`.
* **Removes extra slashes** and normalizes the path.
* **Redirects if necessary** to enforce a clean URL structure.

Example:

```php
echo request_uri('https://phpfast.net/user/info/');
// Output: user/info/

echo request_uri('https://phpfast.net/user//info//');
// Output: user/info/

echo request_uri('https://phpfast.net/user/info?page=3');
// Output: user/info/

echo request_uri('https://phpfast.net/');
// Output: empty
```

### `base_url()`&#x20;

* **Generates the base URL** for the application.
* **Retrieves the `app_url` from the config file** if not already stored in `$base_url`.
* **Trims extra slashes and handles query strings**, ensuring a **clean and structured URL**.

```php
echo base_url('products?page=2');
// Output: https://phpfast.net/products?page=2
```

### `redirect()`

* **Redirects the user** to another URL using the `header()` function.
* `exit();` ensures that no further code is executed after redirection.

Example:

```php
redirect('https://phpfast.net/dashboard');
```

### `sanitize_url()`

* **Sanitizes URLs** by removing invalid characters.
* Uses `FILTER_SANITIZE_URL`, a built-in PHP filter.

Example:

```php
echo sanitize_url('https://phpfast.net/<script>alert(1)</script>');
// Output: https://phpfast.net/ AND alert(1)
```

### `url_slug()`

* **Converts UTF-8 strings into SEO-friendly slugs**.
* **Removes special characters**, spaces, and accents (e.g., `Đ` → `D`).
* **Replaces spaces with a delimiter (`-` by default)**.

Example:

```php
echo url_slug('New Products in 2025!');
// Output: new-products-in-2025
```

<table data-header-hidden><thead><tr><th width="295"></th><th></th></tr></thead><tbody><tr><td><strong>Function</strong></td><td><strong>Purpose</strong></td></tr><tr><td><code>base_url()</code></td><td>Generates the base URL of the application.</td></tr><tr><td><code>redirect()</code></td><td>Redirects to another URL.</td></tr><tr><td><code>sanitize_url()</code></td><td>Cleans a URL from invalid characters.</td></tr><tr><td><code>url_slug()</code></td><td>Converts a UTF-8 string into a slug.</td></tr><tr><td><code>request_uri()</code></td><td>Retrieves the clean request URI.</td></tr></tbody></table>


# Core\_helper

Class Core\_helper in PHPFast provides several **utility functions** to manage helpers, system configurations, server information, and environment variables in a PHP application.

Functions Helper in Core

## `load_helpers()`

Loads helper files dynamically from either the **system** or **application** directories.

```php
function load_helpers(array $helpers = []) {
```

How It Works:

* Uses a global variable `$fast_helpers` to track loaded helpers.
* Checks if the helper is **already loaded** to avoid redundant imports.
* Searches for the helper file in:
  * `ROOT_PATH/system/Helpers/`
  * `ROOT_PATH/application/Helpers/`
* If the file exists, it is **included (`require_once`)**, otherwise, it throws an **exception**.

Example:

```php
load_helpers(['form', 'url']); // Loads form_helper.php and url_helper.php
```

## `DateTime()`

Returns the **current date and time** in the `YYYY-MM-DD HH:MM:SS` format.

```php
function DateTime() {
    return date('Y-m-d H:i:s');
}
```

Example:

```php
echo DateTime(); 
// Output: 2025-03-01 12:34:56
```

## `version_php()`

Returns the **current PHP version**.

Example:

```php
echo version_php(); 
// Output: 8.3.16
```

## `dir_writable()`

* Checks if a given **directory exists and is writable**.
* Returns `true` if writable, otherwise `false`.

Example:

```php
echo dir_writable('/writable/uploads') ? "Writable" : "Not Writable";
```

## `server_info()`

* Returns **an array of server information**, including:
  * PHP version
  * Web server software
  * Document root
  * Server name
  * Server protocol

Example:

```php
[
    [php_version] => 8.3.16
    [server_software] => nginx/1.27.3
    [document_root] => C:/laragon/www/cms/public
    [server_name] => cms.test
    [server_protocol] => HTTP/1.1
]
```

## `random_string()`

Generates a **random alphanumeric string** of the specified length.

```php
function random_string($length = 10) {}
```

Example:

```php
echo random_string(12); 
// Output: A1b2C3d4E5F6
```

## `config()`

Loads **configuration values** from a specified file.

```php
function config($key = '', $file = 'Config') {}
```

* Reads the `/application/Config/Config.php` file and returns the requested setting.
* Uses a static `$config` array to **cache values for performance**.

Example:

```php
$siteName = config('site_name'); // Loads the site_name from Config.php.
```

## `option()`

* Retrieves an **option value** from the `Options.php` config file or from the **database**.
* If the key is not found in the file, it **queries the database** for the value.

```php
function option($key, $lang = LANG) {}
```

Example:

```php
$siteTitle = option('site_title');
// Gets the site title from the options table or configuration file.
```

## `option_set()`

* Updates an **option value** in the configuration file (`Options.php`).
* Supports **multi-language values** if `$lang` is specified.

```php
function option_set($key, $value, $lang = '') {}
```

* Loads the `Options.php` file.
* Updates the key-value pair.
* Saves the new values back to the file.

Example:

```php
option_set('site_title', 'PHPFast site');
// Updates the site_title value in Options.php.

echo option('site_title');
// Ouput: PHPFast site
```

## `env()`

Retrieves **environment variables** from the system or `.env` file.

```php
function env($key, $default = null) {}
```

* First, checks if the value **exists in cache** (`$env_cache`).
* If not found, retrieves it using `getenv()`.
* Cleans the value to prevent security issues (`htmlspecialchars`).
* Converts **"true", "false", "null"** strings into actual boolean values.

Example:

```php
$dbHost = env('DB_HOST', 'localhost');
// Retrieves the database host from environment variables.
```

## `_bytes()`

Converts a **storage unit string** (e.g., `2G`, `512M`, `128K`) into **bytes**.

```php
function _bytes($size) {}
```

* Extracts the **unit** (G, M, K).
* Converts it into bytes accordingly.

Example:

```php
echo _bytes('2G'); 
// Output: 2147483648
```

<table data-header-hidden><thead><tr><th width="242"></th><th></th></tr></thead><tbody><tr><td><strong>Function</strong></td><td><strong>Purpose</strong></td></tr><tr><td><code>load_helpers()</code></td><td>Load helper files dynamically.</td></tr><tr><td><code>DateTime()</code></td><td>Get the current date and time.</td></tr><tr><td><code>version_php()</code></td><td>Retrieve the PHP version.</td></tr><tr><td><code>dir_writable()</code></td><td>Check if a directory is writable.</td></tr><tr><td><code>server_info()</code></td><td>Get server details (PHP version, web server, etc.).</td></tr><tr><td><code>random_string()</code></td><td>Generate a random alphanumeric string.</td></tr><tr><td><code>config()</code></td><td>Retrieve system configuration settings.</td></tr><tr><td><code>option()</code></td><td>Fetch system options from a file or database.</td></tr><tr><td><code>option_set()</code></td><td>Update an option value in <code>Options.php</code>.</td></tr><tr><td><code>env()</code></td><td>Retrieve environment variables from <code>.env</code> or system.</td></tr><tr><td><code>_bytes()</code></td><td>Convert storage units (G, M, K) to bytes.</td></tr></tbody></table>


# Security\_helper

This Helper defines several **security functions** to sanitize user input and prevent security vulnerabilities such as **XSS (Cross-Site Scripting), SQL Injection, and Directory Traversal attacks**.

## Prevent XSS

* Converts special characters into HTML entities (e.g., `<` becomes `&lt;`, `>` becomes `&gt;`).
* Prevents malicious JavaScript from being injected into web pages.

```php
function xss_clean($data) {
    return htmlspecialchars($data, ENT_QUOTES, 'UTF-8');
}
```

Example:

```php
$user_input = "<script>alert('Hacked!');</script>";
$clean_input = xss_clean($user_input);
echo $clean_input; 
// Output: &lt;script&gt;alert('Hacked!');&lt;/script&gt;
```

## Clean Input Data to Prevent Attacks

* **Removes unnecessary spaces and backslashes**.
* **Strips out single (`'`) and double (`"`) quotes** to prevent SQL Injection.
* **Removes any special characters except letters, numbers, spaces, and punctuation**.

**Example:**

```php
$user_input = " DROP TABLE users; ";
$cleaned_input = clean_input($user_input);
echo $cleaned_input; 
// Output: DROP TABLE users
```

**Security Benefit:** Protects against **SQL Injection and XSS attacks**.

## Secure&#x20;

These functions **sanitize user input from URL parameters (`$_GET`) and form data (`$_POST`)**.

```php
// Get data from URL parameters
function S_GET($key, $default = null) {
    if (isset($_GET[$key])) {
        return clean_input($_GET[$key]);
    }
    return $default;
}

// Get data from form
function S_POST($key, $default = null) {
    if (isset($_POST[$key])) {
        return clean_input($_POST[$key]);
    }
    return $default;
}

// Get data from $_GET and $_POST
function S_REQUEST($key, $default = null) {
    if (isset($_REQUEST[$key])) {
        return clean_input($_REQUEST[$key]);
    }
    return $default;
}

// Check data from $_GET is exist
function HAS_GET($key) {
    return isset($_GET[$key]);
}

// Check data from $_POST is exist
function HAS_POST($key) {
    return isset($_POST[$key]);
}

// Check data from both $_GET and $_POST
function HAS_REQUEST($key) {
    if (isset($_REQUEST[$key])) {
        return true;
    }
    return false;
}
```

Example:

```php
$btn    = S_POST('submit', 'default_value');
$id     = S_GET('id', 'default_value');

if (HAS_GET('id')) {
    echo "ID exists in the URL";
}

if (HAS_POST('submit')) {
    echo "Form submitted";
}
```

### Secure URIs to Prevent Attacks

* **Removes dangerous characters** from URLs.
* **Prevents directory traversal attacks** by stripping out `..` and `...`.
* **Allows only alphanumeric characters, underscores (`_`), hyphens (`-`), and dots (`.`) in URL segments**.

Example using `uri_security()`:

```php
$unsafe_uri = "/admin/../../config.php";
$safe_uri = uri_security($unsafe_uri);
echo $safe_uri; 
// Output: admin/config.php
```

**Security Benefit:** Prevents **unauthorized file access and path traversal attacks**.

### Secure All `$_GET` Parameters

* **Sanitizes all `$_GET` keys and values**.
* **Removes dangerous characters** while keeping alphanumeric characters, underscores (`_`), and dashes (`-`).
* **Prevents GET parameter manipulation attacks.**

Example using `sget_security()`**:**

<pre class="language-php"><code class="lang-php"><strong>$_GET['&#x3C;script>alert(1)&#x3C;/script>'] = '123';
</strong>sget_security();
print_r($_GET);

// Output: Array([scriptalert1script] => 123)
</code></pre>

**Security Benefit:** Prevents **parameter-based attacks**.

## Security\_helper in Controller

```php
<?php
namespace App\Controllers;

use System\Core\BaseController;
use App\Models\UsersModel;

class UsersController extends BaseController {
    protected $usersModel;

    public function __construct() {
        $this->usersModel = new UsersModel();
    }
    
    public function profile(){
        $id = S_GET('id') ?? ''; 
        if(empty($id)) {
            $userInfo = $this->usersModel->getUserById($id);
        }
    }
    
    public function login() {
        if (HAS_POST('username')){
            $csrf_token = S_POST('csrf_token') ?? '';
            
            $input = [
                'username'  =>  S_POST('username') ?? '',
                'password'  =>  S_POST('password') ?? ''
            ];
            
            // Validate data $input
            
            $this->render('auth', 'Backend/Auth/login');
    }
}
```

{% hint style="success" %}
Conclusion

These functions improve security by preventing **XSS**, **SQL Injection**, and **Path Traversal attacks**
{% endhint %}


# Drivers

The **PHPFast** framework features a powerful and adaptable driver system that streamlines key functionalities such as database management, caching, and more. Designed for flexibility, these drivers abstract complex implementation details, enabling developers to seamlessly switch between different technologies or services without modifying the core application logic

## [**Cache Drivers**](/documents/drivers/cache)

* Provide caching mechanisms to improve application performance.
* **Supported Cache Systems**: Redis, File-based caching, ...

```php
<?php
$cache = new RedisCache($config);
$cache->set('key', 'value', 600); // Cache for 10 minutes
$value = $cache->get('key');
```

* Store and retrieve cached data.
* Manage cache expiration and invalidation.
* Support for various caching strategies (e.g., in-memory, distributed).

## [**Database Drivers**](/documents/drivers/database)

* Facilitate interactions with different database management systems (DBMS).
* **Supported Databases**: MySQL, PostgreSQL, SQLite, and more.

```php
?php
$configdb = config('db');
$dbConnection = loadDatabaseDriver($configdb['db_driver'], $configdb);
```

* Establish connections to the database.
* Execute queries and retrieve results.
* Handle transactions and ensure data integrity.

{% hint style="success" %}
Summary

The driver system in the **PHPFast** framework provides a powerful and flexible way to interact with various services and technologies. By abstracting the underlying implementation details, drivers allow developers to easily switch between different systems without changing the core application logic. This modular approach enhances the maintainability and scalability of the application, making it easier to integrate new technologies and optimize performance.
{% endhint %}


# Cache

In PHPFast Framework, caching is a crucial technique to improve performance, reduce server load, and enhance user experience. There are various caching strategies available, and choosing the right one depends on the specific requirements of your application. Here, we introduce three popular caching options: `UriCache`, `RedisCache`, and `FilesCache`.

You can see how to use at [Guide Usage Cache](/documents/drivers/cache/guide-usage-cache)

## [Uri Cache](/documents/drivers/cache/uri-cache)

`UriCache` is designed to cache responses based on the URI (Uniform Resource Identifier). It is particularly useful for caching complete HTML pages or API responses that are identified by their URI.

**Feature:**&#x20;

* **Easy to Implement**: Simple to implement and use.
* **Effective for Static Pages**: Effective for static pages or pages with content that does not change frequently.
* **No Additional Setup Required**: Does not require additional software or services to be installed.

**When to Use:**

* When you need to cache complete HTML pages based on the URI.
* When you need a simple caching solution without requiring additional software.
* When you want to reduce server load by caching API responses based on the URI.

## [Redis Cache](/documents/drivers/cache/redis-cache)

`RedisCache` uses Redis, an in-memory data store, to store cache. Redis is a popular choice for caching due to its high performance and scalability.

**Feature:**&#x20;

* **High Performance**: Redis stores data in memory, making data retrieval very fast.
* **Supports Multiple Data Types**: Redis supports various data types such as strings, lists, sets, and hashes.
* **Scalable**: Redis can be easily scaled to handle large amounts of data.
* **Supports Distribution**: Redis supports distribution, increasing the system's load-handling capacity.

**When to Use**:

* When you need high performance and fast data retrieval.
* When you need to store and retrieve complex data types.
* When you need a scalable caching solution that supports distribution.
* When you need to cache temporary data such as sessions, authentication tokens, or frequently changing data.

## [Files Cache](/documents/drivers/cache/files-cache)

`FilesCache` stores cache as files on the server's file system. This is a simple and easy-to-implement caching solution.

**Feature:**&#x20;

* **Easy to Implement**: Simple to implement and use without requiring additional software.
* **Dependent on File System**: Performance depends on the file system's access speed.
* **Not Suitable for Large Data**: Not suitable for storing and retrieving large amounts of data or frequently changing data.

**When to Use**:

* When you need a simple caching solution without requiring additional software.
* When you need to cache temporary data and do not require high performance.
* When you need to store cache on the server's file system and the data does not change frequently.

{% hint style="success" %}
Summary

* [**`UriCache`**](/documents/drivers/cache/uri-cache): Use when you need to cache complete HTML pages or API responses based on the URI. Suitable for static pages or content that does not change frequently.
* [**`RedisCache`**](/documents/drivers/cache/redis-cache): Use when you need high performance, fast data retrieval, and scalability. Suitable for temporary data, sessions, and frequently changing data.
* [**`FilesCache`**](/documents/drivers/cache/files-cache): Use when you need a simple caching solution without requiring additional software. Suitable for temporary data and when high performance is not required.

Choosing the appropriate type of cache depends on the specific requirements of the application and the deployment environment.
{% endhint %}


# Guide Usage Cache

The `Cache.php` file in the `system/Drivers/Cache/` directory of the **PHPFast** framework is an abstract class that provides the basic methods for managing cache. This class defines abstract methods that must be implemented by its subclasses, creating a consistent interface for storing and retrieving cached data.

## **Cache Initialization**:

* The constructor method accepts cache configuration and calls the method to connect to the specific cache driver.

## **Connecting to Cache Driver**:

* The abstract method `connect()` is used to connect to specific cache drivers such as Redis, File-based, etc.

## **Storing and Retrieving Cached Data**:

The `Cache.php` class defines the following abstract methods, which are implemented in subclasses to handle **cache operations efficiently**:

* **`set($key, $value, $ttl)`** – Stores data in the cache with a specified time-to-live (TTL).
* **`get($key)`** – Retrieves cached data using a unique key.
* **`delete($key)`** – Removes a specific item from the cache.
* **`has($key)`** – Checks if a key exists in the cache.
* **`clear()`** – Clears all cached data.

These methods ensure a **consistent and structured approach** to cache management across different caching backends.

## Configuration Cache

See more at [Configurations](/overview/install/configurations)

## Example Usage of `Cache.php`

### **Storing Data in Cache**

```php
<?php
// Create a cache object
$cache = new RedisCache($config);

$phpFast = 'Welcome to PHPFast Framework";

// Store data in cache with a TTL of 10 minutes (600 seconds)
$cache->set('php_fast', $phpFast, 600);
```

### **Retrieving Data from Cache**

```php
<?php
// Retrieve data from cache
$phpFast = $cache->get('php_fast');

if ($phpFast !== null) {
    // Data found in cache
    echo "Data loaded from cache.";
} else {
    // Data not found in cache, need to load from another source
    echo "Data not found in cache.";
}
```

### **Deleting Data from Cache**

```php
<?php
// Delete data from cache
$cache->delete('php_fast');
```

## Subclasses of `Cache.php`

The `Cache.php` class acts as a **parent class** for multiple subclasses, each implementing its own caching mechanism while adhering to the standard interface defined in `Cache.php`. Key subclasses include:

* &#x20;[**`UriCache.php`**](/documents/drivers/cache/uri-cache) – Optimizes request handling by caching URI-based data.
* &#x20;[**`RedisCache.php`**](/documents/drivers/cache/redis-cache) – Provides high-performance caching using Redis.
* &#x20;[**`FilesCache.php`**](/documents/drivers/cache/files-cache) – Implements file-based caching by storing data in structured files.

Each subclass implements the abstract methods defined in `Cache.php`, ensuring a modular and extensible caching system within the PHPFast framework.


# Uri Cache

The `UriCache.php` file is a class in the **PHPFast** framework that provides methods to cache and retrieve content based on the URI (Uniform Resource Identifier). This class helps in optimizing the performance of web applications by caching the output of specific URIs. Below is a detailed explanation of each method along with examples of how to use them.

## `__construct()`

```php
<?php
public function __construct($compression = 0, $type = 'html') {
    // Set the cache directory (assuming ROOT_PATH is defined)
    $this->cacheDir = ROOT_PATH . '/writeable/cache/';
    $this->compression = $compression;
    $this->headerType = $type;
    $this->cacheLogin = false;
}
```

Initializes the `UriCache` object with optional compression level and content type.

* `$compression`: Compression level (0 = no gzip, 1-9 = gzip level).
* `$type`: Content type (e.g., 'html', 'json').
* Sets the cache directory.
* Sets the compression level and content type.
* Initializes the cache login state to `false`.

## `headers()`

```php
function headers($compress = -1)
```

Sends the appropriate HTTP headers for the cached content based on its type and compression settings.

* `$compress`: Compression level (-1 to use default).

## `set()`

```php
function set($content)
```

Stores the given content in the cache after applying optional compression.

* `$content`: Content to be cached.
* `return`: Cached content or false if caching is disabled.

## `get()`

```php
function get()
```

Retrieves and returns cached content if available.

* Note: if the file is gzip, it returns gzip data.
* `return`: Cached content or null if not found.

## `delete()`

Deletes a specific cached file.

* `return`: `true` if the cache file is deleted, `false` otherwise.

## `has()`

Checks if a cached file exists for the requested content.

* `return`: `true` if the cache file exists, `false` otherwise

## `clear()`

Removes all cached files, effectively clearing the cache storage.

* `return`: `true` if the cache directory is cleared

## Example

```php
<?php
// Initialize the UriCache object
$uriCache = new UriCache(1, 'html');

// Check if the cache exists
if ($uriCache->has()) {
    // Retrieve and display the cached content
    $cachedContent = $uriCache->get();
    if ($cachedContent !== null) {
        echo $cachedContent;
        exit;
    }
}

// Generate the content to be cached
$content = '<html><body><h1>Welcome to PHPFast Framework</h1></body></html>';

// Save the content to the cache
$uriCache->set($content);

// Delete cache
$uriCache->delete();

// Clear cache
$uriCache->clear();

// Display the content
echo $content;
```

{% hint style="success" %}
Summary

The `UriCache.php` file provides methods to cache and retrieve content based on the URI. It includes methods to set and get cached content, delete cached content, and check for the existence of cached content. This implementation helps in optimizing the performance of web applications by caching the output of specific URIs.
{% endhint %}


# Redis Cache

The `FilesCache.php` file is a concrete implementation of the abstract `Cache` class in the PHPFast framework. It provides methods to store, retrieve, and manage cached data using the file system. Below is a detailed explanation of each method along with examples of how to use them.

## `connect()`

Connect to the file-based cache system by setting up the cache directory.

```php
<?php
protected function connect() {
    $this->cacheDir = $this->config['cache_dir'] ?? sys_get_temp_dir();
    if (!is_dir($this->cacheDir)) {
        mkdir($this->cacheDir, 0777, true);
    }
}
```

* Sets the cache directory to the configured path or the system's temporary directory if not specified.
* Creates the cache directory if it does not exist.
* This method is called automatically when an instance of `RedisCache` is created.

## `set()`

```php
function set($key, $value, $ttl = 3600)
```

Stores a value in the cache with a specified expiration time (Time-To-Live).

* `$key` – The key under which to store the value.
* `$value` – The value to store.
* `$ttl` – Time-to-live in seconds.
* `$ttl`  - `true` if the value was successfully set, `false` otherwise

Example:

```php
<?php
$cache = new RedisCache();
$phpFast = 'Welcome to PHPFast Framework'
$cache->set('php_fast', $phpFast, 600); // Cache for 10 minutes
```

## `get()`

```php
function get($key)
```

Retrieves a value from the cache using its unique key.

* `$key` – The key of the value to retrieve.
* `return` – The value stored in the cache or null if not found

Example:

```php
<?php
$phpFast = $cache->get('php_fast');
if ($phpFast !== null) {
    echo "Data loaded from cache.";
} else {
    echo "Data not found in cache.";
}
```

## `delete()`

```php
function delete($key)
```

Removes a specific cached value from the system.

* `$key` – The key of the value to delete.
* `return` – `true` if the value was successfully deleted, `false` otherwise.

Example:

```php
$cache->delete('php_fast');
```

## `has()`

```php
function has($key)
```

Checks whether a specific key exists in the cache.

* `$key` – The key to check for existence.
* `return` – `true` if key exists, `false` otherwise.

Example:

```php
<?php
if ($cache->has('php_fast')) {
    echo "Cache exists for php_fast.";
} else {
    echo "No cache for php_fast.";
}
```

## `clear()`

```php
function clear()
```

Removes all cached entries, effectively resetting the cache storage.

* `return` – `true` if the cache was successfully cleared, `false` otherwise

Example:

```php
$cache->clear();
```

{% hint style="success" %}
Summary

The `RedisCache.php` file extends the abstract `Cache` class to provide Redis-based caching functionality. It includes methods to connect to the Redis server, store and retrieve cached data, delete cached data, check for the existence of cached data, and clear all cached data. This implementation allows developers to use Redis as a caching mechanism in their PHPFast applications.
{% endhint %}


# Files Cache

The `FilesCache.php` file is a concrete implementation of the abstract `Cache` class. It provides methods to store, retrieve, and manage cached data using the file system. Below is an explanation of the code in `FilesCache.php`.

It provides methods to store, retrieve, and manage cached data using the file system. Below is an explanation of each method in `FilesCache.php` along with examples:

## `set()`

```php
function set($key, $value, $ttl = 3600)
```

Stores a value in the cache with a specified time-to-live (TTL). The value is serialized and saved in a file identified by the MD5 hash of the key.

* `$key` – The key under which to store the value.
* `$value` – The value to store.
* `$ttl` – Time-to-live in seconds.
* `$ttl`  - `true` if the value was successfully set, `false` otherwise

Example:

```php
<?php
$cache = new FilesCache()
$cache->set('php_fast', ['name' => 'PHPFast Framework', 'version' => '1.0'], 600);
```

## `get()`

```php
function get($key)
```

Retrieves a cached value using its key. If the key exists, the stored data is unserialized and returned; otherwise, `null` is returned.

* `$key` – The key of the value to retrieve.
* `return` – The value stored in the cache or null if not found

Example:

```php
<?php
$phpFast = $cache->get('php_fast');
if ($phpFast !== null) {
    echo "Data loaded from cache.";
} else {
    echo "Data not found in cache.";
}
```

## `delete()`

```php
function delete($key)
```

Removes a cached value based on the provided key. If the key exists, the corresponding data is deleted from the cache.

* `$key` – The key of the value to delete.
* `return` – `true` if the value was successfully deleted, `false` otherwise.

Example:

```php
<?php
$cache->delete('php_fast');
```

## `has()`

```php
function has($key)
```

Checks whether a specific key exists in the cache. Returns `true` if the key is found, otherwise returns `false`.

* `$key` – The key to check for existence.
* `return` – `true` if key exists, `false` otherwise.

Example:

```php
<?php
if ($cache->has('php_fast')) {
    echo "Cache exists for php_fast.";
} else {
    echo "No cache for php_fast.";
}
```

## `clear()`

```php
function clear()
```

Clears all cached data, effectively resetting the cache system by removing all stored keys and their values.

* `return` – `true` if the cache was successfully cleared, `false` otherwise

Example:

```php
<?php
$cache->clear();
```

{% hint style="success" %}
Conclusion

The `FilesCache.php` file implements the abstract `Cache` class to provide file-based caching functionality. It includes methods to **connect** to the file system, **store** and **retrieve** cached data, **delete** cached data, check for the **existence** of cached data, and **clear** all cached data. This implementation allows developers to use the file system as a caching mechanism in their **PHPFast** applications.
{% endhint %}


# Database

The `Database.php` file in the `Drivers/Database/` directory of the <kbd>PHPFast</kbd> framework provides methods to interact with the database. Each specific database driver (e.g., MySQL, PostgreSQL) will implement these methods. Below is a detailed explanation of each method along.

PHPFast is a lightweight and efficient PHP framework designed to streamline web application development while providing flexibility and scalability. One of its key features is the built-in support for multiple database drivers, making it easy to integrate and work with different database systems. PHPFast includes drivers for [**MongoDB**](https://www.mongodb.com/), [**MySQL**](https://www.mysql.com/), and [**PostgreSQL**](https://www.postgresql.org/), allowing developers to choose the best database solution for their application needs.

* [**MongodbDriver**](/documents/drivers/database/mongodbdriver): For applications that require NoSQL databases, PHPFast offers seamless integration with MongoDB, a high-performance, flexible database ideal for handling unstructured data.
* [**MysqlDriver**](/documents/drivers/database/mysqldriver): PHPFast supports MySQL, one of the most widely used relational databases, providing robust and efficient data management for traditional applications.
* [**PostgresqlDriver**](/documents/drivers/database/postgresqldriver): With built-in support for PostgreSQL, PHPFast enables the use of an advanced, open-source relational database known for its reliability, performance, and scalability.

## Constructor (`__construct`)

```php
abstract public function __construct($config);
```

Initializes the database connection with the provided configuration.\\

* `$config`: An array containing the database configuration settings.

## `query()`

```php
abstract public function query($query, $params = []);
```

Executes an arbitrary SQL query with optional parameters.

* `$query`: The SQL query string.
* `$params`: An array of values corresponding to the parameters in the SQL query.

## `lastInsertId()`

```php
abstract public function lastInsertId();
```

Retrieves the ID of the last inserted record.

The ID of the last inserted record.

## `count()`

```php
abstract public function count($table, $where = '', $params = []);
```

Counts the number of records in a table.

* `$table`: The name of the table.
* `$where`: The WHERE clause to filter records (optional).
* `$params`: An array of values corresponding to the parameters in the WHERE clause (optional).

## `fetchAll()`

```php
abstract public function fetchAll($table, $where = '', $params = [], $orderBy = '', $page = 1, $limit = null);
```

Executes a SELECT query to retrieve multiple rows.

* `$table`: The name of the table.
* `$where`: The WHERE clause as a string (optional).
* `$params`: An array of values corresponding to the parameters in the WHERE clause (optional).
* `$orderBy`: The ORDER BY clause (optional).
* `$page`: The current page number (optional).
* `$limit`: The number of results to limit (optional).

## `fetchPagination()`

```php
abstract public function fetchPagination($table, $where = '', $params = [], $orderBy = '', $page = 1, $limit = null);
```

Executes a SELECT query to retrieve multiple rows with pagination support.

* `$table`: The name of the table.
* `$where`: The WHERE clause as a string (optional).
* `$params`: An array of values corresponding to the parameters in the WHERE clause (optional).
* `$orderBy`: The ORDER BY clause (optional).
* `$page`: The current page number (optional).
* `$limit`: The number of results per page (optional).

## `fetchRow()`

```php
abstract public function fetchRow($table, $where = '', $params = [], $orderBy = '', $page = 1);
```

Executes a SELECT query to retrieve a single row.

* `$table`: The name of the table.
* `$where`: The WHERE clause as a string.
* `$params`: An array of values corresponding to the parameters in the WHERE clause.
* `$orderBy`: The ORDER BY clause (optional).
* `$page`: The current page number (optional).

## `insert()`

```php
abstract public function insert($table, $data);
```

Executes an INSERT query to add a new record.

* `$table`: The name of the table.
* `$data`: An array of data to insert (in the form of 'column' => 'value').

## `update()`

```php
abstract public function update($table, $data, $where = '', $params = []);
```

Executes an UPDATE query to modify existing records.

* `$table`: The name of the table.
* `$data`: An array of data to update (in the form of 'column' => 'value').
* `$where`: The WHERE clause to filter records.
* `$params`: An array of values corresponding to the parameters in the WHERE clause.

## `delete()`

```php
abstract public function delete($table, $where = '', $params = []);
```

Executes a DELETE query to remove records.

* `$table`: The name of the table.
* `$where`: The WHERE clause to filter records.
* `$params`: An array of values corresponding to the parameters in the WHERE clause.


# Guide Usage Database


# MongodbDriver

The `MongoDBDriver.php` file, located in the `Drivers/Database/` directory of the PHPFast framework, serves as an interface for seamless interaction with a MongoDB database. It offers essential methods for establishing connections, executing queries, and managing data efficiently. Below is a comprehensive breakdown of each method, complete with usage examples.

## Configuaration

```php
'db' => [
        'db_driver'   => 'mongodb',
        'db_host'     => 'localhost',
        'db_port'     => 3306,
        'db_username' => 'root',
        'db_password' => '',
        'db_database' => 'cms.vn',
        'db_charset'  => 'utf8mb4',
        'db_collate'  => 'utf8mb4_unicode_ci',
    ],
```

## `__construct()`

```php
<?php
public function __construct($config) {
    $this->config = $config;
    $this->connect();
}
```

Initializes the `MongoDBDriver` object with the provided configuration and establishes a connection to the MongoDB database.

* `$config`: An array containing the MongoDB configuration settings.

## `query()`

```php
<?php
public function query($command, $params = []) {}
```

Executes a query on a specified collection with optional filters and options.

* `$command` - An array of MongoDB commands
* `$params` - Optional parameters.
* `return` - Result of the query

## `insert()`

```php
public function insert($collection, $data) {}
```

Inserts a new document into a specified collection.

* `$collection`: The name of the collection.
* `$data`: An array representing the document to insert.
* `return` - Returns true if the data is successfully inserted, otherwise false.

## `update()`

```php
<?php
public function update($collection, $data, $where, $params = []) {}
```

Updates documents in a specified collection that match the filter criteria.

* `$collection` - the name of the collection.
* `$data` - an array of data to update.
* `$where` - optional filter conditions.
* `$params` - optional parameters for the filter.
* `return` - Returns true if the update is successful, otherwise false

## `delete()`

```php
<?php
public function delete($collection, $where, $params = []) {}
```

Deletes documents from a specified collection that match the filter criteria.

* `$collection` - the name of the collection.
* `$where` - optional filter conditions.
* `$params` - optional parameters for the filter.
* `return` - Returns true if the deletion is successful, otherwise false

## `lastInsertId()`

```php
<?php
public function lastInsertId() {
    return $this->lastInsertedId ?? null;
}
```

Retrieves the ID of the last inserted document.

`return` - ID of the last inserted record

## `count()`

```php
public function count($collection, $where = '', $params = []) {}
```

Counts the number of documents in a collection

* `$collection` - the name of the collection&#x20;
* `$where` - optional filter conditions
* `$params` - optional parameters for the filter.
* `return` - Number of records in the collection

Example:

## `fetchAll()`

```php
<?php
public function fetchAll($collection, $where = '', $params = [], $orderBy = '', $page = 1, $limit = null) {}
```

Executes a SELECT query to retrieve multiple documents.

* `$collection`: The name of the collection.
* `$where`: The WHERE clause to filter documents (optional).
* `$params`: An array of values corresponding to the parameters in the WHERE clause (optional).
* `$orderBy`: The ORDER BY clause (optional).
* `$page`: The current page number (optional).
* `$limit`: The number of results to limit (optional).
* `return` - Array containing the query results

## `fetchPagination()`

```php
<?php
public function fetchPagination($collection, $where = '', $params = [], $orderBy = '', $page = 1, $limit = null) {}
```

Executes a SELECT query to retrieve multiple documents with pagination support

* `$collection`: The name of the collection.
* `$where`: The WHERE clause to filter documents (optional).
* `$params`: An array of values corresponding to the parameters in the WHERE clause (optional).
* `$orderBy`: The ORDER BY clause (optional).
* `$page`: The current page number (optional).
* `$limit`: The number of results per page (optional).
* `return` - Query results and information about whether there is a next page

## `fetchRow()`

```php
<?php
public function fetchRow($collection, $where = '', $params = [], $orderBy = '', $page = 1) {}
```

Executes a SELECT query to retrieve a single document.

* `$collection`: The name of the collection.
* `$where`: The WHERE clause to filter documents.
* `$params`: An array of values corresponding to the parameters in the WHERE clause.
* `$orderBy`: The ORDER BY clause (optional).
* `$page`: The current page number (optional).
* `return` - Array containing the query result or null if no result is found

{% hint style="info" %}
Summary

The `MongoDBDriver.php` file provides methods to interact with a MongoDB database, including connecting to the database, executing queries, and managing data. This implementation allows developers to perform MongoDB operations in their **PHPFast** applications efficiently.
{% endhint %}


# MysqlDriver

The `MysqlDriver.php` file in the `Drivers/Database/` directory of the **PHPFast** framework provides methods to interact with a MySQL database. It includes methods for connecting to the database, executing queries, and managing data. Below is a detailed explanation of each method along with examples of how to use them

## Configuaration

```php
'db' => [
        'db_driver'   => 'mysql',
        'db_host'     => 'localhost',
        'db_port'     => 3306,
        'db_username' => 'root',
        'db_password' => '',
        'db_database' => 'cms.vn',
        'db_charset'  => 'utf8mb4',
        'db_collate'  => 'utf8mb4_unicode_ci',
    ],
```

## `__construct()`

```php
<?php
public function __construct($config) {
    $this->config = $config;
    $this->connect();
}
```

Initializes the `MysqlDriver` object with the provided configuration and establishes a connection to the MySQL database.

* `$config`: An array containing the MySQL configuration settings

## `query()`

```php
<?php
public function query($query, $params = []) {}
```

Prepares and executes an SQL query with optional parameters.

* `$query`: The SQL query string.
* `$params`: An array of parameters to bind to the query (optional).
* `return`: Result of the query (used for SELECT, INSERT, UPDATE, DELETE)

## `lastInsertId()`

```php
<?php
public function lastInsertId() {}
```

Retrieves the ID of the last inserted record.

`$return`: Result of the query (used for SELECT, INSERT, UPDATE, DELETE).

## `count()`

```php
<?php
public function count($table, $where = '', $params = []) {}
```

Counts the number of records in a table.

* `$table`: The name of the table.
* `$where`: The WHERE clause to filter records (optional).
* `$params`: An array of values corresponding to the parameters in the WHERE clause (optional).
* `return`: Number of records in the table.

## `fetchAll()`

```php
<?php
public function fetchAll($table, $where = '', $params = [], $orderBy = '', $page = 1, $limit = null) {}
```

Excutes a SELECT query to retrieve multiple rows.

* `$table`: The name of the table.
* `$where`: The WHERE clause as a string (optional).
* `$params`: An array of values corresponding to the parameters in the WHERE clause (optional).
* `$orderBy`: The ORDER BY clause (optional).
* `$page`: The current page number (optional).
* `$limit`: The number of results to limit (optional).
* `return`: Array containing the query results.

## `fetchPagination()`

```php
<?php
fetchPagination($table, $where = '', $params = [], $orderBy = '', $page = 1, $limit = null) {}
```

Execute a SELECT query to fetch multiple rows with pagination.

* `$table`: Name of the table
* `$where`: WHERE condition as a string (optional)
* `$params`: Array of values corresponding to the WHERE string (optional)
* `$orderBy`: ORDER BY clause (optional)
* `$page`: Current page number (optional)
* `$limit`: Number of results per page (optional)
* `return`: Query results and information about whether there is a next page.

## `fetchPaginationWithField()`

```php
<?php
fetchPaginationWithField($table, $fields = '*', $where = '', $params = [], $orderBy = '', $page = 1, $limit = null) {}
```

Execute a SELECT query to fetch multiple rows with pagination.

* `$table`: Name of the table
* `fields` : Fields to query (optional)
* `$where`: WHERE condition as a string (optional)
* `$params`: Array of values corresponding to the WHERE string (optional)
* `$orderBy`: ORDER BY clause (optional)
* `$page`: Current page number (optional)
* `$limit`: Number of results per page (optional)
* `return`: Query results and information about whether there is a next page.

## `fetchRow()`

```php
<?php
public function fetchRow($table, $where = '', $params = [], $orderBy = '', $page = 1) {}
```

Executes a SELECT query to retrieve a single row.

* `$table`: The name of the table.
* `$where`: The WHERE clause as a string.
* `$params`: An array of values corresponding to the parameters in the WHERE clause.
* `$orderBy`: The ORDER BY clause (optional).
* `$page`: The current page number (optional).
* `return`: Array containing the query result or null if no result is found.

## `fetchRowfetchRowField()`

```php
<?php
public function fetchRow($table, $fields = '*', $where = '', $params = [], $orderBy = '', $page = 1) {}
```

Executes a SELECT query to retrieve a single row.

* `$table`: The name of the table.
* `fields` : Fields to query
* `$where`: The WHERE clause as a string.
* `$params`: An array of values corresponding to the parameters in the WHERE clause.
* `$orderBy`: The ORDER BY clause (optional).
* `$page`: The current page number (optional).
* `return`: Array containing the query result or null if no result is found

## `insert()`

```php
<?php
public function insert($table, $data) {}
```

Executes an INSERT query to add a new record.

* `$table`: The name of the table.
* `$data`: An array of data to insert (in the form of 'column' => 'value').
* `return`: Returns true if the data is successfully inserted, otherwise false.

## `update()`

```php
<?php
public function update($table, $data, $where = '', $params = []) {}
```

Executes an UPDATE query to modify existing records.

* `$table`: The name of the table.
* `$data`: An array of data to update (in the form of 'column' => 'value').
* `$where`: The WHERE clause to filter records.
* `$params`: An array of values corresponding to the parameters in the WHERE clause.
* `return`: Returns true if the update is successful, otherwise false.

## `delete()`

```php
<?php
public function delete($table, $where = '', $params = []) {}
```

Executes a DELETE query to remove records.

* `$table`: The name of the table.
* `$where`: The WHERE clause to filter records.
* `$params`: An array of values corresponding to the parameters in the WHERE clause.
* `return`: Returns true if the deletion is successful, otherwise false.

{% hint style="success" %}
Summary

The `MysqlDriver.php` file provides a comprehensive set of methods for interacting with a MySQL database using PDO. It supports various database operations, including querying, inserting, updating, and deleting records, as well as managing transactions and pagination. This implementation allows developers to perform database operations efficiently in their **PHPFast** applications.
{% endhint %}


# PostgresqlDriver

The `PostgresqlDriver.php` file in the **PHPFast** framework defines a class for seamless interaction with a PostgreSQL database using PDO (PHP Data Objects). This class offers essential methods for establishing connections, executing queries, and handling data efficiently. Below is a comprehensive breakdown of each method, along with practical usage examples.

## Configuaration

```php
'db' => [
        'db_driver'   => 'pgsql',
        'db_host'     => 'localhost',
        'db_port'     => 5432,
        'db_username' => 'root',
        'db_password' => '',
        'db_database' => 'cms.vn',
        'db_charset'  => 'utf8mb4',
        'db_collate'  => 'utf8mb4_unicode_ci',
    ],
```

## `__construct()`

```php
<?php
public function __construct($config) {
    try {
        $dsn = 'pgsql:host=' . $config['db_host'] . ';dbname=' . $config['db_database'];
        $this->pdo = new PDO($dsn, $config['db_username'], $config['db_password']);
        $this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    } catch (PDOException $e) {
        throw new \System\Core\AppException("Connect PostgresqlDriver failed: " . $e->getMessage(), 500);
    }
}
```

Initializes the PostgreSQL connection using the provided configuration settings.

* `$config`: An array containing the database configuration settings.

## `query()`

```php
<?php
public function query($query, $params = []) {}
```

Executes an arbitrary SQL query with optional parameters.

* `$query`: The SQL query string.
* `$params`: An array of values corresponding to the parameters in the SQL query.
* `return`: Result of the query (used for SELECT, INSERT, UPDATE, DELETE).

## `lastInsertId()`

```php
<?php
public function lastInsertId() {}
```

Retrieves the ID of the last inserted record.

`return`: ID of the last inserted record.

## `count()`

```php
<?php
public function count($table, $where = '', $params = []) {}
```

Counts the number of records in a table that match the specified filter criteria

* `$table`: The name of the table.
* `$where`: The filter criteria (optional).
* `$params`: An array of values corresponding to the parameters in the filter criteria (optional).
* `return`: Number of records in the table.

## `fetchAll()`

```php
<?php
public function fetchAll($table, $where = '', $params = [], $orderBy = '', $page = 1, $limit = null) {}
```

Executes a SELECT query on a table and retrieves multiple rows that match the specified filter criteria.

* `$table`: The name of the table.
* `$where`: The filter criteria (optional).
* `$params`: An array of values corresponding to the parameters in the filter criteria (optional).
* `$orderBy`: The ORDER BY clause (optional).
* `$page`: The current page number (optional).
* `$limit`: The number of results per page (optional).
* `return`: Array containing the query results.

## `fetchPagination()`

```php
<?php
public function fetchPagination($table, $where = '', $params = [], $orderBy = '', $page = 1, $limit = null) {}
```

Executes a SELECT query on a table and retrieves multiple rows with pagination support.

* `$table`: The name of the table.
* `$where`: The filter criteria (optional).
* `$params`: An array of values corresponding to the parameters in the filter criteria (optional).
* `$orderBy`: The ORDER BY clause (optional).
* `$page`: The current page number (optional).
* `$limit`: The number of results per page (optional).
* `return`: Query results and information about whether there is a next page.

## `fetchRow()`

```php
<?php
public function fetchRow($table, $where = '', $params = [], $orderBy = '', $page = 1) {}
```

Executes a SELECT query on a table and retrieves a single row that matches the specified filter criteria.

* `$table`: The name of the table.
* `$where`: The filter criteria (optional).
* `$params`: An array of values corresponding to the parameters in the filter criteria (optional).
* `$orderBy`: The ORDER BY clause (optional).
* `$page`: The current page number (optional).
* `return`: Array containing the query result or null if no result is found.

## `insert()`

```php
<?php
public function insert($table, $data) {}
```

Inserts a new row into a table with the specified data.

* `$table`: The name of the table.
* `$data`: An array of data to insert (in the form of 'column' => 'value').
* `return`: Returns true if the data is successfully inserted, otherwise false

## `update()`

```php
<?php
public function update($table, $data, $where = '', $params = []) {}
```

Updates rows in a table that match the specified filter criteria with the provided data.

* `$table`: The name of the table.
* `$data`: An array of data to update (in the form of 'column' => 'value').
* `$where`: The filter criteria (optional).
* `$params`: An array of values corresponding to the parameters in the filter criteria (optional).
* `return`: Returns true if the update is successful, otherwise false.

## `delete()`

```php
<?php
public function delete($table, $where = '', $params = []) {}
```

Deletes rows from a table that match the specified filter criteria.

* `$table`: The name of the table.
* `$where`: The filter criteria (optional).
* `$params`: An array of values corresponding to the parameters in the filter criteria (optional).
* `return`: Returns true if the deletion is successful, otherwise false

{% hint style="success" %}
Summary

he `PostgresqlDriver.php` file offers a robust collection of methods for seamless interaction with a PostgreSQL database using PDO. It facilitates essential operations such as querying, inserting, updating, and deleting records, along with transaction management and pagination support. Designed for efficiency, this implementation enables developers to handle database operations smoothly within their **PHPFast** applications.
{% endhint %}


# Commands

The **PHPFast** framework provides a powerful command system to help developers easily manage and automate common tasks during application development. These commands are executed through the Command Line Interface (CLI) and include functionalities such as creating controllers, models, and database tables. Below is an overview of the main commands in this framework.

## Overview

Example for create Controller, add a new file in `system/Commands` and following this code:

```php
<?php
namespace System\Commands;

class ControllersCommand {
    public function create($name) {
        $controllerPath = ROOT_PATH . '/application/Controllers/' . ucfirst($name) . 'Controller.php';

        // Check if controller already exists
        if (file_exists($controllerPath)) {
            echo "Controller $name already exists.\n";
            return;
        }

        // Basic controller template
        $controllerContent = 'Add structure file here.'

        // Write the controller file
        file_put_contents($controllerPath, $controllerContent);
        echo "Controller $name created at $controllerPath.\n";
    }
}
```

In `init` file, register for new Command:

```php
use System\Commands\ControllersCommand;

$command = strtolower($argv[1]) ?? null;
$subCommand = $argv[2] ?? null;

switch ($command) {
    case 'controllers':
        $controllerCommand = new ControllersCommand();
        $controllerCommand->create($subCommand);
        break;
    default:
        echo "Invalid command. Available Commands: Controllers, Models, table.\n";
        break;
}
```

## How to use?

**Step 1: Open Terminal.**

**Step 2: Add the following code:**

```shellscript
php init controllers users
```

**Step 3: Check your defined path and view the result.**

{% hint style="success" %}
Summary

The command system in the **PHPFast** framework provides powerful tools to automate application management tasks such as creating controllers, models, and database tables. By using these commands, developers can save time and effort while ensuring consistency and efficiency in the development process.
{% endhint %}


# Controllers Command

`ControllersCommand.php` defines a command for creating a new **Controller** file in the application. It ensures that a controller does not already exist, generates a basic controller template, and writes it to the appropriate directory. Additionally, it **prompts the user** to create a corresponding model if needed.

## `create()` in `ControllersCommand`

```php
public function create($name) {
        $controllerPath = ROOT_PATH . '/application/Controllers/' . ucfirst($name) . 'Controller.php';

        // Check if controller already exists
        if (file_exists($controllerPath)) {
            echo "Controller $name already exists.\n";
            return;
        }

        // Basic controller template
        $controllerContent = "<?php\n";
        $controllerContent .= "namespace App\Controllers;\n\n";
        $controllerContent .= "use System\Core\BaseController;\n\n";
        $controllerContent .= "class " . ucfirst($name) . "Controller extends BaseController {\n\n";
        $controllerContent .= "    public function index() {\n";
        $controllerContent .= "        echo 'Hello from " . ucfirst($name) . "Controller!';\n";
        $controllerContent .= "    }\n";
        $controllerContent .= "}\n";

        // Write the controller file
        file_put_contents($controllerPath, $controllerContent);
        echo "Controller $name created at $controllerPath.\n";

        // Prompt for model creation
        echo "Do you want to create a model for $name? (y/n): ";
        $response = trim(fgets(STDIN));
        if (strtolower($response) == 'y') {
            $modelCommand = new ModelsCommand();
            $modelCommand->create($name);
        }
    }
```

Example:

If you want to create a new Controller and named as 'User', run the following command:

```
php init controllers user
```

If `UserController.php` is exist:

```php
Controller User already exists.
```

If `UserController.php` is not exist, it will be generated:

```php
<?php
namespace App\Controllers;

use System\Core\BaseController;

class UserController extends BaseController {

    public function index() {
        echo 'Hello from UserController!';
    }
}
```

```
// Then you will see the message:
Controller User created at /root/application/Controllers/UserController.php.
Do you want to create a model for User? (y/n):

// If you enter "y":
Model UserModel created at /root/application/Models/UserModel.php.
```


# Models Command

This `ModelsCommand` class is a **CLI command** used to **generate new Model files** dynamically in the PHPFast framework.

```php
public function create($modelName) {
        // Define the path for the new model
        $modelName = ucfirst($modelName);
        $modelPath = ROOT_PATH . '/application/Models/' . ucfirst($modelName) . 'Model.php';
        
        // Check if the model already exists
        if (file_exists($modelPath)) {
            echo "Model {$modelName} already exists.\n";
            return;
        }

        // Define the contents of the model
        $modelContent = // Model File Structure

        // Create the model file
        file_put_contents($modelPath, $modelContent);

        echo "Model {$modelName}Model has been created successfully.\n";
    }
```

If you want to create a new Model and named as 'User', run the following command:

```
php init models user
```

If `UserModel.php` is exist:

```php
Model User already exists.
```

If `UserModel.php` is not exist, it will be generated:

```php
<?php
namespace App\Models;
use System\Core\BaseModel;

class UserModel extends BaseModel {

    protected $table = 'User';

    // Columns that are fillable (can be added or modified)
    protected $fillable = ['name'];

    // Columns that are guarded (cannot be modified)
    protected $guarded = ['id', 'created_at'];

    /**
     * Define the table schema
     * 
     * @return array Table schema
     */
    public function _schema() {
        return [
            'id' => [
                'type' => 'int unsigned',
                'auto_increment' => true,
                'key' => 'primary',
                'null' => false
            ],
            'name' => [
                'type' => 'varchar(150)',
                'null' => false,
                'default' => ''
            ]
        ];
    }

    /**
     * Get all records
     */
    public function getUsers($where = '', $params = [], $orderBy = 'id DESC', $limit = null, $offset = null) {
        return $this->list($this->table, $where, $params, $orderBy, $limit, $offset);
    }

    /**
     * Add a new record
     */
    public function addUser($data) {
        $data = $this->fill($data);
        return $this->add($this->table, $data);
    }

    /**
     * Update an existing record
     */
    public function setUser($id, $data) {
        $data = $this->fill($data);
        return $this->set($this->table, $data, 'id = ?', [$id]);
    }

    /**
     * Delete a record
     */
    public function delUser($id) {
        return $this->del($this->table, 'id = ?', [$id]);
    }
```

```
Model UserModel created at /root/application/Models/UserModel.php.
```


# Table Command

This **`TableCommand`** class provides methods to **synchronize database tables** by creating, updating, and modifying schema definitions in MySQL.

## `handle()` - Execute Table Synchronization

```php
public function handle($tableName) {
    $modelClass = "\\App\\Models\\".ucfirst($tableName).'Model';
    
    // Initialize the model
    $model = new $modelClass();
    $table = $model->_table();
    $schema = $model->_schema();
    
    // Check the table and synchronize its structure
    $this->syncTableSchema($table, $schema);

    echo "{$table} Table has been synchronized.\n";
}
```

* Dynamically **creates a model class** using the given `$tableName`.
* Calls `_table()` and `_schema()` methods from the model to **retrieve table name and schema definition**.
* Passes these values to `syncTableSchema()` for **synchronization**.

## `syncTableSchema()` - Synchronize Table Schema

```php
protected function syncTableSchema($table, $schema) {
    if (!$this->tableExists($table)) {
        $this->createTable($table, $schema);
    } else {
        $this->updateTable($table, $schema);
    }
}
```

* **Checks if the table exists** using `tableExists()`.
* If the table **does not exist**, calls `createTable()`.
* Otherwise, calls `updateTable()` to **modify the schema**.

## `tableExists()` - Check If Table Exists

```php
protected function tableExists($table) {
    $query = "SHOW TABLES LIKE '{$table}'";
    $stmt = $this->db->prepare($query);
    $stmt->execute();
    return $stmt->rowCount() > 0;
}
```

* Executes a SQL query to **check if a table exists** in the database.
* Returns `true` if the table exists, otherwise `false`.

## `createTable()` **- Create a New Table**

```php
protected function createTable($table, $schema) {
    $columns = [];
    foreach ($schema as $column => $attributes) {
        $columns[] = $this->buildColumnTable($column, $attributes);
    }
    $configdb = config('db');
    $charset = $configdb['db_charset'] ?? 'utf8mb4';
    $collate = $configdb['db_collate'] ?? 'utf8mb4_unicode_ci';

    $query = "CREATE TABLE {$table} (" . implode(', ', $columns) . ") ENGINE=InnoDB DEFAULT CHARSET={$charset} COLLATE={$collate};";
    $stmt = $this->db->prepare($query);
    $stmt->execute();

    echo "Đã tạo bảng {$table}\n";
}
```

* Loops through the schema and **builds SQL column definitions**.
* Constructs a **CREATE TABLE SQL statement** using `utf8mb4` charset.
* Executes the query to **create the table** in MySQL.

## `updateTable()` **- Update Table Schema**

```php
protected function updateTable($table, $schema) {
    $currentColumns = $this->getCurrentColumns($table);
    foreach ($schema as $column => $attributes) {
        if (!array_key_exists($column, $currentColumns)) {
            $this->addColumn($table, $column, $attributes);
        } else if ($this->needsModification($column, $currentColumns[$column], $attributes)) {
            $this->modifyColumn($table, $column, $attributes);
        }
    }
}
```

* Retrieves the **current column list** of the table.
* If a column **does not exist**, calls `addColumn()`.
* If a column **needs modification**, calls `modifyColumn()`.

## `getCurrentColumns`**`()` - Get Current Table Columns**

```php
protected function getCurrentColumns($table) {
    $query = "SHOW COLUMNS FROM {$table}";
    $stmt = $this->db->prepare($query);
    $stmt->execute();
    return $stmt->fetchAll(\PDO::FETCH_ASSOC);
}
```

* Executes the `SHOW COLUMNS` SQL command to **retrieve all columns** in a table.

## Example:

If you want to create a new Table and named as 'user',mMake sure you have the `UserModel.php` file in the `application/Models` directory with the following content:

```php
<?php
namespace App\Models;

use System\Core\BaseModel;

class UserModel extends BaseModel {

    protected $table = 'users';

    /**
     * Định nghĩa schema của bảng
     */
    public function _schema() {
        return [
            'id' => [
                'type' => 'INT',
                'auto_increment' => true,
                'key' => 'primary'
            ],
            'name' => [
                'type' => 'VARCHAR(255)',
                'null' => false
            ],
            'email' => [
                'type' => 'VARCHAR(255)',
                'null' => false,
                'key' => 'unique'
            ],
            'created_at' => [
                'type' => 'TIMESTAMP',
                'default' => 'CURRENT_TIMESTAMP'
            ]
        ];
    }
}
```

Then run the following command:

```
php init table user
```

And the result:

```sql
CREATE TABLE `users` (
    `id` INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    `name` VARCHAR(255) NOT NULL,
    `email` VARCHAR(255) NOT NULL UNIQUE,
    `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

-- Table "users" has been created successfully.
```


# Block Command

The provided code is part of the `BlockCommand` class within the `System\Commands` namespace. This class has a method `create` that is responsible for creating a new block file and a default view file for that block.

## `create()`

```php
public function create($blockName)
    {
        // Define the path for the new model
        $blockName = ucfirst($blockName);
        $blockPath = ROOT_PATH . '/application/Blocks/' . ucfirst($blockName) . '/' . ucfirst($blockName) . 'Block.php';
        $blockViewsPath = ROOT_PATH . '/application/Blocks/' . ucfirst($blockName) . '/Views/index.php';

        // Check if the model already exists
        if (file_exists($blockPath)) {
            echo "Block {$blockName} already exists.\n";
            return;
        }

        // Define the contents of the block controller
        $blockContent = // Block File Structure

        // Create the block control file
        $blockDir = dirname($blockPath);
        if (!is_dir($blockDir) && !mkdir($viewsDir11, 0777, true) && !is_dir($blockDir)) {
            echo "Can not create {$blockName} folder.\n";
            return;
        }
        file_put_contents($blockPath, $blockContent);

        // create block default view
        $viewsDir = dirname($blockViewsPath);
        if (!is_dir($viewsDir) && !mkdir($viewsDir, 0777, true) && !is_dir($viewsDir)) {
            echo "Can not create Views folder.\n";
            return;
        }
        file_put_contents($blockViewsPath, '');


        echo "Block {$blockName}Block has been created successfully.\n";
    }
```


# Welcome CMS Full Form

The CMS is a powerful and flexible content management system designed to help users create, manage, and customize their websites efficiently. It provides a wide range of features, ensuring ease of use and adaptability for different types of web projects.

By building on PHPFast, CMS Full Form combines modern development practices with real-world performance and reliability — empowering developers and non-developers alike to create powerful websites with confidence.

***

## **Comparison**

<table data-header-hidden data-full-width="true"><thead><tr><th width="152"></th><th width="193"></th><th width="198"></th><th width="178"></th><th></th></tr></thead><tbody><tr><td><strong>Criteria</strong></td><td><strong>CMS Full Form</strong></td><td><strong>WordPress</strong></td><td><strong>Joomla</strong></td><td><strong>Drupal</strong></td></tr><tr><td><strong>Page Load Speed</strong></td><td>Up to 70x faster thanks to lightweight architecture, no plugin dependency</td><td>Average – often slowed by heavy plugins</td><td>Average – more complex structure</td><td>Heavy – requires advanced optimization</td></tr><tr><td><strong>Security</strong></td><td>Built-in advanced security, no plugin required</td><td>Relies on third-party plugins</td><td>Basic security, needs add-ons</td><td>Strong but complex to configure</td></tr><tr><td><strong>Admin Interface (UX/UI)</strong></td><td>Intuitive drag-and-drop, easy for non-tech users</td><td>Fairly easy with many menus</td><td>Complicated for beginners</td><td>Technical interface, hard for newcomers</td></tr><tr><td><strong>SEO &#x26; Marketing</strong></td><td>AI-powered SEO + built-in email marketing automation</td><td>Requires plugins like Yoast SEO, Mailchimp</td><td>Needs SEO &#x26; marketing plugins</td><td>Limited, manual setup required</td></tr><tr><td><strong>Scalability &#x26; Stability</strong></td><td>Microservices-based, highly scalable &#x26; performant</td><td>Scalable via plugins but prone to conflicts</td><td>Decent scalability but often buggy</td><td>Very stable, but technically demanding</td></tr></tbody></table>

***

## Key features

* Intuitive and modern admin interface for effortless content management
* Drag-and-drop layout builder with live preview support
* Built-in multilingual system for global-ready websites
* Flexible content control with publish/unpublish and scheduling tools
* Modular architecture for easy customization and scalability
* Role-based access control and user permission management
* Integrated SEO tools with AI suggestions and real-time scoring
* Optimized for high performance, speed, and mobile responsiveness
* Smart backup system with one-click restore and cloud sync
* Native plugin ecosystem with one-click installs and seamless updates

***

## Why Choose **CMS Full Form** over others?

#### Superior Performance

Lightweight core, smart caching, and no plugin bloat.\
→ Up to 70x faster than default WordPress.

#### Modern, User-Friendly Interface

Minimal UI with intuitive drag-and-drop and live preview.\
→ No coding needed – anyone can use it.

#### Smart Modular System

Independent, lightweight modules that don’t slow you down.\
→ No more 10 plugins for one feature.

#### Built-in Security

OWASP-based, XSS/SQLi protection, safe auto-updates.\
→ Say goodbye to shady third-party plugins.

#### Integrated AI and Automation

SEO suggestions, content generation, backups, image optimization, and user behavior insights.\
→ Smarter workflows, less manual effort.

***

## Plugin Ecosystem

CMS Full Form comes with a growing library of native plugins – designed to meet real-world needs without the bloat. Unlike WordPress, which often requires dozens of third-party plugins (and potential compatibility nightmares), our ecosystem is **clean, secure, and fully optimized** for performance.&#x20;

[See](/overview/install) more at [Plugins](/cms/views/plugins).

***

## **Content list in CMS Full Form**

* [**Installation**](/cms/install)  – A streamlined process for setting up the CMS quickly and efficiently.
* [**Posttype**](/cms/posttype) – Allows users to create and manage custom Post Types with various attributes, including multilingual support.
* [**Settings**](/cms/options) – A centralized section to configure the CMS according to your needs.
* [**Languages**](/cms/languages) – Enables multilingual support to manage content in different languages.
* [**Database**](/cms/database) – Provides tools for managing and interacting with the database.
* [**Templates**](/cms/views) – A collection of pre-built templates for flexible design and layout customization.
* [**Blocks**](/cms/blocks) – Modular content components that can be reused across the website.
* [**Events** ](/cms/events)– A system to manage events and trigger actions within the CMS.
* [**Helpers**](/cms/helpers) – A set of utility functions to simplify and speed up development.


# Installation CMS

## **Download CMS Full Form from PHPFast**

1. Visit the official **PHPFast** page at <https://cmsfullform.com/download> or the source to download the CMS Full Form source code.
2. Download the latest version of **CMS Full Form** (in .zip or .tar.gz format)
3. **Extract** the file and check that the files are extracted into the correct directory.

***

## Install CMS Full Form

* After successfully installing and extracting the files, place the extracted files into your **public** folder.&#x20;
* Create new folder and name `themes` in the `root` folder, copy folder `default` from `application/views/default` to `themes`.
* Change the configuration in `application/Config/Config.php`:

```php
'theme' => [
        'theme_path' => 'themes',
        'theme_name' => 'default'
    ]
```

* Then, navigate to the following URL: `http://yourdomain.com/install`

{% hint style="warning" %}
Note

Users are free to rename the **themes** folder to suit their preferences. However, ensure that you update the `theme_path` in `application/Config/Config.php` to match the new folder name. This ensures that the CMS correctly locates and applies your chosen theme.
{% endhint %}

Follow these detailed steps to ensure a successful installation:

***

<figure><img src="/files/HXwflNQhB8ZxuJF0jYR3" alt=""><figcaption></figcaption></figure>

### Step 1: Database Configuration

1. **Enter Database Information:**
   * **Database Host:** Enter the host name (e.g., localhost).
   * **Database Name:** Enter the name of the database you wish to use.
   * **Database Username:** Enter the database username.
   * **Database Password:** Enter the corresponding password.
2. **Test Connection:**
   * Click the **Test Connection** button to verify that the information you entered is correct.
   * If the connection is successful, the button to proceed to the next step will be activated.
   * If the connection fails, recheck your information and try again.
3. **Proceed to the Next Step:**
   * Once the connection is successful, click the **Next** button to continue.

***

<figure><img src="/files/0WdVHeaSWrWxsCDNV49j" alt=""><figcaption></figcaption></figure>

### Step 2: Website Configuration

1. **Enter Website Information:**
   * **Brand Website:** Enter the website’s brand name or title.
   * **Website URL:** Enter the full website URL (e.g., `http://yourdomain.com`).
   * **Site Email:** Enter the website email for notifications and contact purposes.
   * **Theme:** Select your desired theme from the list of available themes (this will determine your website’s appearance).
2. **Save Website Configuration:**
   * After filling in all the required fields, click **Next** to proceed to the next step.

***

<figure><img src="/files/XTvaTQb8gz0tmgL3VPtN" alt=""><figcaption></figcaption></figure>

### Step 3: Admin Account & Advanced Configuration

1. **Set Up the Admin Account:**
   * **Admin Username:** Enter the username for the admin account.
   * **Admin Email:** Enter the admin’s email address.
   * **Admin Password:** Enter a secure password for the admin account.
2. **Mail Configuration:**
   * **SMTP Host:** Enter the SMTP server address (e.g., smtp.yourdomain.com).
   * **SMTP Port:** Enter the SMTP port number (e.g., 587 or 465).
   * **SMTP Username:** Enter the SMTP account username.
   * **SMTP Password:** Enter the SMTP account password.
   * **Purpose***:* These settings allow the system to send notifications, password recovery emails, and other related functions.
   * **Test Mail**: Click the **Test Mail** button to verify that the information you entered is correct.
3. **Files Configuration:**
   * **File Storage Path:** Enter the server path where uploaded files will be stored (e.g., `/public/uploads`).
   * **Allowed File Formats:** List the allowed file formats (e.g., jpg, png, pdf, docx, etc.).
   * **File Size Limit:** Specify the maximum allowed file size (e.g., 2MB or 5MB).
   * **Purpose***:* This configuration ensures that file uploads comply with the specified format and size requirements.
4. **Save Admin & Advanced Settings:**
   * After entering all the required information, click **Next** to move to the final step.

***

<figure><img src="/files/KutOoydcIN4CfaFF3vtz" alt=""><figcaption></figcaption></figure>

### Step 4: Roles Configuration

1. **Configure User Roles:**
   * Confirm that the default Admin account you created has full access to all CMS Full Form functionalities.
   * If desired, create additional roles for other users with specific permissions.
   * A list of available permissions will be displayed, and you can adjust them as needed.
2. **Complete Installation:**
   * After reviewing and confirming all settings and permissions, click **Install** to complete the installation process.

{% hint style="warning" %}
Important

After successful installation, the system will automatically delete the **install.php** file. Please verify that this file has indeed been removed to ensure security. Once confirmed, you may choose to rename the newly created folder or leave it as is—depending on your preference. Be sure to update the configuration file accordingly so that it accurately reflects your system's folder structure and settings.
{% endhint %}


# CMS Dashboard

The CMS Dashboard is your dynamic control center, inspired by WordPress, designed to give you full oversight of your website's performance. It allows you to customize your workspace by simply dragging and dropping various data blocks—each pulling real-time insights from key metrics such as user activity, post types, revenue, and more.

***

## Key Features

In CMS Dashboard, you can:

* **Drag-and-Drop Customization:**\
  Rearrange dashboard blocks to create a layout that suits your workflow. Whether you want a quick snapshot of user activity or detailed revenue trends, simply drag the blocks into your desired order.
* **Data Aggregation & Analysis:**\
  The dashboard automatically compiles data from various parts of your site. Choose the metrics you care about—like new user registrations, post statistics, and sales figures—and see them displayed in interactive charts, graphs, or tables.
* **Detailed Insights:**\
  Click on any block to drill down into more detailed statistics. For instance, clicking on the "Users" block might reveal user demographics, activity logs, and registration trends. Similarly, the "Post Types" block can show which content types are most engaging, while the "Revenue" block provides detailed sales analytics.
* **Customizable Data Fields:**\
  You have full control over which data points are shown. During setup, select the fields you want to track. This ensures that the dashboard reflects the specific metrics that matter most to your business.
* **Real-Time Updates:**\
  The dashboard is designed to update dynamically as new data comes in. This ensures you always have the latest information at your fingertips without needing to refresh the page manually.

## How to Use the CMS Dashboard?

1. **Access the Dashboard:**\
   Log in to your CMS Full Form Admin Panel and navigate to the Dashboard. You'll be greeted by a clean, intuitive interface that displays a default set of blocks.
2. **Customize Your Layout:**
   * **Drag and Drop:** Click and hold any block, then drag it to your preferred position on the screen.
   * **Add/Remove Blocks:** Use the settings menu to add new blocks or remove those that are not relevant to your current needs.
3. **Configure Data Sources:**
   * Open the configuration panel for any block to choose which data fields it should display.
   * Select from various data sources, such as user metrics, post statistics, or sales data, to ensure the block provides the insights you need.
4. **Interact with Detailed Reports:**
   * Click on any block for a more detailed view.
   * Explore interactive charts, tables, and graphs that break down the data further, allowing you to analyze trends and make informed decisions.
5. **Save Your Layout:**\
   Once you’re satisfied with your custom dashboard layout, save your configuration. Your personalized dashboard setup will be retained for future sessions

{% hint style="success" %}
Conclusion

By leveraging the CMS Dashboard, you can keep a pulse on your website’s performance and adapt quickly to new trends. This feature brings the power of data-driven insights to your fingertips—because when it comes to managing your site, you deserve a dashboard that works as hard as you do. Enjoy building a dashboard that’s uniquely yours—your website, your rules!
{% endhint %}


# CMS Posttype

CMS Posttype is a powerful tool that allows you to create and manage custom Post Types within your CMS system. With this feature, you can:\
**Add new Post Types** tailored to your website's content.\
**Edit existing Post Types** to adjust them to your needs.\
**Customize data fields** (Custom Fields) for each Post Type.\
**Manage display settings** and URL structures for each Post Type.

***

## Manage Post Type

When you access the **CMS Posttype** page, a list of all existing Post Types will be displayed. Each Post Type includes the following details:

<table data-header-hidden><thead><tr><th width="193.99993896484375"></th><th></th></tr></thead><tbody><tr><td><strong>Field</strong></td><td><strong>Description</strong></td></tr><tr><td><strong>ID</strong></td><td>Unique identifier for the Post Type</td></tr><tr><td><strong>Name</strong></td><td>The name of the Post Type</td></tr><tr><td><strong>Slug (URL)</strong></td><td>The URL structure for the Post Type</td></tr><tr><td><strong>Languages</strong></td><td>The supported languages for the Post Type</td></tr><tr><td><strong>Status</strong></td><td>Indicates whether the Post Type is active or inactive</td></tr><tr><td><strong>Actions</strong></td><td>Options to edit, copy, or delete the Post Type</td></tr></tbody></table>

<figure><img src="/files/hRUsNgycQWK6VpgNQztN" alt=""><figcaption></figcaption></figure>

### **Available Actions for Each Post Type**

* **Change Status**: Toggle between **Active** and **Inactive**.
* **Edit**: Modify the existing Post Type details.
* **Copy**: Duplicate an existing Post Type to create a new one.
* **Delete**: Permanently remove the Post Type.

### **Step-by-Step Guide**

**Changing Status**

* Click on the **Status** toggle button next to the Post Type.
* The status will switch between **Active** (Show) and **Inactive** (Hidden).
* Inactive Post Types will not be available for content creation.

**Editing a Post Type**

* Click the **Edit** button next to the Post Type.
* Modify any details, including **Name, Slug, Languages, Custom Fields, or Categories**.
* Click **Save** to update the Post Type.

**Copying a Post Type**

* Click the **Copy** button next to a Post Type.
* A new Post Type will be created with the same settings.

**Deleting a Post Type**

* Click the **Delete** button next to a Post Type.
* Confirm the deletion in the pop-up warning.\
  **Note:** This action will permanently delete the Post Type and all related data.

***

## **How to Add a New Post Type**

#### **Access CMS Posttype**

* Log in to the CMS system.
* Navigate to **Posttype** in the admin menu.

#### **Click "Add New"**

* A configuration panel will appear with the following options:

<table data-header-hidden><thead><tr><th width="186.5999755859375"></th><th width="602.3997802734375"></th></tr></thead><tbody><tr><td><strong>Field</strong></td><td><strong>Description</strong></td></tr><tr><td><strong>Post Type Name</strong></td><td>Define the Post Type name</td></tr><tr><td><strong>Menu options</strong></td><td>Choose a options (e.g., Hide Menu, Root Menu, Child Menu, ...)</td></tr><tr><td><strong>Slug (URL)</strong></td><td>Define the URL path for the Post Type</td></tr><tr><td><strong>Languages</strong></td><td>Choose the available languages for this Post Type (en, vi, cn)</td></tr><tr><td><strong>Status</strong></td><td>Choose <strong>Active</strong> (Show) or <strong>Inactive</strong> (Hidden)</td></tr><tr><td><strong>Categories</strong></td><td>Allow custom terms such as: Search keywords, SEO title,...</td></tr><tr><td><strong>Custom Fields</strong></td><td>Add specific data fields for this Post Type</td></tr></tbody></table>

#### **Save and Activate**

* Click **Save** to complete the process.
* The new Post Type will now appear in the content management menu.

<figure><img src="/files/BfY0GCxuHw0mDDP2416C" alt=""><figcaption></figcaption></figure>

***

## **How to Edit a Post Type**

#### **Select the Post Type to Edit**

* Go to **CMS Posttype**.
* Choose the **Post Type** you want to edit.

#### **Modify the Details**

* You can change the **name, slug, menu options**, **languages** or **status**.
* If you need to add **Categories**, click **"Add Term"** and enter the required details.
* If you need to add **Custom Fields**, click **"Add Field"** and enter the required details.

#### **Save Changes**

* After making adjustments, click **Save** to update the Post Type.

<figure><img src="/files/zdo81pvkpluAd1giOwHl" alt=""><figcaption></figcaption></figure>


# CMS Settings

In **CMS Full Form**, the Settings section plays a crucial role in configuring and managing the overall operation of the website. These settings not only help you adjust the basic elements of the website but also allow customization of the interface and features to meet user needs. **CMS Full Form** offers two main categories of settings:&#x20;

## [**Site Settings**](/cms/options/site-settings)

**Site Settings** allows you to configure basic website information and functionality, such as the site logo, description, name, SEO settings, meta tags, and menu management. It also includes settings for authentication scripts, SMTP configuration for email, and optimization for search engines.

## [**Theme Settings**](/cms/options/theme-settings).

**Theme Settings** enables you to customize the website’s appearance, including layout, menu structure, colors, and others. This section helps you tailor the design and user experience to match your brand and needs.


# Site Settings

CMS Full Form is a powerful content management system that allows you to easily create, organize, and manage website content. This CMS supports various content types such as menu, watermark, cache and more.

This section helps you how to manage and setting for your website.

***

<figure><img src="/files/kmpJJNPs3ktCCxpjFSXB" alt=""><figcaption></figcaption></figure>

## General

* **Search engine visibility:** Show or hidden search engine.
* **Date format & Time format:** Custom display date & time.
* **Site Title:** The title of the website.
* **Site Desc:** Description for your website.
* **Brand Name:** The name of the website.

## Meta & SEO

* **Meta Title:** SEO title of the website.
* **Meta Description:** A short description of the website.
* **Keywords:** SEO keywords to improve Google ranking.

## Menu

* Manage the website navigation menu.
* Add, edit, or delete menu items.
* Drag and drop to rearrange the menu order.

## Auth Social & SMTP

* **Social Login:** Connect with Google, Facebook, Twitter for login.
* **SMTP:** Configure email sending, including host, port, username, and password.

## Scripts & Styles

* Manage script integrations like Google Analytics, Facebook Pixel.
* Upload or add custom CSS/JS.

## Watermark

* **Enable/Disable watermark:** Add a logo to uploaded images.
* **Watermark Position:** Choose where the logo appears on images.

## API Config

* Configure API keys for third-party services.
* Manage API connections with other applications.

## Frontend Config

* Configure frontend appearance.
* Customize colors, fonts, and website layout.

## &#x20;Cache

* Configure the caching system (Redis, File, Uri).
* Set cache storage duration.
* Set the level to cache (0-9).

## Home

* Configure the homepage settings.
* Arrange the layout for displaying content on the homepage.

## Custom Settings

<figure><img src="/files/dGHee7ZDCwWWEin8WRLn" alt=""><figcaption></figcaption></figure>

### **Access the Admin Panel**

1. **Log in** to the **Admin Panel** of CMS Full Form using your admin credentials.
2. Once logged in, you will be redirected to the **Dashboard**.

### **Go to "Site Settings" Tab**

1. In the left-hand menu, find and select **Site Settings**.
2. In the **Site Settings** section, you will see the existing settings for your website.

### **Add a New Option**

1. Within the **Site Settings** section, click on **Add Options** to start adding a new option for your website.
2. A form will appear, asking you to fill in information for the new option.
   * **Field Type**: Select the field type you want to use for this option. For example, you can choose from types like **Text**, **Select**, **Checkbox**, etc.
   * **Option Group**: Choose the group that this option will belong to. This helps in organizing options into manageable groups.
   * **Label**: Enter the display name for this option. This will be the label seen by the admin when creating or editing settings.
   * **Other Values**: Fill in any additional values and settings for this option (e.g., default values, choices for select fields, or additional descriptions).

### &#x20;**Save the Option**

1. After filling in all the required fields, click **Save** to store the new option.
2. The new option will be added to the system and will be available for use in other parts of CMS.

### **Result**

After saving, you will see the new option listed in **Site Settings**, and you can apply or modify it later. The changes will be automatically updated on your website.


# Theme Settings

CMS Full Form allows users to personalize the appearance of their CMS by modifying the theme settings. The customization options include:

<figure><img src="/files/D99Lw7pdcC05vDspEHWY" alt=""><figcaption></figcaption></figure>

## Theme Mode

* Choose between **Light Mode** and **Dark Mode** for a comfortable viewing experience.
* Dark Mode helps reduce eye strain and is ideal for low-light environments.

## Theme Contrast

* Adjust the contrast level to enhance visibility and accessibility.
* Options include **Low Contrast** and **High Contrast**.

## Custom Theme

* Users can modify theme colors to match their branding.
* Choose available colors in CMS.

## Theme Layout

* Select from different layout structures such as **Vertical**, **Horizontal**, or **Tab**,...
* The layout choice affects content positioning and responsiveness.

## Sidebar Layout

* Select from different layout for menu such as **Right** or **Left**,...
* Depends on your choice and choose your custom.

## Sidebar Caption

* Enable or disable sidebar captions to improve navigation visibility.
* Helps users quickly identify sections in the sidebar.

## Layout Width

* Adjust the overall width of the CMS interface.
* Options include **Full Width** or **Container** layouts.

## How to Choose the Right Theme

1. **For Business or Corporate Use:** Choose a clean, professional theme with **light mode** and **high contrast**.
2. **For Developers and Night Users:** Dark mode with custom colors enhances focus and reduces eye strain.
3. **For Content Creators:** A fluid layout with sidebar captions helps manage a large volume of content efficiently.
4. **For Personal Use:** Custom theme colors and a boxed layout create a personalized experience.


# CMS Languages

CMS Languages in CMS Full Form is a ultimate tool for creating and managing languages on website. With this feature, you can tailor the display of your post types to match the selected language settings, giving your site that international vibe.

<figure><img src="/files/fgpRJIdE1A3B3ce6RuSw" alt=""><figcaption></figcaption></figure>

***

## How to change and add a new language in CMS Full Form?

### **Add a new language**

If you want to add a new language to CMS Full Form, follow these steps:

1. Log in to the CMS Full Form admin panel.
2. In the left menu, select **Languages**
3. Here, you will see the languages already configured. Click on the **Add Language** button.
4. You will need to provide the following information:
   * **Language Name**: Enter the name of the new language (e.g., Vietnamese, English, Japanese, etc.).
   * **Language Code**: Choose the appropriate language code (e.g., `en` for English, `vi` for Vietnamese, etc.).
   * **Language Status**: Enable or Disable to display on template.
5. Click **Save** to add the new language to the system.

After the new language is added, you can go back to the **Language Settings** section and select it as the default language or use it for specific pages or users.

***

### **Change the current language**

Once you have configured a new language in CMS Full Form, you can change the language displayed on your website by following these steps:

1. Log in to the CMS Full Form admin panel.
2. In the left menu, find and click on **Languages**.
3. Here, you will see a list of the languages that have already been configured for the website.
4. Select the new language you want to use from the list.
5. Click **Save** to apply the new language to the entire website.

Once completed, the CMS interface and content will be displayed in the language you selected

***

### **Change the Default Language**

To change the default language on the website:

1. Go to **Languages**.
2. In the list of languages, select the **default language** you want to apply to the entire website.
3. Click **Save** to apply the changes.

After changing the default language, the pages and elements on the website will be displayed in the language you selected.

***

## How to use Multilingual?

<figure><img src="/files/YFCJnunNN1ICf1iwJ7oM" alt=""><figcaption></figcaption></figure>

### Create a New Post Type

* **Navigate to Post Types:**\
  Log in to your Admin Panel, go to the “Post Types” section, and click on **Add New.**
* **Enter Basic Details:**\
  Fill in the necessary information for your new post type (e.g., name, description).

***

### Add Content for **Post Type** in Each Language

* **Go to Post type you want to add content;**

  Choose the language which you want to add content or Post type.
* **Language-Specific Fields:**\
  Once you select your languages, separate input fields will appear for each language.
  * **Title & Content:** Fill in the title, description, and any other relevant content for each language.
  * **Additional Fields:** Complete any extra fields as required for each language version.
* **Save Your Post Type:**\
  After filling in the content for every selected language, click **Save** to finalize your new post type.

***

### Enable Multilingual Support

* **Activate Multilingual Option:**\
  On the post type creation page, look for the **Enable Multilingual** toggle or checkbox and turn it on.
* **Select Applicable Languages:**\
  A list of available languages will appear. Choose the languages you want to support for this post type. This step ensures that your post type can display content in multiple languages.

***

### How It works

* **Automatic Data Loading:**\
  When a user switches the website’s language, the system automatically loads the corresponding content based on the language-specific data you provided.
* **Seamless User Experience:**\
  This setup ensures that every visitor sees your post types in the language they prefer, making your website more accessible and engaging.

***

### Important Notes

* **Content Synchronization:**\
  Ensure that the content for each language is complete and properly synchronized to avoid display inconsistencies.
* **Default Fallback:**\
  If a translation is missing, the system may fall back to a default language. Keep this in mind when planning your content strategy.
* **Testing:**\
  Always preview your new post type in each language to verify that everything loads correctly and appears as intended.


# CMS Database

In CMS Full Form, the **CMS database** is where all the data for your website is stored, including languages, posttype, terms, users, settings, and other options. CMS Full Form typically uses **MySQL** or **MariaDB** as its database management system.

***

## Default tables

The structure of the CMS Full Form database includes several important tables. Some of the key tables in the CMS database include:

### fast\_comments

This table stores all the comments made by users on posts or pages. It typically contains fields like the comment content, the user who made the comment, the post/page it is associated with, and timestamps.

### fast\_files

This table is used for storing information about uploaded files on your site. It may store data such as the file name, file type, size, file path, and the user who uploaded it.

### fast\_languages

This table holds language settings for your site. It allows you to manage and store multiple languages, enabling multilingual support for your site.

### fast\_options

This table stores site-wide settings and configuration options. It may include general settings such as site name, logo, default language, SEO settings, and other custom configuration options.

### fast\_posttype

This table is used to define custom post types for the CMS. It allows you to create custom content types beyond the default posts and pages (e.g., products, events, etc.), providing more flexibility for content management.

### fast\_terms

The `fast_terms` table stores terms used for categorization, like tags and categories. These terms are used for categorizing and organizing posts or other content types.

### fast\_users

This table stores information about the users of the website. It contains data like usernames, passwords (hashed), roles (e.g., admin, editor, user), and other user-related details.

## Configuring the Database

To configure the database in CMS Full Form, you'll need to set up the database connection in the `Config.php` file, which is located in the `application/Config/` folder. Below is an example of how to configure the database settings:

```php
<?php
'db' => [
    'db_host'     => 'localhost',                // The database host, typically 'localhost'
    'db_username' => 'your_database_user',       // Your database username
    'db_password' => 'your_database_password',   // Your database password
    'db_database' => 'your_database_name',       // Your database name
    'db_driver'   => 'mysqli',                   // The database driver, typically 'mysqli' for MySQL
    'db_port'     => 3306,                       // The port number for the MySQL connection, default is 3306
    'db_charset'  => 'utf8mb4',                  // The character set for the connection, utf8mb4 is recommended
    'db_collate'  => 'utf8mb4_unicode_ci',       // The collation for the connection
],
```

#### Configuration Parameters:

* **db\_host**: The host where the database server is located. Typically, it is `localhost`, but if you're using a remote server, you will need to specify the host address.
* **db\_username**: The username for connecting to the database.
* **db\_password**: The password for the database user.
* **db\_database**: The name of the database you are using for your PHPFast CMS.
* **db\_driver**: This specifies the database driver. For MySQL databases, you will typically use `mysql` or `mongodb` as the driver. (Or you can see [Database ](/documents/drivers/database)to details)
* **db\_port**: The port number used for the database connection. The default MySQL port is `3306`.
* **db\_charset**: The character set for the database connection. It is recommended to use `utf8mb4` to ensure proper support for all characters, including emojis.
* **db\_collate**: The collation for the database connection. `utf8mb4_unicode_ci` is commonly used as it supports a wide range of characters and sorts them correctly.

After configuring the database settings in `Config.php`, PHPFast should be able to connect to the database and use the default tables (e.g., `fast_comments`, `fast_users`, etc.) for storing and retrieving data.


# CMS Templates

In **CMS Full Form**, **Templates** are the foundation for building and customizing any website quickly and efficiently.

A Template includes two key components:

## **Themes** – The Look & Feel

Themes define the visual appearance of your website. From layout structure to colors, fonts, and UI components – everything is crafted to be clean, modern, and responsive.\
→ Easily customize to match your brand – no coding required.

## **Plugins** – The Power & Functionality

Plugins add features and capabilities to your website, such as SEO tools, eCommerce systems, contact forms, analytics, and more.\
→ Each plugin is lightweight, secure, and fully integrated with CMS Full Form.

Together, [themes](/cms/views/themes) and [plugins](/cms/views/plugins) inside CMS Templates give you everything you need to launch fast, scale smart, and deliver a seamless experience — both for you and your visitors.

***


# Themes

## **Choose themes**

**CMS Full Form** provides several **default themes**, allowing users to select and apply them to their website. These themes are designed to meet various needs, from simple blogs and corporate websites to more complex eCommerce sites.

#### **Steps to choose a theme:**

1. **Access the Theme Management Section**:\
   In the **Admin Panel**, go to **Settings** and select **Theme Settings**.
2. **Choose Your Desired Theme** :\
   In the **Theme** section under settings, you will see a list of available themes. Simply select the one you want to apply to your website.
3. **Apply the Theme**:\
   After choosing the themes, click **Save** to apply the theme to your website. The website's interface will instantly change according to the selected theme.

***

## **Customize Theme**

Once you have chosen a theme, you can customize it to suit your personal needs and preferences. **CMS Full Form** allows you to modify various elements of the theme, such as colors, fonts, layouts, and other UI components.

#### **Steps to customize the theme:**

1. **Edit Layout**:\
   You can change the website's layout, including areas like the header, footer, sidebar, and other sections of the page. Modifying the layout helps you create a website that suits your purpose and provides easy navigation for users.
2. **Customize Colors and Fonts**:\
   **Theme Settings** allows you to adjust the colors, including background, text, and link colors. You can also change the font used for various elements on the site to create a unique style.
3. **Modify Menus**:\
   You can customize the main and secondary menus on the website, including adding new links, rearranging them, or removing unnecessary items. This helps users navigate the website more easily.
4. **Set Logo and Favicon**:\
   The **Logo** and **Favicon** are key elements in brand recognition. You can upload your logo and favicon to give the website a professional and cohesive look.
5. **Customize Blocks**:\
   **CMS Full Form** supports blocks to display elements like recent posts, categories, or contact information. You can customize the blocks to highlight content you want to emphasize on your website.

***

## **Create New Theme**

In addition to choosing from existing themes, **CMS Full Form** also allows you to create and upload your custom themes. This gives you full flexibility to design the look and feel of your website exactly how you want it. Here's how you can upload and apply your own theme:

**Step 1: Prepare Your Theme File**

* **Packaging:** Your theme must be packaged as a .zip file.
* **Required Structure:** Make sure your .zip file includes all the necessary files such as `style.css` (which contains metadata like the theme name, version, etc.) and `index.php`, along with any other related files. Missing any crucial file might cause the theme to malfunction.

**Step 2: Access the Upload Theme Section**

* Log in to your Admin Control Panel.
* Navigate to the **Themes** section and select “Upload Theme.” It’s as straightforward as installing a new plugin.

**Step 3: Upload the Theme File**

* Click “Choose file” and select your .zip file.
* Then click “Upload” to send the file to the system.

**Step 4: Verification and Installation**

* The system will automatically unzip the file and check its structure. If everything is in order, the theme will be saved in the themes folder.
* If there’s an error (like a missing `style.css` or incorrect structure), the system will display a clear error message so you know exactly what to fix. You can explore errors at next section.

**Step 5: Activate the Theme**&#x20;

* Once the upload is successful, your new theme will appear in the themes list.
* Click “Preview” to see it in action.
* If you’re satisfied, hit “Activate” to make it live on your website.\\

***

## Common **Theme** Upload Errors

**Theme Name Not Updated in Config.php:**\
Failing to update the theme name in the Config.php file can prevent the system from correctly identifying your custom theme. This may lead to issues when trying to load or activate the theme.

**Corrupted or Invalid .zip File:**\
If your .zip file is damaged or not formatted properly as an archive, the system will fail to extract and process it, resulting in an error.

**File Permission Issues:**\
The server may not have the right permissions to write or extract files into the themes directory. This can halt the installation process and display a permission error.

**Incompatible PHP or CMS Version:**\
Your theme might rely on code or functions that aren’t supported by the current version of CMS Full Form or the PHP version running on your server, leading to compatibility issues.

**Missing Dependent Files or Assets:**\
If your theme depends on additional assets (like JavaScript files, images, or fonts) that are missing from the package, it could cause functionality or display errors once activated.

**Unsupported File Format:**\
CMS Full Form only supports .zip files for theme uploads. Trying to upload a file in another format (like .rar or .tar) will trigger an error.

**Incorrect View Folder Structure:**\
If the views folder's structure doesn't match the required hierarchy, the system won't be able to import the theme components properly. This misalignment can lead to errors when rendering pages, so make sure to follow the documented folder structure exactly. View more at [Application Structure](/framework-overview/application-structure#application).

**Mismatch in Parameters and Variables Structure:**\
Ensure that the structure of parameters and variables between the default theme and your uploaded theme is fully synchronized. Any discrepancies can lead to unexpected behavior or errors, as the system might expect specific settings or variables from the default theme that are missing or altered in your custom theme. Always cross-check your theme’s configuration with the default setup to maintain consistency.


# Plugins

In CMS Full Form, plugins are not just optional tools – they’re essential building blocks of functionality, designed to meet real-world needs without sacrificing speed, security, or simplicity.

Unlike traditional CMS platforms where third-party plugins often cause conflicts or slowdowns, every plugin in CMS Full Form is:

* Built to match the core system architecture
* Lightweight and performance-optimized
* Secure by default, no shady code
* Smart – with features like AI suggestions, automation, and analytics

## What Can Plugins Do?

Plugins let you extend your website’s functionality with just a few clicks. Whether you're running a blog, a business site, or a full-fledged e-commerce store, there’s a plugin for that.

Here are some popular categories:

* **SEO & Marketing** → Improve your visibility with CMSF SEO Pro, CMSF Newsletter
* **Content Tools** → Manage blogs, galleries, or dynamic sections effortlessly
* **E-commerce** → Power up your store with CMSF Ecom and product management tools
* **User Management** → Control access, roles, and permissions securely
* **Automation & Backup** → Schedule backups, sync with the cloud, automate campaigns
* **Analytics & Reports** → Track visitor behavior, conversions, and performance

→ All plugins are fully compatible, regularly updated, and built for stability.

## Plugins Featured

<table data-header-hidden data-full-width="true"><thead><tr><th width="161"></th><th width="413"></th><th></th></tr></thead><tbody><tr><td><strong>Plugin Name</strong></td><td><strong>Functionality</strong></td><td><strong>Why It Stands Out</strong></td></tr><tr><td><strong>CMSF SEO Pro</strong></td><td>Built-in SEO manager with AI keyword suggestions, meta editing, sitemap generation</td><td>No need for Yoast – faster, smarter, native</td></tr><tr><td><strong>CMSF Forms</strong></td><td>Drag-and-drop form builder for contact, survey, or custom forms</td><td>Lightweight, flexible, no extra scripts</td></tr><tr><td><strong>CMSF Blog+</strong></td><td>Advanced blogging tools with category management, related posts, featured images</td><td>Ideal for content-heavy sites</td></tr><tr><td><strong>CMSF Gallery</strong></td><td>Responsive image/video gallery with drag-to-sort, lightbox, and multi-upload</td><td>Built-in compression and lazy load</td></tr><tr><td><strong>CMSF Ecom</strong></td><td>Lightweight eCommerce engine – perfect for small-to-medium stores</td><td>Integrated checkout, inventory, discount codes</td></tr><tr><td><strong>CMSF Newsletter</strong></td><td>Email campaign builder with scheduling, templates, and analytics</td><td>No Mailchimp needed – own your data</td></tr><tr><td><strong>CMSF Analytics</strong></td><td>Simple but powerful dashboard analytics with traffic, behavior, and conversion tracking</td><td>Privacy-focused, no Google dependency</td></tr><tr><td><strong>CMSF User Roles</strong></td><td>Advanced user role editor &#x26; permission control</td><td>Easily manage who can do what</td></tr><tr><td><strong>CMSF Backup &#x26; Sync</strong></td><td>One-click manual or scheduled backup + cloud sync (Google Drive, Dropbox, etc.)</td><td>Peace of mind without config headaches</td></tr><tr><td><strong>CMSF Translator</strong></td><td>Live content translation editor with versioning support</td><td>Built for multilingual workflows</td></tr></tbody></table>


# CMS Blocks

CMS Blocks is a feature that allows you to create and manage content blocks on your website easily and flexibly. With CMS Blocks, you can insert content like text, images, ads, announcements, and custom content into specific locations on your website (e.g., header, footer, sidebar).

The CMS Blocks system in CMS Full Form enables you to manage these blocks without the need for editing the source code, all through an easy-to-use admin interface.

***

## How to Create and Manage CMS Blocks

### **Log In to the Admin Panel**

To create and manage CMS Blocks, you need to log in to your website’s admin panel.

1. Go to Admin Panel URL (e.g., `http://yourwebsite.com/admin`).
2. Enter your username and password to log in.

### **Go to the CMS Blocks Management Section**

Once logged in, you will be redirected to the dashboard. To manage your CMS Blocks, follow these steps:

1. From the left-side menu, click on **CMS Blocks Management** (or a similar name).
2. You will be taken to the page where you can view and manage all created blocks.

### **Create a New CMS Block**

1. On the CMS Blocks management page, click on the **Add New** button.
2. A form will appear, requesting you to enter the following block information:
   * **Block Name**: Enter a name for your block. This name helps you identify it when managing.
   * **Block Type**: Choose the type of block you want to create (e.g., Text, Image, Ads).
   * **Content**: Enter or paste the content for the block. If it's a text block, you can directly type or use the WYSIWYG (What You See Is What You Get) editor to format the text.
   * **Display Position**: Choose where the block should appear (e.g., Header, Footer, Sidebar).
3. After filling out all the information, click **Save** to create the block.

### **Manage CMS Blocks**

Once the block is created, you can perform the following actions:

1. **Edit Block**:
   * In the list of CMS Blocks, click on the block's name you want to edit.
   * Make the necessary changes and click **Update**.
2. **Delete Block**:
   * If you no longer need the block, click on the **Delete** button next to the block you want to remove.
3. **Display Block**:
   * Once created, the block will automatically display in the chosen location (Header, Footer, Sidebar). You can also check the result immediately on the website.

***

## **Tips for Using CMS Blocks**

* **Use different blocks** to make your website more engaging and interactive.
* **Optimize ad blocks** to avoid negatively affecting page load speed.
* **Check the layout on all devices** (PC, mobile, tablet) to ensure blocks display well across all screen sizes.

{% hint style="warning" %}
Note

**Security when using HTML**: If you add HTML to a block, ensure the content doesn’t contain malicious scripts or unsafe JavaScript.

**Optimize for SEO**: Use blocks to optimize your website’s SEO by adding keywords and proper descriptions in the content.
{% endhint %}


# CMS Events

The Events system in CMS Full Form allows you to execute custom actions when specific system events occur. This enables you to extend and customize the functionality of the CMS without modifying the core source code directly.

***

## Events Directory Structure

```plaintext
application/
└── Events/
    ├── Backend/
    │   ├── ExampleEvent.php
    │   └── ...
    └── Frontend/
        ├── ExampleEvent.php
        └── ...
```

* `Backend/`: Contains events related to the admin panel or backend operations.
* `Frontend/`: Contains events related to the public-facing side of the website.

***

## Creating a New Event

Inside the appropriate folder (`Backend` or `Frontend`), create a new PHP file for your event, e.g., `ExampleEvent.php`.

```php
<?php

namespace App\Events\Frontend;

use System\Libraries\Event;

class ExampleEvent extends Event
{
    public function __construct($data)
    {
        $this->data= $data;
    }

    public function handle()
    {
        // Perform an action when the event is triggered
        echo "CMS Full Form Event: Data: " . json_encode($this->data) . "<br>";
    }
}
```

* `$this->data`: Stores the data passed in when the event is triggered.
* `handle()`: This method contains the logic that should run when the event is executed.

***

## Using Event

```php
<?php
namespace App\Controllers\Frontend;

use System\Core\BaseController;

class UsersController extends BaseController
{
    public function index()
    {
        // Process data
        ........
        
        //------------------------------ Call 1 event ------------------------------
        // Setup data
        $data = "Welcome to CMS Full Form Event";
        
        // Call event
        \System\Libraries\Events::run('Frontend\ExampleEvent', $data);
        
        //--------------------------- Call Multiple event --------------------------
        $events = [
            'Frontend\ExampleEvent' => "Example Event",
            'Frontend\AnotherEvent' => "Another Event",
        ];
        
        \System\Libraries\Events::runs($events);
    }
}
```

***

{% hint style="warning" %}
**Note**

* **Use clear event naming:** Follow consistent naming conventions to make event management easier and more organized.
* **Handle exceptions within events:** Ensure that exceptions are properly caught and handled inside the `handle()` method to avoid disrupting the main application flow.
* **Optimize performance:** If the event performs heavy tasks, consider using a **queue system** to handle the process asynchronously.
  {% endhint %}


# CMS Files

CMS Files is your all-in-one media hub within CMS Full Form. It lets you upload, organize, and access your images, docs, videos, and more in a sleek, user-friendly space. Enjoy fast uploads, solid security, and a streamlined workflow—because your website, your rules!

***

* **All-in-One File Management:**\
  Instead of juggling multiple tools, CMS Files gives you one streamlined place to upload and manage all your files. This means less hassle and more time for creativity.
* **User-Friendly Interface:**\
  Designed with a clean and intuitive layout, the file manager is super easy to navigate. Even if you’re new to CMS Full Form, you’ll be able to find, upload, and organize files in just a few clicks.
* **Seamless Integration:**\
  CMS Files is built to work perfectly with the rest of CMS Full Form. Whether you're adding images to your posts, linking documents, or embedding media, it’s all set up to make your website run smoothly.
* **Quick and Efficient:**\
  The upload process is lightning-fast. No more waiting around—select your file, hit open, and it’s instantly available on your server. Plus, the system is smart enough to handle different file types and sizes, ensuring your content always looks top-notch.
* **Security and Reliability:**\
  Your files are stored safely, with built-in security measures that protect against unauthorized access and malicious uploads. You can focus on building your website without worrying about file vulnerabilities.

***

<figure><img src="/files/cgW9DjBgZTbcsu4Yk97m" alt=""><figcaption></figcaption></figure>

## Add a File

1. **Access Files Manager:**\
   Log in to your Admin Panel and head over to the **Files Manager** section.
2. **Upload a File:**\
   Click on the “Upload” button, select your file from your computer, and then hit “Open.”
3. **Confirmation:**\
   Once uploaded, your file will appear in the Files Manager, ready for you to use on your website.

***

## Delete a File

1. **Locate the File:**\
   Browse through your files in the Files Manager or use the search bar to find the specific file you want to remove.
2. **Delete the File:**\
   Click on the “Delete” button and cofirm to delete.
3. **File Removal:**\
   The file will be removed from your CMS, so double-check before confirming deletion.


# CMS Users

The CMS Users puts you in control. You can add, edit, or remove users and customize permissions so every person on your team gets just the right level of access. This way, your website stays secure, efficient, and exactly how you want it.

***

## Access the Users Manager

1. **Log In:**\
   Sign in to your Admin Panel with your admin credentials.
2. **Navigate to Users:**\
   In the main menu, click on **Users Manager** to access the Users Manager

***

<figure><img src="/files/ChczSovMjXfxzehnupNo" alt=""><figcaption></figcaption></figure>

## Add a New User

1. **Click “Add New User”:**\
   Once in the Users Manager, hit the “Add New User” button.
2. **Fill in User Details:**
   * **Username & Email:** Enter a unique username and valid email address.
   * **Password:** Set a strong password.
   * **Role/Permissions:** Assign the appropriate role that defines what this user can access (e.g., Add, Edit, Delete) in each module.
3. **Save:**\
   Click “Add” to add the new user to your system.

***

## Edit a User

1. **Find the User:**\
   Browse or search for the user you want to edit in the Users Manager.
2. **Edit Details:**\
   Click on the “Edit” button next to the user’s name. Update the necessary information—such as email, password, status, or permission.
3. **Save Changes:**\
   After making your edits, click “Save” to update the user’s profile.


# CMS Helpers

CMS Helpers in this system are a collection of utility functions designed to simplify frontend development and content management. These helpers provide essential functionalities for handling URLs, retrieving assets, managing posts, and optimizing images. By integrating these functions, developers can streamline their workflow, reduce redundant coding, and improve system performance.

***

CMS Helpers included:

#### [Frontend helper](/cms/helpers/frontend-helper)

Helper manages various types of URLs within the CMS, ensuring consistency and flexibility when accessing different parts of the system

#### [Images helper](/cms/helpers/images-helper)

Helper provides functions to optimize and manipulate images within the CMS. This ensures that images are handled efficiently, improving both loading speed and visual consistency


# Frontend helper

The `frontend_helper.php` file in the CMS provides helper functions for handling URLs and formatting data for the frontend. These functions facilitate the creation of dynamic URLs, number conversions, debugging data, and API URL construction.

***

#### **`base_url()`**

* **Purpose**: Returns the base URL of the application, including the language.
* **Parameters**:
  * `$path` (string): Additional path to append to `base_url`.
* **Usage**:

  <pre class="language-php"><code class="lang-php"><strong>echo base_url();
  </strong><strong>// Output: https://your_domain//
  </strong><strong>
  </strong><strong>echo base_url('dashboard'); 
  </strong><strong>// Output: https://your_domain/dashboard
  </strong></code></pre>

#### **`public_url()`**

* **Purpose**: Returns the URL of the `public` directory in the application.
* **Parameters**:
  * `$path` (string): File or folder path inside `public`.
* **Usage**:

```php
echo public_url(); 
// Output: https://your_domain/

echo public_url('dashboard'); 
// Output: https://your_domain/dashboard
```

#### **`history_post_url()`**

* **Purpose**: Returns the URL for the user's viewed post history.
* **Parameters**:
  * `$posttype` (string): Type of post.
* **Usage**:

```php
echo history_post_url('novel'); 
// Output: /en/user/history/novel
```

***

#### **`api_rating()`**

* **Purpose**: Returns the API URL for rating a post.
* **Parameters**:
  * `$posttype` (string): Type of post.
  * `$id` (int): Post ID.
* **Usage**:

```php
echo api_rating('movie', 123); 
// Output: https://your_domain/en/api/v1/posts/action/rating/movie/123
```

#### **`api_count_view()`**

* **Purpose**: Returns the API URL to increment the view count of a post.
* **Parameters**:
  * `$posttype` (string): Type of post.
  * `$id` (int): Post ID.
* **Usage**:

```php
echo api_count_view('novel', 456); 
// Output: /vi/api/v1/posts/action/views/novel/456
```

#### **`api_like_post()`**

* **Purpose**: Returns the API URL to like a post.
* **Parameters**:
  * `$posttype` (string): Type of post.
  * `$id` (int): Post ID.
* **Usage**:

```php
echo api_like_post('movie', 789); 
// Output: /vi/api/v1/posts/action/like/movie/789
```

***

## `update_lang_url()`

* **Purpose**: Updates the language in the current URL. Used for use in language switching links.
* **Parameters**:
  * `$new_lang` (string): New language (e.g., `en`, `vi`).
  * `$new_slug` (string): New slug.
* **Usage**:

```php
echo update_lang_url('en'); 
// Output: /en/
```

***

## `auth_url()`

* **Purpose**: Returns the URL for user authentication.
* Parameters:
  * `$path` (string, optional): Additional path.
  * `$lang` (string, optional, default=`LANG`): Language identifier.
* **Usage**:

```php
echo auth_url('login'); 
// Output: https://your_domain/en/user/login/
```

***

## `cat_url()`

* **Purpose**: Returns the URL for a post category.
* Parameters:
  * `$slug` (string): The slug (short URL) of the post category.
  * `$posttype` (string): The type of post (post type).
* **Usage**:

```php
echo cat_url('action', 'movie'); 
// Output: /en/movie/cat/action/
```

***

## `page_url()`

* **Purpose**: Returns the URL for a specific page.
* Parameters:
  * `$slug` (string): The slug (short URL) of the post category.
  * `$posttype` (string): The type of post (post type).
* **Usage**:

```php
echo page_url('about-us', 'page'); 
// Output: /en/page/about-us/
```

***

## **`single_url()`**

* **Purpose**: Returns the URL for a single post.
* Parameters:
  * `$slug` (string): The slug (short URL) of the post category.
  * `$posttype` (string): The type of post (post type).
* **Usage**:

```php
echo single_url('how-to-code', 'blog'); 
// Output: /vi/blog/how-to-code/
```

***

## `chapter_url()`

* **Purpose**: Returns the URL for a post's chapter.
* Parameters:
  * `$slug` (string): The slug (short URL) of the post category.
  * `$chap` (string|int): The chapter or episode number.
  * `$posttype` (string): The type of post (post type).
* **Usage**:

```php
echo chapter_url('novel', 'one-piece', 5); 
// Output: /en/novel/one-piece/tap-5/
```

***

## `table_posttype()` & `table_posttype_relationship()`

* **Purpose**: Returns the database table name for the given `posttype`.
* Parameters:

  `$posttype` (string) : The type of post (e.g., `"blog"`, `"movie"`, `"product"`).
* **Usage**:

```php
echo table_posttype('blog'); 
// Output: fast_posts_blog

echo table_posttype_relationship('blog'); 
// Output: fast_posts_blog_rel
```

***

## `iframe_url()`

* **Purpose**: Returns the URL for viewing content via an iframe.
* Parameters:
  * `$slug` (string): The slug (short URL) of the post category.
  * `$posttype` (string): The type of post (post type).
* **Usage**:

```php
echo iframe_url('movie', 'avatar'); 
// Output: /en/avatar/movie/play/
```

***

## `user_url()`

* **Purpose**: Returns the URL for a user's page.
* Parameters:
  * `$slug` (string): The unique identifier or username of the user
* **Usage**:

```php
echo user_url('profile', 'john-doe'); 
// Output: /en/manage/profile/john-doe/
```

***

## `convert_to_string_number()`

* **Purpose**: Converts numbers to a compact format (`K`, `M`, `B`).
* **Parameters:**
  * `$num` (int|float): The number to be formatted.
* **Usage**:

```php
echo convert_to_string_number(1500); 
// Output: 1.50K
```

***

## `api_upload_url()`

* **Purpose**: Returns the API URL for file uploads.
* **Parameters:**
  * `$act` (string): The action to be performed (e.g., `"image_upload"`, `"video_upload"`).
  * `$params` (array): Additional parameters to be added to the API request.
* **Usage**:

```php
echo api_upload_url(); 
// Output: https://your_domian/api/files/upload
```

{% hint style="success" %}
**Conclusion**

* These functions help generate dynamic URLs for the frontend.
* Most URLs are processed based on language (`LANG`).
* Input parameters are sanitized before use.
  {% endhint %}


# Images helper

The `images_helper.php` file provides helper functions to handle image paths efficiently. These functions ensure that images are correctly resized and assigned default values when necessary.

***

#### `addSizeToPath()`

**Purpose:**

This function appends a given size string before the file extension in an image path. It is useful for handling different image resolutions without modifying the original filenames.

**Parameters:**

* **`$path`** (string) – The original image file path.
* **`$size`** (string) – The size to be appended before the file extension (e.g., "150x150").

**Usage:**

```php
$imagePath = "/uploads/images/sample.jpg";
$resizedPath = addSizeToPath($imagePath, "150x150");

echo $resizedPath; 
// Output: "/uploads/images/sample_150x150.jpg"
```

`img_square()`

**Purpose:**

This function generates a square image URL (150x150) if the input contains a valid path. If no path is provided, it returns a default placeholder image.

**Parameters:**

* **`$item`** (array/object) – An object or array containing:
  * **`path`** (string) – The original image path.
  * **`resize`** (string, optional) – The resize option indicating a required transformation.

**Usage:**

```php
$item = ['path' => '/uploads/images/sample.jpg', 'resize' => '150x150'];

echo img_square($item); 
// Output: "/uploads/images/sample_150x150.jpg"
```

If the input does not contain a valid path:

```php
$item = ['path' => '', 'resize' => ''];
echo img_square($item);
// Output: "/uploads/assets/150x150.webp"
```

***

## `img_vertical()`

**Purpose:**

Similar to `img_square`, this function generates a vertically resized image URL (333x500). If no valid image is found, it returns a default placeholder image.

**Parameters:**

* **`$item`** (array/object) – An object or array containing:
  * **`path`** (string) – The original image path.
  * **`resize`** (string, optional) – The resize option indicating a required transformation.

**Usage:**

```php
$item = (object) ['path' => '/uploads/images/sample.jpg', 'resize' => '333x500'];
echo img_vertical($item); 
// Output: "/uploads/images/sample_333x500.jpg"
```

If the input does not contain a valid path:

```php
$item = ['path' => '', 'resize' => ''];
echo img_vertical($item);
// Output: "/uploads/assets/333x500.webp" 
```

{% hint style="success" %}
**Conclusion**

The `images_helper.php` file provides essential functions for managing image paths dynamically, ensuring that resized images are correctly referenced while providing fallback images when needed.
{% endhint %}


