Skip to content

Commit b38aff2

Browse files
committed
updated more of core concepts
1 parent 0d9ea52 commit b38aff2

1 file changed

Lines changed: 105 additions & 4 deletions

File tree

core-concepts.html

Lines changed: 105 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -848,11 +848,46 @@ <h4 class="text-lg font-semibold mb-3 text-gray-900">When to Use Each Approach</
848848
<section id="database-orm">
849849
<h2 class="text-2xl font-bold text-gray-900 mb-4">Database & ORM (Capabilities)</h2>
850850
<p class="text-gray-600 mb-4">
851-
Database and ORM are <strong>not built into the kernel</strong>. They're capabilities you install when you need them. Install a database capability like <code>ForgeDatabaseSQL</code> or an ORM capability like <code>ForgeSqlOrm</code>.
851+
Database and ORM are <strong>not built into the kernel</strong>. They're capabilities you install when you need them. Install a database capability like <code class="bg-gray-100 px-2 py-1 rounded">ForgeDatabaseSQL</code> or an ORM capability like <code class="bg-gray-100 px-2 py-1 rounded">ForgeSqlOrm</code>.
852852
</p>
853853
<p class="text-gray-600 mb-4">
854-
<strong>Note:</strong> The examples below assume you've installed a database/ORM capability. The kernel itself doesn't include these features.
854+
Forge provides <strong>three ways to work with data</strong>:
855855
</p>
856+
<ol class="list-decimal list-inside space-y-2 text-gray-600 mb-4">
857+
<li><strong>Raw SQL Queries:</strong> Use <code class="bg-gray-100 px-2 py-1 rounded">QueryBuilderInterface</code> or <code class="bg-gray-100 px-2 py-1 rounded">DatabaseConnectionInterface</code> directly, even without installing an ORM capability. This is available through the kernel's database contracts.</li>
858+
<li><strong>Query Builder:</strong> Use the fluent query builder interface for type-safe database operations.</li>
859+
<li><strong>ORM:</strong> Use the ForgeSqlOrm capability for attribute-based models and relationships.</li>
860+
</ol>
861+
<p class="text-gray-600 mb-4">
862+
<strong>Note:</strong> The ORM examples below assume you've installed the <code class="bg-gray-100 px-2 py-1 rounded">ForgeSqlOrm</code> capability. Raw queries and query builder are available through the kernel's database contracts.
863+
</p>
864+
865+
<h3 class="text-lg font-semibold mb-3 text-gray-900">Raw SQL Queries</h3>
866+
<p class="text-gray-600 mb-4">
867+
You can use raw SQL queries without installing any ORM capability. The kernel provides <code class="bg-gray-100 px-2 py-1 rounded">QueryBuilderInterface</code> and <code class="bg-gray-100 px-2 py-1 rounded">DatabaseConnectionInterface</code> for direct database access. This is how migrations work internally.
868+
</p>
869+
<div class="code-block p-6 text-white rounded-lg mb-6">
870+
<pre><code class="language-php">&lt;?php
871+
872+
use Forge\Core\Contracts\Database\QueryBuilderInterface;
873+
use Forge\Core\Contracts\Database\DatabaseConnectionInterface;
874+
use Forge\Core\DI\Container;
875+
876+
// Using QueryBuilderInterface
877+
$queryBuilder = Container::getInstance()->get(QueryBuilderInterface::class);
878+
$results = $queryBuilder->table('users')
879+
->where('status', '=', 'active')
880+
->get();
881+
882+
// Using DatabaseConnectionInterface for raw SQL
883+
$connection = Container::getInstance()->get(DatabaseConnectionInterface::class);
884+
$stmt = $connection->prepare('SELECT * FROM users WHERE status = :status');
885+
$stmt->execute(['status' => 'active']);
886+
$results = $stmt->fetchAll(\PDO::FETCH_ASSOC);
887+
888+
// Execute raw SQL
889+
$queryBuilder->execute('CREATE TABLE IF NOT EXISTS posts (id INTEGER PRIMARY KEY, title TEXT)');</code></pre>
890+
</div>
856891

857892
<h3 class="text-lg font-semibold mb-3 text-gray-900">Model Definition</h3>
858893
<div class="code-block p-6 text-white rounded-lg mb-6">
@@ -956,6 +991,13 @@ <h3 class="text-lg font-semibold mb-3 text-gray-900">Capability Structure</h3>
956991
</div>
957992

958993
<h3 class="text-lg font-semibold mb-3 text-gray-900">Capability Class</h3>
994+
<p class="text-gray-600 mb-4">
995+
The <code class="bg-gray-100 px-2 py-1 rounded">#[Module]</code> attribute supports several options to control module behavior:
996+
</p>
997+
<ul class="list-disc list-inside space-y-2 text-gray-600 mb-4">
998+
<li><code class="bg-gray-100 px-2 py-1 rounded">core: true</code> — Module won't be auto-loaded. You must wire it manually in your bootstrap or service providers.</li>
999+
<li><code class="bg-gray-100 px-2 py-1 rounded">isCli: true</code> — Module won't be loaded in web context. Only loaded when running CLI commands.</li>
1000+
</ul>
9591001
<div class="code-block p-6 text-white rounded-lg mb-6">
9601002
<pre><code class="language-php">&lt;?php
9611003

