diff --git a/versions/3.x/api-presenter.md b/versions/3.x/api-presenter.md index e5dd902..c8aefc9 100644 --- a/versions/3.x/api-presenter.md +++ b/versions/3.x/api-presenter.md @@ -8,7 +8,6 @@ meta: ## API Presenter -### Introduction The API Presenter provides a clean, consistent way to transform your application’s data models into structured API responses. Instead of returning raw Entity models or arrays directly from your controllers, the Presenter layer allows you to: diff --git a/versions/3.x/authentication.md b/versions/3.x/authentication.md index 442ac85..d83a9d6 100644 --- a/versions/3.x/authentication.md +++ b/versions/3.x/authentication.md @@ -7,7 +7,6 @@ meta: --- ## Authentication -### Introduction Authentication is a fundamental part of most web applications. It ensures that users can securely log in, access protected resources, and maintain session integrity. Doppar simplifies this process by providing built-in tools and scaffolding to help you implement user authentication quickly and securely. With a single command, you can generate the routes, controllers, and views necessary for user `login`, `registration`, and `logout`. Doppar's authentication system is built on top of robust components like session handling and secure password hashing, ensuring your users' data remains protected. diff --git a/versions/3.x/caching.md b/versions/3.x/caching.md index 2bec583..603ae64 100644 --- a/versions/3.x/caching.md +++ b/versions/3.x/caching.md @@ -8,8 +8,6 @@ meta: ## Caching -### Introduction - Every production application reaches a point where the same data gets fetched repeatedly: the same database query, the same API response, the same computed payload. Caching breaks that cycle. Instead of running the diff --git a/versions/3.x/collections.md b/versions/3.x/collections.md index 9b8fd8b..c571649 100644 --- a/versions/3.x/collections.md +++ b/versions/3.x/collections.md @@ -7,7 +7,6 @@ meta: --- ## Collections -### Introduction Doppar provides a convenient and fluent Collection class built on top of the powerful `ramsey/collection` package. Collections are an elegant and flexible way to work with arrays of data, especially when you want to perform transformations, filtering, grouping, and other operations in a chainable and expressive syntax. In Doppar, the Collection class enhances `Ramsey\Collection\Collection` with additional utility methods and integrations tailored for Doppar's ecosystem, including Entity model support and developer-friendly features like memory usage tracking and deep flattening. To make it easy to work with collections, Doppar provides the global `collect()` helper function: diff --git a/versions/3.x/configuration.md b/versions/3.x/configuration.md index a286cf1..2f99168 100644 --- a/versions/3.x/configuration.md +++ b/versions/3.x/configuration.md @@ -8,8 +8,6 @@ meta: ## Configuration -### Introduction - All configuration files for the Doppar framework are located in the `config` directory. These files define various options and settings that control how different parts of your application behave. Each configuration file is self-documented, so you are encouraged to explore and familiarize yourself with the available options. Doppar stores the compiled configuration cache in the following path `storage/framework/cache/*`. Doppar usage this config data where needed from this complied cache file. diff --git a/versions/3.x/controllers.md b/versions/3.x/controllers.md index d847d5f..f54fac9 100644 --- a/versions/3.x/controllers.md +++ b/versions/3.x/controllers.md @@ -7,7 +7,6 @@ meta: --- ## Controllers -### Introduction Rather than defining all request-handling logic as closures in route files, you can use controller classes to organize related functionality. Controllers centralize request handling, making your code more structured and maintainable. For example, a UserController can manage user-related actions like displaying, creating, updating, and deleting users. By default, controllers are stored in the `app/Http/Controllers` directory. ## Controller Auto-Discovery diff --git a/versions/3.x/datetime.md b/versions/3.x/datetime.md index f09221e..7b17c4b 100644 --- a/versions/3.x/datetime.md +++ b/versions/3.x/datetime.md @@ -7,7 +7,6 @@ meta: --- ## Datetime -### Introduction Doppar provides a robust and flexible system for working with dates and times, thanks to its integration with the Carbon library. However, understanding how timezones are managed—especially when using functions like `now()` or `Carbon::now()`—can be important when building applications that rely on accurate time data. By default, Doppar uses UTC as the base timezone for datetime functions such as `now()` and `Carbon::now()`. diff --git a/versions/3.x/deployment.md b/versions/3.x/deployment.md index 8682be0..9806f7e 100644 --- a/versions/3.x/deployment.md +++ b/versions/3.x/deployment.md @@ -7,8 +7,6 @@ meta: --- ## Deployment -### Introduction - Deploying a Doppar application is straightforward and optimized for both development and production environments. This guide outlines the essential steps to get your Doppar app running on a live server. ## Server Requirements diff --git a/versions/3.x/directory-structure.md b/versions/3.x/directory-structure.md index d3c9b12..7beddb4 100644 --- a/versions/3.x/directory-structure.md +++ b/versions/3.x/directory-structure.md @@ -7,7 +7,6 @@ meta: --- ## Directory Structure -### Introduction Doppar aims to provide a clean, expressive, and scalable codebase that accelerates web application development while remaining easy to understand and extend. Whether you're building RESTful APIs, full-stack web applications, or microservices, Doppar offers the foundation and flexibility you need. The framework is built around familiar conventions and emphasizes simplicity without compromising on power. It features an MVC (Model-View-Controller) architecture, a powerful routing system, middleware support, a service provider-based bootstrapping mechanism, and organized directory structures. Additionally, it integrates seamlessly with Composer for dependency management and supports environment-based configuration via .env files. diff --git a/versions/3.x/doppar-ai.md b/versions/3.x/doppar-ai.md index c5e2473..c041d05 100644 --- a/versions/3.x/doppar-ai.md +++ b/versions/3.x/doppar-ai.md @@ -7,7 +7,6 @@ meta: --- ## AI -### Introduction Doppar AI is a powerful component that brings advanced artificial intelligence capabilities to your PHP applications. It is built on top of **[Symfony AI](https://github.com/symfony/ai)** and **[Transformers.php](https://github.com/CodeWithKyrian/transformers-php)**, providing a smooth integration of machine learning models and large language models (LLMs) into your Doppar ecosystem. It provides two main components: **`Pipeline`** for running transformer-based machine learning tasks locally, and **`Agent`** for interacting with cloud-based large language models (LLMs) like OpenAI and Gemini. Whether you need sentiment analysis, text generation, image classification, or conversational AI, Doppar AI makes it simple and accessible. diff --git a/versions/3.x/doppar-airbend.md b/versions/3.x/doppar-airbend.md index de93059..f836ad9 100644 --- a/versions/3.x/doppar-airbend.md +++ b/versions/3.x/doppar-airbend.md @@ -8,7 +8,6 @@ meta: ## Airbend -### Introduction Doppar Airbend is a high-performance, real-time broadcasting component of the Doppar PHP Framework, engineered to deliver seamless WebSocket-based event broadcasting, robust channel authorization, and comprehensive performance monitoring. Designed for modern, scalable web applications, Airbend allows developers to build interactive and collaborative features—such as live notifications, chat systems, dashboards, and multiplayer experiences—directly within the Doppar ecosystem. Airbend is highly configurable, offering schema-driven validation and caching mechanisms for robust configuration management. It also includes a comprehensive metrics and monitoring suite, allowing teams to track connection states, message flows, memory usage, and performance statistics in real time. With built-in CLI commands, PHP attributes for declarative event broadcasting, and a developer-friendly facade interface, Doppar Airbend empowers developers to implement real-time features with minimal overhead while maintaining full control over the broadcasting pipeline. diff --git a/versions/3.x/doppar-axios.md b/versions/3.x/doppar-axios.md index ddf58e5..fe98f24 100644 --- a/versions/3.x/doppar-axios.md +++ b/versions/3.x/doppar-axios.md @@ -8,8 +8,6 @@ meta: ## Axios -### Introduction - Doppar Axios is a modern, feature-rich HTTP client for PHP, inspired by the simplicity of JavaScript clients like Axios but built on top of Symfony's robust `HttpClient`. Does not depends on doppar internal core, you can use it any PHP application. It does not depend on any internal Doppar core, making it suitable for use in any PHP application. ## Features diff --git a/versions/3.x/doppar-bloom.md b/versions/3.x/doppar-bloom.md index 73ff381..90c18be 100644 --- a/versions/3.x/doppar-bloom.md +++ b/versions/3.x/doppar-bloom.md @@ -7,7 +7,6 @@ meta: --- ## Bloom Filter -### Introduction A Bloom filter is a space-efficient probabilistic data structure, conceived by Burton Howard Bloom in 1970, that is used to test whether an element is a member of a set. False positive matches are possible, but false negatives are not – in other words, a query returns either "possibly in set" or "definitely not in set". Elements can be added to the set, but not removed (though this can be addressed with a "counting" filter); the more elements that are added to the set, the larger the probability of false positives. Doppar’s Bloom package provides a high-performance, memory-efficient probabilistic set membership test. Instead of storing every item, it keeps a compact bit array and uses hashing to answer: “Is this element possibly in the set?” (false positives possible, false negatives impossible). diff --git a/versions/3.x/doppar-flarion.md b/versions/3.x/doppar-flarion.md index 7893763..58e6209 100644 --- a/versions/3.x/doppar-flarion.md +++ b/versions/3.x/doppar-flarion.md @@ -7,7 +7,6 @@ meta: --- ## Flarion - API Authentication -### Introduction Flarion provides a lightweight API authentication system for the Doppar framework. Flarion allows each user of Doppar application to generate and manage multiple API tokens. These tokens are stateless and designed for use in mobile apps, third-party clients, or any frontend that communicates via a simple token-based API. diff --git a/versions/3.x/doppar-guard.md b/versions/3.x/doppar-guard.md index 3342949..575f963 100644 --- a/versions/3.x/doppar-guard.md +++ b/versions/3.x/doppar-guard.md @@ -8,8 +8,6 @@ meta: ## Guard - Authorization -### Introduction - Guard is a robust and extensible authorization system designed for the Doppar framework. It provides a clean, expressive API for defining and evaluating user abilities across your application. With features like one-time temporary permissions, ability inheritance, grouped permissions, wildcard patterns, ability aliases, conditional runtime gates, and global lifecycle hooks, Guard gives you complete control over access logic without cluttering your codebase. Guard is built to empower your Doppar applications with secure, scalable, and maintainable authorization logic. Whether you're building small tools or large systems, Guard adapts to your needs with clarity and power. diff --git a/versions/3.x/doppar-insight.md b/versions/3.x/doppar-insight.md index 27246a0..4338eb9 100644 --- a/versions/3.x/doppar-insight.md +++ b/versions/3.x/doppar-insight.md @@ -8,7 +8,6 @@ meta: ## Insight -### Introduction Doppar Insight is a request profiler for debugging, performance analysis, and traffic inspection. It gives you a clean in-browser toolbar for the current request, and it also keeps a recent request history so you can compare status codes, response times, errors, and route activity across multiple requests. Insight is useful when you want to inspect SQL queries, cache usage, authentication state, request and response payloads, session data, logs, or performance timing without leaving the page you are working on. It is designed for day-to-day development, but it is especially helpful when you need to trace slow endpoints or understand why a route is returning `4xx` or `5xx` responses. diff --git a/versions/3.x/doppar-notifier.md b/versions/3.x/doppar-notifier.md index 6974fb3..cb494b8 100644 --- a/versions/3.x/doppar-notifier.md +++ b/versions/3.x/doppar-notifier.md @@ -8,7 +8,6 @@ meta: ## Notifier -### Introduction A notification system allows you to send messages to users across multiple channels like email, SMS, Slack, Discord, and in-app notifications. Instead of sending notifications immediately and blocking your application, Doppar's notification system runs in the background using the powerful queue system, ensuring smooth user experiences and reliable delivery even under heavy load. Doppar notification system offers robust features including multi-channel delivery with support for `database`, `Slack`, `Discord`, and custom channel, secure model serialization that safely handles Eloquent models in notification payloads, and automatic retry logic with configurable attempts. diff --git a/versions/3.x/doppar-oauthic.md b/versions/3.x/doppar-oauthic.md index 1e8a3ae..adb0bc3 100644 --- a/versions/3.x/doppar-oauthic.md +++ b/versions/3.x/doppar-oauthic.md @@ -8,8 +8,6 @@ meta: ## OAuthic -### Introduction - Doppar OAuthic is a modern, extensible authentication package that simplifies OAuth 2.0 integration in Doppar Framework. In addition to traditional, form-based authentication, Doppar OAuthic offers a clean, convenient interface for authenticating users via popular OAuth providers such as `Google`, `GitHub`, and `LinkedIn`. It also supports custom drivers, giving you full control over provider integrations. Whether you're building a microservice, a SaaS product, or integrating with social platforms, Doppar OAuthic makes OAuth 2.0 secure, consistent, and easy to implement. diff --git a/versions/3.x/doppar-orion.md b/versions/3.x/doppar-orion.md index b24e6f9..8de4887 100644 --- a/versions/3.x/doppar-orion.md +++ b/versions/3.x/doppar-orion.md @@ -7,7 +7,6 @@ meta: --- ## Processes -### Introduction The Doppar Framework provides a powerful and expressive abstraction over the [Symfony Process Component](https://symfony.com/doc/current/components/process.html) via the Process facade. This feature enables developers to run and manage system-level commands and scripts with ease—whether synchronously, asynchronously, or in concurrent pools. ### Key Features diff --git a/versions/3.x/doppar-queue.md b/versions/3.x/doppar-queue.md index af5809f..8275b97 100644 --- a/versions/3.x/doppar-queue.md +++ b/versions/3.x/doppar-queue.md @@ -7,7 +7,6 @@ meta: --- ## Queue -### Introduction A queue is a background job processing system that allows tasks to run asynchronously instead of blocking your main application flow. It improves performance, distributes workload efficiently, and ensures time-consuming tasks are handled reliably in the background. Queues are essential for scaling modern applications and maintaining smooth user experiences. Doppar queue system offers robust features including multiple queue support for organizing jobs by priority or category, automatic retry logic with configurable attempts and delays, and comprehensive failed job tracking for easier debugging. It supports delayed execution for scheduling jobs in the future, graceful shutdown handling to safely stop workers, and built-in memory management that automatically restarts workers when limits are exceeded. diff --git a/versions/3.x/doppar-twig-bridge.md b/versions/3.x/doppar-twig-bridge.md index cdb55c9..bd0af32 100644 --- a/versions/3.x/doppar-twig-bridge.md +++ b/versions/3.x/doppar-twig-bridge.md @@ -8,8 +8,6 @@ meta: ## Twig Bridge -### Introduction - The Doppar Twig Bridge is an integration layer that allows applications built on the Doppar Framework to render views using Twig, a powerful and flexible templating engine. The bridge is intentionally minimalistic and non-intrusive so you can adopt Twig progressively without disrupting your existing Odo-based templates. This document provides an in-depth explanation of how the bridge works, how to install it, and how to use it effectively in real-world Doppar applications. diff --git a/versions/3.x/encryption.md b/versions/3.x/encryption.md index a4c79f6..be72970 100644 --- a/versions/3.x/encryption.md +++ b/versions/3.x/encryption.md @@ -7,7 +7,6 @@ meta: --- ## Encryption -### Introduction Doppar's encryption services provide a simple, convenient interface for encrypting and decrypting text via PHP's OpenSSL using `AES-256` and `AES-128` encryption. All of Doppar's encrypted values are signed using a message authentication code (MAC) so that their underlying value cannot be modified or tampered with once encrypted. Before using Doppar's encrypter, you must set the key configuration option in your `config/app.php` configuration file. This configuration value is driven by the `APP_KEY` environment variable. You should use the php pool `key:generate` command to generate this variable's value since the `key:generate` command will use PHP's secure random bytes generator to build a cryptographically secure key for your application. Typically, the value of the `APP_KEY` environment variable will be generated for you during Doppar's installation. diff --git a/versions/3.x/entity-builder.md b/versions/3.x/entity-builder.md index bed3b1c..cb874cf 100644 --- a/versions/3.x/entity-builder.md +++ b/versions/3.x/entity-builder.md @@ -19,7 +19,6 @@ meta: - [Handling Multiple Database Connection](#handling-multiple-database-connection) ## Entity Builder -### Introduction Doppar introduces Entity Builder, a powerful, flexible, and model-free query builder designed for developers who want full control over their database interactions — without the need for predefined data models. With Entity Builder, you can construct, execute, and manage complex SQL queries using a clean, expressive, and chainable interface. Whether you're fetching data, inserting records, updating fields, or performing intricate joins and filters, Entity Builder brings the full power of SQL into an intuitive, object-oriented syntax that feels natural and effortless. diff --git a/versions/3.x/entity-orm.md b/versions/3.x/entity-orm.md index e2caea0..a0fbf6b 100644 --- a/versions/3.x/entity-orm.md +++ b/versions/3.x/entity-orm.md @@ -22,7 +22,6 @@ meta: - [Handling Multiple Database Connection](#handling-multiple-database-connection) ## Entity ORM -### Introduction Doppar introduces Entity, a modern, intuitive, and powerful Object-Relational Mapper (ORM) designed to make database interactions seamless and efficient. With Entity ORM, every database table is represented by a dedicated Data Model, providing a clean, object-oriented interface to query, insert, update, and delete records without writing raw SQL. Beyond simple CRUD operations, Doppar Entity ORM empowers developers to build complex queries, manage relationships effortlessly, and perform advanced data operations with clarity and precision. Features like eager loading, nested relationships, and relationship-based filtering let you work with related data intuitively, reducing boilerplate code and boosting productivity. diff --git a/versions/3.x/error-handling.md b/versions/3.x/error-handling.md index 5950b71..97f595b 100644 --- a/versions/3.x/error-handling.md +++ b/versions/3.x/error-handling.md @@ -7,7 +7,6 @@ meta: --- ## Error Handling -### Introduction Error handling is a crucial aspect of web application development. It not only allows you to catch and handle potential errors gracefully but also ensures that users receive meaningful feedback when something goes wrong. In the Doppar framework, managing HTTP errors is seamless and allows you to customize responses to provide a better user experience. Whether it’s handling unexpected server errors, invalid page requests, or custom HTTP responses, Doppar provides a flexible and intuitive system for managing these issues. By using tools like the `abort()` function, custom error pages, and HTTP status codes, you can ensure that your application responds in a way that makes sense for your users. diff --git a/versions/3.x/facades.md b/versions/3.x/facades.md index 0b0c1c2..1deb535 100644 --- a/versions/3.x/facades.md +++ b/versions/3.x/facades.md @@ -8,8 +8,6 @@ meta: ## Facades -### Introduction - Doppar facades are static proxies to services bound in the application's service container. They give you a clean, expressive way to access framework features without manually injecting or instantiating classes. diff --git a/versions/3.x/file-storage.md b/versions/3.x/file-storage.md index 415bd59..6a8b55b 100644 --- a/versions/3.x/file-storage.md +++ b/versions/3.x/file-storage.md @@ -7,7 +7,6 @@ meta: --- ## File Uploads -### Introduction Doppar's filesystem configuration file is located at `config/filesystem.php`. Within this file, you may configure all of your filesystem "disks". Each disk represents a particular storage driver and storage location. Example configurations for each supported driver are included in the configuration file so you can modify the configuration to reflect your storage preferences and credentials. You may configure as many disks as you like and may even have multiple disks that use the same driver. But if you change any of your configuration, and that is not wokring, please clean the application configuration by running the command `config:clear`. diff --git a/versions/3.x/flash-message.md b/versions/3.x/flash-message.md index b09152a..7e33076 100644 --- a/versions/3.x/flash-message.md +++ b/versions/3.x/flash-message.md @@ -7,7 +7,6 @@ meta: --- ## Flash Message -### Introduction Flash messages are short-lived session messages used to give users feedback after certain actions — like form submissions, authentication, or redirects. These messages persist only for the next HTTP request and are automatically removed after they are read. Doppar provides an elegant and expressive syntax to retrieve flash messages during redirects, making it easy to give users a seamless experience. diff --git a/versions/3.x/frozen-services.md b/versions/3.x/frozen-services.md index ea82906..f8a72e1 100644 --- a/versions/3.x/frozen-services.md +++ b/versions/3.x/frozen-services.md @@ -8,8 +8,6 @@ meta: ## Frozen Services -### Introduction - Frozen Services is a container-level feature in Doppar that enforces a clear lifecycle boundary for your application's singleton services. A service marked with the `#[Immutable]` attribute is fully configurable during the application boot phase — your service providers can set it up from config files, environment variables, databases, or any external source — and then **permanently frozen** once the container completes its build. After freezing, any attempt to mutate a property on that service throws an `ImmutableViolationException` immediately, regardless of where in the application the mutation is attempted — controllers, middleware, event listeners, closures, or anywhere else. @@ -23,9 +21,9 @@ A Frozen Service is a singleton service whose state becomes permanently read-onl During the boot phase, the service can be fully configured from configuration files, environment variables, databases, or any external source. Once the container completes building the service, Doppar freezes the instance and guarantees that its public state cannot change for the rest of the request lifecycle. This creates a strict and enforceable boundary: -- *Boot phase* → configuration is allowed -- *Runtime phase* → mutation is impossible -- *Guarantee* → every consumer receives a consistent, trustworthy instance +- Boot phase → configuration is allowed +- Runtime phase → mutation is impossible +- Guarantee → every consumer receives a consistent, trustworthy instance They eliminate an entire class of bugs caused by accidental shared-state mutation. diff --git a/versions/3.x/hashing.md b/versions/3.x/hashing.md index 2702cd1..16021a4 100644 --- a/versions/3.x/hashing.md +++ b/versions/3.x/hashing.md @@ -7,7 +7,6 @@ meta: --- ## Hashing -### Introduction Hashing is a critical part of securing sensitive data in web applications, particularly when it comes to storing passwords. Unlike encryption, which can be reversed to retrieve the original data, hashing is a one-way process designed to securely transform data (such as passwords) into a fixed-length string of characters. When a user creates or updates their password, the application does not store the raw password. Instead, it stores a hashed version of the password, which is a unique string generated by a cryptographic algorithm. This ensures that even if the database is compromised, the actual passwords are not exposed. diff --git a/versions/3.x/helpers.md b/versions/3.x/helpers.md index ee77093..0fbf862 100644 --- a/versions/3.x/helpers.md +++ b/versions/3.x/helpers.md @@ -7,7 +7,6 @@ meta: --- ## Helpers -### Introduction Doppar offers a rich set of global helper functions designed to streamline common tasks throughout your application. These helpers encapsulate repetitive logic and provide a more expressive, readable syntax for tasks like working with arrays, strings, URLs, paths, and more. While many of these functions are used internally by the framework itself, they are fully accessible within your application and can significantly simplify your code when used appropriately. diff --git a/versions/3.x/hooks.md b/versions/3.x/hooks.md index 2bcf3fb..000b8ae 100644 --- a/versions/3.x/hooks.md +++ b/versions/3.x/hooks.md @@ -6,7 +6,6 @@ meta: content: Model Hooks, Lifecycle, before_created, after_created, before_updated, after_updated, before_deleted, after_deleted, booting, booted --- -- [Introduction](#introduction) - [Supported Events](#supported-events) - [Hook Registration Formats](#hook-registration-formats) - [Array Property Hooks](#array-property-hooks) @@ -34,8 +33,6 @@ meta: - [Important Constraints](#important-constraints) ## Hooks -### Introduction - Model Hooks in Doppar provide a clean, expressive way to respond to lifecycle events on your models. They allow you to execute custom logic automatically when specific events occur — such as when a model is being created, updated, deleted, or booted for the first time. Hooks are the right place for cross-cutting concerns that belong close to the model but should not live inside your controllers or service classes. Common use cases include: diff --git a/versions/3.x/lens.md b/versions/3.x/lens.md index e926610..d450e81 100644 --- a/versions/3.x/lens.md +++ b/versions/3.x/lens.md @@ -7,7 +7,6 @@ meta: --- ## Lens -### Introduction The `Phaseolies\Support\Lens` utility is a powerful and expressive helper for working with PHP arrays. Inspired by functional programming principles and dot notation access patterns, it provides a clean, chainable, and readable way to access, modify, flatten, and filter arrays — including deeply nested structures. Whether you're working with configuration data, nested API responses, or transforming data collections, `Lens` simplifies your logic and keeps your code expressive. diff --git a/versions/3.x/localization.md b/versions/3.x/localization.md index 523fd00..01e9857 100644 --- a/versions/3.x/localization.md +++ b/versions/3.x/localization.md @@ -7,7 +7,6 @@ meta: --- ## Localization -### Introduction Localization is a key feature in Doppar that allows your application to support multiple languages. It enables you to display content in the user's preferred language by using translation files stored in the `lang` directory. Doppar provides several tools to work with localization, including facades and helper functions. ## Setting the Locale diff --git a/versions/3.x/logging.md b/versions/3.x/logging.md index f924fcd..4407b2e 100644 --- a/versions/3.x/logging.md +++ b/versions/3.x/logging.md @@ -8,8 +8,6 @@ meta: ## Logging -### Introduction - Logging is one of the first tools you reach for when you need to understand what happened inside a request, background command, or integration flow. Doppar's logging layer is built on top of diff --git a/versions/3.x/mail.md b/versions/3.x/mail.md index 788cd06..cfebc92 100644 --- a/versions/3.x/mail.md +++ b/versions/3.x/mail.md @@ -7,7 +7,6 @@ meta: --- ## Mail -### Introduction Doppar provides a robust and flexible mailing system using `PHPMailer` that enables your application to send emails using various drivers. The `config/mail.php` configuration file manages all mail-related settings, including the default mailer, SMTP credentials, and global “from” addresses. This file allows you to define how your application handles outgoing email by setting up one or more mailers, each with its own configuration. By default, Doppar uses the smtp mailer, but you can customize or extend this based on your requirements. diff --git a/versions/3.x/middleware.md b/versions/3.x/middleware.md index 9ec78fb..e93050a 100644 --- a/versions/3.x/middleware.md +++ b/versions/3.x/middleware.md @@ -7,7 +7,6 @@ meta: --- ## Middleware -### Introduction Middleware offers a powerful way to inspect, filter, and act on HTTP requests before they reach your application's core logic. For instance, Doppar includes built-in middleware that ensures a user is authenticated. If the user isn't authenticated, the middleware can redirect them to a login page; otherwise, it allows the request to proceed. Beyond authentication, middleware can handle a wide range of tasks. For example, a logging middleware might record every incoming request, while another could handle input sanitization or API rate limiting. Doppar comes bundled with several useful middleware for tasks like authentication and CSRF protection. Custom middleware can be created and are typically stored in the `app/Http/Middleware` directory of your application. diff --git a/versions/3.x/migrations.md b/versions/3.x/migrations.md index 77ac839..1e8c3fd 100644 --- a/versions/3.x/migrations.md +++ b/versions/3.x/migrations.md @@ -8,8 +8,6 @@ meta: ## Database Migration -### Introduction - Managing database schema changes manually is error-prone and difficult to coordinate across teams and environments. The migration system solves this by providing a structured, version-controlled way to evolve your database schema over time — keeping diff --git a/versions/3.x/model.md b/versions/3.x/model.md index 0283d33..7013491 100644 --- a/versions/3.x/model.md +++ b/versions/3.x/model.md @@ -12,7 +12,6 @@ content: Model - [Computed Properties](#computed-properties) ## Model -### Introduction Before diving into Doppar's data management capabilities, it’s important to familiarize yourself with some key model properties that shape how your data is handled. Doppar offers the flexibility to customize these properties to suit your specific needs. Key properties include `$pageSize`, which controls the number of records displayed per page; `$primaryKey`, which defines the unique identifier for your table; $table, which specifies the database table associated with the model; `$creatable`, which determines whether new records can be added and `$unexposable` and `$timeStamps`, which allows you to hide sensitive or irrelevant data from being exposed and handle datetime columns. The `$connection` property specifies the database connection the model should use. Once this property is defined, all queries and operations on the model will automatically use the specified connection With Doppar, you have full control to tweak these properties, ensuring your data interactions are both efficient and secure. Let's see the User model as for example. ## Creating Model Classes diff --git a/versions/3.x/observable-model.md b/versions/3.x/observable-model.md index 802661d..82e0fee 100644 --- a/versions/3.x/observable-model.md +++ b/versions/3.x/observable-model.md @@ -6,7 +6,6 @@ meta: content: Watches, Observable, Model, Reactive, Doppar, Property Observer --- -- [Introduction](#introduction) - [How Watches Work](#how-watches-work) - [Generating a Watcher](#generating-a-watcher) - [Defining a Watch](#defining-a-watch) @@ -26,8 +25,6 @@ meta: ## Observable Model -### Introduction - Observable Model Properties let you declare reactive watchers directly on model properties using the `#[Watches]` PHP attribute. When a watched property is modified and `save()` or `update()` succeeds, Doppar automatically detects the change and invokes your watcher — passing the old value, the new value, and the full model instance. This is **property-level** observation. It is fundamentally different from Doppar's own `#[Hook]` system (which fires on lifecycle events like `before_updated`). Watches react to which specific column changed and what its new value is. diff --git a/versions/3.x/odo-templates.md b/versions/3.x/odo-templates.md index 596d7d7..9827c47 100644 --- a/versions/3.x/odo-templates.md +++ b/versions/3.x/odo-templates.md @@ -8,8 +8,6 @@ meta: ## Odo Templates -### Introduction - Doppar includes **Odo**, a modern, lightweight, and fully customizable templating engine designed exclusively for the Doppar Framework. Odo makes it easy to build dynamic HTML views using expressive directives and clean syntax — without scattering raw PHP throughout your markup. Instead of writing PHP directly in your views, Odo gives you readable, expressive template directives like `#if`, `#foreach`, and `#include`, along with powerful echo tags like `[[ ]]`, `[[! !]]`, and `[[[ ]]]`. diff --git a/versions/3.x/package-development.md b/versions/3.x/package-development.md index 639f7d3..9903a25 100644 --- a/versions/3.x/package-development.md +++ b/versions/3.x/package-development.md @@ -7,7 +7,6 @@ meta: --- ## Doppar Framework – Package Development Guide -### Introduction Welcome to the official Doppar Framework Package Development Guide! This document walks you through the full lifecycle of creating, structuring, and maintaining packages within the Doppar PHP ecosystem. In Doppar, packages are designed to promote modularity, reusability, and maintainability within applications. By encapsulating functionality into discrete, self-contained components, developers can isolate concerns and build features that are easy to test, share, and maintain. diff --git a/versions/3.x/pool-console.md b/versions/3.x/pool-console.md index d4800ef..4e75b62 100644 --- a/versions/3.x/pool-console.md +++ b/versions/3.x/pool-console.md @@ -7,7 +7,6 @@ meta: --- ## Pool Console -### Introduction Pool Console is Doppar's built-in command-line interface (CLI), designed to streamline development and automate repetitive tasks. The entry point is the `pool` script located at the root of your project. It provides a wide range of built-in commands and lets you register your own custom commands to run from the terminal. To see every available command grouped by category, run: diff --git a/versions/3.x/property-casts.md b/versions/3.x/property-casts.md index 94179ee..000f36e 100644 --- a/versions/3.x/property-casts.md +++ b/versions/3.x/property-casts.md @@ -7,8 +7,6 @@ meta: --- ## Attribute Casting -### Introduction - Attribute casting allows you to automatically transform model attribute values when reading from or writing to the database — without cluttering your application code with manual type conversions. Databases store everything as strings, integers, or raw bytes. Without casting, your PHP code is littered with `(bool)`, `(int)`, `json_decode()`, and `Carbon::parse()` calls scattered across controllers and services. Doppar's casting system centralises all of this transformation logic on the model itself — declared once, applied everywhere. diff --git a/versions/3.x/rate-limiting.md b/versions/3.x/rate-limiting.md index 8257f43..2743cd0 100644 --- a/versions/3.x/rate-limiting.md +++ b/versions/3.x/rate-limiting.md @@ -7,7 +7,6 @@ meta: --- ## Rate Limiter -### Introduction Rate limiting is a technique used to control the number of requests a client can make to an endpoint within a specified timeframe. It helps prevent abuse, reduce server load, and enhance security by limiting how frequently a user can access a given route. By applying rate limits to routes or groups of routes, Doppar ensures fair usage and protects your system from potential misuse. In the Doppar PHP framework, you can apply rate limiting to specific routes using middleware. diff --git a/versions/3.x/relationships.md b/versions/3.x/relationships.md index 3e9b350..77e4ae3 100644 --- a/versions/3.x/relationships.md +++ b/versions/3.x/relationships.md @@ -17,7 +17,6 @@ meta: - [Relationship Count](#relationship-count) ## Relationships -### Introduction The Doppar Entity relationship system provides a powerful way to represent and manage connections between database tables in an object-oriented manner. In real-world applications, tables are often interconnected. For instance, a library system might have Book records linked to multiple Author records, or a Customer may have multiple Orders. Doppar Entity ORM makes it simple to define and work with these relationships, whether one-to-one, one-to-many, or many-to-many. diff --git a/versions/3.x/request-lifecycle.md b/versions/3.x/request-lifecycle.md index 3d506bf..30080b5 100644 --- a/versions/3.x/request-lifecycle.md +++ b/versions/3.x/request-lifecycle.md @@ -8,8 +8,6 @@ meta: ## Request Lifecycle -### Introduction - Understanding the request lifecycle makes the framework easier to reason about. When you know where the request enters, how it becomes a response, and what runs after the response is sent, debugging and diff --git a/versions/3.x/requests.md b/versions/3.x/requests.md index ade4e88..f5e2669 100644 --- a/versions/3.x/requests.md +++ b/versions/3.x/requests.md @@ -8,8 +8,6 @@ meta: ## HTTP Requests -### Introduction - Doppar’s `Phaseolies\Http\Request` class provides a powerful, object-oriented interface for working with the current HTTP request. It goes far beyond simple input retrieval—offering an expressive API designed for modern, data-driven applications. With the Request class, you can seamlessly: diff --git a/versions/3.x/responses.md b/versions/3.x/responses.md index 0d1b45d..d0c16e2 100644 --- a/versions/3.x/responses.md +++ b/versions/3.x/responses.md @@ -8,8 +8,6 @@ meta: ## HTTP Responses -### Introduction - Every web application communicates with clients through HTTP responses. Whether you're building a REST API, a traditional web application, or a hybrid system, crafting proper responses is fundamental to creating reliable software. The Doppar framework provides a powerful and expressive response system that handles everything from simple text output to complex streamed data transfers. The response layer abstracts HTTP protocol complexities while giving you fine-grained control when you need it. diff --git a/versions/3.x/routing.md b/versions/3.x/routing.md index 82d4667..5dc7597 100644 --- a/versions/3.x/routing.md +++ b/versions/3.x/routing.md @@ -7,7 +7,6 @@ meta: --- ## Routing -### Introduction Doppar’s routing system, available through the `Phaseolies\Support\Facades\Route` namespace and using `Phaseolies\Utilities\Attributes\Route` attributes, provides a clean, expressive way to define your application’s URL structure and map it to the appropriate controller actions or closures. Doppar’s routing engine offers features such as route prefix grouping, named routes, throttling, middleware assignment, and RESTful resource routing. Whether you’re building a lightweight API or a complex web application, Doppar’s routing system ensures your code remains consistent, maintainable, and scalable. diff --git a/versions/3.x/seeders.md b/versions/3.x/seeders.md index c4666b0..6cf9146 100644 --- a/versions/3.x/seeders.md +++ b/versions/3.x/seeders.md @@ -7,7 +7,6 @@ meta: --- ## Database Seeder -### Introduction Database seeding is a crucial aspect of web application development, especially when populating your database with sample data for testing or development. Doppar supports database seeding, allowing you to easily generate data using custom seed classes. Seed classes are stored in the `database/seeders` directory, and you can use them to define the data that should be inserted into your database tables. diff --git a/versions/3.x/service-container.md b/versions/3.x/service-container.md index 1da280f..2bb57b2 100644 --- a/versions/3.x/service-container.md +++ b/versions/3.x/service-container.md @@ -7,7 +7,6 @@ meta: --- ## Service Container -### Introduction The Doppar Service Container is a robust and versatile tool designed to streamline dependency management and facilitate dependency injection within application. At its core, dependency injection is a sophisticated concept that simplifies how class dependencies are handled: instead of a class creating or managing its own dependencies, they are "injected" into the class—typically through the constructor or, in certain scenarios, via setter methods. This approach promotes cleaner, more modular, and testable code, making the Doppar framework an ideal choice for modern, scalable web development. Background diff --git a/versions/3.x/service-providers.md b/versions/3.x/service-providers.md index 4511b6c..4a8981f 100644 --- a/versions/3.x/service-providers.md +++ b/versions/3.x/service-providers.md @@ -8,8 +8,6 @@ meta: ## Service Providers -### Introduction - In Doppar, a service provider is the place where a feature joins the framework. diff --git a/versions/3.x/session.md b/versions/3.x/session.md index e2b49a2..887bc72 100644 --- a/versions/3.x/session.md +++ b/versions/3.x/session.md @@ -7,7 +7,6 @@ meta: --- ## HTTP Session -### Introduction Since HTTP is inherently stateless, Doppar provides session support to maintain user-specific data across multiple requests. Sessions allow your application to temporarily store information—such as user preferences, login status, or flash messages—that can persist between page loads. In Doppar, session data is stored using a backend driver. Out of the box, Doppar supports file-based and cookie-based session drivers, giving you flexibility based on your application's scale and environment. diff --git a/versions/3.x/stream-collection.md b/versions/3.x/stream-collection.md index a0903a0..0115feb 100644 --- a/versions/3.x/stream-collection.md +++ b/versions/3.x/stream-collection.md @@ -7,7 +7,6 @@ meta: --- ## Stream Collections -### Introduction Doppar’s `StreamCollection` provides a lazy, memory-efficient way to handle large or infinite datasets. Built on top of PHP’s powerful generator system, StreamCollection enables data to be processed incrementally, only as needed, instead of materializing the entire dataset in memory. This design makes it exceptionally well suited for working with large files, database cursors, API streams, or any situation where efficiency and scalability are critical. Unlike a traditional collection, which stores all of its items in memory, a StreamCollection represents a continuous flow of data that can be transformed, filtered, and mapped lazily through an expressive, chainable API. Each operation — such as `map()`, `filter()`, or `chunk()` — returns a new stream without evaluating the underlying data until you explicitly iterate or collect it. This approach makes it possible to build complex data-processing pipelines that remain elegant, composable, and performant even when working with gigabytes of information. diff --git a/versions/3.x/task-schedule.md b/versions/3.x/task-schedule.md index a37b90a..fee263a 100644 --- a/versions/3.x/task-schedule.md +++ b/versions/3.x/task-schedule.md @@ -7,7 +7,6 @@ meta: --- ## Task Schedule -### Introduction In Doppar, scheduled tasks allow you to automate repetitive operations such as sending emails, processing invoices, or cleaning up stale data — all defined directly inside your application. Instead of relying on scattered shell scripts or manually crafted crontabs, you register every schedule in a single `App\Schedule\Schedule` class. This keeps your automation logic version-controlled, readable, and easy to maintain. Doppar's scheduler supports two modes of execution: a standard minute-based mode compatible with any system cron, and a built-in daemon mode capable of sub-minute, per-second precision. Both modes share the same expressive API. diff --git a/versions/3.x/temporal-orm.md b/versions/3.x/temporal-orm.md index a8c2a4a..ed4aba4 100644 --- a/versions/3.x/temporal-orm.md +++ b/versions/3.x/temporal-orm.md @@ -6,7 +6,6 @@ meta: content: Temporal, Time-Travel, ORM, History, Audit, Snapshot --- -- [Introduction](#introduction) - [How It Works](#how-it-works) - [Marking a Model as Temporal](#marking-a-model-as-temporal) - [Attribute Options](#attribute-options) @@ -23,8 +22,6 @@ content: Temporal, Time-Travel, ORM, History, Audit, Snapshot ## Temporal ORM -### Introduction - Doppar's **Temporal Time-Travel ORM** gives every model a complete, automatic audit history. Every time a record is created, updated, or deleted, a full snapshot of its state is written to a companion history table. You can then query what any record looked like at any point in the past — down to the microsecond — without changing a single line of your existing model or controller code. This is useful for: diff --git a/versions/3.x/validation.md b/versions/3.x/validation.md index 4fffde2..6614ac6 100644 --- a/versions/3.x/validation.md +++ b/versions/3.x/validation.md @@ -7,7 +7,6 @@ meta: --- ## Validation -### Introduction Doppar offers multiple flexible ways to validate incoming data in your application. The most common approach is using the `sanitize()` method available on all HTTP request instances, making it easy to apply validation directly where data enters your system. Beyond this, Doppar provides a robust set of built-in validation rules that you can apply to ensure your data meets expected formats and constraints. This includes powerful features like checking for unique values within database tables. diff --git a/versions/3.x/views.md b/versions/3.x/views.md index ce4b972..969777e 100644 --- a/versions/3.x/views.md +++ b/versions/3.x/views.md @@ -7,7 +7,6 @@ meta: --- ## Views -### Introduction In Doppar, it's not practical to return entire HTML document strings directly from your routes and controllers. Fortunately, views offer a clean and structured way to manage your application's UI by keeping HTML in separate files. Views help separate your application's logic from its presentation layer, improving maintainability and readability. In Doppar, views are typically stored in the `resources/views` directory. The templating system in Doppar allows you to create dynamic and reusable UI components efficiently. A basic view file might look like this: diff --git a/versions/4.x/api-presenter.md b/versions/4.x/api-presenter.md index 570643e..64cc093 100644 --- a/versions/4.x/api-presenter.md +++ b/versions/4.x/api-presenter.md @@ -8,8 +8,6 @@ meta: ## API Presenter -### Introduction - The API Presenter provides a structured and consistent way to transform application data into clean, predictable API responses. Rather than exposing your Entity models or raw arrays directly from controllers, Presenters give you a dedicated layer for defining how your data should be represented to API consumers. A Presenter acts as a presentation layer between your application’s data and its JSON response. It allows you to control which attributes are exposed, transform and format values, conditionally include additional data, and organize related resources without placing presentation logic inside your controllers. This keeps your controllers focused on application flow while making API responses easier to maintain and evolve. diff --git a/versions/4.x/architecture-concept.md b/versions/4.x/architecture-concept.md index 0cfb150..3397b63 100644 --- a/versions/4.x/architecture-concept.md +++ b/versions/4.x/architecture-concept.md @@ -7,8 +7,6 @@ meta: --- ## System Architecture -### Introduction - Doppar follows the Model-View-Controller (MVC) architectural pattern, a widely accepted standard in web application development. This design separates the application logic into three distinct components: `Model`, `View`, and `Controller`. The Model is responsible for managing the data, business rules, and interactions with the database. The View handles the presentation layer, rendering content for users based on the data it receives. The Controller acts as a mediator, processing user input, calling the appropriate model logic, and returning the corresponding view. This separation of concerns improves code organization and makes the application easier to maintain and scale. diff --git a/versions/4.x/asset-bundling.md b/versions/4.x/asset-bundling.md index b43465f..94170da 100644 --- a/versions/4.x/asset-bundling.md +++ b/versions/4.x/asset-bundling.md @@ -7,7 +7,6 @@ meta: --- ## Asset Bundling -### Introduction In Doppar, managing front-end assets like CSS and JavaScript is straightforward thanks to the `enqueue()` function. This helper simplifies referencing your static files—such as stylesheets, scripts, or images—by generating the correct path from the `public/` directory. ### How It Works diff --git a/versions/4.x/authentication.md b/versions/4.x/authentication.md index 873d07e..ca86270 100644 --- a/versions/4.x/authentication.md +++ b/versions/4.x/authentication.md @@ -7,7 +7,6 @@ meta: --- ## Authentication -### Introduction Authentication is a fundamental part of building secure web applications. It provides a reliable way to identify users, manage authenticated sessions, and control access to protected areas of your application. Doppar provides a complete authentication system that simplifies these common requirements while giving developers the flexibility to customize authentication flows to fit their application. Doppar includes built-in authentication scaffolding that can generate the essential routes, controllers, views, and middleware needed to get started with user authentication. It also provides a convenient Auth facade and auth() helper for handling common authentication operations such as verifying credentials, logging users in and out, retrieving the currently authenticated user, and managing persistent sessions with "Remember Me". @@ -221,7 +220,9 @@ public $middlewareGroups = [ The middleware compares the password the session was signed in with to the user's current password. A session that no longer matches is signed out, and the request carries on as a guest, so the `auth` middleware of a protected route sends it to the login page. -This also signs a user out of their other devices whenever their password changes, for example after a password reset. The device that changed the password stays signed in when it changed the password on the signed-in user (`auth()->user()`). If you change it another way, such as with a query or on another instance of the model, call `refreshSessionFingerprint()` after the change to keep the current device signed in. It reads the user's password from the database: +This also signs a user out of their other devices whenever their password changes, for example after a password reset. The device that changed the password stays signed in when it saves the new password through the model, with `save()` or `update()`, on any instance of the user, including when a model hook hashes the new password before it is written. Its other requests that are running at the same time stay signed in too, and so does the device when a surrounding database transaction rolls the change back. + +If you change the password with a query instead, which bypasses the model, call `refreshSessionFingerprint()` after the change to keep the current device signed in. It reads the user's password from the database. Another request of this device that checks the session between the query and that call can still be signed out, so prefer the model: ```php User::where('id', auth()->id()) @@ -236,7 +237,11 @@ The middleware does not read the password from the database by itself. A passwor > **Note:** The middleware is optional with the `database` driver, which deletes the other sessions immediately. Registering it anyway also covers password changes made outside `logoutOtherDevices()`. -Sessions that were signed in before the middleware was registered do not record which password they were signed in with, so the middleware signs them out on their next request. A device with a valid remember-me cookie is signed straight back in, so only users who did not choose "Remember Me" have to sign in again. A remember-me cookie that `logoutOtherDevices()` has replaced does not sign the device back in. +Sessions that were signed in before the middleware was registered do not record which password they were signed in with, so registering it signs them out on their next request. Only the sign-in ends: the rest of the session's data, such as a shopping cart, is kept. A device with a valid remember-me cookie is signed straight back in, so only users who did not choose "Remember Me" have to sign in again. A remember-me cookie that `logoutOtherDevices()` has replaced does not sign the device back in. + +When the same user is signed in to several actors on one device, for example `web` and `admin`, `logoutOtherDevices()` on any of them keeps all of them signed in on this device, including an actor that is signed in only by its remember-me cookie. Other requests of this device that are running at the same time stay signed in too. + +> **Note:** Keeping running requests signed in needs a session driver that stores sessions on the server: `file` or `database`. With the `cookie` driver the session lives in the browser, so a request already on its way with the old cookie cannot see the new fingerprint and is signed out. A remember-me cookie that is out of date, for example because the user chose "Remember Me" on another device since, signs out only the device that sends it. The user's other devices are not affected. diff --git a/versions/4.x/caching.md b/versions/4.x/caching.md index 52f8aaf..8cf6c87 100644 --- a/versions/4.x/caching.md +++ b/versions/4.x/caching.md @@ -8,8 +8,6 @@ meta: ## Caching -### Introduction - Caching is an essential part of building fast, responsive, and scalable applications. When the same data needs to be retrieved or computed repeatedly, performing that work on every request can introduce unnecessary database queries, API calls, computation, and overall application overhead. A cache provides a temporary, efficient storage layer that allows frequently accessed data to be reused instead of being generated again each time. Doppar provides a unified caching system that abstracts the underlying storage mechanism, allowing your application to work with cached data consistently regardless of the configured backend. Whether you are caching a database result, an API response, a computed value, or application state, the same API can be used without coupling your application logic to a specific cache driver. diff --git a/versions/4.x/collections.md b/versions/4.x/collections.md index b6d72e7..ef91ae4 100644 --- a/versions/4.x/collections.md +++ b/versions/4.x/collections.md @@ -7,7 +7,6 @@ meta: --- ## Collections -### Introduction Doppar provides a convenient and fluent Collection class built on top of the powerful `ramsey/collection` package. Collections are an elegant and flexible way to work with arrays of data, especially when you want to perform transformations, filtering, grouping, and other operations in a chainable and expressive syntax. In Doppar, the Collection class enhances `Ramsey\Collection\Collection` with additional utility methods and integrations tailored for Doppar's ecosystem, including Entity model support and developer-friendly features like memory usage tracking and deep flattening. To make it easy to work with collections, Doppar provides the global `collect()` helper function: diff --git a/versions/4.x/configuration.md b/versions/4.x/configuration.md index e58aa60..0db190c 100644 --- a/versions/4.x/configuration.md +++ b/versions/4.x/configuration.md @@ -8,8 +8,6 @@ meta: ## Configuration -### Introduction - All configuration files for the Doppar framework are located in the `runtime/config` directory. These files define various options and settings that control how different parts of your application behave. Each configuration file is self-documented, so you are encouraged to explore and familiarize yourself with the available options. Doppar stores the compiled configuration cache in the following path `storage/framework/cache/*`. Doppar usage this config data where needed from this complied cache file. diff --git a/versions/4.x/container.md b/versions/4.x/container.md index 31bf5fb..51c4414 100644 --- a/versions/4.x/container.md +++ b/versions/4.x/container.md @@ -7,7 +7,6 @@ meta: --- ## Container -### Introduction The Doppar Container is a robust and versatile tool designed to streamline dependency management and facilitate dependency injection within application. At its core, dependency injection is a sophisticated concept that simplifies how class dependencies are handled: instead of a class creating or managing its own dependencies, they are "injected" into the class—typically through the constructor or, in certain scenarios, via setter methods. This approach promotes cleaner, more modular, and testable code, making the Doppar framework an ideal choice for modern, scalable web development. The Doppar Container simplifies dependency management by providing a clean and intuitive API for binding and resolving services. Whether you're working with regular bindings, singletons, or conditional logic, the container ensures your application remains modular, testable, and scalable. diff --git a/versions/4.x/controllers.md b/versions/4.x/controllers.md index 49ce595..ce86eb2 100644 --- a/versions/4.x/controllers.md +++ b/versions/4.x/controllers.md @@ -7,7 +7,6 @@ meta: --- ## Controllers -### Introduction Rather than defining all request-handling logic as closures in route files, you can use controller classes to organize related functionality. Controllers centralize request handling, making your code more structured and maintainable. For example, a UserController can manage user-related actions like displaying, creating, updating, and deleting users. By default, controllers are stored in the `src/Http/Controllers` directory. ## Controller Auto-Discovery diff --git a/versions/4.x/cookie.md b/versions/4.x/cookie.md index 98f5bef..7557874 100644 --- a/versions/4.x/cookie.md +++ b/versions/4.x/cookie.md @@ -8,8 +8,6 @@ meta: ## Cookies -### Introduction - Doppar provides a simple and expressive API for managing HTTP cookies throughout your application. Whether you need to store temporary data, retrieve values from incoming requests, configure cookie behavior, or remove cookies when they are no longer needed, Doppar keeps cookie management straightforward and consistent. You can work with cookies through the **`Phaseolies\Support\Facades\Cookie`** facade or the global **`cookie()`** helper. Both provide access to the same cookie management capabilities, allowing you to choose the syntax that best fits your application and coding style. diff --git a/versions/4.x/csrf-protection.md b/versions/4.x/csrf-protection.md index 46ee822..371acff 100644 --- a/versions/4.x/csrf-protection.md +++ b/versions/4.x/csrf-protection.md @@ -7,8 +7,6 @@ meta: --- ## CSRF Protectection -### Introduction - Cross-site request forgery (CSRF) attacks are a type of security threat where unauthorized actions are executed on behalf of an authenticated user without their knowledge. Fortunately, Doppar provides robust built-in protection to safeguard your application against such attacks. You can access the current session's CSRF token either through the request's session data or by using the `csrf_token()` helper function. This seamless integration ensures that your application remains secure while requiring minimal effort on your part. With Doppar, you can focus on building your application with confidence, knowing that CSRF protection is handled efficiently in the background. diff --git a/versions/4.x/datetime.md b/versions/4.x/datetime.md index f09221e..7b17c4b 100644 --- a/versions/4.x/datetime.md +++ b/versions/4.x/datetime.md @@ -7,7 +7,6 @@ meta: --- ## Datetime -### Introduction Doppar provides a robust and flexible system for working with dates and times, thanks to its integration with the Carbon library. However, understanding how timezones are managed—especially when using functions like `now()` or `Carbon::now()`—can be important when building applications that rely on accurate time data. By default, Doppar uses UTC as the base timezone for datetime functions such as `now()` and `Carbon::now()`. diff --git a/versions/4.x/defer.md b/versions/4.x/defer.md index dd87660..39ee6ed 100644 --- a/versions/4.x/defer.md +++ b/versions/4.x/defer.md @@ -8,8 +8,6 @@ meta: ## Defer -### Introduction - Code that acquires a temporary resource such as a cache lock, a file handle, a temporary file, a tracing span, or an open transaction must give that resource back no matter how the work ends. Doing it by hand usually means wrapping everything in `try`/`finally`, or remembering which lifecycle hook runs late enough to be safe. Doppar's `defer()` method lets you register the cleanup **right next to the line that acquires the resource**. The callback is held until the current execution finishes, then runs whether the execution succeeded or threw an exception. @@ -31,10 +29,10 @@ defer(static function () use ($lock): void { ### Why Use defer() -- *Acquire and release stay together* → you cannot forget the cleanup half -- *Guaranteed* → cleanup runs after success and after an exception -- *Ordered* → resources are released in reverse order of acquisition -- *Isolated* → a callback belongs to one execution and never leaks into the next request, job, or command in a long-lived worker +- Acquire and release stay together → you cannot forget the cleanup half +- Guaranteed → cleanup runs after success and after an exception +- Ordered → resources are released in reverse order of acquisition +- Isolated → a callback belongs to one execution and never leaks into the next request, job, or command in a long-lived worker ## Registering a Callback diff --git a/versions/4.x/deployment.md b/versions/4.x/deployment.md index 98beb2e..fb51ead 100644 --- a/versions/4.x/deployment.md +++ b/versions/4.x/deployment.md @@ -7,8 +7,6 @@ meta: --- ## Deployment -### Introduction - Deploying a Doppar application is straightforward and optimized for both development and production environments. This guide outlines the essential steps to get your Doppar app running on a live server. ## Server Requirements diff --git a/versions/4.x/directory-structure.md b/versions/4.x/directory-structure.md index 93af87f..43e0150 100644 --- a/versions/4.x/directory-structure.md +++ b/versions/4.x/directory-structure.md @@ -7,7 +7,6 @@ meta: --- ## Directory Structure -### Introduction Doppar aims to provide a clean, expressive, and scalable codebase that accelerates web application development while remaining easy to understand and extend. Whether you're building RESTful APIs, full-stack web applications, or microservices, Doppar offers the foundation and flexibility you need. The framework is built around familiar conventions and emphasizes simplicity without compromising on power. It features an MVC (Model-View-Controller) architecture, a powerful routing system, middleware support, a launcher-based bootstrapping mechanism, and organized directory structures. Additionally, it integrates seamlessly with Composer for dependency management and supports environment-based configuration via env.toml files. diff --git a/versions/4.x/doppar-ai.md b/versions/4.x/doppar-ai.md index 1f096e6..c27409b 100644 --- a/versions/4.x/doppar-ai.md +++ b/versions/4.x/doppar-ai.md @@ -18,7 +18,6 @@ meta: ## AI -### Introduction Doppar AI is a powerful component that brings advanced artificial intelligence capabilities to your PHP applications. It is built on top of **[Symfony AI](https://github.com/symfony/ai)** and **[Transformers.php](https://github.com/CodeWithKyrian/transformers-php)**, providing a smooth integration of machine learning models and large language models (LLMs) into your Doppar ecosystem. It provides two main components: **`Pipeline`** for running transformer-based machine learning tasks locally, and **`Agent`** for interacting with cloud-based large language models (LLMs) like OpenAI and Gemini. Whether you need sentiment analysis, text generation, image classification, or conversational AI, Doppar AI makes it simple and accessible. diff --git a/versions/4.x/doppar-airbend.md b/versions/4.x/doppar-airbend.md index 0710fbf..9b575ce 100644 --- a/versions/4.x/doppar-airbend.md +++ b/versions/4.x/doppar-airbend.md @@ -8,7 +8,6 @@ meta: ## Airbend -### Introduction Doppar Airbend is a high-performance, real-time broadcasting component of the Doppar PHP Framework, engineered to deliver seamless WebSocket-based event broadcasting and robust channel authorization. Designed for modern, scalable web applications, Airbend allows developers to build interactive and collaborative features—such as live notifications, chat systems, dashboards, and multiplayer experiences—directly within the Doppar ecosystem. Airbend is highly configurable, offering schema-driven validation and caching mechanisms for robust configuration management. With built-in CLI commands, PHP attributes for declarative event broadcasting, and a developer-friendly facade interface, Doppar Airbend empowers developers to implement real-time features with minimal overhead while maintaining full control over the broadcasting pipeline. diff --git a/versions/4.x/doppar-axios.md b/versions/4.x/doppar-axios.md index 479b041..f968fb1 100644 --- a/versions/4.x/doppar-axios.md +++ b/versions/4.x/doppar-axios.md @@ -8,8 +8,6 @@ meta: ## Axios -### Introduction - Doppar Axios is a modern, feature-rich HTTP client for PHP, inspired by the simplicity and developer-friendly API of JavaScript clients like Axios. Built on top of Symfony HttpClient, it provides a fluent and expressive interface for making HTTP requests while offering the flexibility and reliability needed for real-world applications. Unlike components that are tightly coupled to Doppar’s internal framework core, Doppar Axios is completely standalone and can be used in any modern PHP application. It supports common HTTP operations such as `GET`, `POST`, `PUT`, `PATCH`, and `DELETE`, while also providing convenient features for query parameters, custom headers, authentication, form data, redirects, SSL verification, and response handling. diff --git a/versions/4.x/doppar-bloom.md b/versions/4.x/doppar-bloom.md index 405e2c3..41f07fe 100644 --- a/versions/4.x/doppar-bloom.md +++ b/versions/4.x/doppar-bloom.md @@ -7,7 +7,6 @@ meta: --- ## Bloom Filter -### Introduction A Bloom filter is a space-efficient probabilistic data structure, conceived by Burton Howard Bloom in 1970, that is used to test whether an element is a member of a set. False positive matches are possible, but false negatives are not – in other words, a query returns either "possibly in set" or "definitely not in set". Elements can be added to the set, but not removed (though this can be addressed with a "counting" filter); the more elements that are added to the set, the larger the probability of false positives. Doppar’s Bloom package provides a high-performance, memory-efficient probabilistic set membership test. Instead of storing every item, it keeps a compact bit array and uses hashing to answer: “Is this element possibly in the set?” (false positives possible, false negatives impossible). diff --git a/versions/4.x/doppar-embeds.md b/versions/4.x/doppar-embeds.md index 9ce248a..ce7b013 100644 --- a/versions/4.x/doppar-embeds.md +++ b/versions/4.x/doppar-embeds.md @@ -8,8 +8,6 @@ meta: ## Embeds -### Introduction - Semantic search finds records by what they *mean*, not by which words they contain. A plain `WHERE description LIKE '%backpack%'` only matches the literal word — it will never find a product described as "rugged daypack for hiking," even though a shopper searching for "waterproof backpack" would consider that an excellent match. Embeds adds this to Doppar models as a single attribute. Mark a column with `#[Embeds]`, and Doppar keeps a numeric representation of its meaning — a *vector* — in sync automatically. diff --git a/versions/4.x/doppar-flarion.md b/versions/4.x/doppar-flarion.md index 46ae499..af65d22 100644 --- a/versions/4.x/doppar-flarion.md +++ b/versions/4.x/doppar-flarion.md @@ -8,7 +8,6 @@ meta: ## Flarion -### Introduction Flarion provides a lightweight, stateless API authentication system for Doppar applications. It allows users to generate and manage multiple Personal Access Tokens (PATs) that can be used to authenticate requests from mobile applications, third-party clients, CLI tools, and other services that communicate with your API. Each token is securely associated with a user and can be assigned specific abilities, allowing you to control exactly which operations the token is permitted to perform. Tokens can also have configurable expiration times, making it possible to implement fine-grained and time-limited access without relying on traditional cookies or session-based authentication. diff --git a/versions/4.x/doppar-guard.md b/versions/4.x/doppar-guard.md index 24cd5d9..c9647fd 100644 --- a/versions/4.x/doppar-guard.md +++ b/versions/4.x/doppar-guard.md @@ -8,8 +8,6 @@ meta: ## Guard - Authorization -### Introduction - Guard is a robust and extensible authorization system designed for the Doppar framework. It provides a clean, expressive API for defining and evaluating user abilities across your application. With features like one-time temporary permissions, ability inheritance, grouped permissions, wildcard patterns, ability aliases, conditional runtime gates, and global lifecycle hooks, Guard gives you complete control over access logic without cluttering your codebase. Guard is built to empower your Doppar applications with secure, scalable, and maintainable authorization logic. Whether you're building small tools or large systems, Guard adapts to your needs with clarity and power. diff --git a/versions/4.x/doppar-insight.md b/versions/4.x/doppar-insight.md index c92cd4a..80e8981 100644 --- a/versions/4.x/doppar-insight.md +++ b/versions/4.x/doppar-insight.md @@ -8,7 +8,6 @@ meta: ## Insight -### Introduction Doppar Insight is a request profiler for debugging, performance analysis, and traffic inspection. It gives you a clean in-browser toolbar for the current request, and it also keeps a recent request history so you can compare status codes, response times, errors, and route activity across multiple requests. Insight is useful when you want to inspect SQL queries, cache usage, authentication state, request and response payloads, session data, logs, or performance timing without leaving the page you are working on. It is designed for day-to-day development, but it is especially helpful when you need to trace slow endpoints or understand why a route is returning `4xx` or `5xx` responses. diff --git a/versions/4.x/doppar-notifier.md b/versions/4.x/doppar-notifier.md index ccb14ed..44c3cbf 100644 --- a/versions/4.x/doppar-notifier.md +++ b/versions/4.x/doppar-notifier.md @@ -8,7 +8,6 @@ meta: ## Notifier -### Introduction A notification system allows you to send messages to users across multiple channels like email, SMS, Slack, Discord, and in-app notifications. Instead of sending notifications immediately and blocking your application, Doppar's notification system runs in the background using the powerful queue system, ensuring smooth user experiences and reliable delivery even under heavy load. Doppar notification system offers robust features including multi-channel delivery with support for `database`, `mail`, `Slack`, `Discord`, `webhook`, and custom channel, secure model serialization that safely handles Eloquent models in notification payloads, and automatic retry logic with configurable attempts. Every channel is delivered by its own queued job, so a channel that fails is retried on its own and never sends the others again. diff --git a/versions/4.x/doppar-oauthic.md b/versions/4.x/doppar-oauthic.md index 2abf8a6..88678fb 100644 --- a/versions/4.x/doppar-oauthic.md +++ b/versions/4.x/doppar-oauthic.md @@ -8,8 +8,6 @@ meta: ## OAuthic -### Introduction - Doppar OAuthic is a modern, extensible authentication package that simplifies OAuth 2.0 integration in Doppar Framework. In addition to traditional, form-based authentication, Doppar OAuthic offers a clean, convenient interface for authenticating users via popular OAuth providers such as `Google`, `GitHub`, and `LinkedIn`. It also supports custom drivers, giving you full control over provider integrations. Whether you're building a microservice, a SaaS product, or integrating with social platforms, Doppar OAuthic makes OAuth 2.0 secure, consistent, and easy to implement. diff --git a/versions/4.x/doppar-orion.md b/versions/4.x/doppar-orion.md index a934e4f..88ed8d0 100644 --- a/versions/4.x/doppar-orion.md +++ b/versions/4.x/doppar-orion.md @@ -7,7 +7,6 @@ meta: --- ## Processes -### Introduction Doppar Processes provides a powerful and expressive abstraction for running and managing system-level commands and scripts from within your PHP application. Built on top of the Symfony Process Component, it gives you a fluent interface for executing commands, handling their output, managing timeouts, and controlling processes without having to work directly with the underlying process APIs. Processes supports both synchronous and asynchronous execution, allowing you to choose whether your application should wait for a command to finish or continue working while a long-running process executes. Output can be captured, streamed in real time, or disabled entirely when it is not needed, giving you control over both process behavior and resource usage. diff --git a/versions/4.x/doppar-queue.md b/versions/4.x/doppar-queue.md index 5d4aabf..0c2df97 100644 --- a/versions/4.x/doppar-queue.md +++ b/versions/4.x/doppar-queue.md @@ -8,7 +8,6 @@ meta: ## Queue -### Introduction A queue is a background job processing system that allows tasks to run asynchronously instead of blocking your main application flow. It improves performance, distributes workload efficiently, and ensures time-consuming tasks are handled reliably in the background. Queues are essential for scaling modern applications and maintaining smooth user experiences. **Doppar Queue v4.1.0** turns the queue into a driver-based system. Jobs can now be stored in **Redis** as well as the database, and the queue gains job priorities, unique jobs, retry backoff, automatic recovery of jobs from crashed workers, and more. Everything that is new in v4.1.0 is marked **Available from v4.1.0** throughout this page. Existing code keeps working. diff --git a/versions/4.x/doppar-twig-bridge.md b/versions/4.x/doppar-twig-bridge.md index 3d29f24..3c1ebac 100644 --- a/versions/4.x/doppar-twig-bridge.md +++ b/versions/4.x/doppar-twig-bridge.md @@ -8,8 +8,6 @@ meta: ## Twig Bridge -### Introduction - The Doppar Twig Bridge is an integration layer that allows applications built on the Doppar Framework to render views using Twig, a powerful and flexible templating engine. The bridge is intentionally minimalistic and non-intrusive so you can adopt Twig progressively without disrupting your existing Odo-based templates. This document provides an in-depth explanation of how the bridge works, how to install it, and how to use it effectively in real-world Doppar applications. diff --git a/versions/4.x/encryption.md b/versions/4.x/encryption.md index a4c79f6..be72970 100644 --- a/versions/4.x/encryption.md +++ b/versions/4.x/encryption.md @@ -7,7 +7,6 @@ meta: --- ## Encryption -### Introduction Doppar's encryption services provide a simple, convenient interface for encrypting and decrypting text via PHP's OpenSSL using `AES-256` and `AES-128` encryption. All of Doppar's encrypted values are signed using a message authentication code (MAC) so that their underlying value cannot be modified or tampered with once encrypted. Before using Doppar's encrypter, you must set the key configuration option in your `config/app.php` configuration file. This configuration value is driven by the `APP_KEY` environment variable. You should use the php pool `key:generate` command to generate this variable's value since the `key:generate` command will use PHP's secure random bytes generator to build a cryptographically secure key for your application. Typically, the value of the `APP_KEY` environment variable will be generated for you during Doppar's installation. diff --git a/versions/4.x/entity-builder.md b/versions/4.x/entity-builder.md index 64e411e..16faf7a 100644 --- a/versions/4.x/entity-builder.md +++ b/versions/4.x/entity-builder.md @@ -19,7 +19,6 @@ meta: - [Handling Multiple Database Connection](#handling-multiple-database-connection) ## Entity Builder -### Introduction Doppar introduces Entity Builder, a powerful, flexible, and model-free query builder designed for developers who want full control over their database interactions — without the need for predefined data models. With Entity Builder, you can construct, execute, and manage complex SQL queries using a clean, expressive, and chainable interface. Whether you're fetching data, inserting records, updating fields, or performing intricate joins and filters, Entity Builder brings the full power of SQL into an intuitive, object-oriented syntax that feels natural and effortless. diff --git a/versions/4.x/entity-orm.md b/versions/4.x/entity-orm.md index fd9027c..f530ea6 100644 --- a/versions/4.x/entity-orm.md +++ b/versions/4.x/entity-orm.md @@ -22,7 +22,6 @@ meta: - [Handling Multiple Database Connection](#handling-multiple-database-connection) ## Entity ORM -### Introduction Doppar introduces Entity, a modern, intuitive, and powerful Object-Relational Mapper (ORM) designed to make database interactions seamless and efficient. With Entity ORM, every database table is represented by a dedicated Data Model, providing a clean, object-oriented interface to query, insert, update, and delete records without writing raw SQL. Beyond simple CRUD operations, Doppar Entity ORM empowers developers to build complex queries, manage relationships effortlessly, and perform advanced data operations with clarity and precision. Features like eager loading, nested relationships, and relationship-based filtering let you work with related data intuitively, reducing boilerplate code and boosting productivity. diff --git a/versions/4.x/error-handling.md b/versions/4.x/error-handling.md index 80574cb..364427f 100644 --- a/versions/4.x/error-handling.md +++ b/versions/4.x/error-handling.md @@ -7,7 +7,6 @@ meta: --- ## Error Handling -### Introduction Error handling is a crucial aspect of web application development. It not only allows you to catch and handle potential errors gracefully but also ensures that users receive meaningful feedback when something goes wrong. In the Doppar framework, managing HTTP errors is seamless and allows you to customize responses to provide a better user experience. Whether it’s handling unexpected server errors, invalid page requests, or custom HTTP responses, Doppar provides a flexible and intuitive system for managing these issues. By using tools like the `abort()` function, custom error pages, and HTTP status codes, you can ensure that your application responds in a way that makes sense for your users. diff --git a/versions/4.x/execution-context.md b/versions/4.x/execution-context.md index 654ce9a..57169df 100644 --- a/versions/4.x/execution-context.md +++ b/versions/4.x/execution-context.md @@ -8,8 +8,6 @@ meta: ## Execution Context -### Introduction - Every piece of work a Doppar application performs happens inside an **execution**: an HTTP request, a console command, or a job handled by a worker. Most of the state your code keeps is meant to live for exactly one of them. The tenant resolved from a header, the user being impersonated, a unit-of-work object, a per-request cache. When that state is held in a plain singleton, it outlives the execution that created it. In a persistent process such as a queue worker or a long-lived server, the next request or job then starts with the previous one's tenant, and nothing tells you it happened. An **execution context** gives each execution an identity and a lifetime. It is a small immutable object holding a unique id, a type (`request`, `console` or `worker`) and metadata, and the container uses it as a boundary: services bound to the `execution` scope are created inside a context and destroyed with it. @@ -29,11 +27,11 @@ Log::error('Payment failed'); // the log entry carries the id, type and tenant ### Why Use Execution Contexts -- *Leak-proof* → an execution-scoped service can never be seen by the next request, command or job -- *Traceable* → one id ties together every log entry an execution wrote -- *Uniform* → requests, console commands and workers follow the same lifecycle and the same API -- *Immutable* → a context never changes after it is created, so it is safe to pass to listeners and closures -- *No global state to manage* → the container owns the stack of active contexts, and it is cleaned up for you +- Leak-proof → an execution-scoped service can never be seen by the next request, command or job +- Traceable → one id ties together every log entry an execution wrote +- Uniform → requests, console commands and workers follow the same lifecycle and the same API +- Immutable → a context never changes after it is created, so it is safe to pass to listeners and closures +- No global state to manage → the container owns the stack of active contexts, and it is cleaned up for you ## How an Execution Is Described diff --git a/versions/4.x/facades.md b/versions/4.x/facades.md index dce6a99..71c6eee 100644 --- a/versions/4.x/facades.md +++ b/versions/4.x/facades.md @@ -8,8 +8,6 @@ meta: ## Facades -### Introduction - Doppar facades are static proxies to services bound in the application's service container. They give you a clean, expressive way to access framework features without manually injecting or instantiating classes. diff --git a/versions/4.x/file-storage.md b/versions/4.x/file-storage.md index 0d69ab5..6c42f7a 100644 --- a/versions/4.x/file-storage.md +++ b/versions/4.x/file-storage.md @@ -7,7 +7,6 @@ meta: --- ## File Uploads -### Introduction Doppar's filesystem configuration file is located at `runtime/config/filesystem.php`. Within this file, you may configure all of your filesystem "disks". Each disk represents a particular storage driver and storage location. Example configurations for each supported driver are included in the configuration file so you can modify the configuration to reflect your storage preferences and credentials. You may configure as many disks as you like and may even have multiple disks that use the same driver. But if you change any of your configuration, and that is not wokring, please clean the application configuration by running the command `config:clear`. diff --git a/versions/4.x/flash-message.md b/versions/4.x/flash-message.md index b09152a..7e33076 100644 --- a/versions/4.x/flash-message.md +++ b/versions/4.x/flash-message.md @@ -7,7 +7,6 @@ meta: --- ## Flash Message -### Introduction Flash messages are short-lived session messages used to give users feedback after certain actions — like form submissions, authentication, or redirects. These messages persist only for the next HTTP request and are automatically removed after they are read. Doppar provides an elegant and expressive syntax to retrieve flash messages during redirects, making it easy to give users a seamless experience. diff --git a/versions/4.x/frozen-services.md b/versions/4.x/frozen-services.md index f79e74c..29bd415 100644 --- a/versions/4.x/frozen-services.md +++ b/versions/4.x/frozen-services.md @@ -8,8 +8,6 @@ meta: ## Frozen Services -### Introduction - Frozen Services is a container-level feature in Doppar that enforces a clear lifecycle boundary for your application's singleton services. A service marked with the `#[Immutable]` attribute is fully configurable during the application boot phase — your launchers can set it up from config files, environment variables, databases, or any external source — and then **permanently frozen** once the container completes its build. After freezing, any attempt to mutate a property on that service throws an `ImmutableViolationException` immediately, regardless of where in the application the mutation is attempted — controllers, middleware, event listeners, closures, or anywhere else. @@ -23,9 +21,9 @@ A Frozen Service is a singleton service whose state becomes permanently read-onl During the boot phase, the service can be fully configured from configuration files, environment variables, databases, or any external source. Once the container completes building the service, Doppar freezes the instance and guarantees that its public state cannot change for the rest of the request lifecycle. This creates a strict and enforceable boundary: -- *Boot phase* → configuration is allowed -- *Runtime phase* → mutation is impossible -- *Guarantee* → every consumer receives a consistent, trustworthy instance +- Boot phase → configuration is allowed +- Runtime phase → mutation is impossible +- Guarantee → every consumer receives a consistent, trustworthy instance They eliminate an entire class of bugs caused by accidental shared-state mutation. diff --git a/versions/4.x/hashing.md b/versions/4.x/hashing.md index 1db3f54..94445cd 100644 --- a/versions/4.x/hashing.md +++ b/versions/4.x/hashing.md @@ -7,7 +7,6 @@ meta: --- ## Hashing -### Introduction Hashing is a critical part of securing sensitive data in web applications, particularly when it comes to storing passwords. Unlike encryption, which can be reversed to retrieve the original data, hashing is a one-way process designed to securely transform data (such as passwords) into a fixed-length string of characters. When a user creates or updates their password, the application does not store the raw password. Instead, it stores a hashed version of the password, which is a unique string generated by a cryptographic algorithm. This ensures that even if the database is compromised, the actual passwords are not exposed. diff --git a/versions/4.x/helpers.md b/versions/4.x/helpers.md index 97d609b..216e147 100644 --- a/versions/4.x/helpers.md +++ b/versions/4.x/helpers.md @@ -7,7 +7,6 @@ meta: --- ## Helpers -### Introduction Doppar offers a rich set of global helper functions designed to streamline common tasks throughout your application. These helpers encapsulate repetitive logic and provide a more expressive, readable syntax for tasks like working with arrays, strings, URLs, paths, and more. While many of these functions are used internally by the framework itself, they are fully accessible within your application and can significantly simplify your code when used appropriately. diff --git a/versions/4.x/hooks.md b/versions/4.x/hooks.md index ccbf0f5..5f3b65f 100644 --- a/versions/4.x/hooks.md +++ b/versions/4.x/hooks.md @@ -7,7 +7,6 @@ meta: --- ## Hooks -### Introduction Model hooks let you run code at specific moments in the life of a model: just before it is inserted, right after it is updated, when it is deleted, when it is restored, and so on. You attach small pieces of logic to those moments, and Doppar runs them for you every time the model is saved through its own methods. Hooks are the right place for rules that belong close to the model but should not be repeated in every controller or service. Typical examples are building a slug from a title, setting a default status, clearing a cache after a delete, or writing an audit record. diff --git a/versions/4.x/launchers.md b/versions/4.x/launchers.md index 77f3297..a3a5d0e 100644 --- a/versions/4.x/launchers.md +++ b/versions/4.x/launchers.md @@ -8,8 +8,6 @@ meta: ## Launchers -### Introduction - In Doppar, a launcher is the place where a feature joins the framework. That feature might be small, like one container binding, or large, like a package that brings routes, migrations, translations, console commands, and publishable assets. Instead of scattering setup across random files, Doppar keeps that integration work inside launcher classes. diff --git a/versions/4.x/lens.md b/versions/4.x/lens.md index 94b9289..c960d66 100644 --- a/versions/4.x/lens.md +++ b/versions/4.x/lens.md @@ -7,7 +7,6 @@ meta: --- ## Lens -### Introduction The `Phaseolies\Support\Lens` utility is a powerful and expressive helper for working with PHP arrays. Inspired by functional programming principles and dot notation access patterns, it provides a clean, chainable, and readable way to access, modify, flatten, and filter arrays — including deeply nested structures. Whether you're working with configuration data, nested API responses, or transforming data collections, `Lens` simplifies your logic and keeps your code expressive. diff --git a/versions/4.x/localization.md b/versions/4.x/localization.md index 90c86a8..64e1eb8 100644 --- a/versions/4.x/localization.md +++ b/versions/4.x/localization.md @@ -7,7 +7,6 @@ meta: --- ## Localization -### Introduction Localization is a key feature in Doppar that allows your application to support multiple languages. It enables you to display content in the user's preferred language by using translation files stored in the `templates/lang` directory. Doppar provides several tools to work with localization, including facades and helper functions. ## Setting the Locale diff --git a/versions/4.x/logging.md b/versions/4.x/logging.md index 4f8118b..598887a 100644 --- a/versions/4.x/logging.md +++ b/versions/4.x/logging.md @@ -8,8 +8,6 @@ meta: ## Logging -### Introduction - Logging is one of the first tools you reach for when you need to understand what happened inside a request, background command, or integration flow. Doppar's logging layer is built on top of diff --git a/versions/4.x/mail.md b/versions/4.x/mail.md index f225890..0928184 100644 --- a/versions/4.x/mail.md +++ b/versions/4.x/mail.md @@ -8,8 +8,6 @@ meta: ## Mail -### Introduction - Doppar provides a robust and flexible mailing system using [Symfony Mailer](https://symfony.com/doc/current/mailer.html) that enables your application to send emails using various transports. The `runtime/config/mail.php` configuration file manages all mail-related settings, including the default mailer, SMTP credentials, and global "from" address. This file allows you to define how your application handles outgoing email by setting up one or more mailers, each with its own configuration. By default, Doppar uses the `smtp` mailer, but you can customize or extend this based on your requirements. diff --git a/versions/4.x/middleware.md b/versions/4.x/middleware.md index 7af0121..6cbd3d3 100644 --- a/versions/4.x/middleware.md +++ b/versions/4.x/middleware.md @@ -7,7 +7,6 @@ meta: --- ## Middleware -### Introduction Middleware offers a powerful way to inspect, filter, and act on HTTP requests before they reach your application's core logic. For instance, Doppar includes built-in middleware that ensures a user is authenticated. If the user isn't authenticated, the middleware can redirect them to a login page; otherwise, it allows the request to proceed. Beyond authentication, middleware can handle a wide range of tasks. For example, a logging middleware might record every incoming request, while another could handle input sanitization or API rate limiting. Doppar comes bundled with several useful middleware for tasks like authentication and CSRF protection. Custom middleware can be created and are typically stored in the `src/Http/Middleware` directory of your application. diff --git a/versions/4.x/migrations.md b/versions/4.x/migrations.md index 639e997..766f39c 100644 --- a/versions/4.x/migrations.md +++ b/versions/4.x/migrations.md @@ -8,8 +8,6 @@ meta: ## Database Migration -### Introduction - Managing database schema changes manually is error-prone and difficult to coordinate across teams and environments. The migration system solves this by providing a structured, version-controlled way to evolve your database schema over time — keeping diff --git a/versions/4.x/model.md b/versions/4.x/model.md index a7d4663..0d9e39f 100644 --- a/versions/4.x/model.md +++ b/versions/4.x/model.md @@ -12,7 +12,6 @@ content: Model - [Computed Properties](#computed-properties) ## Model -### Introduction Models are at the heart of Doppar’s data management system, providing a convenient and expressive way to interact with your application’s database. A model represents a database table and gives you a structured interface for retrieving, creating, updating, and managing records without having to work directly with raw database queries for every operation. Doppar models are built on the Phaseolies\Database\Entity\Model class and provide a range of configurable properties that allow you to control how your data is stored, accessed, and exposed. You can define the table and primary key used by a model, specify which attributes can be mass-assigned, hide sensitive attributes from serialized output, manage timestamps, and select the database connection used by the model. diff --git a/versions/4.x/odo-templates.md b/versions/4.x/odo-templates.md index 07f4d2e..8d0d322 100644 --- a/versions/4.x/odo-templates.md +++ b/versions/4.x/odo-templates.md @@ -8,8 +8,6 @@ meta: ## Odo Templates -### Introduction - Doppar includes **Odo**, a modern, lightweight, and fully customizable templating engine designed exclusively for the Doppar Framework. Odo makes it easy to build dynamic HTML views using expressive directives and clean syntax — without scattering raw PHP throughout your markup. Instead of writing PHP directly in your views, Odo gives you readable, expressive template directives like `#if`, `#foreach`, and `#include`, along with powerful echo tags like `[[ ]]`, `[[! !]]`, and `[[[ ]]]`. diff --git a/versions/4.x/package-development.md b/versions/4.x/package-development.md index 5f85288..4305b7c 100644 --- a/versions/4.x/package-development.md +++ b/versions/4.x/package-development.md @@ -7,7 +7,6 @@ meta: --- ## Package Development -### Introduction Welcome to the official Doppar Framework Package Development Guide! This document walks you through the full lifecycle of creating, structuring, and maintaining packages within the Doppar PHP ecosystem. In Doppar, packages are designed to promote modularity, reusability, and maintainability within applications. By encapsulating functionality into discrete, self-contained components, developers can isolate concerns and build features that are easy to test, share, and maintain. diff --git a/versions/4.x/pool-console.md b/versions/4.x/pool-console.md index 44787d2..5c1f3af 100644 --- a/versions/4.x/pool-console.md +++ b/versions/4.x/pool-console.md @@ -7,7 +7,6 @@ meta: --- ## Pool Console -### Introduction Pool Console is Doppar’s built-in command-line interface (CLI), providing a convenient and powerful way to interact with your application directly from the terminal. Through the pool script at the root of your project, you can perform common development tasks, automate repetitive operations, create custom commands, and execute application processes without relying on a web interface. Pool Console is designed to make command-line operations feel like a natural part of the Doppar development workflow. It provides a collection of built-in commands for everyday tasks while also giving you the flexibility to define your own commands for application-specific operations. Custom commands can accept arguments and options, interact with services through dependency injection, prompt users for input, display formatted output, show progress bars and tables, measure execution time, and even be invoked programmatically from within your application. diff --git a/versions/4.x/property-casts.md b/versions/4.x/property-casts.md index 94179ee..000f36e 100644 --- a/versions/4.x/property-casts.md +++ b/versions/4.x/property-casts.md @@ -7,8 +7,6 @@ meta: --- ## Attribute Casting -### Introduction - Attribute casting allows you to automatically transform model attribute values when reading from or writing to the database — without cluttering your application code with manual type conversions. Databases store everything as strings, integers, or raw bytes. Without casting, your PHP code is littered with `(bool)`, `(int)`, `json_decode()`, and `Carbon::parse()` calls scattered across controllers and services. Doppar's casting system centralises all of this transformation logic on the model itself — declared once, applied everywhere. diff --git a/versions/4.x/rate-limiting.md b/versions/4.x/rate-limiting.md index 331447d..cc3e827 100644 --- a/versions/4.x/rate-limiting.md +++ b/versions/4.x/rate-limiting.md @@ -7,7 +7,6 @@ meta: --- ## Rate Limiter -### Introduction Rate limiting is a technique used to control the number of requests a client can make to an endpoint within a specified timeframe. It helps prevent abuse, reduce server load, and enhance security by limiting how frequently a user can access a given route. By applying rate limits to routes or groups of routes, Doppar ensures fair usage and protects your system from potential misuse. In the Doppar PHP framework, you can apply rate limiting to specific routes using middleware. diff --git a/versions/4.x/reactive-model.md b/versions/4.x/reactive-model.md index ccf7f77..c1db2f5 100644 --- a/versions/4.x/reactive-model.md +++ b/versions/4.x/reactive-model.md @@ -8,8 +8,6 @@ meta: ## Reactive Model -### Introduction - Reactive Model provides a convenient way to react to changes on individual model properties using the `#[Watches]` attribute. When a watched property is modified and `save()` or `update()` succeeds, Doppar automatically detects the change and invokes the registered watcher with the old value, the new value, and the complete model instance. This is property-level observation. Unlike Doppar's `#[Hook]` system, which responds to model lifecycle events such as `before_updated` or `after_updated`, `#[Watches]` focuses on which specific property changed and how its value changed. diff --git a/versions/4.x/relationships.md b/versions/4.x/relationships.md index 6255cbd..1f2b175 100644 --- a/versions/4.x/relationships.md +++ b/versions/4.x/relationships.md @@ -7,7 +7,6 @@ meta: --- ## Relationships -### Introduction Doppar Entity provides a powerful relationship system for defining and working with connections between related database records. Instead of manually managing foreign keys and separate queries, relationships allow your models to describe how their data is connected and provide an expressive interface for retrieving and querying related records. Relationships are defined as methods on your Entity models and can represent common database associations such as one-to-one, one-to-many, and many-to-many relationships. Once defined, these relationships can be accessed through dynamic relationship properties, while the relationship methods themselves can be used as query builders to apply additional conditions, sorting, and other query constraints. diff --git a/versions/4.x/request-lifecycle.md b/versions/4.x/request-lifecycle.md index a7a48fb..6f5e1b0 100644 --- a/versions/4.x/request-lifecycle.md +++ b/versions/4.x/request-lifecycle.md @@ -8,8 +8,6 @@ meta: ## Request Lifecycle -### Introduction - Understanding the request lifecycle makes the framework easier to reason about. When you know where the request enters, how it becomes a response, and what runs after the response is sent, debugging and diff --git a/versions/4.x/requests.md b/versions/4.x/requests.md index 3a8001d..46442db 100644 --- a/versions/4.x/requests.md +++ b/versions/4.x/requests.md @@ -8,8 +8,6 @@ meta: ## Requests -### Introduction - Doppar’s `Phaseolies\Http\Request` class is the central interface for working with data coming into your application. Rather than treating an HTTP request as a collection of raw values, it provides an expressive, object-oriented API for retrieving, transforming, validating, and shaping that data as it moves through your application. From simple input access to more advanced request processing, the Request class lets you work with query parameters, headers, cookies, uploaded files, sessions, routes, and validation results through a consistent API. Its fluent transformation methods make it possible to normalize or reshape input directly at the request layer, while features such as conditional processing, structured extraction, blank-value normalization, and DTO binding help turn incoming payloads into application-ready data. diff --git a/versions/4.x/responses.md b/versions/4.x/responses.md index 3496150..50a270f 100644 --- a/versions/4.x/responses.md +++ b/versions/4.x/responses.md @@ -8,8 +8,6 @@ meta: ## HTTP Responses -### Introduction - Every web application communicates with clients through HTTP responses. Whether you're building a REST API, a traditional web application, or a hybrid system, crafting proper responses is fundamental to creating reliable software. The Doppar framework provides a powerful and expressive response system that handles everything from simple text output to complex streamed data transfers. The response layer abstracts HTTP protocol complexities while giving you fine-grained control when you need it. diff --git a/versions/4.x/routing.md b/versions/4.x/routing.md index f84e16d..c6dedc8 100644 --- a/versions/4.x/routing.md +++ b/versions/4.x/routing.md @@ -11,7 +11,6 @@ meta: - [Route Helper Method](#route-helper-method) ## Routing -### Introduction Doppar’s routing system provides a clean and expressive way to define your application’s URL structure and map incoming requests to the appropriate controller actions or closures. Routes can be defined using the **`Route`** facade or through the **`#[Route]`** attribute. The routing engine includes powerful features such as route grouping and prefixes, named routes, request throttling, middleware assignment, and RESTful resource routing. Whether you’re building a lightweight API or a full-scale web application, Doppar’s routing system helps keep your application’s routes organized, consistent, maintainable, and easy to scale. diff --git a/versions/4.x/seeders.md b/versions/4.x/seeders.md index 31f3997..9861e28 100644 --- a/versions/4.x/seeders.md +++ b/versions/4.x/seeders.md @@ -7,7 +7,6 @@ meta: --- ## Database Seeder -### Introduction Database seeding is a crucial aspect of web application development, especially when populating your database with sample data for testing or development. Doppar supports database seeding, allowing you to easily generate data using custom seed classes. Seed classes are stored in the `schema/seeders` directory, and you can use them to define the data that should be inserted into your database tables. diff --git a/versions/4.x/session.md b/versions/4.x/session.md index d6bf8f2..fa8d598 100644 --- a/versions/4.x/session.md +++ b/versions/4.x/session.md @@ -8,8 +8,6 @@ meta: ## HTTP Session -### Introduction - HTTP is a stateless protocol, so each request is unaware of the ones before it. Sessions solve this by storing information about a visitor, such as an authenticated user, their preferences, or a message to show after a redirect, and making it available on every subsequent request from the same browser. Doppar sessions are **lazy**. A session is only read when your code uses it, and it is only stored when it holds data. A request that never touches the session creates no storage and sends no cookie, which keeps API endpoints, health checks, and crawler traffic from leaving anything behind. @@ -22,11 +20,11 @@ $name = $request->session()->get('name'); ### Why Doppar Sessions -- *Lazy* → nothing is created until the session is used, and an empty session is never saved -- *Driver based* → the same API works with the `file`, `cookie`, `database`, and `array` drivers, or your own -- *Non-blocking* → concurrent requests from the same browser never wait for each other -- *Self-cleaning* → expired sessions are removed automatically, without a background job -- *Stateless when you need it* → API routes can opt out of sessions entirely +- Lazy → nothing is created until the session is used, and an empty session is never saved +- Driver based → the same API works with the `file`, `cookie`, `database`, and `array` drivers, or your own +- Non-blocking → concurrent requests from the same browser never wait for each other +- Self-cleaning → expired sessions are removed automatically, without a background job +- Stateless when you need it → API routes can opt out of sessions entirely ## Configuration @@ -65,7 +63,7 @@ Browsers reject `SameSite=None` cookies that are not `Secure`. When `same_site` |--------|-----------|----------|--------| | `file` | Files on the server | Most applications | One server, or a shared filesystem | | `cookie` | The browser, in an encrypted cookie | Small payloads and servers with no writable storage | About 4 KB in total. Cannot be revoked from the server | -| `database` | A database table | Several servers behind a load balancer, and listing or ending a user's sessions | One small query per request | +| `database` | A database table | Several servers behind a load balancer, and listing or ending a user's sessions | Two primary-key lookups per request that uses the session | | `array` | Process memory | Automated tests | Lost when the process ends | ### File Driver @@ -114,7 +112,7 @@ Schema::create('sessions', function (Blueprint $table) { $table->string('ip_address', 45)->nullable(); $table->text('user_agent')->nullable(); $table->longText('payload'); - $table->unsignedInteger('last_activity')->index(); + $table->unsignedBigInteger('last_activity')->index(); }); ``` @@ -155,7 +153,7 @@ The table name must be a plain name of letters, digits, and underscores, such as The driver is built to stay cheap on every request: - Loading a session is one lookup by primary key, and saving it is a single upsert. Statements are prepared once per connection and reused. -- A request that does not change the session does not write it. Its expiry is refreshed at most about once a minute. +- A request that does not change the session does not write it. It looks the session up once more at the end, to check that another request did not end or rotate it in the meantime. Its expiry, IP address, and user agent are refreshed at most about once a minute. - The database is only contacted once the session is used, so requests that never touch it never connect. - Expired sessions are removed in bounded batches using the `last_activity` index. diff --git a/versions/4.x/signals.md b/versions/4.x/signals.md index 3c73497..99e6fe8 100644 --- a/versions/4.x/signals.md +++ b/versions/4.x/signals.md @@ -8,8 +8,6 @@ meta: ## Signals -### Introduction - Applications often need to react to something that just happened: send a receipt after an invoice is paid, refresh a search index after an order is stored, notify a warehouse after stock changes. If that reaction fires **inside** a database transaction, it can announce work that is later rolled back, and the customer gets a receipt for a payment that never happened. A **signal** is a small object describing something that happened. Doppar's signal bus delivers it to your listeners **synchronously**, and when the signal is emitted inside a transaction it can hold it back until the transaction has **settled**, meaning the outermost transaction really committed. If the transaction rolls back, the signal is simply discarded. @@ -29,11 +27,11 @@ DB::transaction(function () use ($invoice) { ### Why Use Signals -- *Commit-safe* → listeners only run for work that was actually committed -- *Rollback-safe* → a rolled back transaction leaves no signal behind -- *Nesting-aware* → inner transactions hand their signals to the parent, and an inner rollback only drops its own -- *Per connection* → every database connection settles on its own -- *Predictable* → synchronous, priority ordered, no queue, no background process +- Commit-safe → listeners only run for work that was actually committed +- Rollback-safe → a rolled back transaction leaves no signal behind +- Nesting-aware → inner transactions hand their signals to the parent, and an inner rollback only drops its own +- Per connection → every database connection settles on its own +- Predictable → synchronous, priority ordered, no queue, no background process ## Defining a Signal diff --git a/versions/4.x/soft-deletes.md b/versions/4.x/soft-deletes.md index 356d3a6..866439a 100644 --- a/versions/4.x/soft-deletes.md +++ b/versions/4.x/soft-deletes.md @@ -8,8 +8,6 @@ meta: ## Soft Deletes -### Introduction - Sometimes a record should disappear from your application without actually being removed from the database. A user deletes a post but may want it back, an admin needs to review removed accounts, or a compliance rule requires that nothing is ever physically erased. Soft deletes solve this: instead of running a `DELETE`, Doppar stamps a timestamp column on the row, and from then on every query on that model quietly skips it. Soft deletes are opt-in per model through the `#[SoftDeletes]` attribute. Once a model carries the attribute, `delete()` marks the row as deleted, every query excludes trashed rows by default, and you get a small API for including them again, restoring them, or removing them for good. diff --git a/versions/4.x/stream-collection.md b/versions/4.x/stream-collection.md index 6a87ac9..cba89b2 100644 --- a/versions/4.x/stream-collection.md +++ b/versions/4.x/stream-collection.md @@ -7,7 +7,6 @@ meta: --- ## Stream Collections -### Introduction Doppar’s `StreamCollection` provides a lazy, memory-efficient way to handle large or infinite datasets. Built on top of PHP’s powerful generator system, StreamCollection enables data to be processed incrementally, only as needed, instead of materializing the entire dataset in memory. This design makes it exceptionally well suited for working with large files, database cursors, API streams, or any situation where efficiency and scalability are critical. Unlike a traditional collection, which stores all of its items in memory, a StreamCollection represents a continuous flow of data that can be transformed, filtered, and mapped lazily through an expressive, chainable API. Each operation — such as `map()`, `filter()`, or `chunk()` — returns a new stream without evaluating the underlying data until you explicitly iterate or collect it. This approach makes it possible to build complex data-processing pipelines that remain elegant, composable, and performant even when working with gigabytes of information. diff --git a/versions/4.x/task-schedule.md b/versions/4.x/task-schedule.md index 545d66b..9c4fdff 100644 --- a/versions/4.x/task-schedule.md +++ b/versions/4.x/task-schedule.md @@ -7,7 +7,6 @@ meta: --- ## Task Schedule -### Introduction In Doppar, scheduled tasks allow you to automate repetitive operations such as sending emails, processing invoices, or cleaning up stale data — all defined directly inside your application. Instead of relying on scattered shell scripts or manually crafted crontabs, you register every schedule in a single `App\Schedule\Schedule` class. This keeps your automation logic version-controlled, readable, and easy to maintain. Doppar's scheduler supports two modes of execution: a standard minute-based mode compatible with any system cron, and a built-in daemon mode capable of sub-minute, per-second precision. Both modes share the same expressive API. diff --git a/versions/4.x/temporal-orm.md b/versions/4.x/temporal-orm.md index f0e4245..4d4feee 100644 --- a/versions/4.x/temporal-orm.md +++ b/versions/4.x/temporal-orm.md @@ -8,8 +8,6 @@ content: Temporal, Time-Travel, ORM, History, Audit, Snapshot ## Temporal ORM -### Introduction - Doppar’s Temporal Time-Travel ORM brings automatic history tracking and time-travel capabilities directly to your models. By marking a model with the `#[Temporal]` attribute, Doppar automatically records a complete snapshot of the model whenever a record is created, updated, or deleted. These snapshots are stored in a dedicated history table, allowing you to inspect how a record changed over time without requiring additional audit logic in your controllers or services. Temporal ORM is designed to make historical data easy to work with while keeping the normal model workflow unchanged. Once enabled, Doppar handles the lifecycle hooks and history capture automatically, recording the state of each record together with metadata such as the action performed, the exact timestamp of the change, the columns that were modified, and optionally the authenticated user responsible for the change. diff --git a/versions/4.x/trust-proxies.md b/versions/4.x/trust-proxies.md index ae8b59d..16c5034 100644 --- a/versions/4.x/trust-proxies.md +++ b/versions/4.x/trust-proxies.md @@ -7,8 +7,6 @@ meta: --- ## Trusted Proxies -### Introduction - When deploying your Doppar application behind a reverse proxy or load balancer—especially one that handles TLS/SSL termination—you might find that the application fails to generate secure (`https://`) URLs, defaulting instead to plain `http://`. This typically occurs because requests are being forwarded over port 80, causing the framework to assume the original request was insecure. To resolve this, Doppar allows you to explicitly trust your proxy servers. This ensures accurate detection of the original request scheme, host, and client IP. diff --git a/versions/4.x/url-generation.md b/versions/4.x/url-generation.md index 54368ac..bdd9d2c 100644 --- a/versions/4.x/url-generation.md +++ b/versions/4.x/url-generation.md @@ -7,8 +7,6 @@ meta: --- ## URL Generation -### Introduction - Doppar provides several helpers to assist you in generating URLs for your application. These helpers are primarily helpful when building links in your templates, or when generating redirect responses to another part of your application. The most basic URL generation will be like assume we want to generate url using route name. ## Generating URLs diff --git a/versions/4.x/validation.md b/versions/4.x/validation.md index 9442298..3ae5ca6 100644 --- a/versions/4.x/validation.md +++ b/versions/4.x/validation.md @@ -7,8 +7,6 @@ meta: --- ## Validation -### Introduction - The API Presenter provides a structured and consistent way to transform application data into clean, predictable API responses. Rather than exposing your Entity models or raw arrays directly from controllers, Presenters give you a dedicated layer for defining how your data should be represented to API consumers. A Presenter acts as a presentation layer between your application’s data and its JSON response. It allows you to control which attributes are exposed, transform and format values, conditionally include additional data, and organize related resources without placing presentation logic inside your controllers. This keeps your controllers focused on application flow while making API responses easier to maintain and evolve. diff --git a/versions/4.x/views.md b/versions/4.x/views.md index 333e5c5..9fc3166 100644 --- a/versions/4.x/views.md +++ b/versions/4.x/views.md @@ -7,7 +7,6 @@ meta: --- ## Views -### Introduction In Doppar, it's not practical to return entire HTML document strings directly from your routes and controllers. Fortunately, views offer a clean and structured way to manage your application's UI by keeping HTML in separate files. Views help separate your application's logic from its presentation layer, improving maintainability and readability. In Doppar, views are typically stored in the `templates/views` directory. The templating system in Doppar allows you to create dynamic and reusable UI components efficiently. A basic view file might look like this: