update
This commit is contained in:
150
.paul/codebase/conventions.md
Normal file
150
.paul/codebase/conventions.md
Normal file
@@ -0,0 +1,150 @@
|
||||
# Coding Conventions
|
||||
|
||||
**Analysis Date:** 2026-05-10
|
||||
|
||||
## Naming Patterns
|
||||
|
||||
**Files:**
|
||||
- PHP class files: PascalCase matching class — `classes/Product.php`, `classes/Cart.php`
|
||||
- Module entry file: lowercase, matches directory — `modules/crosssellpro/crosssellpro.php`
|
||||
- Smarty templates: camelCase per module — `cartCrossSell.tpl`, `checkoutCrossSell.tpl`
|
||||
- Asset files: camelCase — `cartCrossSell.css`, `cartCrossSell.js`
|
||||
|
||||
**Functions / Methods:**
|
||||
- camelCase — `buildCrossSellProducts()`, `collectAccessoryIds()`, `getCombinationFlags()`, `presentProducts()` (`modules/crosssellpro/crosssellpro.php`)
|
||||
- Hook handlers: literal prefix `hook` + PascalCase hook name — `hookDisplayShoppingCartFooter()`, `hookActionFrontControllerSetMedia()`
|
||||
|
||||
**Variables:**
|
||||
- New custom code: `$camelCase` — `$cartProducts`, `$inCartProductIds`, `$productId`
|
||||
- Legacy / DB-driven code: `$snake_case` — `$id_product`, `$id_cart`, `$id_shop` (mirrors PrestaShop column names; expected when interacting with ObjectModel data)
|
||||
|
||||
**Classes:**
|
||||
- PascalCase, suffixed `Core` for PrestaShop core — `class ProductCore extends ObjectModel` (`classes/Product.php`)
|
||||
- Module classes: PascalCase matching folder — `class Crosssellpro extends Module`
|
||||
|
||||
**Hook names (string identifiers):**
|
||||
- camelCase, registered as strings — `displayShoppingCartFooter`, `displayHeader`, `actionFrontControllerSetMedia`
|
||||
|
||||
## Code Style
|
||||
|
||||
**PHP Formatting:**
|
||||
- 4-space indentation (no tabs)
|
||||
- PSR-12-compatible style for new custom code
|
||||
- Opening braces on same line: `class Crosssellpro extends Module {`
|
||||
- Single quotes preferred for strings
|
||||
- Escape filter pattern in templates: `{$product.name|escape:'htmlall':'UTF-8'}`
|
||||
|
||||
**JavaScript Formatting:**
|
||||
- 2-space indentation
|
||||
- Legacy ES5 in custom module JS (`var` declarations) — `modules/crosssellpro/views/js/cartCrossSell.js`
|
||||
- camelCase for functions/variables
|
||||
- Data-attribute targeting: `[data-crosssellpro-block="1"]`
|
||||
|
||||
**Smarty:**
|
||||
- `{$variable|filter:'arg':'arg'}` for output with escaping
|
||||
- `{if}…{/if}`, `{foreach}…{/foreach}`, `{assign}` block syntax
|
||||
|
||||
**Linting:**
|
||||
- No root-level `.php-cs-fixer.php` or `phpstan.neon`
|
||||
- Per-module PHPStan/PHP-CS-Fixer config available in some PrestaShop modules (`modules/<m>/tests/phpstan/phpstan.neon`)
|
||||
|
||||
## Import Organization
|
||||
|
||||
**PHP:**
|
||||
- `<?php` opener with no namespace declared in custom modules (PrestaShop legacy autoloader convention)
|
||||
- `use` statements for Symfony / vendor classes when needed
|
||||
- No enforced ordering — follow existing file's pattern
|
||||
|
||||
**JS:**
|
||||
- Vanilla DOM manipulation in custom module JS — no module bundler
|
||||
- Theme JS bundled in `themes/leo_gstore/assets/cache/`
|
||||
|
||||
## Error Handling
|
||||
|
||||
**Patterns:**
|
||||
- PrestaShop convention: input via `Tools::getValue('key')` (sanitizes; preferred over raw `$_GET`/`$_POST`)
|
||||
- DB queries via `Db::getInstance()` with `pSQL()` for sanitization (legacy pattern; not parameterized)
|
||||
- `try/catch` rare — exceptions surfaced via `Tools::displayError()` or logged
|
||||
- Hook methods generally return rendered output; failure typically silent (returns empty string)
|
||||
|
||||
**Custom-code observations:**
|
||||
- `import-product.php` has minimal error handling, no transaction wrapping
|
||||
- `buy-by-phone.php` accesses `$_POST` directly without `Tools::getValue()` — see `concerns.md`
|
||||
|
||||
## Logging
|
||||
|
||||
**Framework:**
|
||||
- Symfony Monolog (admin layer) via `app/AppKernel.php`
|
||||
- File logs at `errors.log` (root) and `iadmin/errors.log`
|
||||
- No structured/contextual logging in custom code
|
||||
|
||||
**Patterns:**
|
||||
- PrestaShop core `PrestaShopLogger::addLog()` — used in some modules
|
||||
- Custom code prefers `error_log()` or no logging
|
||||
|
||||
## Comments
|
||||
|
||||
**When to Comment:**
|
||||
- PHPDoc blocks above public methods (recommended)
|
||||
- Inline `//` for non-obvious business logic
|
||||
|
||||
**PHPDoc style (used in custom module):**
|
||||
```php
|
||||
/**
|
||||
* Builds presented products list from accessories of products currently in cart.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function buildCrossSellProducts()
|
||||
```
|
||||
Parameter form:
|
||||
```php
|
||||
/**
|
||||
* @param int[] $productIds
|
||||
* @return array<int, bool>
|
||||
*/
|
||||
protected function getCombinationFlags(array $productIds)
|
||||
```
|
||||
Property form:
|
||||
```php
|
||||
/** @var int Manufacturer identifier */
|
||||
public $id_manufacturer;
|
||||
```
|
||||
|
||||
**TODO Comments:**
|
||||
- Format varies (`// TODO`, `// FIXME`, `// HACK`) — found in core, rare in custom code
|
||||
|
||||
## Function Design
|
||||
|
||||
**Size:**
|
||||
- Module hook methods kept short; logic delegated to private helpers (e.g. `buildCrossSellProducts()`, `presentProducts()`)
|
||||
- Long legacy scripts exist (`import-product.php` 813 lines) — anti-pattern
|
||||
|
||||
**Parameters:**
|
||||
- Hook method signatures match PrestaShop dispatcher: `hookXxx(array $params)` where `$params` carries context
|
||||
|
||||
## Module Design (PrestaShop-specific)
|
||||
|
||||
**Module class skeleton:**
|
||||
- Constructor sets `$this->name`, `$this->tab`, `$this->version`, `$this->author`, `$this->bootstrap`, then `parent::__construct()`
|
||||
- `install()` calls `parent::install()` and chains `$this->registerHook(...)` calls
|
||||
- `uninstall()` calls `parent::uninstall()` (cleans hook table)
|
||||
- Hook handlers named `hook<HookName>()`
|
||||
|
||||
**Template overrides:**
|
||||
- Module ships defaults in `modules/<m>/views/templates/hook/`
|
||||
- Theme overrides resolved at `themes/<theme>/modules/<m>/views/templates/hook/`
|
||||
|
||||
**Assets:**
|
||||
- Registered in `hookActionFrontControllerSetMedia()` via `$this->context->controller->registerStylesheet()` / `registerJavascript()`
|
||||
|
||||
## Override Design
|
||||
|
||||
- Place in `override/classes/<ClassName>.php` or `override/classes/controller/<Name>.php`
|
||||
- Extend the core class verbatim and add/override methods only
|
||||
- Document the *why* of each override (currently undocumented in this project — see `concerns.md`)
|
||||
|
||||
---
|
||||
|
||||
*Convention analysis: 2026-05-10*
|
||||
*Update when patterns change*
|
||||
Reference in New Issue
Block a user