@@ -965,6 +1007,9 @@ <h3 class="text-lg font-semibold mb-3 text-gray-900">Capability Class</h3>
9651007
use Forge\Core\Module\Attributes\Compatibility;
9661008
use Forge\Core\Module\Attributes\Module;
9671009
use Forge\Core\Module\Attributes\Repository;
1010+
use Forge\Core\Module\Attributes\ConfigDefaults;
1011+
use Forge\Core\Module\Attributes\PostInstall;
1012+
use Forge\Core\Module\Attributes\PostUninstall;
9681013
use Forge\Core\DI\Attributes\Service;
9691014
use Forge\Core\Module\Attributes\LifecycleHook;
9701015
use Forge\Core\Module\LifecycleHookName;
@@ -974,11 +1019,21 @@ <h3 class="text-lg font-semibold mb-3 text-gray-900">Capability Class</h3>
9741019
#[Module(
9751020
name: 'MyModule',
9761021
description: 'A custom module for my application',
977-
order: 100
1022+
order: 100,
1023+
core: false, // Set to true to disable auto-loading
1024+
isCli: false // Set to true to only load in CLI context
9781025
)]
9791026
#[Service]
9801027
#[Compatibility(kernel: '>=0.1.0', php: '>=8.3')]
9811028
#[Repository(type: 'git', url: 'https://github.com/your-repo/modules')]
1029+
#[ConfigDefaults(defaults: [
1030+
'my_module' => [
1031+
'enabled' => true,
1032+
'default_option' => 'value'
1033+
]
1034+
])]
1035+
#[PostInstall(command: 'migrate', args: ['--type=module', '--module=my-module'])]
1036+
#[PostUninstall(command: 'migrate:rollback', args: ['--type=module', '--module=my-module'])]
9821037
final class MyModule
9831038
{
9841039
public function register(Container $container): void
@@ -993,7 +1048,53 @@ <h3 class="text-lg font-semibold mb-3 text-gray-900">Capability Class</h3>
9931048
// Boot logic after module registration
9941049
}
9951050
}</code></pre>
996-
</div>
1051+
</div>
1052+
1053+
<h3 class="text-lg font-semibold mb-3 text-gray-900">Configuration Defaults</h3>
1054+
<p class="text-gray-600 mb-4">
1055+
The <code class="bg-gray-100 px-2 py-1 rounded">#[ConfigDefaults]</code> attribute allows you to define default configuration values directly in your module class, eliminating the need for a separate <code class="bg-gray-100 px-2 py-1 rounded">config/</code> folder and config file.
1056+
</p>
1057+
<p class="text-gray-600 mb-4">
1058+
You can still override these defaults by creating a config file in <code class="bg-gray-100 px-2 py-1 rounded">/config/</code> (e.g., <code class="bg-gray-100 px-2 py-1 rounded">config/my_module.php</code>). When loading configuration in your module, you need to explicitly define that the config can be overridden from the <code class="bg-gray-100 px-2 py-1 rounded">/config/</code> directory.
1059+
</p>
1060+
<div class="code-block p-6 text-white rounded-lg mb-6">
1061+
<pre><code class="language-php">&lt;?php
1062+
1063+
#[ConfigDefaults(defaults: [
1064+
'my_module' => [
1065+
'enabled' => true,
1066+
'default_option' => 'value',
1067+
'nested' => [
1068+
'setting' => 'default'
1069+
]
1070+
]
1071+
])]
1072+
class MyModule
1073+
{
1074+
// Config defaults are automatically available
1075+
// Can be overridden in config/my_module.php
1076+
}</code></pre>
1077+
</div>
1078+
1079+
<h3 class="text-lg font-semibold mb-3 text-gray-900">Post-Install and Post-Uninstall Hooks</h3>
1080+
<p class="text-gray-600 mb-4">
1081+
Use <code class="bg-gray-100 px-2 py-1 rounded">#[PostInstall]</code> and <code class="bg-gray-100 px-2 py-1 rounded">#[PostUninstall]</code> attributes to automatically run CLI commands after a module is installed or removed. This is useful for running migrations, linking assets, seeding data, or performing other setup/cleanup tasks.
1082+
</p>
1083+
<div class="code-block p-6 text-white rounded-lg mb-6">
1084+
<pre><code class="language-php">&lt;?php
1085+
1086+
#[PostInstall(command: 'migrate', args: ['--type=module', '--module=my-module'])]
1087+
#[PostInstall(command: 'asset:link', args: ['--type=module', '--module=my-module'])]
1088+
#[PostUninstall(command: 'migrate:rollback', args: ['--type=module', '--module=my-module'])]
1089+
#[PostUninstall(command: 'asset:unlink', args: ['--type=module', '--module=my-module'])]
1090+
class MyModule
1091+
{
1092+
// Commands run automatically after install/uninstall
1093+
}</code></pre>
1094+
</div>
1095+
<p class="text-gray-600 mb-4">
1096+
You can specify multiple <code class="bg-gray-100 px-2 py-1 rounded">#[PostInstall]</code> or <code class="bg-gray-100 px-2 py-1 rounded">#[PostUninstall]</code> attributes. Commands are executed in the order they appear on the class.
1097+
</p>
9971098
</section>
9981099

9991100
<section id="configuration">

0 commit comments

Comments
 (0)