Sukarix is an open-source modern PHP framework built to empower developers by facilitating rapid development of web and CLI applications with a focus on simplicity and efficiency. Born out of the need for a streamlined, performance-oriented framework, Sukarix builds on top of the Fat-Free Framework to offer a solid foundation that is both lightweight and feature-rich.
Introduction
Philosophy
Sukarix Framework embraces a philosophy built on principles designed to enhance your development process and deliver robust, scalable applications. Here’s what defines our approach:
-
Lean yet Robust
- Powered with F3 (Fat-Free Framework): While F3 provides a lightweight core, Sukarix builds on this foundation, adding just the right amount of structure and modern features to deliver a robust, feature-rich experience without overwhelming complexity.
-
Proven Expertise
- Real world experience: Sukarix has been rigorously tested in production environments from 2016 to 2024, covering a wide range of applications including CLI tools, web apps, React applications, APIs, middleware, and reverse proxy apps. This extensive testing under diverse conditions demonstrates the framework's reliability and versatility, ensuring its readiness for public release in 2024.
-
Stability Over PHP Versions
- Minimalistic upgrades: Sukarix is designed to ensure stability across different PHP versions with minimal changes required. The framework is built in such a way that upgrading your PHP version typically requires no adjustments to the framework itself, simplifying maintenance and ensuring long-term compatibility.
-
Rich in features
- Best-in-Class Libraries: Sukarix incorporates the best PHP libraries available from the open-source community, offering enterprise-level features that meet the demands of complex business applications.
-
Efficiency first
- Simplicity and Performance: When multiple approaches exist for a feature, we prioritise using the Fat-Free Framework's methods for their proven efficiency. Features are designed and continually refined to ensure the most performant outcomes while maintaining simplicity.
-
Flexibility in approach
- Multiple ways to succeed: While Sukarix standardises the use of the Fat-Free Framework (F3), it remains flexible, allowing developers to utilize F3’s core features, its plugins, and a range of open-source libraries to craft alternative solutions. This approach provides developers the freedom to choose or create the method that best fits the specific requirements of their projects.
-
Smart defaults
- Convention Over Configuration: Sukarix is built on the principle of "It just works!" By promoting conventions over configurations, the framework provides smart defaults that streamline development tasks, enabling developers to focus more on innovation and less on setup.
-
Testability
- Comprehensive Testing: Sukarix is equipped with built-in tools for both CLI and browser-based unit testing, ensuring the reliability and performance of applications through thorough testing. While the framework does not depend on PHPUnit, developers have the flexibility to integrate it or any other testing frameworks into their projects as needed.
Features
- Intuitive Routing System: Define your routes intuitively, ensuring that your application logic is separated from the routing layer and stay human-readable.
- Powerful Templating Engine: Comes with a powerful templating engine that facilitates creating dynamic content in a clean and manageable way.
- Built-in Caching Solutions: Reduce load times and enhance application performance with advanced caching techniques.
- ORM Layer: Simplify database interactions with a robust ORM that supports a variety of database systems.
Getting Started
Starting with Sukarix is straightforward. Our documentation is designed to guide you through setting up your development environment, creating your first project, and exploring Sukarix’s capabilities. Whether you’re building a small website or a complex application, Sukarix provides all the tools you need to succeed.
Contributing
Sukarix is an open-source project and thrives on your contributions. Whether it's fixing bugs, adding features, or improving documentation, your help is always welcome. Join our community and help shape the future of Sukarix!
The Sukarix Framework
What is Sukarix?
Sukarix is an open-source PHP framework built on top of the Fat-Free Framework (F3) designed to create enterprise-grade web and server/CLI applications. The name "Sukarix" is derived from the Arabic word "سُكَّر" (sukkar), which means sugar, symbolizing the framework's goal to add sweetness and efficiency to the robust and lightweight Fat-Free Framework.
Purpose of Sukarix
The primary purpose of Sukarix is to provide developers with a powerful and efficient framework for building enterprise-level PHP applications. Whether you are developing web applications or server-side/command-line interface ( CLI) applications, Sukarix aims to streamline the development process by leveraging the strengths of Fat-Free Framework and enhancing it with additional features and tools for modern development needs. Sukarix seeks to combine the best available PHP libraries to build the most robust and usable PHP framework.
Why Choose Sukarix?
Stability Across PHP Upgrades
One of the key strengths of Sukarix, inherited from Fat-Free Framework, is its stability across PHP upgrades. The framework is designed to be robust and reliable, ensuring that your code remains functional and intact even as PHP evolves. This minimizes the need for extensive refactoring and reduces the risk of breaking changes during upgrades.
Robustness
Sukarix offers a robust foundation for building applications. It is designed to handle various use cases and edge scenarios gracefully, ensuring that your application remains stable and secure under different conditions. This robustness comes from years of development and real-world use, making it a trustworthy choice for enterprise applications.
Resource Efficiency
Sukarix is built to be resource-efficient. It has a minimal footprint and is optimized for performance, ensuring that it consumes fewer resources compared to heavier frameworks. This efficiency translates to faster response times and lower operational costs, making it ideal for high-performance applications.
Usability and Practicality
The Fat-Free Framework, which forms the backbone of Sukarix, boasts a well-established history of stability and performance. Over the years, it has been employed in numerous projects, showcasing its reliability and versatility. Sukarix capitalizes on this robust foundation, enhancing it with additional features to meet modern development needs.
Proven Track Record
Fat-Free Framework, the foundation of Sukarix, has a proven track record of stability and performance. It has been used in numerous projects over the years, demonstrating its reliability and versatility. Sukarix builds on this solid foundation, offering additional features and enhancements that cater to modern development needs.
Features
Introduction
Sukarix builds upon the robust and lightweight foundation of the Fat-Free Framework (F3), a micro-framework known for its efficiency and simplicity. We have retained the best features of F3 where it excels, ensuring a solid, stable, and high-performance core. At the same time, we have integrated or replaced certain components with more powerful and feature-rich libraries to make Sukarix enterprise-ready. These enhancements provide additional functionality, improve scalability, and offer a more comprehensive development experience for building complex, modern PHP applications.
Feature List
Feature Name | F3 Native | Sukarix Replacement (Library) |
---|---|---|
Fast and clean template engine | Yes | - |
Unit testing toolkit (Web UI & CLI) | Yes | PHPUnit Code Coverage |
Database-managed sessions | Yes | - |
Markdown-to-HTML converter | Yes | - |
Atom/RSS feed reader | Yes | - |
Image processor | Yes | - |
Geodata handler | Yes | - |
On-the-fly Javascript/CSS compressor | Yes | Matthias Mullie Minify |
OpenID (consumer) | Yes | - |
Custom logger | Yes | Monolog |
Basket/Shopping cart | Yes | - |
Pingback server/consumer | Yes | - |
Unicode-aware string functions | Yes | - |
SMTP over SSL/TLS | Yes | F3 Mailer |
Tools for communicating with other servers | Yes | - |
Data Validation | Yes | Sukarix extends F3 |
ORM | - | F3 Cortex |
ACL | - | F3 Access |
Multi-language | - | F3 Multilang |
Event Dispatching | - | F3 Events |
Messages to chat platforms | - | Guanguans Notify |
Database Migrations | - | Phinx |
Debugging & Global Event Catching | - | Tracy |
Cron job scheduler | - | peppeocchi/php-cron-scheduler |
Dependency Injection | - | Sukarix |
Inversion of Control | - | Sukarix |
Bash tool | - | Sukarix (coming...) |
Description of Features
- Fast and clean template engine: Provides a lightweight and efficient templating system that allows for easy creation of dynamic web pages.
- Unit testing toolkit (Web UI & CLI): Integrated tools for unit testing both web interfaces and command-line interfaces, ensuring comprehensive code coverage and reliability.
- Database-managed sessions: Manages user sessions through the database, enhancing security and scalability.
- Markdown-to-HTML converter: Converts Markdown syntax into HTML, facilitating easy content creation and management.
- Atom/RSS feed reader: Parses and reads Atom and RSS feeds, allowing for integration with external content sources.
- Image processor: Handles image manipulation tasks such as resizing, cropping, and format conversion.
- Geodata handler: Manages geographical data, enabling features such as location-based services and mapping.
- On-the-fly Javascript/CSS compressor: Minifies JavaScript and CSS files on the fly to improve page load times and performance.
- OpenID (consumer): Supports OpenID authentication, allowing users to log in using their existing OpenID accounts.
- Custom logger: Enhanced logging capabilities using Monolog, providing flexible and powerful logging options.
- Basket/Shopping cart: Manages e-commerce functionalities such as shopping carts and order processing.
- Pingback server/consumer: Implements pingback functionality for communication between blogs and websites.
- Unicode-aware string functions: Handles string operations with full Unicode support, ensuring compatibility with multiple languages and character sets.
- SMTP over SSL/TLS: Securely sends emails using SMTP with SSL/TLS encryption, enhancing email security.
- Tools for communicating with other servers: Provides utilities for making HTTP requests and interacting with external APIs.
- Data Validation: Sukarix extends F3 to validate input data, ensuring it meets specified rules and constraints before processing.
- ORM: Uses F3 Cortex for object-relational mapping, simplifying database interactions.
- ACL: Manages access control using F3 Access, enforcing permissions and roles.
- Multi-language: Supports multiple languages using F3 Multilang, allowing for easy localisation of content adn routes.
- Event Dispatching: Handles event management using F3 Events, allowing for flexible and decoupled event-driven architecture.
- Messages to chat platforms: Sends notifications to chat platforms like Zulip and Slack using Guanguans Notify.
- Database Migrations: Manages database schema changes using Phinx, ensuring smooth and controlled migrations.
- Debugging & Global Event Catching: Utilizes Tracy for debugging and catching global events, providing detailed error reports and insights.
- Cron job scheduler: Schedules and manages cron jobs using peppeocchi/php-cron-scheduler, automating repetitive tasks.
- Dependency Injection: Facilitates dependency management using Sukarix's own DI container, promoting loose coupling and testability.
- Inversion of Control: Implements IoC using Sukarix, ensuring modular and maintainable code.
- Bash tool: A forthcoming feature in Sukarix for creating and managing bash scripts, enhancing CLI capabilities.
Understanding Fat-Free Framework
Introduction
Fat-Free Framework (F3) is a powerful yet lightweight PHP framework designed to help developers build dynamic web applications quickly and efficiently. One of the core concepts in F3 is the "Hive," which is a centralized place where the framework stores and manages all application data.
The Hive and F3 Class
The Hive
The Hive is a key-value store that acts as the central repository for all configuration settings, routing information, session data, and more. It is accessible throughout the application, making it easy to manage and retrieve necessary data from anywhere in your code.
The F3 Class
The F3
class is a singleton, meaning there is only one instance of this class throughout the application's lifecycle.
This singleton instance is accessible from anywhere in your application, providing a consistent and centralized way to
interact with the framework's core functionalities.
How It Works
- Initialization: When the application starts, the F3 singleton is created and the Hive is initialized with system variables and configurations.
- Routing: F3 uses the Hive to manage routes, mapping URLs to specific functions or controllers.
- Session Management: The framework uses the Hive to store and manage session data, ensuring user states are maintained across different requests.
- Configuration: All configuration settings are stored in the Hive, making it easy to adjust and retrieve settings as needed.
- Template Rendering: F3’s template engine uses the Hive to access variables and directives needed to render views dynamically.
More Resources
To dive deeper into how Fat-Free Framework works and to explore its extensive features, refer to the following resources:
User Guide
For a comprehensive understanding of F3, including installation, basic usage, and advanced features, consult the User Guide.
API Reference
The API Reference provides detailed information on all the classes, methods, and properties available in F3, making it an essential resource for developers looking to utilize the framework to its fullest potential.
System Variables
System variables are predefined variables that F3 uses to manage various aspects of the application. For a quick reference on these variables, check out the System Variables page.
Template Directives
F3's template engine comes with a set of powerful directives that make it easy to render dynamic content. You can find a list of these directives and how to use them on the Template Directives page.
By leveraging these resources, you can gain a thorough understanding of the Fat-Free Framework and harness its full potential to build efficient, scalable, and robust PHP applications.
Instructions for a new Sukarix application
- Introduction
- Step 1: Create a new Sukarix project
- Step 2: Navigate to the project directory
- Step 3: Initialize vagrant
- Step 4: Access the Application
- Configuration Details
Introduction
To set up your Sukarix application with Vagrant follow these steps:
Step 1: Create a new Sukarix project
Run the following command to create a new Sukarix project using Composer:
composer create-project sukarix/application
It is also possible to create a new Sukarix project using the current development version of the framework by adding --stability=dev to the command.
composer create-project --stability=dev sukarix/application
Step 2: Navigate to the project directory
Once the project is created, navigate to the project directory:
cd application
Step 3: Initialize vagrant
The Sukarix project includes a Vagrant setup to help streamline the development environment. Initialize Vagrant by running:
vagrant up
This command will set up the Vagrant environment and automatically install PostgreSQL and Redis.
Step 4: Access the Application
After the Vagrant setup is complete, the application will be accessible via:
http://sukarix.test
Configuration Details
- PostgreSQL and Redis are installed by default in the current version of the Sukarix project.
- Ensure your local environment is configured to handle
.test
domains (you might need to adjust your hosts file if necessary).
Accessing the Application
After running vagrant up
, you can access your application at http://sukarix.test
. If you encounter issues accessing
the site, ensure your system's hosts file includes the correct entry, typically something like:
192.168.56.100 sukarix.test
Configuration
Configuration Files
Sukarix is configured via .ini
files by default, allowing for clear and manageable settings. The configuration load
order ensures that settings can be overridden based on the environment.
Configuration Load Order
-
Base Configuration:
config/classes.ini
config/default.ini
-
Additional Configurations:
- Files listed in the
CONFIGS
variable, e.g.,smtp
,notifications
,upload
. No need to add.ini
extension. config/validation.ini
(loaded only when a data validation request is initiated).
- Files listed in the
-
Environment-Specific Configuration:
config/config-<environment>.ini
-
Routing and Access Control:
config/routes.ini
config/routes-<environment>.ini
config/access.ini
orconfig/access-cli.ini
(based on environment).
Configuration changes are automatically reloaded, meaning there is no need to restart any service.
When specifying additional configuration files in the CONFIGS
variable, you do not need to include the .ini
extension. Sukarix will automatically append .ini
to the file name during the loading process. For example, if you set CONFIGS=notifications,smtp,upload
, Sukarix will load config/notifications.ini
, config/smtp.ini
, and config/upload.ini
.
Environment Overrides
Any configuration setting can be overridden in the environment-specific .ini
file (config/config-<environment>.ini
).
This allows for tailored configurations depending on whether the application is in development, testing, or production.
Default Configuration Example
Here is an overview of the default settings found in default.ini
:
-
Global Settings:
DEBUG
: Stack trace verbosity.PACKAGE
: Display name in requests.LOGS
: Custom log location.TEMP
: Temporary folder for cache and compiled templates.UPLOADS
: Directory for file uploads.UI
: Paths for user interface files.LOCALES
: Location of language dictionaries.ENCODING
: Default character encoding.LANGUAGE
: Active language.FALLBACK
: Fallback language.
-
Cache and Minification:
CACHE
: Cache configuration.SEED
: Cache seed.MINIFY_JS
andMINIFY_CSS
: Toggle minification.
-
Timezone and Environment:
TZ
: Timezone setting.application.environment
: Current environment.log.session
: Log session queries.session.table
: Table for session storage.pagination.limit
: Default pagination limit.template.default
: Default view to render.log.keep
: Log retention period.server.host
: Host for command-line actions.error.channel
: Error notification channel.
-
Security:
csrf.enabled
: Enable or disable CSRF protection.csrf.expiry
: CSRF token expiry time in seconds.
Directory Structure
Structure
Understanding the directory structure of a Sukarix application is crucial for effective development and maintenance. Below is an overview of the typical directory layout and the purpose of each directory and file.
app
├── config
│ ├── access.ini
│ ├── access-cli.ini
│ ├── classes.ini
│ ├── config-development.ini
│ ├── config-test.ini
│ ├── default.ini
│ ├── notifications.ini
│ ├── routes.ini
│ ├── routes-cli.ini
│ ├── routes-test.ini
│ ├── smtp.ini
│ ├── upload.ini
│ ├── validation.ini
├── i18n
├── src
├── templates
data
db
├── data
├── migrations
├── seeds
logs
public
├── css
├── js
├── index.php
├── minified
uploads
tmp
├── mail
test
vendor
.php-cs-fixer
phinx.yml
Directory and File Descriptions
app
This is the main application directory containing configuration files, source code, templates, and localization files.
config
Contains various configuration files for the application.
- access.ini: Defines access control rules for web applications.
- access-cli.ini: Defines access control rules for CLI applications.
- classes.ini: Configuration for class mappings and dependencies.
- config-development.ini: Configuration specific to the development environment.
- config-test.ini: Configuration specific to the test environment.
- default.ini: Default configuration settings.
- notifications.ini: Settings for notifications (e.g., email, chat integrations).
- routes.ini: Defines routes for web applications.
- routes-cli.ini: Defines routes for CLI applications.
- routes-test.ini: Defines routes for test environments.
- smtp.ini: Configuration for SMTP settings.
- upload.ini: Settings for file uploads.
- validation.ini: Configuration for data validation.
i18n
Directory for internationalization (i18n) files, containing localization strings for different languages.
src
Contains the source code for the application, including controllers, models, and other classes.
templates
Directory for template files used by the application. These are typically .phtml
files that define the HTML structure
and content.
data
Directory for storing the SQLite database files.
db
Contains database-related files and directories.
- data: Directory for storing the SQLite database files.
- migrations: Directory for database migration scripts.
- seeds: Directory for database seed files.
logs
Directory for log files generated by the application.
public
The web root directory containing publicly accessible files.
- css: Directory for CSS files.
- js: Directory for JavaScript files.
- index.php: The entry point for the application.
- minified: Directory for minified JavaScript and CSS files.
uploads
Directory for user-uploaded files.
tmp
Directory for temporary files.
- mail: Directory for emails sent in development and test environments, stored as files.
- cache: Directory for cache files.
test
Directory for unit tests and testing-related files.
vendor
Directory for Composer dependencies.
.php-cs-fixer
Configuration file for PHP-CS-Fixer, a tool for automatically fixing PHP coding standards issues.
phinx.yml
Configuration file for Phinx, a PHP database migration tool.
This directory structure helps to keep your application organized and maintainable, ensuring that related files and configurations are logically grouped together.
Terminology
- Hive
- Configuration File
- Action
- Bootstrapping
- Environment
- Injector
- Processor
- Session
- ErrorChannel
- User Role
- Assets
- View
- Flash
- I18n
- MailSender
- Model
- Notifier
- Constraints
- Tailored
- Template Directive
Hive
A central place where Fat-Free Framework (F3) stores and manages application data, including configuration settings, routing, and session information. The Hive acts as a global registry, making data accessible throughout the application.
Configuration File
Refers to any ini
configuration file used to define application settings and dependencies. This file helps in managing
the application's configuration in a structured and centralized manner.
Action
Refers to action-wise micro-controllers inspired by ForkCMS. These are responsible for handling specific tasks or requests within the application, typically mapped to routes and executed to perform a particular function.
Bootstrapping
The application initialization phase where the framework, akin to the kernel in other frameworks, loads configurations, sets up the environment, and prepares the application for handling requests.
Environment
The automatically detected application environment, which can be test
, development
, or production
. This setting
can be overridden to suit specific needs during development or deployment.
Injector
A component responsible for injecting and initializing Inversion of Control (IoC) classes defined in the configuration file. It manages dependencies and ensures that required services are available throughout the application.
Processor
A component responsible for applying behaviors or traits to classes. It ensures that specific functionalities or attributes are consistently applied across relevant classes.
Session
The class responsible for managing user sessions, including session creation, data storage, and session termination.
ErrorChannel
The global exception handling component used to manage and route errors. It supports multiple channels like Zulip and email for notifying about exceptions.
User Role
Defines the various roles within the application, such as visitor
, admin
, customer
, or api
user. These roles
determine the level of access and permissions for different parts of the application.
Assets
The class responsible for injecting JavaScript and CSS assets into views, either from the action or directly within the view itself.
View
Refers to the F3 template view files, typically ending with .phtml
, used to render the user interface.
Flash
Contains notifications to be displayed in the frontend. It manages temporary messages that inform users about the status of their actions.
I18n
The class that contains different types of messages depending on the localization settings. It supports internationalization and helps manage translations.
MailSender
The class responsible for sending emails within the application. It handles email composition, configuration, and delivery.
Model
A Cortex class with additional behaviors, used to represent and manage the application's data layer. It includes ORM features for interacting with the database.
Notifier
The component responsible for sending notifications to third parties, such as Zulip, Slack, or email, ensuring that important events are communicated effectively.
Constraints
The class responsible for validating data inputs within the application. It ensures that data conforms to specified rules and constraints before processing.
Tailored
The Tailored
class is a singleton that extends F3's \Prefab
, ensuring only one instance of the class exists. It has
the ability to glue trait behaviour to a class while maintaining its singleton nature and integrating it into the
dependency injection registry.
Template Directive
Directives used within F3 templates to insert dynamic content, control flow, and manage template inheritance. These directives allow developers to create flexible and reusable templates for rendering views. For a detailed list and explanation of template directives, refer to the F3 Quick Reference.
Application Lifecycle
- Entry-point
- 1. Detect if the Application is Running in CLI Mode
- 2. Create an Instance of the Fat-Free Framework (F3) Singleton Class
- 3. Set Up PHP Variables
- 4. Automatically Detect the Application Environment
- 5. Load the Configuration Files
- 6. Set Up Logging
- 7. Add the Global Exception Handler
- 8. Connect to the Database
- 9. Prepare the Session
- 10. Load Additional Application Settings
- 11. Load Additional CLI Configuration if CLI Mode is Detected
- 12. Load Routing and Access Control Lists (ACL)
- 13. Execute the Start Function
- 14. Log Performance Metrics and Finish
Entry-point
The entry point for a Sukarix application is public/index.php
.
This is where initial detection happens to determine if unit tests need to be run in the browser, a process that will be covered in detail later.
Once the Application is instantiated, the following steps occur:
1. Detect if the Application is Running in CLI Mode
The application first checks if it is being executed from the command line (CLI) or through a web server. This allows for conditional loading of CLI-specific configurations and behaviors.
2. Create an Instance of the Fat-Free Framework (F3) Singleton Class
An instance of the F3 singleton class is created. This instance acts as the central hub for managing application configuration, routing, and other core functionalities.
3. Set Up PHP Variables
The application sets up necessary PHP variables, including error reporting levels, timezone settings, and memory limits, to ensure a consistent execution environment. Up to the developer to override it.
4. Automatically Detect the Application Environment
The application detects the current environment (test
, development
, or production
). This setting can be overridden
if needed, and it dictates how the application behaves, including error reporting and debugging levels.
5. Load the Configuration Files
The application loads its configuration settings from ini
configuration files. These files define various parameters
and settings required for the application's operation.
6. Set Up Logging
Logging is set up to capture and record important events, errors, and performance metrics. This is crucial for monitoring the application and diagnosing issues.
7. Add the Global Exception Handler
A global exception handler is added to catch and manage any unhandled exceptions, ensuring that errors are logged and appropriate responses are provided without crashing the application.
8. Connect to the Database
The application establishes a connection to the database using the settings defined in the configuration files. This connection is essential for data storage and retrieval.
9. Prepare the Session
The session handler is initialized to manage user sessions, including creating, storing, and terminating sessions. This is important for maintaining user state across requests.
10. Load Additional Application Settings
Additional settings and configurations specific to the application are loaded. These can include custom parameters, feature toggles, and other application-specific settings.
11. Load Additional CLI Configuration if CLI Mode is Detected
If the application is running in CLI mode, additional configurations specific to the command-line environment are loaded. This ensures that CLI commands have the necessary settings and resources.
12. Load Routing and Access Control Lists (ACL)
The routing configuration and ACLs are loaded to define how incoming requests are handled and to enforce access permissions. This ensures that routes are correctly mapped to actions and that users have appropriate access rights.
13. Execute the Start Function
The start
function of the application is executed, which in turn calls the F3 run
function. This kicks off the
application, allowing it to handle incoming requests or execute CLI commands.
14. Log Performance Metrics and Finish
Finally, the application logs performance metrics for the entire lifecycle process. This includes timing information and resource usage statistics, which are useful for performance monitoring and optimization.
This comprehensive sequence ensures that the Sukarix application is thoroughly initialized, configured, and prepared to handle both web requests and CLI commands efficiently and reliably.
Dependency Injection
- Overview
- Example Usage
- Configuration & Default Dependencies
- Creating Injectable Singletons
- Storing DI Classes
Overview
Dependency Injection in Sukarix is facilitated through the singleton class Injector::instance()->get('access')
. This
method allows for easy and efficient management of dependencies within your application.
Example Usage
In this example, access
is the default ACL Middleware tied to f3-access
:
$access = Injector::instance()->get('access');
Additionally, the Injector
can find an object from its class directly:
$multiLang = Injector::instance()->get(\Multilang::class);
Configuration & Default Dependencies
These default classes can be easily changed or overridden by updating the classes.ini
file. The default configuration
is in the table below:
Key | Class |
---|---|
mailer | Sukarix\Mail\MailSender |
notifier | Sukarix\Notification\Notifier |
session | Sukarix\Core\Session |
i18n | Sukarix\Helpers\I18n |
assets | Sukarix\Helpers\Assets |
access | \Access |
events | Sugar\Event |
template | \Template |
html | Sukarix\Helpers\HTML |
multi_language | \Multilang |
receiver | Sukarix\Helpers\Receiver |
Creating Injectable Singletons
For classes that should be singletons with behaviors, they must extend the Sukarix\Core\Tailored
class. This ensures
the framework can automatically integrate their behaviors. More details on these behaviors can be found in the Behaviors
section of the documentation.
There is no need to manually instantiate the injected object, Sukarix will do it for you.
Storing DI Classes
The F3 \Registry
class is used to store these dependency-injected classes, ensuring they are easily accessible
throughout your application. However, it is recommended to use the Injector
class that already wraps this
functionality, as it provides additional features and should be preferred over direct usage of \Registry
.
Routing and Access Control
Introduction
Sukarix leverages the powerful routing and access control capabilities of the Fat-Free Framework (F3) to manage web and
CLI application routes. The configuration for routing and access control is handled through routes.ini
and access.ini
for web applications, and routes-cli.ini
and access-cli.ini
for CLI applications. Additionally,
multi-language routing is supported via f3-multilang
.
Routing
Concepts
Routing in Sukarix allows you to map URLs to specific actions in your application. This is managed through configuration files where you define patterns for web and CLI routes. Key concepts include:
- HTTP Methods: Define the HTTP methods (GET, POST, PUT, DELETE, etc.) that the route will respond to.
- Route Aliases: Provide named routes for easier reference.
- Tokens: Use tokens to capture parts of the URL (e.g.,
/users/@id
). - Modifiers: Use
[ajax]
for AJAX requests and[cli]
for CLI routes. - Asterisk (*): Use wildcards to match any subpath.
- Named Routes: Assign names to routes for easy referencing.
- Rerouting: Redirect requests to different routes or actions.
- ReST: Implement RESTful APIs using standard HTTP methods.
- Multi-language Routing: Support multiple languages using
f3-multilang
.
Web Application Routing (routes.ini
)
In Sukarix, routes for web applications are defined in the routes.ini
file.
Example Configuration
[routes]
; default route
GET @home : / = Actions\Core\Main->execute
GET @docs : /docs/* = Actions\Core\Docs->execute
POST|PUT @set_locale : /set-locale/@locale [ajax] = Actions\Account\SetLocale->execute
DELETE @user_delete : /users/@id = Actions\Users\Delete->execute
Explanation
-
GET @home : / = Actions\Core\Main->execute
- GET: The HTTP method for the route.
@home
: The route alias./
: The URL pattern for the home page.= Actions\Core\Main->execute
: The action and method that handle the request.
-
GET @docs : /docs/* = Actions\Core\Docs->execute
- GET: The HTTP method for the route.
@docs
: The route alias./docs/*
: The URL pattern with a wildcard to match any subpath.= Actions\Core\Docs->execute
: The action and method that handle the request.
-
POST|PUT @set_locale : /set-locale/@locale [ajax] = Actions\Account\SetLocale->execute
- POST|PUT: The HTTP methods for the route.
@set_locale
: The route alias./set-locale/@locale
: The URL pattern with a token (@locale
).[ajax]
: Modifier indicating the route should handle AJAX requests.= Actions\Account\SetLocale->execute
: The action and method that handle the request.
-
DELETE @user_delete : /users/@id = Actions\Users\Delete->execute
- DELETE: The HTTP method for the route.
@user_delete
: The route alias./users/@id
: The URL pattern with a token (@id
).= Actions\Users\Delete->execute
: The action and method that handle the request.
CLI Application Routing (routes-cli.ini
)
In Sukarix, routes for CLI applications are defined in the routes-cli.ini
file.
Example Configuration
[routes]
; route to the main task scheduler
GET @run_job : /cli/jobs/run [cli] = Actions\Jobs\TaskScheduler->execute
GET @logs_clean : /cli/logs/clean [cli] = Sukarix\Actions\Logs\Clean->execute
GET @sessions_clean : /cli/sessions/clean [cli] = Sukarix\Actions\Core\SessionsClean->execute
Explanation
-
GET @run_job : /cli/jobs/run [cli] = Actions\Jobs\TaskScheduler->execute
- GET: The HTTP method for the route.
@run_job
: The route alias./cli/jobs/run
: The URL pattern for running jobs.[cli]
: Modifier indicating the route is for CLI mode.= Actions\Jobs\TaskScheduler->execute
: The action and method that handle the request.
-
GET @logs_clean : /cli/logs/clean [cli] = Sukarix\Actions\Logs\Clean->execute
- GET: The HTTP method for the route.
@logs_clean
: The route alias./cli/logs/clean
: The URL pattern for cleaning logs.[cli]
: Modifier indicating the route is for CLI mode.= Sukarix\Actions\Logs\Clean->execute
: The action and method that handle the request.
-
GET @sessions_clean : /cli/sessions/clean [cli] = Sukarix\Actions\Core\SessionsClean->execute
- GET: The HTTP method for the route.
@sessions_clean
: The route alias./cli/sessions/clean
: The URL pattern for cleaning sessions.[cli]
: Modifier indicating the route is for CLI mode.= Sukarix\Actions\Core\SessionsClean->execute
: The action and method that handle the request.
Multi-language Routing
Sukarix supports multi-language routing using f3-multilang
. This allows you to define routes that adapt to different
languages.
Configuration Example
[MULTILANG.languages]
en = en-GB
fr = fr-FR
ar = ar-AR
es = es-ES
[MULTILANG]
global = locale,/cli
[MULTILANG.languages]
: Defines the languages and their respective locale codes.[MULTILANG]
: Specifies global aliases that are not localized by default.
Access Control
Access control in Sukarix is managed through access.ini
and access-cli.ini
files, defining policies and rules for
both web and CLI applications.
Web Application Access Control (access.ini
)
Sukarix uses the access.ini
file to manage access control for web applications. The configuration defines policies and
rules for access control using the F3-Access component.
Example Configuration
[ACCESS]
; deny all routes by default
policy = deny
[ACCESS.rules]
; Routes allowed to all type of users
deny * /* = *
allow GET @home = *
allow GET @docs = admin,customer
allow @set_locale = *
allow DELETE @user_delete = admin
Explanation
-
policy = deny
- Sets the default policy to deny access to all routes.
-
deny * /* = *
- Denies access to all users for all routes by default.
-
allow GET @home = *
- Allows access to the home route (
@home
) for all users.
- Allows access to the home route (
-
allow GET @docs = admin,customer
- Allows access to the documentation route (
@docs
) only foradmin
andcustomer
roles.
- Allows access to the documentation route (
-
allow @set_locale = *
- Allows access to the set locale route (
@set_locale
) for all users.
- Allows access to the set locale route (
-
allow DELETE @user_delete = admin
- Allows access to delete user route (
@user_delete
) only foradmin
role.
- Allows access to delete user route (
CLI Application Access Control (access-cli.ini
)
Sukarix uses the access-cli.ini
file to manage access control for CLI applications.
Example Configuration
[ACCESS]
; allow all routes by default
policy = allow
Explanation
policy = allow
- Sets the default policy to allow access to all CLI routes.
References
For more detailed information on F3's routing and access control mechanisms, refer to the following resources:
Framework Variables
Fat Free Framework Variables
Detailed information on Fat-Free Framework variables can be found here.
Globals
Global variables and their usage are explained here.
Naming Rules
Naming conventions are outlined here. Sukarix follows these rules, using capital letters when possible. If F3 extensions deviate from this rule, they are used as is.
Sukarix Framework Variables
Fat-Free Framework system variables are listed here.
Example Sukarix framework variables:
MINIFY_JS
boolean
Default: TRUE
in production configuration
Turns JavaScript minification on or off. Should be environment dependant.
MINIFY_CSS
boolean
Default in template application: TRUE
in production configuration
Turns CSS minification on or off. Should be environment dependant.
CONFIGS
string
Default in template application: smtp,notifications,upload
List of configuration files to load.
application.environment
string
Sets the application environment (e.g., development, testing).
If the server hostname ends with .test
the application.environment
variable will automatically be set
to development
.
template.default
string
Default in template application: website
Default view to render.
log.keep
integer
Default in template application: 14
Days to keep logs before cleanup.
server.host
string
Default: NULL
Server host for command line actions.
error.channel
string
Default: NULL
Error notification channel ("email" or "zulip").
Databases Management
Database Configuration
For configuring database access, the framework follows the guidelines outlined by the Fat-Free Framework. This includes setting up database connections and handling queries efficiently.
Cortex ORM
The framework utilizes Cortex ORM for object-relational mapping, simplifying interactions with the database. For detailed usage and configuration instructions, refer to the Cortex documentation.
Database Migrations
Database migrations are managed using the Phinx library, which is included in the template application with
a phinx.json
file. This file can be customised, although Phinx is the recommended tool. Comprehensive documentation
for Phinx is available here.
Model Class
The Model
class provides a structured way to access data using Cortex ORM. It includes methods for pagination, data
conversion, and change detection, ensuring robust and efficient data handling.
The Model
class follows conventions for managing timestamps:
- created_on: Automatically set when a record is created.
- updated_on: Automatically updated when a record is modified.
File Upload
Introduction
The Receiver
class in Sukarix is designed to handle file uploads efficiently. It provides methods for saving uploaded
files and preparing upload directories, ensuring that your application can manage file uploads seamlessly.
Configuration
To use the Receiver
class, you need to configure it in the classes.ini
file:
receiver = \Helpers\Receiver
Methods
saveUploadedFile
This method saves the uploaded file to the specified destination. It checks the environment to decide whether to
use rename
or move_uploaded_file
for saving the file.
prepareUploadDirectory
This method prepares the upload directory by creating it if it does not exist. It throws a RuntimeException
if the
directory cannot be created.
Example Usage
To use the Receiver
class for handling file uploads, you can get an instance from the Injector
and use
the \Web::instance()->receive
method to process the uploaded files.
/**
* @var Receiver $receiver
*/
$receiver = Injector::instance()->get('receiver');
\Web::instance()->receive(static function(&$file, &$formFieldName) use (&$action, &$receiver) {
if (0 === $file['size']) {
return false;
}
$uploadDirectory = 'path/to/upload/directory';
$receiver->prepareUploadDirectory($uploadDirectory);
$destination = $uploadDirectory . '/' . $file['name'];
return $receiver->saveUploadedFile($file, $destination);
});
The Receiver
class ensures that file uploads are handled efficiently and securely, with proper directory preparation
and file movement based on the environment. This setup allows for easy management of uploaded files in your Sukarix
application.
Data Validation
- Human-readable data validation syntax
- Configuration
- Using the Validator
- How Validation Works
- Available Validation Rules
Human-readable data validation syntax
Form validation is a crucial part of building robust web applications. Sukarix simplifies this process by allowing you to declare your validation rules in an easy-to-read configuration file. This page provides an overview of how to use Sukarix's data validation capabilities.
Configuration
Validation rules are declared in an INI file. Here's an example:
[CONSTRAINTS.users.edit]
email = email
username = length:4,32
role = in:Enum\UserRole
status = in:Sukarix\Enum\UserStatus
Using the Validator
To validate data, use the Constraints
class in your controller or model. Below are various examples demonstrating
different usages.
Example: Basic Usage
public function save($f3, $params): void
{
$form = $this->getDecodedBody();
Constraints::instance()->verify($form, 'users.edit');
// Process the validated data
}
Example: Multiple Rulesets
You can validate against multiple rulesets by separating them with a pipe (|
).
public function save($f3, $params): void
{
$form = $this->getDecodedBody();
Constraints::instance()->verify($form, 'settings.save.default|users.edit');
// Process the validated data
}
You can also pass ruleset names as an array.
public function save($f3, $params): void
{
$form = $this->getDecodedBody();
Constraints::instance()->verify($form, ['settings.save.default', 'users.edit']);
// Process the validated data
}
Example: Individual Checks
You can also perform individual checks using the check
method.
$filePath = '/path/to/file.css';
Constraints::instance()->check($this->f3->get('ROOT') . $filePath, 'file', true, 'css_file');
How Validation Works
-
Audit Class:
- If available, validation rules are first checked in the
Audit
class.
- If available, validation rules are first checked in the
-
Constraints Class:
- If the rule is not found in the
Audit
class, it falls back to theConstraints
class.
- If the rule is not found in the
-
Custom Validator:
- If the rule is not found in the
Constraints
class, it checks for a user-defined validator class specified in theVALIDATOR
configuration property.
- If the rule is not found in the
Validator names are case insensitive, meaning notempty
, notEmpty
, NotEmpty
, and NOTEMPTY
are treated the same.
Available Validation Rules
Here is a list of available validation rules that you can use in your INI configuration file or directly in your code:
email
: Validates that the input is a valid email address.length:min,max
: Validates that the input length is betweenmin
andmax
.in:Enum\ClassName
: Validates that the input is one of the values in the specified enumeration.notEmpty
: Validates that the input is not empty.file
: Validates that the input is a valid file path.
Example: Custom Validator
You can define custom validation rules in your own validator class and configure Sukarix to use it.
class CustomValidator
{
public static function isCustom($value)
{
// Custom validation logic
return $value === 'custom';
}
}
// Usage
$customRules = [
'custom_field' => 'custom'
];
Constraints::instance()->verifyRules($form, $customRules, true);
Error Handling
When validation fails, the verify
method throws an exception if the throwOnFail
parameter is set to true
.
try {
Constraints::instance()->verify($form, 'users.edit', true);
} catch (\RuntimeException $e) {
echo "Validation failed: " . $e->getMessage();
}
To get all validation errors, use the getErrors
method.
$errors = Constraints::instance()->getErrors();
print_r($errors);
Combining Validators
You can combine multiple validation rules using the pipe (|
) separator.
[CONSTRAINTS.users.edit]
email = email
username = length:4,32|notEmpty
role = in:Enum\UserRole|notEmpty
status = in:Sukarix\Enum\UserStatus|notEmpty
public function save($f3, $params): void
{
$form = $this->getDecodedBody();
Constraints::instance()->verify($form, 'users.edit');
// Process the validated data
}
Session
Session Management
Session handler documentation can be found here.
By default, sessions are stored in the database but can be configured to use the cache system. This allows session data to be debuggable in non-production environments, while in production, storing sessions in cache enhances performance.
Storing a session in the database can be problematic when using transactions, as the database connection is tied to that session. Rolling back or failing a transaction may result in failed updates to the session data. It's important to carefully consider this when designing your application's session management strategy.
Session Functions
The session management system includes the following functions:
- authorizeUser: Authorizes a user and initiates their session.
- revokeUser: Revokes a user's session and logs them out.
- getRole: Retrieves the role of the current user.
- isRole: Checks if the current user has a specific role.
Logging
Introduction
The framework uses Monolog by default for logging. To enable logging, use the LogWriter
behavior trait in your class.
If the class does not extend the Tailored
singleton class, ensure to call the initLogWriter
method in the constructor.
Logging Naming Conventions
Logs follow these naming patterns:
- Application Logs:
app-yyyy-mm-dd.log
- Application Error Logs:
app-error-yyyy-mm-dd.log
- CLI Logs:
cli-yyyy-mm-dd.log
- CLI Error Logs:
cli-error-yyyy-mm-dd.log
- Exception Logs:
exception.log
Log Rotation
Logs are kept for 14 days by default, configurable via the log.keep
setting (an integer in days).
The Sukarix\Actions\Action\Clean
action is responsible for rotating and cleaning logs.
Debugging
Introduction
Sukarix uses the Tracy library for debugging. Tracy offers powerful tools to help you debug your applications efficiently.
Basic Usage
To use Tracy, simply call the following functions in your code:
- Dumping Variables:
dump($variable)
ordumpe($variable)
Debugger::dump($variable)
Debugger::barDump($variable)
For more detailed usage and advanced features, refer to the Tracy documentation.
Emails
MailSender Class
The MailSender
class in Sukarix is used to send emails with a predefined template. The primary method for sending
emails is send()
, which has the following signature:
send($template, $vars, $to, $title, $subject): bool
Method Parameters
- $template: The name of the email template, which must be located in the
/mail
folder. - $vars: An array of variables to be used within the template.
- $to: The recipient's email address.
- $title: The title of the email.
- $subject: The subject line of the email.
Usage Example
Here’s how you might use the send()
method to send an email:
/**
* @var MailSender $mailSender
*/
$mailSender = Injector::instance()->get('mailer');
$template = 'welcome';
$vars = ['name' => 'John Doe', 'link' => 'https://example.com'];
$to = 'johndoe@example.com';
$title = 'Welcome to Our Service';
$subject = 'Getting Started with Our Service';
$mailSender->send($template, $vars, $to, $title, $subject);
This example sends a welcome email using the welcome
template, passing in the recipient’s name and a link to be used
within the email body.
Notifications
Notifier Class
The Notifier
class in Sukarix is designed to send notifications about exceptions that occur in the application. This
class extends the Tailored
class and uses the HasF3
and LogWriter
traits.
Methods
notifyException
The notifyException
method is responsible for sending an exception notification. It generates a unique error ID,
creates a notification message, and sends it to a specified Zulip stream.
Method Signature:
public function notifyException($exception): void
Parameters:
- $exception: An instance of
\Exception
containing the exception details to be notified.
Usage
Here is an example of how to use the notifyException
method:
/**
* @var Notifier $notifier
*/
$notifier = Injector::instance()->get('notifier');
try {
// Code that may throw an exception
} catch (\Exception $e) {
$notifier->notifyException($e);
}
Configuration
Ensure the following configuration settings in your .ini
file:
[globals]
; error notification channel "email" or "zulip"
error.channel = zulip
[NOTIFICATIONS.zulip]
token = "your-zulip-token"
mail = "your-zulip-email"
uri = "your-zulip-uri"
stream = "your-zulip-stream"
topic = "your-zulip-topic"
Translation / i18n
- Localisation Helper Class
- Methods
- Example Usage
- locales.js
- Example Usage in locales.js
- Routing for JSON localisation
- Caching
Localisation Helper Class
The I18n
class in Sukarix provides methods to retrieve localized strings from different translation tables. There are
four types of translation tables:
- Labels (
i18n.label
) - Messages (
i18n.message
) - Errors (
i18n.error
) - Lists (
i18n.list
)
Methods
lbl
Fetches a localized label.
public function lbl($key): string
msg
Fetches a localized message.
public function msg($key): string
err
Fetches a localized error message.
public function err($key): string
lst
Fetches a localized list.
public function lst($key): array
Example Usage
$i18n = Injector::instance()->get('i18n');
echo $i18n->lbl('welcome'); // Fetches the 'welcome' label
echo $i18n->msg('greeting'); // Fetches the 'greeting' message
echo $i18n->err('not_found'); // Fetches the 'not_found' error message
print_r($i18n->lst('countries')); // Fetches the 'countries' list
locales.js
The locales.js
file handles loading and switching of localisation data in JSON format.
Functions
- loadLocale: Loads the locale data from a JSON file.
- init: Initializes the locale settings and language menu.
- initLanguageMenu: Sets up the language selection menu.
- setLocale: Sets the current locale.
- switchLocale: Switches to the selected locale and updates the displayed strings.
- translaterStrings: Updates all strings in the document with localized content.
- get: Retrieves a localized string based on type, module, and key.
- err: Retrieves a localized error message.
- lbl: Retrieves a localized label.
- loc: Retrieves a localized string.
- msg: Retrieves a localized message.
- lst: Retrieves a localized list item.
Example Usage in locales.js
Locale.init(); // Initializes the locale settings
Locale.setLocale('en-GB'); // Sets the current locale to 'en-GB'
Locale.switchLocale('fr-FR'); // Switches to 'fr-FR' and updates the displayed strings
Routing for JSON localisation
The routing for generating JSON localisation files is defined as follows:
GET @locale: /locale/json/@locale.json = Sukarix\Actions\Core\GetLocale->execute
Caching
JSON locale data is cached whenever the translation file is updated to improve performance and reduce load times.
Behaviours
Introduction
Behaviours in Sukarix are traits that can be plugged into classes to extend their functionality. By convention,
an init<TraitName>
method should be implemented and is called immediately after the injector creates an instance of
the class using the trait.
Example Behaviours
-
LogWriter
- Description: Enables the implementing class to write to the application logs.
- Usage:
class MyClass { use LogWriter; public function initLogWriter() { // Initialization code for LogWriter } }
-
HasF3
- Description: Injects the
$f3
property into the class, providing access to the Fat-Free Framework instance. - Usage:
class MyClass { use HasF3; public function initHasF3() { // Initialization code for HasF3 } }
- Description: Injects the
Singleton Classes
Any singleton class inheriting from Tailored
will have the init<TraitName>
methods called by default. This ensures
that all behaviours are initialised properly without additional code.
Non-Singleton Classes
If a class does not inherit from Tailored
, it must call Processor::instance()->initialize($this);
in the constructor
to ensure that the init<TraitName>
methods are called.
Example Usage
Here’s how you might use these behaviours in a class:
class MyService {
use LogWriter;
use HasF3;
public function __construct() {
Processor::instance()->initialize($this); // Initialise traits manually
}
public function logSomething() {
$this->log->write('Logging something!');
}
public function getFrameworkInstance() {
return $this->f3;
}
}
In this example, MyService
uses both the LogWriter
and HasF3
traits. Since it does not extend Tailored
, it
explicitly calls Processor::instance()->initialize($this);
in the constructor to ensure that the traits are
initialised.
CRON / Task Scheduling
TaskScheduler
TaskScheduler
is an Action in Sukarix designed for task scheduling. The CLI toolbox installs it as a cron job by
default, utilizing the GO\Scheduler syntax.
Default Configuration
The route-cli.ini
file contains the default route for task scheduling:
[routes]
; route to the main task scheduler
GET @run_job : /cli/jobs/run [cli] = Actions\Jobs\TaskScheduler->execute
Setting Up Cron
The default cron job should contain:
* * * * * /usr/bin/php /var/www/sukarix/public/index.php "/cli/jobs/run"
Defining Jobs
Each job must be defined in route-cli.ini
. For example, the default log cleaning job is implemented as:
GET @logs_clean : /cli/logs/clean [cli] = Sukarix\Actions\Logs\Clean->execute
Implementing the Execute Function
The execute
function should schedule tasks using the scheduler
:
public function execute() {
// Clean old sessions every 8 hours at 10 minutes after the hour
$this->scheduler->php($this->documentRoot, null, ['/cli/sessions/clean' => ''], 'sessions-clean')
->onlyOne()
->at('20 */8 * * *');
}
This example schedules a session cleaning task to run every 8 hours at 10 minutes past the hour, ensuring only one instance runs at a time.
Events
Introduction
In Sukarix, events are managed using the Sukarix\Behaviours\HasEvents
trait. This allows any class to emit and handle events throughout the application using the Sugar Events system integrated with the PHP Fat-Free Framework.
Key Features of Sugar Events
- Emit events from any point in your application
- Attach multiple listeners to an event with priority
- Local events on specific objects
- Send payload and context data with events
- Support for sub-events and event propagation
- Stop the event chain
- Works with F3 v3.5 and PHP v7.2+
Example Usage
Initializing Events
To initialize the event system and get the global Event
instance:
$events = \Sugar\Event::instance();
Defining a Listener
You can define a listener (or hook) to an event using a typical F3 callstring, callback, or callable:
$events->on('user_login', 'Notification->user_login');
$events->on('user_login', function() {
// ...
});
$events->on('user_login', [$this, 'method']);
Emitting an Event
To emit an event and notify all listeners:
$events->emit('user_login');
Sending Payload with Event
You can send additional data (payload) with an event:
$events->on('user_login', function($username) {
\Logger::log($username . ' logged in');
});
$events->emit('user_login', 'freakazoid');
Multiple Listeners with Prioritization
Listeners can be prioritized; higher numbers are called first:
$events->on('user_login', function($username) {
\Logger::log($username . ' logged in');
}, 10);
$events->on('user_login', function() {
\Flash::addMessage('You have logged in successfully');
}, 20);
$events->emit('user_login', 'freakazoid');
Stopping the Event Chain
A listener can stop further listeners from being called:
$events->on('user_login', function($username) {
\Logger::log($username . ' logged in');
});
$events->on('user_login', function() {
\Flash::addMessage('You have logged in successfully');
return false;
}, 20);
$events->emit('user_login', 'freakazoid');
Additional Event Context Data
Send additional context data with an event:
$events->on('user_login', function($username, $context) {
if ($context['lang'] == 'en')
\Flash::addMessage('You have logged in successfully');
elseif ($context['lang'] == 'de')
\Flash::addMessage('Du hast dich erfolgreich angemeldet');
});
$events->emit('user_login', 'freakazoid', array('lang' => 'en'));
Additional Listener Options
Listeners can have additional options:
$events->on('user_login', function($username, $context, $event) {
\Flash::addMessage('You have logged in successfully', $event['options']['type']);
}, 20, array('type' => 'success'));
Filtering Payload
Listeners can modify and return the event payload:
$events->on('get_total', function($basket) {
$sum = 0;
foreach ($basket as $prod) {
$sum += $prod;
}
return $sum;
});
$products = array('a' => 2, 'b' => 8, 'c' => 15);
$sum = $events->emit('get_total', $products);
echo $sum; // 25
Adding Sub-Events
Sub-events are called after the parent event:
$events->on('get_total.tax', function($sum) {
return $sum + ($sum * 0.2);
});
$events->on('get_total.shipping', function($sum) {
return $sum + 5;
});
$sum = $events->emit('get_total', $products);
echo $sum; // 35
Removing Hooks
Remove listeners for specific events:
$events->off('get_total.tax');
$sum = $events->emit('get_total', $products);
echo $sum; // 30
Local Events for Mappers
Support for local events on specific objects:
$user = new \Model\User();
$events->watch($user)->on('update.email', '\Mailer->sendEmailActivationLink');
Error Handling
Introduction
In Sukarix, error handling is managed by a global error handler that can be overridden in the Application
class. The
default implementation uses Tracy\Debugger
for managing errors and handling fatal exceptions. The global exception
handling is only active in the production environment.
Default Implementation
The Application
class includes a protected method handleException()
that sets up the error handler. The default
implementation is capable of sending email or Zulip notifications based on the configuration of error.channel
. Before
sending the email, it stores the exception stack trace in HTML format. It's important to note that the error stack might
contain sensitive information, so sending it by default is not enabled.
Additionally, notifications for the same exception hash are sent only once every 24 hours.
Customizing Error Handling
To customize the error handling, you can override the handleException()
method in your Application
class:
protected function handleException(): void {
if (Debugger::$productionMode) {
Debugger::$onFatalError[] = function($exception) {
// Custom fatal error handling logic
};
}
}
Template Engine
Introduction
The template engine in Sukarix is built on top of the Fat-Free Framework's (F3) template engine. It provides a flexible and efficient way to render views, leveraging F3's powerful features while adding enhancements specific to Sukarix.
Template Loading
In Sukarix, templates are loaded into views using a specific pattern. By default, the view files are stored in
the templates
directory and have a .phtml
extension.
Mapping Actions to Templates
Sukarix maps actions to templates by following a convention-based approach. When an action
calls $this->render();
, it maps to the template based on the namespace and class name, converted to snake_case.
For example:
- Action Class:
Actions\Core\Main
- Mapped Template:
templates/actions/core/main.phtml
The default template extension in Sukarix is .phtml
and is automatically appended.
Example Code
$this->render('commons/api/response');
This method call will automatically render the templates/commons/api/response.phtml
when called from any action.
JavaScript and CSS Template Directives
Sukarix adds custom template directives for including JavaScript and CSS files in your views. These directives simplify the process of managing assets.
-
JavaScript Directive:
<js src="path/to/script.js" type="module"></js>
This directive is used to include JavaScript files in your view. You can pass an optional
type
attribute, such as"module"
. If thetype
attribute is not provided,"text/javascript"
will be chosen by default. -
CSS Directive:
<css href="path/to/style.css"></css>
This directive is used to include CSS files in your view.
The existence of the specified file is validated when the directive attempts to load it. If the file is not found, an exception will be thrown. This ensures that developers can handle missing files during the development phase before deploying to production.
By utilizing these custom directives, Sukarix ensures that assets are managed efficiently and that any issues with missing files are caught early in the development cycle.
F3 Template Directives
F3 provides a set of powerful template directives that make it easy to render dynamic content, control flow, and manage template inheritance. Some of the key directives include:
-
Include Directive:
<include href="partial.phtml" />
This directive includes another template file within the current template.
-
Repeat Directive:
<repeat group="{{ @items }}" value="{{ @item }}"> <!-- Content to repeat --> </repeat>
This directive repeats a block of content for each item in a collection.
-
Conditional Directive:
<check if="{{ @condition }}"> <!-- Content to show if condition is true --> </check>
This directive conditionally renders content based on a boolean expression.
-
Set Directive:
<set name="variable" value="value" />
This directive sets a variable to a specified value within the template.
-
Session Directive:
<session name="variable" />
This directive retrieves a value from the session.
-
Cookie Directive:
<cookie name="variable" />
This directive retrieves a value from cookies.
-
Locale Directive:
<locale name="variable" />
This directive retrieves a localized value.
Additional Resources
For more detailed information on F3's template engine and directives, you can refer to the F3 Views and Templates Documentation.
Assets
Introduction
Sukarix uses the Assets
class to manage and render CSS and JavaScript files efficiently. By default, it looks for CSS
files under public/css
and JavaScript files under public/js
.
Default Storage Locations
- CSS Files:
public/css
- JavaScript Files:
public/js
- Minified Files:
public/minified
The Assets
class automatically handles the minification of CSS and JS files and places the minified versions in
the public/minified
directory.
By default, CSS files are stored in public/css
, JavaScript files in public/js
, and minified files in public/minified
.
Rendering Groups
Sukarix provides two rendering groups named head
and footer
to organize asset rendering. To render these groups in
your template, use:
{{ \Sukarix\Helpers\Assets::instance()->renderGroup('footer') }}
JavaScript Initialization
The Assets
class can also call JavaScript functions and initialize them. Example:
<script>
jQuery(document).ready(function () {
{{ \Sukarix\Helpers\Assets::instance()->currentJsLocale() }}
{{ \Sukarix\Helpers\Assets::instance()->setUserRole() }}
{{ \Sukarix\Helpers\Assets::instance()->initJsClasses() }}
});
</script>
Example Usage
Adding CSS and JS Files in a View
In your action, you can add CSS and JS files like this:
$this->assets->addJs('core.js');
$this->assets->addJs('core/servers.js');
$this->assets->addJs('vendors/datatables.min.js');
$this->assets->addCss('datatables.min.css');
$f3->push('init.js', 'Servers');
Rendering Assets
To render assets in the head
group:
{{ \Sukarix\Helpers\Assets::instance()->renderGroup('head') }}
To render assets in the footer
group:
{{ \Sukarix\Helpers\Assets::instance()->renderGroup('footer') }}
By using these functionalities, Sukarix ensures efficient management and rendering of assets, enhancing the performance and maintainability of your web application.
JavaScript
Introduction
The default Sukarix application template includes locale.js
, which downloads the session locale using AJAX and
provides functions to access localized strings. Additionally, Common.userRole
is accessible via JavaScript and is set
from the session.
locale.js
locale.js
handles the localization of strings in your application. It downloads the session locale and provides easy
access to localized strings. This ensures that your application can support multiple languages and dynamically switch
between them based on the user's session.
Common.userRole
The Common.userRole
variable is set from the session and is accessible via JavaScript. This allows you to manage user
roles on the client side and adjust your application's behavior based on the user's role.
Minimalistic Implementation
Sukarix provides this minimalistic implementation, giving developers the flexibility to use modern frontend frameworks as needed. You can integrate libraries and frameworks such as React, Vue, or Angular to build more complex and interactive user interfaces.
Example Usage
Accessing Localized Strings
var welcomeMessage = Locale.msg('welcome');
console.log(welcomeMessage);
Using Common.userRole
if (Common.userRole === 'admin') {
console.log('User is an admin');
} else {
console.log('User is not an admin');
}
Users
Introduction
The User
Model class in Sukarix is the central class for managing users. It includes user status, roles, and
authentication mechanisms.
User Status
User status can be either active
or inactive
, managed using the Sukarix\Enum\UserStatus
enum.
User Roles
Sukarix provides four default user roles:
- visitor: Default role, represented as
*
in the routing ACL. - admin
- customer
- api: A user that can authenticate through HTTP basic authentication.
These roles impact the access control list (ACL) in the configuration and can be extended by developers as needed.
Extending User Roles
Developers can extend user roles by adding new roles to the UserRole
enum and updating the ACL configuration
accordingly. This allows for greater flexibility and customization to fit the needs of your application.
Authentication
Introduction
Sukarix provides a straightforward method for authenticating users using models and session management. Below are examples and explanations on how to implement authentication and handle user verification in Sukarix.
Authenticating a User
To authenticate a user, retrieve the user model by their email, check their status and role, and verify their password. If all conditions are met, authorize the user in the session.
Example Code
$user = new UserModel();
$user = $user->getByEmail($email);
if (UserStatus::ACTIVE === $user->status && UserRole::API !== $user->role && $user->verifyPassword($password)) {
$this->session->authorizeUser($user);
}
Authorizing a User
The authorizeUser
method is used to authorize a user in the session. This method sets the necessary session variables
to mark the user as authenticated.
Verifying API Users
In the Action
class, the isApiUserVerified()
method checks if a user has authenticated via the HTTP Basic Auth
header. This is useful for API endpoints where HTTP Basic Authentication is preferred.
Example Usage
if ($this->isApiUserVerified()) {
// API user is authenticated
}
Authorisation System
Introduction
The authorisation system in Sukarix is managed through the f3-access
library. The documentation for f3-access
is
available in the f3-access repository.
Access Instance
The access instance is available in classes using the HasAccess
behaviour trait. This trait integrates the access
control mechanisms provided by f3-access
into your Sukarix application.
Default Authorization System
The beforeroute
method of the Action
class implements the default authorization system. This method checks the
user's permissions before allowing access to specific routes or actions.
Security Best Practices
By default, everything is set to deny
in the template application for security reasons. This default setting ensures
that only explicitly allowed actions are accessible, enhancing the overall security of your application.
CSRF Protection
Overview
Sukarix provides built-in CSRF (Cross-Site Request Forgery) protection mechanisms to ensure the security of your forms and requests. By enabling CSRF protection, you can safeguard your application from unauthorized actions performed by malicious users.
Configuration
CSRF protection is configured in the config.ini
file. The following default settings enable CSRF protection and set
the token expiry time:
[SECURITY]
csrf.enabled = true
csrf.expiry = 3600
- csrf.enabled: Enables or disables CSRF protection.
- csrf.expiry: Sets the expiry time for the CSRF token in seconds (default is 3600 seconds or 1 hour).
The CSRF token has an expiry time configured in the config.ini
file. If the token has expired, it will be considered invalid. Ensure your application handles token expiry by prompting the user to refresh the form or session.
Generating CSRF Token
To include a hidden CSRF token input in your forms, use the <csrf/>
template directive. This directive generates a
hidden input field with the CSRF token, ensuring that each form submission includes a valid token.
Example Usage
<form method="post" action="{{ @ALIASES.login }}">
<csrf/>
<!-- other form fields -->
<input type="submit" value="Submit">
</form>
This example shows how to include a CSRF token in a form. The <csrf/>
directive automatically generates and includes
the token.
Validating CSRF Token
To validate the CSRF token, use the isCsrfValid()
method from the session. This method checks whether the token
submitted with the form matches the token stored in the user's session.
Example Usage
if ($this->session->isCsrfValid()) {
// Token is valid, proceed with form processing
} else {
// Token is invalid, handle the error
}
This code snippet shows how to validate the CSRF token when processing a form submission. If the token is valid, you can proceed with the form processing. If the token is invalid, handle the error appropriately.
Like many other frameworks, Sukarix handles a single CSRF token per session. This means that each user's session is associated with one unique CSRF token, which is used to validate all form submissions within that session.
Statera: The Testing Package
Overview
Statera is a testing package designed to work with Sukarix, offering an alternative to PHPUnit. It supports generating coverage reports in formats like Clover, HTML, and Text. Statera operates in both Web and CLI modes, providing flexible testing options.
Key Concepts
TestGroup
A TestGroup
is used to group multiple TestScenario
instances. It helps organize related test scenarios into logical
groups, making it easier to manage and run tests collectively.
TestScenario
A TestScenario
represents a specific test case or scenario. It encompasses multiple UnitTest
instances that define
the individual tests to be run as part of the scenario.
UnitTest
A UnitTest
is an individual test case created inside a TestScenario
. It contains the actual test logic and
assertions to verify the expected behavior of the code under test.
Running Tests
Statera can run tests in both Web and CLI modes, providing detailed coverage reports.
Sukarix Shell Toolbox
Introduction
The Sukarix Shell Toolbox is a versatile utility designed to assist with the configuration, development, monitoring, and
administration of Sukarix applications. It is installed by default in the tools
directory of the template application
when running vagrant up
and is currently optimized for Ubuntu 22.04.
Functionality
Configuration
- --version: Display Sukarix application version.
- --selfinstall: Make Sukarix runnable from anywhere.
Development
- --enabletests: Enable running unit tests.
- --test <-c>
: Run unit tests with a test name. Use -c
for coverage. - --fix: Fix PHP code style.
- --migrate: Run database migrations.
- --metrics: Generate code metrics.
Monitoring
- --check: Check configuration files and processes for problems.
Administration
- --pull: Pull source code from its repository.
- --deploy: Deploy the application on a production server.
- --build-docs: Build the documentation.
- --jobs: Install the cron jobs.
- --restart: Restart Sukarix Stack.
- --stop: Stop Sukarix Stack.
- --start: Start Sukarix Stack.
- --clean: Restart and clean all log files.
- --cleansessions: Clean sessions from the database.
- --status: Display the running status of components.
- --zip: Zip up log files for reporting an error.
Example Usage
# Display Sukarix application version
sukarix --version
# Enable running unit tests
sukarix --enabletests
# Run unit tests with a test name and coverage
sukarix --test -c <name>
# Check configuration files and processes for problems
sukarix --check
# Restart Sukarix Stack
sukarix --restart
Testing with Sukarix
The Sukarix Shell Toolbox provides several commands to facilitate testing, ensuring your application maintains high quality and reliability. Here’s how you can leverage these testing commands:
Enabling and Running Tests
Enable Tests
To enable the testing environment, use:
sukarix --enabletests
Running Unit Tests
Run unit tests with an optional coverage report using:
sukarix --test <-c> <name>
-c
: Generates a coverage report.<name>
: Specify the name of the test to run.
Deployment
Introduction
Deploying a Sukarix application involves several steps to ensure your code is properly set up on the production server.
Sukarix Deployment Basics
-
Upload Your Code:
- Transfer your application's codebase to the production server using your preferred method (e.g., FTP, SCP, or Git).
-
Ensure
sukarix.sh
is in thetools
Directory:- Make sure the
sukarix.sh
script is located in thetools
directory of your application.
- Make sure the
-
Run the Deployment Script:
- Execute the deployment script with the
-d
option:./tools/sukarix.sh -d
- This command performs the following actions:
- Pulls the latest code from the Git repository.
- Runs Composer to install dependencies.
- Applies default permissions to the
www-data
user. - Runs database migrations.
- Clears the application cache.
- Execute the deployment script with the
Contribution Guide
How to Contribute
We welcome contributions from the community! Here’s how you can help.
- Fork the Repository: Create a fork of the Sukarix repository.
- Create a Branch: Make a new branch for your feature or bugfix.
- Commit Changes: Commit your changes with clear commit messages.
- Create a Pull Request: Submit a pull request to the main repository.
Reporting Issues
If you find any bugs or have feature requests, please report them through GitHub Issues.
Community Help
We encourage everyone to contribute to Sukarix and be part of our vibrant community. Whether you have ideas for new features, need support with testing, or want to discuss CLI tools, your input is valuable. Join the conversations and help us improve Sukarix together:
Your contributions make a difference!
Code of Conduct
We strive to maintain a welcoming and inclusive community. Please read our Code of Conduct before contributing.
Thank you for your contributions!
Code of Conduct
Our Pledge
In the interest of fostering an open and welcoming environment, we pledge to make participation in our project and community a harassment-free experience for everyone.
Our Standards
Examples of behavior that contributes to creating a positive environment include:
- Using welcoming and inclusive language
- Being respectful of differing viewpoints and experiences
- Gracefully accepting constructive criticism
- Focusing on what is best for the community
- Showing empathy towards other community members
Examples of unacceptable behavior include:
- The use of inappropriate or unwelcome language or imagery
- Trolling, insulting/derogatory comments, and personal or political attacks
- Public or private harassment
- Publishing others’ private information, such as a physical or electronic address, without explicit permission
- Other conduct which could reasonably be considered inappropriate in a professional setting
Our Responsibilities
Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
Scope
This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community.
Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at [contact@riadvice.tn]. All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances.
Attribution
This Code of Conduct is adapted from the Contributor Covenant, version 1.4, available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html.
Release Notes
Support Policy
Sukarix is currently supported for PHP 8.2+.
Released versions
v0.1.0
🚀 Introduction
- Version Number: 0.1.0
- Release Date: 2024-06-14
- General Overview: First version of the Sukarix Framework.