# Coding Conventions **Analysis Date:** 2026-04-27 ## Naming Patterns **Files:** - Module main file: `{modulename}.php` (lowercase, no hyphens) - ObjectModel classes: PascalCase — `CustomFeatureTabRule.php` - Admin controllers: `Admin{Name}Controller.php` - Templates: `{page-name}.tpl` (kebab-case) **Classes:** - Modules: PascalCase matching folder — `class CustomFeatureTab extends Module` - ObjectModels: PascalCase — `class CustomFeatureTabRule extends ObjectModel` - Overrides: same name as core — `class Order extends OrderCore` - Admin controllers: `class AdminCustomFeatureTabController extends ModuleAdminController` **Methods:** - camelCase for all methods: `install()`, `getMatchingRules()`, `installDb()` - Hook methods: `hook{HookName}()` — e.g., `hookDisplayProductExtraContent($params)` - AJAX handlers: `ajaxProcess{ActionName}()` — e.g., `ajaxProcessGetFeatureValues()` - Private helpers: underscore prefix — `_installDb()`, `_uninstallDb()` **Variables:** - camelCase: `$featureValue`, `$tabContent` - Constants: `UPPER_SNAKE_CASE` — `_DB_PREFIX_`, `_PS_VERSION_`, `_MYSQL_ENGINE_` ## Code Style **PHP:** - Indentation: 4 spaces (custom modules); some legacy (AddOrderExtraFields) uses 2 spaces - No strict line length limit observed - Every PHP file begins with: `if (!defined('_PS_VERSION_')) exit;` **SCSS:** - Tool: VSCode Live Sass Compiler - Compile directives at top: `// out: custom.css, compress: true, sourceMap: true` - Variables: `$cOrange: #ff7100;`, `$cBlue: #218fff;` - Section separators: `/** Sekcja *****/` comment blocks (Polish labels) - Comments in Polish - Output: compressed CSS with sourcemap **JavaScript:** - jQuery as primary framework: `$()`, `$(function() { ... })` - camelCase variables: `scrollTrigger`, `backToTop`, `phoneBox` - Polish comments for feature descriptions - Event handlers: `$(element).on('event', handler)` ## PrestaShop-Specific Patterns **Translations:** - Always use: `$this->l('Text to translate')` — never hardcode user-facing strings - Primary locale: Polish (`pl-PL`) - Example: `$this->displayName = $this->l('Karty cech produktu');` **Module `__construct()`:** ```php $this->name = 'customfeaturetab'; $this->tab = 'front_office_features'; $this->version = '1.0.0'; $this->bootstrap = true; $this->ps_versions_compliancy = array('min' => '1.7.0.0', 'max' => _PS_VERSION_); parent::__construct(); // always AFTER property assignment ``` **Install method pattern:** ```php public function install() { return parent::install() && $this->registerHook('displayProductExtraContent') && $this->_installDb(); } ``` **Database queries:** - Direct execution: `Db::getInstance()->execute($sql)` or `Db::getInstance()->executeS($sql)` - Always use `_DB_PREFIX_` for table names - Always use `_MYSQL_ENGINE_` for CREATE TABLE statements - Backtick-escape table/column names in SQL **ObjectModel `$definition`:** ```php public static $definition = [ 'table' => 'custom_feature_tab', 'primary' => 'id_custom_feature_tab', 'multilang' => true, 'fields' => [ 'id_feature' => ['type' => self::TYPE_INT, 'validate' => 'isUnsignedId'], 'active' => ['type' => self::TYPE_BOOL, 'validate' => 'isBool'], // lang fields: 'title' => ['type' => self::TYPE_STRING, 'lang' => true, 'validate' => 'isGenericName'], ], ]; ``` **Smarty templates:** - Extend layouts: `{extends file='page.tpl'}` - Blocks: `{block name='page_content'}{/block}` - Unescaped HTML: `{$variable nofilter}` - Loop: `{foreach from=$items item=item}{/foreach}` ## Import Organization No enforced import order — standard PHP `require_once` or PrestaShop autoloader. ## Error Handling - Standard pattern: return `false` from `install()`/`uninstall()` on failure - Some legacy modules use `die()` for errors (avoid in new code) - No exception handling standard in custom modules ## Comments - File headers with author/copyright in legacy modules - Polish comments in SCSS and JS for section descriptions - `/** Comment */` doc-style for public methods in newer custom modules - PrestaShop security check at top of every file: `if (!defined('_PS_VERSION_')) exit;` --- *Convention analysis: 2026-04-27* *Update when patterns change*