# Coding Conventions

**Analysis Date:** 2026-04-27

## Naming Patterns

**Files:**
- `Mf{Entity}.class.php` — model classes (e.g., `MfParticipant.class.php`)
- `Mf{Entity}DAL.class.php` — data access classes (e.g., `MfParticipantDAL.class.php`)
- `{Name}Controller.php` — controller classes (e.g., `IndexController.php`, `CalcController.php`)
- `{Name}.tpl` — Smarty template files (e.g., `Index.tpl`, `Reg.tpl`)

**Classes:**
- PascalCase for all classes: `MfParticipant`, `IndexController`, `DefaultDAL`
- `Mf` prefix for domain model/DAL classes (short for "mediaflex")

**Methods:**
- PascalCase for public methods: `GetById()`, `GetResult()`, `GetName()`, `SetStatus()`
- camelCase for getters/setters in newer models: `getAdditionalInfo()`, `setAdditionalInfo()`
- `{Name}Action` suffix for controller action methods: `IndexAction`, `RegAction`, `RegEditAction`

**Variables:**
- camelCase for local variables: `$objParticipant`, `$arrayObjReg`, `$dalData`
- `$array*` prefix for arrays: `$arrayObj`, `$arrayFee`, `$arrayObjParameters`
- `$obj*` prefix for single model instances: `$objParam`, `$objParameters`

**DB Columns:**
- `snake_case` in database: `id_mf_participant`, `date_add`, `additional_info`
- Mapped to camelCase properties via `$fields` array in model

## Code Style

**Formatting:**
- Tabs for indentation (not spaces)
- No enforced line length
- No Prettier/PHP-CS-Fixer — manual formatting
- PHP opening tag `<?php`, closing tag `?>` present in all files

**Linting:**
- No configured linter
- No static analysis tools

## Model Field Mapping Pattern

The `$fields` static array in each model class maps DB column names to property names:

```php
static $fields = array(
    'id_mf_participant' => 'Id',
    'name'              => 'Name',
    'nip'               => 'Nip',
    'additional_info'   => 'additionalInfo',
);
```

Getters/setters follow `get{PropertyName}()` / `set{PropertyName}()` convention.

## Template Conventions (Smarty)

**Always use these Smarty plugins — do not inline PHP:**
- `{translate word='key'}` — all visible text strings (reads from `mf_dictionary` table)
- `{url label=X}` or `{url Calc=Y id=$id}` — all URL generation (never hardcode paths)
- `{formField name="x" type="text"}` — text/hidden inputs only; does NOT support textarea
- `{dropDownContainer title='...'}` — admin collapsible sections

**Textarea limitation:**
- `{formField}` Smarty plugin only supports `type="text"` and `type="hidden"`
- Multi-line fields require raw `<textarea>` with manual POST repopulation:

```smarty
<textarea name="field_name" rows="3">{if isset($smarty.post.field_name)}{$smarty.post.field_name|escape}{/if}</textarea>
```

**Template structure:**
- Public templates: `_rejestracja/template/partial/Index/{Name}.tpl`
- Admin templates: `_rejestracja/Admin/template/partial/{Controller}/{Name}.tpl`
- Smarty `assign`: done in controller via `$this->smarty->assign('key', $value)`

## Controller Pattern

Every controller has three methods:

```php
public function preDispatch($param) {
    $this->RunShared('Auth', $param);  // admin only
    $this->Run($param);
    $this->smarty->assign('titleAdmin', '...');
    // nav structure setup
}

public function {Name}Action($param) {
    // business logic + smarty assigns
}

public function postDispatch($param) {
    // usually empty
}
```

## DAL Usage Pattern

```php
$dalData = Mf{Entity}DAL::GetDalDataObj();
$dalData->addCondition('column_name', $value);
$dalData->setSortBy('column_name DESC');  // DESC must be in the string
$results = Mf{Entity}DAL::GetResult($dalData);
$single = Mf{Entity}DAL::GetById($id);
Mf{Entity}DAL::Save($obj);
```

## Migration Runner Pattern

```php
// Check before altering (idempotent)
$check = $conn->query("SELECT ... FROM INFORMATION_SCHEMA.COLUMNS WHERE ...");
if ($check->num_rows > 0) {
    echo "already exists — skipped";
    exit;
}
$conn->query("ALTER TABLE `table` ADD COLUMN `col` TEXT NULL DEFAULT NULL AFTER `other_col`");
echo "success";
```

Runner files require `?run=YYYYMMDD` param to prevent accidental execution.

## Comments

- Minimal comments in existing code
- `//Utils::ArrayDisplay()` debug calls left commented — remove before deploy
- PHPDoc-style block headers on controller classes (legacy format, not enforced)
- `TODO` comments used sparingly: `// TODO: consider disc field logic`

---

*Convention analysis: 2026-04-27*
*Update when patterns change*
