create-grid-query-builder — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited create-grid-query-builder (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Read @.ai/Component/Grid/CONTEXT.md for the factory trilogy and GridDataFactory decoration pattern.
Create src/Adapter/{Domain}/Grid/Query/{Domain}QueryBuilder.php implementing DoctrineQueryBuilderInterface or extending AbstractDoctrineQueryBuilder:
Two required methods:
getSearchQueryBuilder(SearchCriteriaInterface $searchCriteria): QueryBuilder — returns rows for the current pagegetCountQueryBuilder(SearchCriteriaInterface $searchCriteria): QueryBuilder — returns total count (no LIMIT/OFFSET)SELECT c.id_{domain}, c.name, c.active FROM ps_{domain} c$searchCriteria->getFilters(), add a WHERE clause with parameterized values$searchCriteria->getOrderBy() to actual column expressions->setFirstResult($offset)->setMaxResults($limit) (search query only, not count)_lang table with the current language IDReference: src/Core/Grid/Query/LanguageQueryBuilder.php (simple), src/Adapter/Manufacturer/QueryBuilder/ManufacturerQueryBuilder.php (with joins)
For most grids, the standard DoctrineGridDataFactory is sufficient — it calls the query builder automatically. Just wire it in DI:
prestashop.core.grid.data.factory.{domain}:
class: 'PrestaShop\PrestaShop\Core\Grid\Data\Factory\DoctrineGridDataFactory'
arguments:
- '@prestashop.core.admin.{domain}.query_builder'
# ... hook dispatcher, query parser, etc.When grid data needs transformation after query execution (e.g. resolving image URLs from IDs, formatting computed columns), create a decorator:
GridDataFactoryInterfaceGridDataFactorygetData(SearchCriteriaInterface $searchCriteria): call the wrapped factory, then modify the RecordCollectiondecorates: in DI YAMLclass {Domain}GridDataFactory implements GridDataFactoryInterface
{
public function __construct(
private readonly GridDataFactoryInterface $dataFactory,
) {}
public function getData(SearchCriteriaInterface $searchCriteria): GridData
{
$gridData = $this->dataFactory->getData($searchCriteria);
$modifiedRecords = $this->applyModifications($gridData->getRecords());
return new GridData($modifiedRecords, $gridData->getRecordsTotal(), $gridData->getQuery());
}
}Reference: Check existing *GridDataFactory decorators in src/Adapter/ for examples.
Conventions (column alias matching, parameterized queries, PK aliasing, count query rules, decoration preference) are in Grid/CONTEXT.md.
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.