AI datasource
Add unified AI datasource with OpenAI, Claude, Gemini, Mistral, OpenRouter, Ollama and OpenAI-compatible providers.
- Change DSN format to use
#for the API key separator instead of/, allowing model names to contain/and:(e.g. OpenRouter, Ollama). - Bracket syntax supports URLs for any OpenAI-compatible service and class names for custom providers.
- Fix JSON output: move
json_decodefromread()toget(), add JSON instruction to system prompt instead of relying onresponse_format. - Override
offsetGet()so array-access syntax usesread()(text) instead ofget()(JSON). - Mark
\Temma\Datasources\OpenAias deprecated.
Datasources and DAOs
Add $sort parameter to find() and search() and accept bool true in Dao::search().
- Datasources: new
$sortparameter (null|bool|string|array) between$getValuesand$offset.
null=natural,true=descending,false=random,string/array=fields with '-' prefix or['field' => 'asc'|'desc']. SQL datasource supports fieldskeyanddata; Redis/File/S3 only handlenull/true/false(field-based sort throws); queue datasources (Beanstalk/Sqs/Smsmode) keepsearch()disabled. Dao::search()andDao::update():$sortwidened tonull|bool|string|array;truenow generatesORDER BY {primary_key} DESC.- Base/Datasource:
protected _normalizeSort()helper to parse string/array sort criteria into[field, 'asc'|'desc']pairs. - Datasources: Add pagination (offset/limit) to find()/search() and pattern filtering to count().
Data validation
Request: Filter empty strings from GET/POST data before validation.
HTML forms send empty strings for unfilled fields, causing optional fields to fail validation. Treat empty strings as absent values in Request::validateInput() so that optional keys with empty values are correctly ignored and required keys with empty values properly fail.
Check attributes
Add logging on validation failure.
Redis datasource
Debug find() and search() when no matching key.
Controllers
Methods _view() and _template() returns self::EXEC_FORWARD.
Loader
Normalize keys in set() like in get() (remove leading backslashes).