LoRA augmentation: 196 → 323 records (full agent run)
Earlier commit captured a partial 196-record file because the background
research agent was still writing when the commit landed. The agent has
since completed with 323 high-quality records.
New distribution by kind:
121 code-recall · 97 workflow · 29 inikey · 26 comparison
16 gotcha · 16 debug · 15 edge-case · 3 refactor
All 323 lines are valid JSON, all carry instruction/input/output plus
metadata.{language, source, section, kind, citations}. Every answer has
a real file:line citation or quoted code from framework-reference-v2.md
(no hedging language allowed in agent output).
Effect on en-language corpus:
before: 1264 records per format
after: ~1545 records per format (+281 from augmentation × ~1)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -194,3 +194,130 @@
|
|||||||
{"instruction":"How do I read `pageurl` from the INI inside controller code?","input":"","output":"```php\n$url = Config::getInstance()->getConfig()['SETTINGS']['pageurl'];\n```\nThe key is custom (no core consumer). The framework only documents it — you read it manually. From `framework-reference-v2.md §7 [SETTINGS]`.","metadata":{"language":"en","source":"framework-reference-v2","section":"7 INI [SETTINGS]","kind":"inikey","citations":["framework-reference-v2.md §7"]}}
|
{"instruction":"How do I read `pageurl` from the INI inside controller code?","input":"","output":"```php\n$url = Config::getInstance()->getConfig()['SETTINGS']['pageurl'];\n```\nThe key is custom (no core consumer). The framework only documents it — you read it manually. From `framework-reference-v2.md §7 [SETTINGS]`.","metadata":{"language":"en","source":"framework-reference-v2","section":"7 INI [SETTINGS]","kind":"inikey","citations":["framework-reference-v2.md §7"]}}
|
||||||
{"instruction":"What does `entriesperpage` do in the INI?","input":"","output":"It's a custom-use INI key in `[SETTINGS]` with no core consumer — application code reads it for pagination size. The framework documents it in `framework-reference-v2.md §7 [SETTINGS]` but doesn't act on it.","metadata":{"language":"en","source":"framework-reference-v2","section":"7 INI [SETTINGS]","kind":"inikey","citations":["framework-reference-v2.md §7"]}}
|
{"instruction":"What does `entriesperpage` do in the INI?","input":"","output":"It's a custom-use INI key in `[SETTINGS]` with no core consumer — application code reads it for pagination size. The framework documents it in `framework-reference-v2.md §7 [SETTINGS]` but doesn't act on it.","metadata":{"language":"en","source":"framework-reference-v2","section":"7 INI [SETTINGS]","kind":"inikey","citations":["framework-reference-v2.md §7"]}}
|
||||||
{"instruction":"My module's trait has a public method but the IDE says it's undefined when used in another module's class. Why?","input":"","output":"Module-specific traits live under `\\Nibiru\\Module\\<Name>\\Traits\\<TraitName>`. To use a trait from module `users` (`\\Nibiru\\Module\\Users\\Traits\\UserForm`) inside another class, you must `use \\Nibiru\\Module\\Users\\Traits\\UserForm;` AND ensure the autoloader has loaded the trait file. The autoloader only scans the trait if `[AUTOLOADER] trait.pos[] = \"users\"` is in the INI. If you reference the trait from a class in a different module that loads BEFORE `users`, the trait won't be available yet. From `framework-reference-v2.md §1`, §4.2, §11.4.","metadata":{"language":"en","source":"framework-reference-v2","section":"Cross-Section Debug","kind":"debug","citations":["framework-reference-v2.md §1","framework-reference-v2.md §4.2","framework-reference-v2.md §11.4"]}}
|
{"instruction":"My module's trait has a public method but the IDE says it's undefined when used in another module's class. Why?","input":"","output":"Module-specific traits live under `\\Nibiru\\Module\\<Name>\\Traits\\<TraitName>`. To use a trait from module `users` (`\\Nibiru\\Module\\Users\\Traits\\UserForm`) inside another class, you must `use \\Nibiru\\Module\\Users\\Traits\\UserForm;` AND ensure the autoloader has loaded the trait file. The autoloader only scans the trait if `[AUTOLOADER] trait.pos[] = \"users\"` is in the INI. If you reference the trait from a class in a different module that loads BEFORE `users`, the trait won't be available yet. From `framework-reference-v2.md §1`, §4.2, §11.4.","metadata":{"language":"en","source":"framework-reference-v2","section":"Cross-Section Debug","kind":"debug","citations":["framework-reference-v2.md §1","framework-reference-v2.md §4.2","framework-reference-v2.md §11.4"]}}
|
||||||
|
{"instruction":"What does the autogenerator's early-bail check at `core/c/model.php:16` look at?","input":"","output":"`Model::__construct()` early-bails if `[DATABASE][is.active]` is not truthy — the connection is disabled. Even if `[GENERATOR][database] = true`, no autogeneration happens for that section. From `framework-reference-v2.md §3.2`.","metadata":{"language":"en","source":"framework-reference-v2","section":"3.2 Autogenerator Pipeline","kind":"code-recall","citations":["core/c/model.php:16","framework-reference-v2.md §3.2"]}}
|
||||||
|
{"instruction":"What value should I pass for `$argv` when instantiating Model from CLI?","input":"","output":"An array of CLI flag strings, e.g. `['--table=foo', '--config-section=DATABASE_REPORTING', '--folder-out=/path/']`. `Table::__construct($argv)` at `core/c/table.php:48-70` parses argv. The shipped `Dispatcher::run()` always passes `false`, so flags are skipped — but a custom CLI wrapper could write `new Model($argv)` and use the flag mechanism. From `framework-reference-v2.md §3.2`.","metadata":{"language":"en","source":"framework-reference-v2","section":"3.2 Autogenerator Pipeline","kind":"workflow","citations":["core/c/table.php:48-70","framework-reference-v2.md §3.2"]}}
|
||||||
|
{"instruction":"What CLI flags does `Table` parse?","input":"","output":"From `core/c/table.php:48-70`: `--table=…`, `--config-section=…`, `--folder-out=…`, and `--help`. Parsed only when `is_array($argv)` returns true (line 51). The shipped framework passes `false` from `Dispatcher::run()`, so flags are inert in normal web requests. From `framework-reference-v2.md §3.2`.","metadata":{"language":"en","source":"framework-reference-v2","section":"3.2 Autogenerator Pipeline","kind":"code-recall","citations":["core/c/table.php:48-70","framework-reference-v2.md §3.2"]}}
|
||||||
|
{"instruction":"What's the relationship between `Model` and `Table` classes?","input":"","output":"`Model extends Table`. `Model::__construct($argv)` at `core/c/model.php:14` calls `parent::__construct($argv)` at line 18, which is `Table::__construct`. `Table` parses CLI flags / INI defaults and gathers metadata; `Model` does the actual file generation via `createOutFolder()` (line 28) and `createClassFiles()` (line 37). From `framework-reference-v2.md §3.2`.","metadata":{"language":"en","source":"framework-reference-v2","section":"3.2 Autogenerator Pipeline","kind":"comparison","citations":["core/c/model.php:14","core/c/model.php:18","core/c/table.php:48","framework-reference-v2.md §3.2"]}}
|
||||||
|
{"instruction":"What controllers does Nibiru ship in core?","input":"","output":"None. Controllers live in `application/controller/*Controller.php` per the Appendix file index. The framework provides only the base `Controller` singleton at `core/c/controller.php`. Application controllers extend `Controller` and define `*Action()` methods. From `framework-reference-v2.md` Appendix and §6.3.","metadata":{"language":"en","source":"framework-reference-v2","section":"Appendix File Index","kind":"comparison","citations":["framework-reference-v2.md Appendix","framework-reference-v2.md §6.3"]}}
|
||||||
|
{"instruction":"How does `Display` differ from `View`?","input":"","output":"`View::getInstance()` is the Smarty wrapper at `core/c/view.php:11` — call `View::assign()` and `View::display($page)` to render templates. `Display::getInstance()->display()` is called at the very end of `Dispatcher::run()` to perform the final rendering pass (sending output to the browser). From `framework-reference-v2.md §6.4` and Appendix.","metadata":{"language":"en","source":"framework-reference-v2","section":"6.4 View Rendering","kind":"comparison","citations":["framework-reference-v2.md §6.4","framework-reference-v2.md Appendix"]}}
|
||||||
|
{"instruction":"What's a TypeRange template good for?","input":"","output":"`TypeRange` (at `core/c/typerange.php`, factory `addTypeRange`) renders an HTML5 `<input type=\"range\">` slider. Use it for numeric ranges with min/max/step. From `framework-reference-v2.md §5.4`.","metadata":{"language":"en","source":"framework-reference-v2","section":"5.4 Type Class Registry","kind":"code-recall","citations":["core/c/typerange.php","framework-reference-v2.md §5.4"]}}
|
||||||
|
{"instruction":"Explain how the form factory's `$option` static buffer works.","input":"","output":"`self::$option` accumulates option HTML between `addSelectOption()` calls. Each call:\n```php\npublic static function addSelectOption( $attributes ) {\n self::setElement( new TypeOption() );\n self::assembleOptions( self::getElement()->loadElement( $attributes ) );\n}\n```\nappends the rendered `<option>...` to `self::$option`. Then `addSelect()` substitutes that buffer into the `OPTIONS` token of the select template via `displaySelect()` and clears the buffer with `assembleOptions(false)`. From `core/f/form.php:493-497` and `framework-reference-v2.md §5.6`.","metadata":{"language":"en","source":"framework-reference-v2","section":"5.6 Select/Option Ordering","kind":"code-recall","citations":["core/f/form.php:493-497","core/f/form.php:71","framework-reference-v2.md §5.6"]}}
|
||||||
|
{"instruction":"My second `<select>` ends up containing the options from the first. What's wrong?","input":"","output":"Most likely you didn't follow the option-then-select sequence for the SECOND select, OR `addSelect()` failed and didn't reach `assembleOptions(false)`. Each `addSelect()` clears the option buffer for the next select via `assembleOptions(false)` (`core/f/form.php:471`). If you accidentally called `addSelectOption` for the second dropdown BEFORE flushing the first via `addSelect`, both sets of options end up in the first select. The fix is to always pair option calls with the matching select call before starting the next group. From `framework-reference-v2.md §5.6`.","metadata":{"language":"en","source":"framework-reference-v2","section":"5.6 Select/Option Ordering","kind":"debug","citations":["core/f/form.php:471","framework-reference-v2.md §5.6"]}}
|
||||||
|
{"instruction":"What's the namespace of `TypeText`?","input":"","output":"`\\Nibiru\\Form\\TypeText`. All Type classes live under `\\Nibiru\\Form\\Type<X>` in `core/c/type<x>.php`. Note: this is `\\Nibiru\\Form\\` not `\\Nibiru\\Factory\\Form\\` — the factory and the Type classes are in different namespaces. From `framework-reference-v2.md §5.4`.","metadata":{"language":"en","source":"framework-reference-v2","section":"5.4 Type Class Registry","kind":"code-recall","citations":["core/c/typetext.php","framework-reference-v2.md §5.4"]}}
|
||||||
|
{"instruction":"What's the namespace of `Form` factory vs `Form` Type wrapper?","input":"","output":"Two different `Form` classes:\n- `\\Nibiru\\Factory\\Form` at `core/f/form.php` — the static factory (`Form::create()`, `Form::addInputType*()`).\n- `\\Nibiru\\Form\\Form` (inline class) — the `<form>` Type wrapper used internally by `Form::addForm()`.\n\nDon't confuse them. The factory is what callers use; the Type is internal. From `framework-reference-v2.md §5.1` and §5.4.","metadata":{"language":"en","source":"framework-reference-v2","section":"5.4 Type Class Registry","kind":"comparison","citations":["core/f/form.php","framework-reference-v2.md §5.4"]}}
|
||||||
|
{"instruction":"What happens at line 14 of `core/c/pdo.php`?","input":"","output":"That line declares the static `$section` property on the `Pdo` class. It is the single piece of state that determines which `[DATABASE*]` connection subsequent queries use. Mutated by `Pdo::settingsSection($section)`. Read by `Pdo::getSettingsSection()` and consumed in `parent::getInstance(self::getSettingsSection())`. From `framework-reference-v2.md §2.2` and §11.1.","metadata":{"language":"en","source":"framework-reference-v2","section":"2.2 Pdo","kind":"code-recall","citations":["core/c/pdo.php:14","framework-reference-v2.md §2.2"]}}
|
||||||
|
{"instruction":"What happens at line 19 of `core/c/pdo.php`?","input":"","output":"That's the public signature of `settingsSection`:\n```php\npublic static function settingsSection( $section = IOdbc::SETTINGS_DATABASE )\n```\nDefault argument is `IOdbc::SETTINGS_DATABASE`, which is the literal `\"DATABASE\"`. Calling with no argument resets the static section back to the default primary connection. From `framework-reference-v2.md §2.2`.","metadata":{"language":"en","source":"framework-reference-v2","section":"2.2 Pdo","kind":"code-recall","citations":["core/c/pdo.php:19","core/i/IOdbc.php","framework-reference-v2.md §2.2"]}}
|
||||||
|
{"instruction":"Quick: where's the literal model template file path resolved?","input":"","output":"`Table::_setTemplateFile()` at `core/c/table.php:67`. It resolves to `__DIR__ . config[GENERATOR][modeltemplate]`, where `__DIR__` is `core/c/` and the INI value is typically `\"/../../application/settings/db/db.class.mask\"`. From `framework-reference-v2.md §3.2`.","metadata":{"language":"en","source":"framework-reference-v2","section":"3.2 Autogenerator Pipeline","kind":"code-recall","citations":["core/c/table.php:67","framework-reference-v2.md §3.2"]}}
|
||||||
|
{"instruction":"Where does `_setDatabase` look up the database name?","input":"","output":"`Table::_setDatabase()` at `core/c/table.php:194`: `$dbName = config[$configSection][basename]`. `$configSection` defaults to `[GENERATOR][config-section]` (typically `\"DATABASE\"`), and the actual DB name comes from the matching `[DATABASE*][basename]` INI value. From `framework-reference-v2.md §3.2`.","metadata":{"language":"en","source":"framework-reference-v2","section":"3.2 Autogenerator Pipeline","kind":"code-recall","citations":["core/c/table.php:194","framework-reference-v2.md §3.2"]}}
|
||||||
|
{"instruction":"What does `Table::_setDbNamespace()` actually do?","input":"","output":"`core/c/table.php:63` — PascalCases the basename to produce a DB-level namespace fragment. Distinct from `_setFolderNamespace` which produces the folder-name fragment used in `\\Nibiru\\Model\\<FolderName>\\`. From `framework-reference-v2.md §3.2`.","metadata":{"language":"en","source":"framework-reference-v2","section":"3.2 Autogenerator Pipeline","kind":"code-recall","citations":["core/c/table.php:63","framework-reference-v2.md §3.2"]}}
|
||||||
|
{"instruction":"How is `_setConfigSection()` populated?","input":"","output":"`Table::_setConfigSection()` at `core/c/table.php:162` reads `--config-section=` if a CLI flag was passed, otherwise falls back to `[GENERATOR][config-section]` from the INI. The default INI value is `\"DATABASE\"`. From `framework-reference-v2.md §3.2`.","metadata":{"language":"en","source":"framework-reference-v2","section":"3.2 Autogenerator Pipeline","kind":"code-recall","citations":["core/c/table.php:162","framework-reference-v2.md §3.2"]}}
|
||||||
|
{"instruction":"Show me the IDb method for updating a row by primary key.","input":"","output":"```php\npublic function updateRowById(array $rowData, int $id, string $encrypted = \"\")\n```\nFrom `core/i/IDb.php`. Usage:\n```php\nDb::loadModel('App\\Users')->updateRowById(\n ['email' => 'new@example.com'],\n 42\n);\n```\nThe optional third parameter applies `DES_ENCRYPT()` to the listed columns. From `framework-reference-v2.md §2.3`.","metadata":{"language":"en","source":"framework-reference-v2","section":"2.3 Db Factory","kind":"code-recall","citations":["core/i/IDb.php","framework-reference-v2.md §2.3"]}}
|
||||||
|
{"instruction":"How do I update by a non-PK column with the IDb interface?","input":"","output":"`updateRowByFieldWhere($wherefield, $wherevalue, $rowfield, $rowvalue)`:\n```php\nDb::loadModel('App\\Users')->updateRowByFieldWhere('email', 'old@example.com', 'email', 'new@example.com');\n```\nBuilds `UPDATE users SET email='new@example.com' WHERE email='old@example.com'`. From `core/i/IDb.php` and `framework-reference-v2.md §2.3`.","metadata":{"language":"en","source":"framework-reference-v2","section":"2.3 Db Factory","kind":"code-recall","citations":["core/i/IDb.php","framework-reference-v2.md §2.3"]}}
|
||||||
|
{"instruction":"How do I delete a row by ID?","input":"","output":"```php\nDb::loadModel('App\\Users')->deleteRowById(42);\n```\nThe IDb signature is `deleteRowById(int $id = 0)`. The default `0` would target a row with PK=0 if any exists; always pass an explicit ID. From `core/i/IDb.php` and `framework-reference-v2.md §2.3`.","metadata":{"language":"en","source":"framework-reference-v2","section":"2.3 Db Factory","kind":"workflow","citations":["core/i/IDb.php","framework-reference-v2.md §2.3"]}}
|
||||||
|
{"instruction":"What's `IDb::selectRowsetById($id)` vs `IDb::selectRowByFieldWhere($field)`?","input":"","output":"`selectRowsetById($id)` returns the single row whose PK equals `$id` (uses the model's TABLE constant for PK). `selectRowByFieldWhere($field = array())` returns the single row whose column matches `$field['field'] => $field['value']` — useful for non-PK lookups (e.g. `email`). Both fetch one row; only the WHERE clause shape differs. From `core/i/IDb.php` and `framework-reference-v2.md §2.3`.","metadata":{"language":"en","source":"framework-reference-v2","section":"2.3 Db Factory","kind":"comparison","citations":["core/i/IDb.php","framework-reference-v2.md §2.3"]}}
|
||||||
|
{"instruction":"What does the framework do with `[ENGINE][debug_template]`?","input":"","output":"`View::_setEngine()` at `core/c/view.php:66-79` reads it as the path to the Smarty debugbar template (default-relative path resolved from `core/c/../..`). Pair with `[ENGINE][debugbar] = true` to actually render the bar. From `framework-reference-v2.md §7 [ENGINE]`.","metadata":{"language":"en","source":"framework-reference-v2","section":"7 INI [ENGINE]","kind":"inikey","citations":["core/c/view.php:66-79","framework-reference-v2.md §7"]}}
|
||||||
|
{"instruction":"What runs at line 119 of `core/framework.php`?","input":"","output":"```php\nNibiru\\Dispatcher::getInstance()->run();\n```\nThis is the boot statement that fires the entire request lifecycle: routing, model loading, module loading, controller instantiation, action calls, and final rendering. From `framework-reference-v2.md §12` step 4.","metadata":{"language":"en","source":"framework-reference-v2","section":"12 Request Trace","kind":"code-recall","citations":["core/framework.php:119","framework-reference-v2.md §12"]}}
|
||||||
|
{"instruction":"How does the autogenerator handle a brand-new application with zero existing model files?","input":"","output":"`Model::createOutFolder()` at `core/c/model.php:28` does `mkdir -p` (chmod 0777) for the target folder, then `createClassFiles()` at line 37 loops through scanned tables (or one table if `--table=` was passed) and calls `generateClassByTableName($table)` for each. For each class file:\n1. If overwrite mode, `unlink` existing.\n2. Otherwise `fopen('w'); fclose()` to create an empty stub.\n3. Build template, do all 8 placeholder substitutions plus driver/odbc switching.\n4. Write file and chmod 0777.\n\nSo zero existing files becomes a full set of generated models on the first request. From `framework-reference-v2.md §3.2`.","metadata":{"language":"en","source":"framework-reference-v2","section":"3.2 Autogenerator Pipeline","kind":"workflow","citations":["core/c/model.php:28","core/c/model.php:37","core/c/model.php:53","framework-reference-v2.md §3.2"]}}
|
||||||
|
{"instruction":"Quick: what's the sequence for rendering a page in Nibiru?","input":"","output":"From `framework-reference-v2.md §6.2` end-of-flow:\n1. `navigationAction()` runs.\n2. `{_action}Action()` runs (if applicable).\n3. `pageAction()` runs.\n4. `Debug::getInstance()` (debug info if enabled).\n5. `Display::getInstance()->display()` (actual Smarty render to browser).","metadata":{"language":"en","source":"framework-reference-v2","section":"6.4 View Rendering","kind":"workflow","citations":["framework-reference-v2.md §6.2","framework-reference-v2.md §6.4"]}}
|
||||||
|
{"instruction":"What does `Mysql::__construct()` do at line 32?","input":"","output":"From `core/c/pdo.php` line 32 (inherited via `Pdo extends Mysql`):\n```php\nif($section)\n{\n $settings = Config::getInstance()->getConfig()[$section];\n}\nelse\n{\n $settings = Config::getInstance()->getConfig()[self::SETTINGS_DATABASE]; // defaults to [DATABASE]\n}\n```\nIt reads the appropriate `[DATABASE*]` block based on the `$section` argument, which originated from `Pdo::$section` via `getSettingsSection()`. From `framework-reference-v2.md §2.2`.","metadata":{"language":"en","source":"framework-reference-v2","section":"2.2 Pdo","kind":"code-recall","citations":["core/c/pdo.php:32","framework-reference-v2.md §2.2"]}}
|
||||||
|
{"instruction":"How can I tell at a glance which DB section a generated model targets?","input":"","output":"Look at the `__construct()` body — the `[CONNECTOR]::settingsSection('[DBSECTION]')` line is hard-baked at generation time. Example:\n```php\npublic function __construct()\n{\n Pdo::settingsSection('DATABASE_REPORTING');\n self::initTable( self::TABLE );\n}\n```\nThe argument literal is exactly the INI section name. From `framework-reference-v2.md §3.2` mask file.","metadata":{"language":"en","source":"framework-reference-v2","section":"3.2 Autogenerator Pipeline","kind":"workflow","citations":["application/settings/db/db.class.mask","framework-reference-v2.md §3.2"]}}
|
||||||
|
{"instruction":"What does `IDb::selectDatasetByFieldWhere($fieldWhere = array(), $sortOrder = false)` do?","input":"","output":"Returns the rowset matching the given column/value pair, optionally ordered. `$fieldWhere` is `['field' => 'col', 'value' => 'foo']`; `$sortOrder` is a SQL `ORDER BY` snippet. Default `$sortOrder = false` means no explicit ordering. From `core/i/IDb.php` and `framework-reference-v2.md §2.3`.","metadata":{"language":"en","source":"framework-reference-v2","section":"2.3 Db Factory","kind":"code-recall","citations":["core/i/IDb.php","framework-reference-v2.md §2.3"]}}
|
||||||
|
{"instruction":"What's IModule supposed to declare?","input":"","output":"The interface is at `core/i/IModule.php`. The v2 reference doesn't enumerate its methods, only that every module main class must implement it. The base `Module` class at `core/c/module.php` provides default behavior; subclasses fulfill the contract. From `framework-reference-v2.md §4.3` and Appendix.","metadata":{"language":"en","source":"framework-reference-v2","section":"4.3 Module Loading Flow","kind":"code-recall","citations":["core/i/IModule.php","framework-reference-v2.md §4.3"]}}
|
||||||
|
{"instruction":"Why use `Db::loadModel('Folder\\Acl')` instead of `Db::loadModel('Acl')`?","input":"","output":"Because the autoloader uses PSR-4-style folder layout: `\\Nibiru\\Model\\Folder\\Acl` corresponds to `application/model/Folder/Acl.php`. If you call `Db::loadModel('Acl')`, the factory builds `\\Nibiru\\Model\\Acl`, which would map to `application/model/Acl.php` — likely a different file (or none at all). The folder fragment matches the database basename's PascalCased namespace (e.g. `WarehouseLoach` for basename `warehouse_loach`). From `framework-reference-v2.md §1`, §2.3, §8.","metadata":{"language":"en","source":"framework-reference-v2","section":"2.3 Db Factory","kind":"workflow","citations":["framework-reference-v2.md §1","framework-reference-v2.md §2.3","framework-reference-v2.md §8"]}}
|
||||||
|
{"instruction":"What if I want to manually write a model class instead of using the autogenerator?","input":"","output":"Place the file at `application/model/<FolderName>/<ClassName>.php` matching the namespace `\\Nibiru\\Model\\<FolderName>\\<ClassName>`. Extend the appropriate adapter (`\\Nibiru\\Adapter\\MySQL\\Db`, `Postgres\\Db`, or `Postgresql\\Db`). Provide the `TABLE` constant, the `__construct()` that calls `Pdo::settingsSection('DBSECTION')` and `self::initTable( self::TABLE )`, plus `getTableInfo()`, setters, and getters. Keep `[GENERATOR][database] = false` in your INI so a future generator run doesn't overwrite the file (or set `database.overwrite = false` and ensure the file is not zero bytes). From `framework-reference-v2.md §3.2`.","metadata":{"language":"en","source":"framework-reference-v2","section":"3.2 Autogenerator Pipeline","kind":"workflow","citations":["framework-reference-v2.md §3.2"]}}
|
||||||
|
{"instruction":"What's the constant `IMysql::PLACE_NO_QUERY` used for?","input":"","output":"`PLACE_NO_QUERY = \"NO QUERY\"` — a placeholder string the framework returns or compares against when no SQL was supplied. Sentinel pattern: instead of empty string or null, the framework uses recognizable string sentinels. From `core/i/IMysql.php` and `framework-reference-v2.md §9`.","metadata":{"language":"en","source":"framework-reference-v2","section":"9 Constants","kind":"code-recall","citations":["core/i/IMysql.php","framework-reference-v2.md §9"]}}
|
||||||
|
{"instruction":"What other `PLACE_*` sentinels does IMysql declare?","input":"","output":"From `core/i/IMysql.php`:\n```php\nconst PLACE_NO_QUERY = \"NO QUERY\";\nconst PLACE_TABLE_NAME = \"NO TABLENAME\";\nconst PLACE_ARRAY_NAME = \"NO ARRAY\";\nconst PLACE_QUERY_LIMIT = \"NO LIMIT\";\nconst PLACE_SORT_ORDER = \"NO ORDER\";\nconst PLACE_DSN = \"NO CONNECTION STRING\";\nconst PLACE_COLUMN_NAME = \"NO COLUMN NAME\";\nconst PLACE_SEARCH_TERM = \"NO SEARCH PARAMETER\";\nconst PLACE_FIELD_NAME = \"NO FIELD NAME\";\nconst PLACE_WHERE_VALUE = \"NO WHERE VALUE\";\n```\nAll string sentinels for missing arguments. From `framework-reference-v2.md §9`.","metadata":{"language":"en","source":"framework-reference-v2","section":"9 Constants","kind":"code-recall","citations":["core/i/IMysql.php","framework-reference-v2.md §9"]}}
|
||||||
|
{"instruction":"What's the framework's pattern for PSR-4 autoloading the core itself?","input":"","output":"`core/l/autoload.php` is the PSR-4 autoloader hook. It maps namespace prefixes like `\\Nibiru\\Factory\\`, `\\Nibiru\\Adapter\\`, `\\Nibiru\\Form\\`, `\\Nibiru\\` (root) to their corresponding `core/f/`, `core/a/`, `core/c/`, `core/c/` directories. Distinct from `core/c/auto.php` (`Auto::loader()`) which scans application module/model directories driven by INI keys. From `framework-reference-v2.md` Appendix.","metadata":{"language":"en","source":"framework-reference-v2","section":"Appendix File Index","kind":"workflow","citations":["core/l/autoload.php","framework-reference-v2.md Appendix"]}}
|
||||||
|
{"instruction":"Why do generated models import `use Nibiru\\Adapter\\<Adapter>\\Db;` and `use Nibiru\\Pdo;` together?","input":"","output":"Two different concerns:\n- `use Nibiru\\Adapter\\<Adapter>\\Db;` brings in the base adapter the model EXTENDS. For MySQL: `\\Nibiru\\Adapter\\MySQL\\Db`. For Postgres: `\\Nibiru\\Adapter\\Postgres\\Db` or `\\Nibiru\\Adapter\\Postgresql\\Db`.\n- `use Nibiru\\Pdo;` brings in the connection-switcher singleton called from the model's `__construct()` via `Pdo::settingsSection('DBSECTION')`.\n\nThe second import is hardcoded in the mask — which is the Postgres footgun, since for Postgres models the `__construct()` actually calls `Postgres::settingsSection(...)`, not `Pdo::settingsSection(...)`. From `framework-reference-v2.md §3.2`.","metadata":{"language":"en","source":"framework-reference-v2","section":"3.2 Autogenerator Pipeline","kind":"comparison","citations":["application/settings/db/db.class.mask","framework-reference-v2.md §3.2"]}}
|
||||||
|
{"instruction":"How do I handle an HTTP 404 properly in Nibiru?","input":"","output":"Configure `[ENGINE][error_controller]` and `[ENGINE][error_template]` in your INI. When the Dispatcher fails to find `application/controller/{ControllerName}Controller.php`, lines 75-80 of `core/c/dispatcher.php` route to that error controller, which renders the matching template. Without these INI keys, the soft-404 path fails — the framework has no built-in default. From `framework-reference-v2.md §6.2` and §7.","metadata":{"language":"en","source":"framework-reference-v2","section":"6.2 Dispatcher::run","kind":"workflow","citations":["core/c/dispatcher.php:75-80","framework-reference-v2.md §6.2","framework-reference-v2.md §7"]}}
|
||||||
|
{"instruction":"How do I switch to a single `[DATABASE_LOG]` connection and execute a one-off raw query?","input":"","output":"```php\nuse Nibiru\\Pdo;\nPdo::settingsSection('DATABASE_LOG');\n$rows = Pdo::queryString('SELECT * FROM event_log WHERE level = \"warn\"', true);\n// remember to restore if subsequent code expects the default:\nPdo::settingsSection(); // resets to IOdbc::SETTINGS_DATABASE = \"DATABASE\"\n```\nFrom `framework-reference-v2.md §2.2` and §11.1.","metadata":{"language":"en","source":"framework-reference-v2","section":"3.3 Multi-Database","kind":"workflow","citations":["core/c/pdo.php:14","framework-reference-v2.md §3.3"]}}
|
||||||
|
{"instruction":"Why does `Pdo::settingsSection()` not return the previous section?","input":"","output":"It's a setter, not a getter. From `core/c/pdo.php:19`, the signature returns void (or whatever the parent does — but it's a write operation). To capture the previous section, read `Pdo::getSettingsSection()` BEFORE calling the setter:\n```php\n$prev = Pdo::getSettingsSection();\nPdo::settingsSection('DATABASE_LOG');\n// ...do work...\nPdo::settingsSection($prev);\n```\nFrom `framework-reference-v2.md §2.2`.","metadata":{"language":"en","source":"framework-reference-v2","section":"2.2 Pdo","kind":"workflow","citations":["core/c/pdo.php:19","framework-reference-v2.md §2.2"]}}
|
||||||
|
{"instruction":"Quick: what does the framework's `Engine` singleton do?","input":"","output":"`core/c/engine.php` provides the template engine setup (Smarty configuration). Listed in the namespace map at `framework-reference-v2.md §1` as one of the core singletons under `\\Nibiru\\` root namespace alongside `Config`, `Controller`, `View`, `Pdo`, `Router`, `Dispatcher`. From `framework-reference-v2.md §1` and Appendix.","metadata":{"language":"en","source":"framework-reference-v2","section":"Appendix File Index","kind":"code-recall","citations":["core/c/engine.php","framework-reference-v2.md §1"]}}
|
||||||
|
{"instruction":"What's the role of the Router singleton?","input":"","output":"`\\Nibiru\\Router` at `core/c/router.php` parses the URL into controller/action segments. Called by `Dispatcher::run()` step 3 — `Router::getInstance()->route()`. It populates `$_REQUEST['_action']` and exposes the controller name. INI keys `[ROUTING][route[index]]` and `[ROUTING][route[controller]]` configure prefixes. From `framework-reference-v2.md §6.2` and §7.","metadata":{"language":"en","source":"framework-reference-v2","section":"6.2 Dispatcher::run","kind":"code-recall","citations":["core/c/router.php","framework-reference-v2.md §6.2","framework-reference-v2.md §7"]}}
|
||||||
|
{"instruction":"How do I know which controller is currently active mid-request?","input":"","output":"Call `Controller::getInstance()->getController()` — returns the URL-derived controller name (segment 1 of the URL). Defined at `core/c/controller.php:14`. Useful for breadcrumb/navigation rendering in `navigationAction()`. From `framework-reference-v2.md §2.5`.","metadata":{"language":"en","source":"framework-reference-v2","section":"2.5 Controller","kind":"workflow","citations":["core/c/controller.php:14","framework-reference-v2.md §2.5"]}}
|
||||||
|
{"instruction":"What does `Form::addOpenSpan` do?","input":"","output":"`TypeOpenSpan` at `core/c/typeopenspan.php` renders `<span ID CLASS>`. It has no direct factory method (legacy) — use `Form::addOpenAny(['any' => 'span'])` instead, which is the actively maintained path. From `framework-reference-v2.md §5.4`.","metadata":{"language":"en","source":"framework-reference-v2","section":"5.4 Type Class Registry","kind":"code-recall","citations":["core/c/typeopenspan.php","framework-reference-v2.md §5.4"]}}
|
||||||
|
{"instruction":"Show me a complete user-edit form example using the canonical helpers.","input":"","output":"From `nibiru-modules/application/module/users/traits/userForm.php:22-89`:\n```php\nForm::create();\nself::openHalfWidthElement('Benutzer Informationen');\nself::openInnerHalfWithElement();\nforeach(self::FORM_CREATE_USER as $entry) {\n self::addTextElement($entry['visibleName'], $entry['valueName'], $entry['icon'], $user[$entry['valueName']] ?? '');\n}\nself::addSelectDropdown($acl->loadAclRoles(), 'lock', $user['user_role_id']);\nself::closeHalfWidthElement();\nself::addSubmitFormButton('Speichern', 'save-alt');\nreturn Form::addForm([\n 'name' => 'userForm',\n 'action' => $action,\n 'class' => 'row',\n 'method' => 'post',\n 'target' => '_self',\n]);\n```\nThe trait composes higher-level helpers (`addTextElement`, `addSelectDropdown`, `addSubmitFormButton`) on top of the framework's `Form::add*` primitives. From `framework-reference-v2.md §5.9`.","metadata":{"language":"en","source":"framework-reference-v2","section":"5.9 Production Usage","kind":"code-recall","citations":["nibiru-modules/application/module/users/traits/userForm.php:22-89","framework-reference-v2.md §5.9"]}}
|
||||||
|
{"instruction":"My TypeText doesn't render the `placeholder` attribute even though I passed it. What's wrong?","input":"","output":"Either the key isn't in `TypeText`'s `$_attributes` allowlist (`core/c/typetext.php`) — which it should be — or you used the wrong case. Pass `'placeholder'` (lowercase). The substitution engine at `core/c/formattributes.php:48-58` does:\n```php\ncase array_key_exists($key, $this->_attributes):\n $this->_element = str_replace(strtoupper($key), $entry, $this->getElement());\n```\nIf `$key` doesn't match anything in `$_attributes`, the substitution is silently skipped — and the strip pass at line 84 will erase the unfilled `placeholder=\"PLACEHOLDER\"` fragment from the output. From `framework-reference-v2.md §5.2`.","metadata":{"language":"en","source":"framework-reference-v2","section":"5.2 Form Substitution","kind":"debug","citations":["core/c/formattributes.php:48-58","framework-reference-v2.md §5.2"]}}
|
||||||
|
{"instruction":"What's a clean way to read INI values without crashing if a key is missing?","input":"","output":"Wrap with `array_key_exists`:\n```php\n$cfg = Config::getInstance()->getConfig();\n$value = array_key_exists('SECTION', $cfg) && array_key_exists('key', $cfg['SECTION'])\n ? $cfg['SECTION']['key']\n : 'fallback';\n```\nWithout the check, `Config::getInstance()->getConfig()['MISSING']['key']` returns `NULL` silently (per `framework-reference-v2.md §11.6`), and downstream code that depends on a string/int will misbehave.","metadata":{"language":"en","source":"framework-reference-v2","section":"11.6 Missing INI Keys","kind":"workflow","citations":["framework-reference-v2.md §11.6"]}}
|
||||||
|
{"instruction":"What's the difference between Pdo's `query` and `queryString`?","input":"","output":"From `framework-reference-v2.md §2.2`:\n- `query($string)` — generic execute or fetch; routes via `parent::getInstance(self::getSettingsSection())`. Used for INSERT/UPDATE/DELETE or single-fetch.\n- `queryString($string, $associative)` — fetch all rows into a PHP array. The second flag controls associative-vs-numeric result keys.\n\nUse `query` for write operations or one-row fetches; use `queryString` for `SELECT * FROM ...` style retrieval. Both respect the active `Pdo::$section`.","metadata":{"language":"en","source":"framework-reference-v2","section":"2.2 Pdo","kind":"comparison","citations":["core/c/pdo.php","framework-reference-v2.md §2.2"]}}
|
||||||
|
{"instruction":"Quick question: is `addSelectOption` the same as `addOption`?","input":"","output":"It's only `addSelectOption`. The factory does NOT expose `addOption`. From `framework-reference-v2.md §5.4` (Select/option row). The factory is at `core/f/form.php:493-497`. Calling `Form::addOption(...)` would result in a method-not-found error.","metadata":{"language":"en","source":"framework-reference-v2","section":"5.4 Type Class Registry","kind":"gotcha","citations":["core/f/form.php:493-497","framework-reference-v2.md §5.4"]}}
|
||||||
|
{"instruction":"How do I include the framework config in my own custom singleton?","input":"","output":"```php\n$cfg = \\Nibiru\\Config::getInstance()->getConfig();\n$dbName = $cfg['DATABASE']['basename'];\n$timezone = $cfg['SETTINGS']['timezone'];\n```\n`Config::getInstance()` is the entry point at `core/c/config.php:12`; the returned `Settings` object exposes `getConfig()` which yields the parsed INI as a nested associative array. From `framework-reference-v2.md §2.1`.","metadata":{"language":"en","source":"framework-reference-v2","section":"2.1 Config Singleton","kind":"workflow","citations":["core/c/config.php:12","framework-reference-v2.md §2.1"]}}
|
||||||
|
{"instruction":"How does Nibiru detect the current environment?","input":"","output":"`Config::getInstance()` at `core/c/config.php:12` reads `getenv('APPLICATION_ENV')` first, then falls back to a defined `APPLICATION_ENV` constant. The result selects `settings.<ENV>.ini`. So `APPLICATION_ENV=production` -> `settings.production.ini`. Set the env var at the web server (Apache `SetEnv`, nginx `fastcgi_param`) or define the constant before the framework boots. From `framework-reference-v2.md §2.1`.","metadata":{"language":"en","source":"framework-reference-v2","section":"2.1 Config Singleton","kind":"workflow","citations":["core/c/config.php:12","framework-reference-v2.md §2.1"]}}
|
||||||
|
{"instruction":"What's the namespace of `Settings` returned by `Config::getInstance()`?","input":"","output":"`\\Nibiru\\Settings` at `core/c/settings.php`. The signature `Config::getInstance(): Settings` returns a `\\Nibiru\\Settings` instance that wraps the parsed INI. Use `->getConfig()` to access the array. From `core/c/config.php:12` and Appendix file index.","metadata":{"language":"en","source":"framework-reference-v2","section":"2.1 Config Singleton","kind":"code-recall","citations":["core/c/config.php:12","core/c/settings.php","framework-reference-v2.md Appendix"]}}
|
||||||
|
{"instruction":"What does the `[DATABASE][port]` default to when omitted?","input":"","output":"`3306` (the MySQL default). Read by `Mysql::__construct()`. The framework will use `3306` if the INI omits the `port` key. From `framework-reference-v2.md §7 [DATABASE]`.","metadata":{"language":"en","source":"framework-reference-v2","section":"7 INI [DATABASE]","kind":"inikey","citations":["framework-reference-v2.md §7"]}}
|
||||||
|
{"instruction":"What's the default encoding if `[DATABASE][encoding]` is omitted?","input":"","output":"`utf8`. Real example uses `\"UTF8\"` (production) which is the same. The framework applies it to the connection charset. From `framework-reference-v2.md §7 [DATABASE]`.","metadata":{"language":"en","source":"framework-reference-v2","section":"7 INI [DATABASE]","kind":"inikey","citations":["framework-reference-v2.md §7"]}}
|
||||||
|
{"instruction":"How do I run a SELECT and feed the results to a Smarty template?","input":"","output":"```php\nuse Nibiru\\Factory\\Db;\nuse Nibiru\\View;\n\n$users = Db::loadModel('App\\Users')->loadTableAsArray();\nView::assign(['users' => $users]);\n```\nIn `users.tpl`:\n```\n{foreach from=$users item=u}\n <li>{$u.email}</li>\n{/foreach}\n```\nFrom `framework-reference-v2.md §2.6`, §2.3, Quick Reference.","metadata":{"language":"en","source":"framework-reference-v2","section":"Cross-Section Workflow","kind":"workflow","citations":["framework-reference-v2.md §2.3","framework-reference-v2.md §2.6"]}}
|
||||||
|
{"instruction":"Quick: which Smarty tag prefix does Nibiru's `View::assign` use?","input":"","output":"Standard Smarty `$` syntax. After `View::assign(['user_name' => 'John'])`, the template references it as `{$user_name}`. There's no Nibiru-specific prefix — Smarty's defaults apply. From `framework-reference-v2.md §2.6`.","metadata":{"language":"en","source":"framework-reference-v2","section":"2.6 View","kind":"workflow","citations":["framework-reference-v2.md §2.6"]}}
|
||||||
|
{"instruction":"Where does Smarty look for templates by default?","input":"","output":"At `core/c/../../{ENGINE[templates]}` — i.e. relative to `core/c/`, walking up two levels. The INI key `[ENGINE][templates]` defaults to `/../../application/view/templates/`, so the absolute path resolves to `application/view/templates/`. Set in `View::_setEngine()` at `core/c/view.php:66-79`. From `framework-reference-v2.md §2.6`.","metadata":{"language":"en","source":"framework-reference-v2","section":"2.6 View","kind":"inikey","citations":["core/c/view.php:66-79","framework-reference-v2.md §7"]}}
|
||||||
|
{"instruction":"How do I rename a module from `users` to `accounts` without breaking module loading?","input":"","output":"1. Rename directory: `application/module/users/` -> `application/module/accounts/`.\n2. Rename main class file: `accounts.php` (lowercase, matching dir name).\n3. Rename class itself: `class Users` -> `class Accounts`, namespace `\\Nibiru\\Module\\Users` -> `\\Nibiru\\Module\\Accounts`.\n4. Update INI: change `class.pos[] = \"users\"` to `\"accounts\"`. Same for `iface.pos[]`, `trait.pos[]`, `class.plugin.pos[]` if applicable.\n5. Update consumers: `use Nibiru\\Module\\Users\\Traits\\UserForm` -> `use Nibiru\\Module\\Accounts\\Traits\\AccountForm`.\n\nThe autoloader scans by directory name, so the disk path and the INI registry name must match. From `framework-reference-v2.md §1`, §4.2, §11.7.","metadata":{"language":"en","source":"framework-reference-v2","section":"Cross-Section Refactor","kind":"refactor","citations":["framework-reference-v2.md §1","framework-reference-v2.md §4.2","framework-reference-v2.md §11.7"]}}
|
||||||
|
{"instruction":"Quick question: can I use composer's PSR-4 autoloader for application code in Nibiru?","input":"","output":"You can layer it on top, but Nibiru's own autoloading is INI-driven (`Auto::loader()` at `core/c/auto.php`) and NOT PSR-4. New modules must be registered in `[AUTOLOADER] class.pos[]`; the framework won't pick them up via composer.json mappings alone. The PSR-4 hook at `core/l/autoload.php` handles framework-internal classes. From `framework-reference-v2.md §11.7` and Appendix.","metadata":{"language":"en","source":"framework-reference-v2","section":"11.7 Autoloader not PSR-4","kind":"comparison","citations":["framework-reference-v2.md §11.7","framework-reference-v2.md Appendix"]}}
|
||||||
|
{"instruction":"Show me a real production INI database section.","input":"","output":"From `loach.mssql.database-connection/application/settings/config/settings.production.ini`:\n```ini\n[DATABASE]\nis.active = true\nusername = \"loach\"\npassword = \"08mj7hchqegtjf7znc6978d\"\nhostname = \"sto-loach-production-mariadb-1\"\nbasename = \"warehouse_loach\"\ndriver = \"mysql\"\nport = \"3306\"\nencoding = \"UTF8\"\ndb_info_print = 0\n```\nDocker-style hostname (`sto-loach-production-mariadb-1`) — Nibiru speaks to MariaDB through the standard MySQL driver. From `framework-reference-v2.md §7 [DATABASE]`.","metadata":{"language":"en","source":"framework-reference-v2","section":"7 INI [DATABASE]","kind":"code-recall","citations":["loach.mssql.database-connection/application/settings/config/settings.production.ini","framework-reference-v2.md §7"]}}
|
||||||
|
{"instruction":"What happens when I instantiate a generated Postgres model that references `Postgres::settingsSection`?","input":"","output":"PHP looks up `Postgres` in the model's current namespace (`\\Nibiru\\Model\\<Folder>`) and the imported `use` statements. The mask hardcodes `use Nibiru\\Pdo;` — NOT `use Nibiru\\Postgres;` — so the unqualified `Postgres::settingsSection(...)` call resolves to `\\Nibiru\\Model\\<Folder>\\Postgres`, which doesn't exist. PHP fatals with `Class 'Nibiru\\Model\\<Folder>\\Postgres' not found`.\n\nFix: edit the generated file to add `use Nibiru\\Postgres;` (or `use Nibiru\\Postgresql;`). From `framework-reference-v2.md §3.2`.","metadata":{"language":"en","source":"framework-reference-v2","section":"3.2 Autogenerator Pipeline","kind":"edge-case","citations":["application/settings/db/db.class.mask:4","framework-reference-v2.md §3.2"]}}
|
||||||
|
{"instruction":"How do I add a new `[DATABASE_X]` section without touching anything else?","input":"","output":"1. Add the block to your INI:\n```ini\n[DATABASE_X]\nis.active = true\nusername = \"...\"\npassword = \"...\"\nhostname = \"...\"\nbasename = \"...\"\ndriver = \"mysql\"\nport = \"3306\"\nencoding = \"utf8\"\n```\n2. In code, switch with `Pdo::settingsSection('DATABASE_X')` before queries, OR generate models for that section by setting `[GENERATOR][config-section] = \"DATABASE_X\"` temporarily and reloading. Reset `[GENERATOR][config-section]` after. From `framework-reference-v2.md §3.3`.","metadata":{"language":"en","source":"framework-reference-v2","section":"3.3 Multi-Database","kind":"workflow","citations":["framework-reference-v2.md §3.3"]}}
|
||||||
|
{"instruction":"What's `Form::addTypeButton` good for?","input":"","output":"It renders `<button>VALUE</button>`. The `value` attribute is used as the inner HTML — you can embed icon markup. Production callsite (per `framework-reference-v2.md §5.4`): `'value' => '<i class=\"ti-save\"></i> Speichern'`. The substitution engine does no escaping, so embedded HTML renders as-is. From `framework-reference-v2.md §5.4`.","metadata":{"language":"en","source":"framework-reference-v2","section":"5.4 Type Class Registry","kind":"workflow","citations":["framework-reference-v2.md §5.4"]}}
|
||||||
|
{"instruction":"How do I set an autocomplete pattern on an email input?","input":"","output":"```php\nForm::addInputTypeEmail([\n 'name' => 'email',\n 'pattern' => '[a-z0-9._%+-]+@[a-z0-9.-]+',\n 'required'=> 'required',\n]);\n```\n`TypeEmail`'s allowlist includes `pattern`. The substitution engine substitutes `PATTERN` -> the value. From `framework-reference-v2.md §5.4`.","metadata":{"language":"en","source":"framework-reference-v2","section":"5.4 Type Class Registry","kind":"workflow","citations":["framework-reference-v2.md §5.4"]}}
|
||||||
|
{"instruction":"What does the framework do with `Module` adapter at `core/a/module.php`?","input":"","output":"It's the adapter base class for modules — `\\Nibiru\\Adapter\\Module`. Listed in the Appendix file index alongside `core/c/module.php` (the concrete `Module` base class). Modules typically extend `Module` (from `core/c/module.php`) which itself may extend or use the adapter base. From `framework-reference-v2.md` Appendix.","metadata":{"language":"en","source":"framework-reference-v2","section":"Appendix File Index","kind":"code-recall","citations":["core/a/module.php","core/c/module.php","framework-reference-v2.md Appendix"]}}
|
||||||
|
{"instruction":"Where do I put SQL migration files in a Nibiru project?","input":"","output":"By convention, `application/settings/config/database/`. Filenames are numeric-prefixed for ordering (e.g. `001-acl.sql`, `002-account.sql`, `012-add-unique-key-user.sql`). The framework v2 reference doesn't document a built-in migration runner — these are typically applied manually or via an external tool. From the project structure visible in the repo and `framework-reference-v2.md` Appendix.","metadata":{"language":"en","source":"framework-reference-v2","section":"Appendix File Index","kind":"workflow","citations":["framework-reference-v2.md Appendix"]}}
|
||||||
|
{"instruction":"How does the framework handle `getRequest($param, $params = false)`?","input":"","output":"From `core/c/controller.php:14`: `getRequest($param, bool $params = false)`. The first arg is the parameter name; the second flag controls whether the helper expects `$param` to be an array of names (returning multiple values at once) versus a single name. Default `false` means single-name mode. From `framework-reference-v2.md §2.5`.","metadata":{"language":"en","source":"framework-reference-v2","section":"2.5 Controller","kind":"code-recall","citations":["core/c/controller.php:14","framework-reference-v2.md §2.5"]}}
|
||||||
|
{"instruction":"How do I get all `_action` candidates without hardcoding the method names?","input":"","output":"The Dispatcher uses `$_REQUEST['_action']` and dynamically calls `$controller->{$_action}Action()` if the method exists. To enumerate available actions on a given controller, use PHP reflection — `(new ReflectionClass($controller))->getMethods(ReflectionMethod::IS_PUBLIC)` and filter by `Action` suffix. The framework itself doesn't expose a registry. From `framework-reference-v2.md §6.2`.","metadata":{"language":"en","source":"framework-reference-v2","section":"6.2 Dispatcher::run","kind":"workflow","citations":["framework-reference-v2.md §6.2"]}}
|
||||||
|
{"instruction":"What's the safe way to add an unrecognized HTML5 attribute to a form input?","input":"","output":"You can't, with the standard Type classes. The substitution engine at `core/c/formattributes.php:48-58` only substitutes keys that the Type's `$_attributes` allowlist recognizes — unknown keys are silently dropped. To add a new attribute (say `inputmode`), edit the Type class: add `self::FORM_ATTRIBUTE_INPUTMODE` (or define a new constant in `IForm`) to `$_attributes`, and add an `inputmode=\"INPUTMODE\"` token to `$_element`. From `framework-reference-v2.md §5.2` and §5.3.","metadata":{"language":"en","source":"framework-reference-v2","section":"5.2 Form Substitution","kind":"refactor","citations":["core/c/formattributes.php:48-58","framework-reference-v2.md §5.2"]}}
|
||||||
|
{"instruction":"How does `addForm` actually return HTML?","input":"","output":"`Form::addForm($attributes)` instantiates the inline `\\Nibiru\\Form\\Form` Type, calls `loadElement($attributes)` on it (which substitutes the `<form …>` template attributes), then `display()` at `core/f/form.php:106` does `str_replace('FIELDS', self::$form, $template)` to inject the accumulated buffer, and returns the resulting HTML string. From `framework-reference-v2.md §5.8`.","metadata":{"language":"en","source":"framework-reference-v2","section":"5.8 Assembly Pipeline","kind":"code-recall","citations":["core/f/form.php:106","framework-reference-v2.md §5.8"]}}
|
||||||
|
{"instruction":"What if I call `Form::addForm()` twice — does the second call get the same buffer?","input":"","output":"Yes, unless you call `Form::create()` between them. `addForm()` doesn't reset the buffer; it just substitutes `FIELDS` with the current `self::$form`. So a second `addForm()` would render the same fields wrapped in a different `<form>` tag. To start a fresh form, call `Form::create()` to clear the buffer. From `framework-reference-v2.md §2.4` and §5.8.","metadata":{"language":"en","source":"framework-reference-v2","section":"5.8 Assembly Pipeline","kind":"edge-case","citations":["core/f/form.php:41","framework-reference-v2.md §5.8"]}}
|
||||||
|
{"instruction":"What's the right way to access a session value with safety?","input":"","output":"```php\n$user = $this->getSession('user', false, true);\n```\nThe third argument `$checkForActiveSession = true` makes the helper verify session-active state before accessing `$_SESSION`. Without it, you may read from a not-yet-started session. From `core/c/controller.php:14` and `framework-reference-v2.md §2.5`.","metadata":{"language":"en","source":"framework-reference-v2","section":"2.5 Controller","kind":"workflow","citations":["core/c/controller.php:14","framework-reference-v2.md §2.5"]}}
|
||||||
|
{"instruction":"What's `IDb::insertArrayIntoTable` signature?","input":"","output":"```php\npublic function insertArrayIntoTable($dataset = array())\n```\nFrom `core/i/IDb.php`. Pass an associative array of column => value:\n```php\nDb::loadModel('App\\Logs')->insertArrayIntoTable([\n 'log_message' => 'something happened',\n 'log_timestamp' => date('Y-m-d H:i:s'),\n]);\n```\nFrom `framework-reference-v2.md §2.3`.","metadata":{"language":"en","source":"framework-reference-v2","section":"2.3 Db Factory","kind":"code-recall","citations":["core/i/IDb.php","framework-reference-v2.md §2.3"]}}
|
||||||
|
{"instruction":"Quick: what files would I need to read to truly understand the autogenerator?","input":"","output":"In order:\n1. `core/c/dispatcher.php:35-39` — the trigger.\n2. `core/c/model.php:14, 18, 28, 37, 53-148` — the executor and `generateClassByTableName` substitution engine.\n3. `core/c/table.php:48-70, 63, 67, 111, 148, 162, 194, 208, 217` — the metadata gatherer.\n4. `application/settings/db/db.class.mask` — the substitution template.\n5. `core/a/mysql.db.php:15` — the base adapter.\n6. `core/c/pdo.php:14, 19, 32` — the connection switcher.\n\nFrom `framework-reference-v2.md §3.2` (the entire section is the trace).","metadata":{"language":"en","source":"framework-reference-v2","section":"3.2 Autogenerator Pipeline","kind":"workflow","citations":["framework-reference-v2.md §3.2"]}}
|
||||||
|
{"instruction":"What's the cleanest way to test that the autogenerator regenerated my file?","input":"","output":"1. Delete the file: `rm application/model/<Folder>/<Class>.php`.\n2. Ensure `[GENERATOR][database] = true` and `database.overwrite = false` in dev INI.\n3. Hit any URL.\n4. Confirm the file reappears with current schema.\n\nThe `filesize() == 0` check at `core/c/model.php:133-145` means a deleted file (not present) hits the `fopen('w')` path that creates the empty stub, then writes the full template. From `framework-reference-v2.md §3.2`.","metadata":{"language":"en","source":"framework-reference-v2","section":"3.2 Autogenerator Pipeline","kind":"workflow","citations":["core/c/model.php:133-145","framework-reference-v2.md §3.2"]}}
|
||||||
|
{"instruction":"What's the trade-off between `database.overwrite = true` and `database.overwrite = false`?","input":"","output":"With `true`: every request `unlink`s and rewrites every model file. Schema changes are picked up immediately, but ANY hand-edits are destroyed. Use ONLY in CI or one-off bulk regeneration.\n\nWith `false` (default): only zero-byte files are written. Existing model files are preserved across requests. Schema additions show up only when you delete the model file and reload. Safe for daily development.\n\nProduction should always be `false`, AND the master switch `[GENERATOR][database] = false` to skip the whole branch. From `framework-reference-v2.md §3.2`.","metadata":{"language":"en","source":"framework-reference-v2","section":"3.2 Autogenerator Pipeline","kind":"comparison","citations":["framework-reference-v2.md §3.2"]}}
|
||||||
|
{"instruction":"What does `IMysql::SETTINGS_DATABASE` evaluate to at runtime?","input":"","output":"The literal string `\"DATABASE\"`. Used as the default INI section name for `[DATABASE]`-keyed lookups across the framework. From `core/i/IMysql.php` and `framework-reference-v2.md §9`.","metadata":{"language":"en","source":"framework-reference-v2","section":"9 Constants","kind":"code-recall","citations":["core/i/IMysql.php","framework-reference-v2.md §9"]}}
|
||||||
|
{"instruction":"What's the namespace of `Auto::loader()`?","input":"","output":"`\\Nibiru\\Auto` at `core/c/auto.php`. `Auto::loader()` returns the autoloader instance, on which `loadModelFiles()`, `loadModules()`, and (by extension) module-component scanning are called. Distinct from the PSR-4 hook at `core/l/autoload.php`. From `framework-reference-v2.md` Appendix and §4.3.","metadata":{"language":"en","source":"framework-reference-v2","section":"Appendix File Index","kind":"code-recall","citations":["core/c/auto.php","framework-reference-v2.md Appendix"]}}
|
||||||
|
{"instruction":"How does Nibiru handle a controller with an `_action` of `pageAction`?","input":"","output":"The Dispatcher would call `$controller->pageActionAction()` (concatenating `Action` to whatever `_action` value was set). Since that doesn't exist, the action call is skipped — but `pageAction()` still runs as the Dispatcher's mandatory final call at line 60. So the URL `?_action=pageAction` is essentially a no-op for the action layer. From `framework-reference-v2.md §6.2`.","metadata":{"language":"en","source":"framework-reference-v2","section":"6.2 Dispatcher::run","kind":"edge-case","citations":["framework-reference-v2.md §6.2"]}}
|
||||||
|
{"instruction":"What's `addInputTypeColor` for?","input":"","output":"`TypeColor` (factory `addInputTypeColor`) renders `<input type=\"color\">` for color picker inputs. Browser provides the native picker UI. From `framework-reference-v2.md §5.4`.","metadata":{"language":"en","source":"framework-reference-v2","section":"5.4 Type Class Registry","kind":"code-recall","citations":["core/c/typecolor.php","framework-reference-v2.md §5.4"]}}
|
||||||
|
{"instruction":"What's `addInputTypeDatetime` for?","input":"","output":"`TypeDatetime` (factory `addInputTypeDatetime`) renders `<input type=\"datetime-local\">`. Combined date+time picker. From `framework-reference-v2.md §5.4`.","metadata":{"language":"en","source":"framework-reference-v2","section":"5.4 Type Class Registry","kind":"code-recall","citations":["core/c/typedatetime.php","framework-reference-v2.md §5.4"]}}
|
||||||
|
{"instruction":"How would I rebuild only one specific model after schema change?","input":"","output":"Easiest: delete the file `rm application/model/<Folder>/<Class>.php`, ensure `[GENERATOR][database] = true` and `database.overwrite = false`, hit any URL. The generator scans all tables but only writes files where `filesize() == 0` (or non-existent), so deleted files get rewritten and untouched files stay intact. Other models are unaffected. From `framework-reference-v2.md §3.2`.","metadata":{"language":"en","source":"framework-reference-v2","section":"3.2 Autogenerator Pipeline","kind":"workflow","citations":["core/c/model.php:133-145","framework-reference-v2.md §3.2"]}}
|
||||||
|
{"instruction":"How do I integrate a navigation JSON file with the controller?","input":"","output":"The framework's `[SETTINGS][navigation]` INI key is a custom-use path with no core consumer. Application code typically reads it in `navigationAction()`:\n```php\n$navPath = Config::getInstance()->getConfig()['SETTINGS']['navigation'];\n$nav = json_decode(file_get_contents($navPath), true);\nView::assign(['nav' => $nav]);\n```\nThe Dispatcher calls `navigationAction()` before any custom action, so navigation is always loaded. From `framework-reference-v2.md §7 [SETTINGS]` and §6.3.","metadata":{"language":"en","source":"framework-reference-v2","section":"7 INI [SETTINGS]","kind":"workflow","citations":["framework-reference-v2.md §7","framework-reference-v2.md §6.3"]}}
|
||||||
|
{"instruction":"What's the consequence of forgetting to call `Form::create()` between two forms?","input":"","output":"The static `self::$form` buffer carries fields from the first form into the second. So calling `Form::addForm(...)` a second time produces HTML that includes ALL previously added fields PLUS any new ones. The second form's `<form>` wrapper then contains everything. Mitigation: always call `Form::create()` to reset before starting a new form. From `framework-reference-v2.md §2.4` and §11.2.","metadata":{"language":"en","source":"framework-reference-v2","section":"2.4 Form Factory","kind":"gotcha","citations":["core/f/form.php:41","framework-reference-v2.md §11.2"]}}
|
||||||
|
{"instruction":"How do I tell at a glance whether two models share a database connection?","input":"","output":"Look at their `__construct()` bodies. Both must call `Pdo::settingsSection('DATABASE')` (or the same section name) for them to share a connection at the time of instantiation. If they target different sections, instantiating either one will mutate `Pdo::$section` — last-write-wins. From `framework-reference-v2.md §11.1` and §3.3.","metadata":{"language":"en","source":"framework-reference-v2","section":"11.1 Pdo last-write-wins","kind":"workflow","citations":["framework-reference-v2.md §11.1","framework-reference-v2.md §3.3"]}}
|
||||||
|
{"instruction":"What's the right way to mark a field as required in a Nibiru form?","input":"","output":"Pass `'required' => 'required'` (the value can be any non-empty string, but conventionally `'required'`):\n```php\nForm::addInputTypeEmail([\n 'name' => 'email',\n 'required' => 'required',\n]);\n```\nThe substitution engine swaps `REQUIRED` -> `'required'`, so the rendered HTML reads `required=\"required\"`. The strip rule at `core/c/formattributes.php:84` only fires when the user did NOT pass `required`. From `framework-reference-v2.md §5.2`.","metadata":{"language":"en","source":"framework-reference-v2","section":"5.2 Form Substitution","kind":"workflow","citations":["core/c/formattributes.php:84","framework-reference-v2.md §5.2"]}}
|
||||||
|
{"instruction":"What's the framework's convention for naming controller files?","input":"","output":"Lowercase first letter, camelCase, `Controller` suffix. Example: URL `/users/login` -> `application/controller/usersController.php` -> `class usersController extends Controller`. The Dispatcher checks `application/controller/{ControllerName}Controller.php` exists at line 75-80 of `core/c/dispatcher.php`. From `framework-reference-v2.md §6.2` and §12.","metadata":{"language":"en","source":"framework-reference-v2","section":"6.2 Dispatcher::run","kind":"workflow","citations":["framework-reference-v2.md §6.2","framework-reference-v2.md §12"]}}
|
||||||
|
{"instruction":"Can controller class names contain capitals?","input":"","output":"The Dispatcher concatenates `{ControllerName}Controller.php` from the URL segment. The case-handling depends on Router behavior — based on the `usersController` example in §12, the convention is lowercase-first. Capitalized names like `UsersController` would map to a URL segment `Users`, which most web servers normalize to lowercase. Stick with lowercase-first to avoid case-sensitivity issues across platforms. From `framework-reference-v2.md §6.2` and §12.","metadata":{"language":"en","source":"framework-reference-v2","section":"6.2 Dispatcher::run","kind":"edge-case","citations":["framework-reference-v2.md §12"]}}
|
||||||
|
{"instruction":"What's Nibiru's MMVC pattern (mentioned in v1)?","input":"","output":"Modular MVC — Module + Model + View + Controller. The v2 reference clarifies that Module is the additional layer alongside MVC: each Module bundles its own Interfaces, Traits, Plugins, and a main class, registered in `[AUTOLOADER]`. Models are autogenerated; Views are Smarty templates; Controllers handle requests. From `framework-reference-v2.md §0` and §4.","metadata":{"language":"en","source":"framework-reference-v2","section":"0 Executive Summary","kind":"comparison","citations":["framework-reference-v2.md §0","framework-reference-v2.md §4"]}}
|
||||||
|
{"instruction":"Where does Pdo's `query()` method route through?","input":"","output":"Through `parent::getInstance(self::getSettingsSection())->getConn()`. `parent::` is `Mysql`, `getSettingsSection()` returns the static `Pdo::$section`, `getInstance($section)` returns the lazy singleton connection for that section, and `->getConn()` exposes the underlying PDO/connection handle. From `framework-reference-v2.md §2.2`.","metadata":{"language":"en","source":"framework-reference-v2","section":"2.2 Pdo","kind":"code-recall","citations":["core/c/pdo.php","framework-reference-v2.md §2.2"]}}
|
||||||
|
{"instruction":"How do I add a hidden token to a Nibiru form for CSRF protection?","input":"","output":"```php\nForm::addTypeHidden(['name' => 'csrf_token', 'value' => $token]);\n```\n`TypeHidden` accepts `name` and `value`. Place this call BEFORE `Form::addForm(...)` so the field ends up inside the rendered `<form>` via the FIELDS placeholder. From `framework-reference-v2.md §5.4` and §5.8.","metadata":{"language":"en","source":"framework-reference-v2","section":"5.4 Type Class Registry","kind":"workflow","citations":["framework-reference-v2.md §5.4"]}}
|
||||||
|
{"instruction":"Show me the exact wrapper pattern for a single input with a single-shot div.","input":"","output":"```php\nForm::addInputTypeText(['name' => 'username'], ['class' => 'form-group']);\n```\nProduces:\n```html\n<div class=\"form-group\">\n<input type=\"text\" name=\"username\">\n</div>\n```\nThe `assemble()` method at `core/f/form.php:86-97` substitutes `ELEMENT` -> the rendered input, then resets `self::$div` to `false`. From `framework-reference-v2.md §5.7`.","metadata":{"language":"en","source":"framework-reference-v2","section":"5.7 div Wrapping","kind":"code-recall","citations":["core/f/form.php:86-97","framework-reference-v2.md §5.7"]}}
|
||||||
|
{"instruction":"Quick question: where's `self::$form` actually appended?","input":"","output":"In `assemble()` at `core/f/form.php:86-97`, after the optional `ELEMENT` substitution:\n```php\nself::$form .= $element;\n```\nEvery `add*` method that emits a field calls `assemble()` to append. The buffer accumulates until `Form::addForm()` substitutes it into the `FIELDS` placeholder of the `<form>` wrapper. From `framework-reference-v2.md §5.8`.","metadata":{"language":"en","source":"framework-reference-v2","section":"5.8 Assembly Pipeline","kind":"code-recall","citations":["core/f/form.php:86-97","framework-reference-v2.md §5.8"]}}
|
||||||
|
{"instruction":"What's the production-ready way to store API keys in INI?","input":"","output":"Add a custom section, e.g.:\n```ini\n[API_KEYS]\nstripe = \"sk_test_...\"\nmailgun = \"key-...\"\n```\nRead via `Config::getInstance()->getConfig()['API_KEYS']['stripe']`. The framework doesn't restrict section names — any block parsed by `parse_ini_file(..., true)` is accessible. From `framework-reference-v2.md §2.1`.","metadata":{"language":"en","source":"framework-reference-v2","section":"2.1 Config Singleton","kind":"workflow","citations":["framework-reference-v2.md §2.1"]}}
|
||||||
|
{"instruction":"What are the 28 form Type classes' common parent?","input":"","output":"`FormAttributes` at `core/c/formattributes.php`. All Type classes extend it and inherit the `_setAttributes()` method (the substitution engine) plus the static `$_element` storage. They also implement `IForm` to access the 60+ `FORM_*` constants. From `framework-reference-v2.md §5.1` and §5.3.","metadata":{"language":"en","source":"framework-reference-v2","section":"5.1 Form Architecture","kind":"code-recall","citations":["core/c/formattributes.php","framework-reference-v2.md §5.1"]}}
|
||||||
|
{"instruction":"What templates does TypeRadio's allowlist support?","input":"","output":"From `framework-reference-v2.md §5.4` (TypeRadio row): `name, value, id, class, checked`. Renders `<input type=\"radio\" …>`. The `checked` attribute follows the same gotcha as TypeCheckbox — passing `true` produces `checked=\"CHECKED\"` literal output. From `framework-reference-v2.md §5.4` and §5.2.","metadata":{"language":"en","source":"framework-reference-v2","section":"5.4 Type Class Registry","kind":"code-recall","citations":["core/c/typeradio.php","framework-reference-v2.md §5.4"]}}
|
||||||
|
{"instruction":"How do I render a `<textarea>`?","input":"","output":"```php\nForm::addInputTypeTextarea([\n 'name' => 'description',\n 'rows' => '5',\n 'cols' => '60',\n 'value' => 'Initial text content',\n]);\n```\nUses `TypeTextarea`, template `<textarea …>VALUE</textarea>`. The `VALUE` token is replaced by the inner text. From `framework-reference-v2.md §5.4`.","metadata":{"language":"en","source":"framework-reference-v2","section":"5.4 Type Class Registry","kind":"workflow","citations":["framework-reference-v2.md §5.4"]}}
|
||||||
|
{"instruction":"My fileupload form posts but `$_FILES` is empty. What's wrong?","input":"","output":"The `<form>` tag is missing `enctype=\"multipart/form-data\"`. Pass it to `Form::addForm`:\n```php\nForm::addForm([\n 'method' => 'POST',\n 'action' => '/upload',\n 'enctype' => 'multipart/form-data',\n]);\n```\nWithout the enctype, browsers send only the filename in `$_POST`, not the file contents in `$_FILES`. From `framework-reference-v2.md §5.4`.","metadata":{"language":"en","source":"framework-reference-v2","section":"5.4 Type Class Registry","kind":"debug","citations":["framework-reference-v2.md §5.4"]}}
|
||||||
|
{"instruction":"What's the URL convention that maps to a Nibiru controller?","input":"","output":"URL segment 1 -> controller name, segment 2 -> via `_action` (or default). Example: `/users/login` -> `usersController.php` with `$_REQUEST['_action'] = 'login'` -> `loginAction()`. From `framework-reference-v2.md §12`.","metadata":{"language":"en","source":"framework-reference-v2","section":"12 Request Trace","kind":"workflow","citations":["framework-reference-v2.md §12"]}}
|
||||||
|
{"instruction":"How do I unit test an action method that uses `View::forwardTo`?","input":"","output":"`View::forwardTo($page)` triggers an HTTP redirect — typically `header('Location: …')` and `exit`. To unit-test, mock the `View` singleton or wrap the controller's `forwardTo` call behind a method you can stub. The framework doesn't ship a test harness; the static singleton makes direct testing awkward. The pragmatic approach is integration testing via HTTP. From `framework-reference-v2.md §2.6`.","metadata":{"language":"en","source":"framework-reference-v2","section":"2.6 View","kind":"workflow","citations":["framework-reference-v2.md §2.6"]}}
|
||||||
|
{"instruction":"How do I read an INI int value as int instead of string?","input":"","output":"PHP's `parse_ini_file(..., true)` returns scalar values as strings (numeric or otherwise) unless interpreted with `INI_SCANNER_TYPED` flag. Nibiru's `Config::getInstance()` (per `framework-reference-v2.md §2.1`) uses `parse_ini_file(..., true)`, so values come back as strings. Cast at the read site: `(int) Config::getInstance()->getConfig()['SETTINGS']['entriesperpage']`.","metadata":{"language":"en","source":"framework-reference-v2","section":"2.1 Config Singleton","kind":"edge-case","citations":["framework-reference-v2.md §2.1"]}}
|
||||||
|
{"instruction":"How does `addInputTypeSwitch` differ from `addInputTypeCheckbox`?","input":"","output":"Both render boolean controls. `TypeCheckbox` (factory `addInputTypeCheckbox`) is a plain `<input type=\"checkbox\" …>`. `TypeSwitch` (factory `addInputTypeSwitch`) renders an HTML5 toggle/switch markup with `name, id, class, checked, onchange` attributes — visually styled as a slider. Functionally similar; the difference is the rendered markup style. From `framework-reference-v2.md §5.4`.","metadata":{"language":"en","source":"framework-reference-v2","section":"5.4 Type Class Registry","kind":"comparison","citations":["framework-reference-v2.md §5.4"]}}
|
||||||
|
{"instruction":"What's the cleanest pattern for a page that lists all rows from a table?","input":"","output":"```php\nclass UsersController extends Controller {\n public function navigationAction() {\n // load nav for this page\n }\n\n public function pageAction() {\n $rows = Db::loadModel('App\\Users')->loadTableAsArray();\n View::assign(['users' => $rows]);\n // display the template\n }\n}\n```\nDispatcher calls `navigationAction()` first, then `pageAction()` last (per `framework-reference-v2.md §6.3`). The `View::assign` exposes data to Smarty.","metadata":{"language":"en","source":"framework-reference-v2","section":"Cross-Section Workflow","kind":"workflow","citations":["framework-reference-v2.md §6.3","framework-reference-v2.md §2.3","framework-reference-v2.md §2.6"]}}
|
||||||
|
{"instruction":"How do I bail out of an action early?","input":"","output":"`View::forwardTo($page)` redirects and exits. Useful for ACL plugins:\n```php\nif(!$this->validate()) {\n View::forwardTo('/users/login');\n}\n```\nFrom `loach.mssql.database-connection/application/module/users/plugins/acl.php` and `framework-reference-v2.md §4.4`.","metadata":{"language":"en","source":"framework-reference-v2","section":"4.4 Plugin Pattern","kind":"workflow","citations":["loach.mssql.database-connection/application/module/users/plugins/acl.php","framework-reference-v2.md §4.4"]}}
|
||||||
|
{"instruction":"What's the relationship between `[GENERATOR][config-section]` and `[DATABASE]`?","input":"","output":"`[GENERATOR][config-section]` (default `\"DATABASE\"`) tells the autogenerator WHICH `[DATABASE*]` block to introspect for table schema. So `config-section = \"DATABASE_REPORTING\"` makes the generator connect to the database described in `[DATABASE_REPORTING]` and write models that hardcode `Pdo::settingsSection('DATABASE_REPORTING')` in their `__construct()`. From `framework-reference-v2.md §3.2` and §7.","metadata":{"language":"en","source":"framework-reference-v2","section":"3.2 Autogenerator Pipeline","kind":"comparison","citations":["framework-reference-v2.md §3.2","framework-reference-v2.md §7"]}}
|
||||||
|
{"instruction":"My Smarty template can't find `{$user_name}` even though I assigned it. What's wrong?","input":"","output":"Likely causes:\n1. `View::assign()` was called AFTER the page was rendered. The Dispatcher renders at the end of `run()` via `Display::getInstance()->display()`, so all `assign` calls must happen before that — typically inside `pageAction()`.\n2. You assigned to a different singleton scope. `View::assign(...)` must use the framework's static — make sure you're not instantiating a separate Smarty in your code.\n3. The variable was assigned with a different key than referenced (case-sensitive).\n\nFrom `framework-reference-v2.md §6.4` and §2.6.","metadata":{"language":"en","source":"framework-reference-v2","section":"2.6 View","kind":"debug","citations":["framework-reference-v2.md §2.6","framework-reference-v2.md §6.4"]}}
|
||||||
|
{"instruction":"What does `[GENERATOR][folder-out]` look like in real INIs?","input":"","output":"```ini\nfolder-out = \"/../../application/model/\"\n```\nResolved as `__DIR__ . $value` in `core/c/table.php:217` where `__DIR__` is `core/c/`. The leading `/../../` walks up to project root. The folder-namespace fragment (PascalCased basename) is appended afterward. From `framework-reference-v2.md §3.2` and §7.","metadata":{"language":"en","source":"framework-reference-v2","section":"7 INI [GENERATOR]","kind":"inikey","citations":["core/c/table.php:217","framework-reference-v2.md §7"]}}
|
||||||
|
{"instruction":"How do I attach an Observer to a module that implements `SplSubject`?","input":"","output":"Production `Users` module example uses PHP's built-in pattern (`framework-reference-v2.md §10.3`):\n```php\nclass Users extends Module implements Interfaces\\Users, SplSubject\n{\n protected SplObjectStorage $observers;\n\n public function __construct() {\n $this->observers = new SplObjectStorage();\n }\n\n public function attach(SplObserver $obs): void { $this->observers->attach($obs); }\n public function detach(SplObserver $obs): void { $this->observers->detach($obs); }\n public function notify(): void { foreach ($this->observers as $o) $o->update($this); }\n}\n```\nNot core — convention only. The framework neither requires nor wires this up automatically.","metadata":{"language":"en","source":"framework-reference-v2","section":"10.3 Observer Pattern","kind":"workflow","citations":["develop.maschinen-stockert.de/application/module/users/users.php:20-32","framework-reference-v2.md §10.3"]}}
|
||||||
|
{"instruction":"What's the canonical 'load nav, render page' controller skeleton?","input":"","output":"```php\nclass usersController extends Controller {\n public function navigationAction() {\n $nav = json_decode(file_get_contents(/* nav path */), true);\n View::assign(['nav' => $nav]);\n }\n\n public function pageAction() {\n // your data loading\n View::assign(['title' => 'Users']);\n // template assignments...\n }\n}\n```\nThe Dispatcher always calls `navigationAction()` before `pageAction()` (per `framework-reference-v2.md §6.3`). Smarty has access to both sets of variables when rendering.","metadata":{"language":"en","source":"framework-reference-v2","section":"6.3 Controller Lifecycle","kind":"workflow","citations":["framework-reference-v2.md §6.3"]}}
|
||||||
|
{"instruction":"Quick: how do I read `$_GET['page']` safely?","input":"","output":"```php\n$page = (int) $this->getGet('page');\n```\n`Controller::getGet($param)` returns the value from `$_GET` (or null/empty when absent). Cast to int for pagination. The framework helper doesn't auto-validate — caller is responsible. From `framework-reference-v2.md §2.5`.","metadata":{"language":"en","source":"framework-reference-v2","section":"2.5 Controller","kind":"workflow","citations":["core/c/controller.php:14","framework-reference-v2.md §2.5"]}}
|
||||||
|
{"instruction":"How does Nibiru's autogenerator handle a Postgres view (not a table)?","input":"","output":"The v2 reference doesn't document special view handling. `Table::_setTables()` runs `SHOW TABLES` (MySQL) or queries `information_schema` (Postgres). On Postgres, `information_schema.tables` includes views by default unless filtered — so a view will be picked up and a model generated for it. SELECT-only operations work; INSERT/UPDATE on a non-updatable view will fail at query time. From `framework-reference-v2.md §3.2`.","metadata":{"language":"en","source":"framework-reference-v2","section":"3.2 Autogenerator Pipeline","kind":"edge-case","citations":["core/c/table.php","framework-reference-v2.md §3.2"]}}
|
||||||
|
{"instruction":"What does `IDb::loadTableAsArray()` return?","input":"","output":"The entire table as a PHP array of rows. Each row is itself an associative array of column => value. From `core/i/IDb.php` and `framework-reference-v2.md §2.3`. Equivalent to `SELECT * FROM <table>` with no LIMIT.","metadata":{"language":"en","source":"framework-reference-v2","section":"2.3 Db Factory","kind":"code-recall","citations":["core/i/IDb.php","framework-reference-v2.md §2.3"]}}
|
||||||
|
{"instruction":"How does the framework choose between `MySQL\\Db`, `Postgres\\Db`, and `Postgresql\\Db` adapters at runtime?","input":"","output":"Choice is baked into the GENERATED model file at autogen time, not runtime. The mask line `use Nibiru\\Adapter\\[ADAPTER]\\Db;` is substituted with `MySQL`, `Postgres`, or `Postgresql` based on `[GENERATOR][driver]` and `[GENERATOR][odbc]` (see `core/c/model.php:115-132`). After generation, the model `extends Db` forever. To change adapter you must regenerate. From `framework-reference-v2.md §3.2`.","metadata":{"language":"en","source":"framework-reference-v2","section":"3.2 Autogenerator Pipeline","kind":"edge-case","citations":["core/c/model.php:115-132","framework-reference-v2.md §3.2"]}}
|
||||||
|
{"instruction":"Show me how INI section names map to constants on `IMysql`.","input":"","output":"From `core/i/IMysql.php`:\n- `SETTINGS_DATABASE = \"DATABASE\"` -> the default `[DATABASE]` block.\n- `PLACE_DATABASE = \"basename\"` -> the `basename` key inside that block.\n- `PLACE_USERNAME = \"username\"`, `PLACE_PASSWORD = \"password\"`, etc.\n\nThese constants are how the framework spells the literal INI keys when looking values up. Avoids string typos at the call site. From `framework-reference-v2.md §9`.","metadata":{"language":"en","source":"framework-reference-v2","section":"9 Constants","kind":"code-recall","citations":["core/i/IMysql.php","framework-reference-v2.md §9"]}}
|
||||||
|
{"instruction":"Why is there both `core/c/auto.php` and `core/c/autoloader.php`?","input":"","output":"`auto.php` hosts `Auto::loader()` — the modern, INI-driven autoloader actively used by `Dispatcher::run()`. `autoloader.php` is the deprecated legacy one kept for backward compatibility. New code should always use `Auto::loader()`. From `framework-reference-v2.md` Appendix file index.","metadata":{"language":"en","source":"framework-reference-v2","section":"Appendix File Index","kind":"comparison","citations":["framework-reference-v2.md Appendix"]}}
|
||||||
|
{"instruction":"How do I customize the `<form>` action attribute?","input":"","output":"Pass `'action'` in the `addForm` attributes array:\n```php\nForm::addForm([\n 'method' => 'POST',\n 'action' => '/users/save',\n]);\n```\nThe Form Type's template `<form … action=\"ACTION\" …>` substitutes `ACTION` -> `/users/save`. From `framework-reference-v2.md §5.4` (Form wrapper row).","metadata":{"language":"en","source":"framework-reference-v2","section":"5.4 Type Class Registry","kind":"workflow","citations":["framework-reference-v2.md §5.4"]}}
|
||||||
|
{"instruction":"How does Smarty find templates relative to the project root?","input":"","output":"`View::_setEngine()` at `core/c/view.php:66-79` builds the template dir as `core/c/../../{ENGINE[templates]}`. With `[ENGINE][templates] = \"/../../application/view/templates/\"` (default-style), the absolute path becomes `application/view/templates/`. Templates inside are addressed relative to that root: `View::display('users/list.tpl')` -> `application/view/templates/users/list.tpl`. From `framework-reference-v2.md §2.6` and §7.","metadata":{"language":"en","source":"framework-reference-v2","section":"2.6 View","kind":"workflow","citations":["core/c/view.php:66-79","framework-reference-v2.md §2.6"]}}
|
||||||
|
{"instruction":"Quick: what's the strict order in which Auto::loader does work?","input":"","output":"From `core/c/dispatcher.php:42-43` and `framework-reference-v2.md §4.3`:\n1. `loadModelFiles()` (line 42).\n2. `loadModules()` (line 43), which internally:\n a. iterates `iface.pos[]` and requires interfaces.\n b. iterates `trait.pos[]` and requires traits.\n c. iterates `class.pos[]` and requires + instantiates module mains.\n d. iterates `class.plugin.pos[]` and requires + instantiates plugins.","metadata":{"language":"en","source":"framework-reference-v2","section":"4.3 Module Loading Flow","kind":"workflow","citations":["core/c/dispatcher.php:42-43","framework-reference-v2.md §4.3"]}}
|
||||||
|
{"instruction":"What's the gotcha with `addSelectDropdown` in production traits?","input":"","output":"Production `addSelectDropdown` (lines 183-225 of `nibiru-modules/application/module/users/traits/userForm.php`) uses a `foreach` to add `addSelectOption` calls, then a single `addSelect` to flush them. If the helper is called twice without `Form::create()` between, options from both calls accumulate (because `addSelect` clears the option buffer per call, but the form buffer stays put). The pattern works because each `addSelect` clears the option buffer for the next group. From `framework-reference-v2.md §5.6` and §5.9.","metadata":{"language":"en","source":"framework-reference-v2","section":"5.9 Production Usage","kind":"gotcha","citations":["nibiru-modules/application/module/users/traits/userForm.php:183-225","framework-reference-v2.md §5.6"]}}
|
||||||
|
{"instruction":"What's the role of `core/c/debug.php`?","input":"","output":"It hosts the `Debug` class invoked at the end of `Dispatcher::run()` via `Debug::getInstance()`. Adds debug info (timing, query counts) to the response if enabled. Pairs with `[ENGINE][debugbar] = true` and `[ENGINE][debug_template]`. From `framework-reference-v2.md §6.4` and Appendix.","metadata":{"language":"en","source":"framework-reference-v2","section":"Appendix File Index","kind":"code-recall","citations":["core/c/debug.php","framework-reference-v2.md §6.4"]}}
|
||||||
|
{"instruction":"What does it look like when I'm writing my own INI from scratch for a tiny dev app?","input":"","output":"```ini\n[ENGINE]\ntemplates = \"/../../application/view/templates/\"\ntemplates_c = \"/../../application/view/templates_c/\"\ncache = \"/../../application/view/cache/\"\nconfig_dir = \"/../../application/view/configs/\"\ncaching = false\ndebugbar = true\nerror_controller = \"errorController\"\nerror_template = \"error.tpl\"\n\n[AUTOLOADER]\nclass.pos[] = \"users\"\n\n[GENERATOR]\ndatabase = true\ndatabase.overwrite = false\nconfig-section = \"DATABASE\"\nfolder-out = \"/../../application/model/\"\nmodeltemplate = \"/../../application/settings/db/db.class.mask\"\n\n[DATABASE]\nis.active = true\nusername = \"dev\"\npassword = \"devpass\"\nhostname = \"localhost\"\nbasename = \"my_app\"\ndriver = \"mysql\"\nport = \"3306\"\nencoding = \"utf8\"\n\n[SETTINGS]\ntimezone = \"Europe/Berlin\"\n\n[ROUTING]\nroute[index] = \"/\"\nroute[controller] = \"/controller\"\n```\nFrom `framework-reference-v2.md §7`.","metadata":{"language":"en","source":"framework-reference-v2","section":"7 INI Reference","kind":"workflow","citations":["framework-reference-v2.md §7"]}}
|
||||||
|
{"instruction":"What's special about the `class.plugin.pos[]` array vs the others?","input":"","output":"It's loaded LAST. The Auto::loader processes `iface.pos[]` first, then `trait.pos[]`, then `class.pos[]`, then `class.plugin.pos[]`. Plugins thus have access to all interfaces, traits, and module main classes already required. Within `class.plugin.pos[]` itself, the array order dictates load order — same gotcha as other categories. From `framework-reference-v2.md §4.3`.","metadata":{"language":"en","source":"framework-reference-v2","section":"4.3 Module Loading Flow","kind":"workflow","citations":["framework-reference-v2.md §4.3"]}}
|
||||||
|
{"instruction":"What's the most efficient way to load a single row by ID?","input":"","output":"```php\n$row = Db::loadModel('App\\Users')->selectRowsetById(42);\n```\nFrom `core/i/IDb.php`. Uses the model's TABLE constant to know the PK column. Returns the matching row or empty result. One round-trip. From `framework-reference-v2.md §2.3`.","metadata":{"language":"en","source":"framework-reference-v2","section":"2.3 Db Factory","kind":"workflow","citations":["core/i/IDb.php","framework-reference-v2.md §2.3"]}}
|
||||||
|
{"instruction":"Why does the substitution language use UPPERCASE tokens specifically?","input":"","output":"To avoid colliding with valid HTML attribute values (which are typically lowercase) and PHP variable names. The user passes lowercase keys (`'name'`); the substitution engine `strtoupper`s them at replace time (`core/c/formattributes.php:54`). The tokens in the templates are written in the all-caps form (`NAME`, `VALUE`, `PLACEHOLDER`). This separation keeps user-supplied values from accidentally matching template tokens. From `framework-reference-v2.md §5.2`.","metadata":{"language":"en","source":"framework-reference-v2","section":"5.2 Form Substitution","kind":"comparison","citations":["core/c/formattributes.php:48-58","framework-reference-v2.md §5.2"]}}
|
||||||
|
{"instruction":"How do I build a quick three-field form to capture a contact?","input":"","output":"```php\nForm::create();\nForm::addInputTypeText(['name' => 'name', 'placeholder' => 'Name']);\nForm::addInputTypeEmail(['name' => 'email', 'placeholder' => 'Email', 'required' => 'required']);\nForm::addInputTypeTextarea(['name' => 'message', 'rows' => '4']);\nForm::addInputTypeSubmit(['value' => 'Send']);\n$html = Form::addForm(['method' => 'POST', 'action' => '/contact/submit']);\necho $html;\n```\nFrom `framework-reference-v2.md §2.4` and §5.4.","metadata":{"language":"en","source":"framework-reference-v2","section":"5.4 Type Class Registry","kind":"workflow","citations":["framework-reference-v2.md §2.4","framework-reference-v2.md §5.4"]}}
|
||||||
|
{"instruction":"What does `Form::create()` reset?","input":"","output":"It clears `self::$form` (the field-buffer static). It does NOT clear `self::$option` (the option buffer for selects) or `self::$div` (the wrap state) — those are managed independently. From `core/f/form.php:41` and `framework-reference-v2.md §2.4`.","metadata":{"language":"en","source":"framework-reference-v2","section":"2.4 Form Factory","kind":"edge-case","citations":["core/f/form.php:41","framework-reference-v2.md §2.4"]}}
|
||||||
|
{"instruction":"What's the difference between `IMysql::PLACE_DRIVER` and `[DATABASE][driver]`?","input":"","output":"`IMysql::PLACE_DRIVER` is the constant `\"driver\"` — it's the string used to look up the INI key. `[DATABASE][driver]` is the actual INI key/value pair (e.g. `\"mysql\"`). Code reads it as `Config::getInstance()->getConfig()[IMysql::SETTINGS_DATABASE][IMysql::PLACE_DRIVER]` -> `\"mysql\"`. The constants are typo-proofing for the lookup keys. From `framework-reference-v2.md §9`.","metadata":{"language":"en","source":"framework-reference-v2","section":"9 Constants","kind":"comparison","citations":["core/i/IMysql.php","framework-reference-v2.md §9"]}}
|
||||||
|
{"instruction":"How do generated Postgres models call settingsSection?","input":"","output":"For `driver = \"psql\"` with `odbc = true`, the mask substitution produces:\n```php\npublic function __construct()\n{\n Postgres::settingsSection('DBSECTION');\n self::initTable( self::TABLE );\n}\n```\nWith `odbc = false`, it's `Postgresql::settingsSection(...)`. The Postgres-mode footgun is that the mask hardcodes `use Nibiru\\Pdo;` regardless of driver — so unless you patch the import, the unqualified call fails. From `framework-reference-v2.md §3.2`.","metadata":{"language":"en","source":"framework-reference-v2","section":"3.2 Autogenerator Pipeline","kind":"code-recall","citations":["application/settings/db/db.class.mask","framework-reference-v2.md §3.2"]}}
|
||||||
|
{"instruction":"How is `Config::getInstance()` typed?","input":"","output":"```php\npublic static function getInstance(): Settings\n```\nReturn type `Settings` is `\\Nibiru\\Settings` from `core/c/settings.php`. Defined at `core/c/config.php:12`. From `framework-reference-v2.md §2.1`.","metadata":{"language":"en","source":"framework-reference-v2","section":"2.1 Config Singleton","kind":"code-recall","citations":["core/c/config.php:12","framework-reference-v2.md §2.1"]}}
|
||||||
|
|||||||
Reference in New Issue
Block a user