# AGENTS.md — инструкция для агентов

## О проекте

**ocStore (OpenCart) 3.0.3.7** — интернет-магазин на PHP с Twig-шаблонами.

- **Платформа:** ocStore 3.0.3.7 (форк OpenCart)
- **PHP:** >= 8.5
- **Шаблонизатор:** Twig 3.0
- **Язык:** русский (ru-ru)
- **База данных:** MySQL (драйвер mysqli)
- **Веб-сервер:** Apache с mod_rewrite

## Структура проекта

```
public/
├── admin/          # Админ-панель (MVC)
│   ├── controller/ # Контроллеры
│   ├── language/   # Языковые файлы ru-ru
│   ├── model/      # Модели
│   ├── view/       # Twig-шаблоны (.twig)
│   └── index.php
├── store/          # Витрина / каталог (MVC)
│   ├── controller/
│   ├── language/
│   ├── model/
│   └── view/theme/ # Тема оформления
├── system/         # Ядро (фреймворк, библиотеки, хелперы)
│   ├── engine/     # Роутинг, экшены, загрузчик
│   ├── library/    # Библиотеки (language, config, template, …)
│   ├── helper/     # Хелперы
│   └── config/     # Конфигурация ядра
├── image/          # Изображения товаров
├── config.php      # Конфигурация (в .gitignore!)
└── index.php       # Точка входа
storage/
├── cache/          # Кэш (в .gitignore)
├── logs/           # Логи (в .gitignore)
├── modification/   # Модификации OCMOD (в .gitignore)
├── session/        # Сессии PHP (в .gitignore)
├── upload/         # Загрузки (в .gitignore)
├── download/       # Файлы для скачивания (в .gitignore)
└── vendor/         # Composer-зависимости (в .gitignore, Twig)
```

## Важные правила

### Никогда не коммитить
- `public/config.php` и `public/admin/config.php` — содержат пароли БД
- `storage/` целиком (кроме `index.html`)
- `vendor/` — устанавливается через Composer
- Файлы кэша, логов, сессий
- `public/image/` — изображения хранятся отдельно

### Коммиты
- Сообщения коммитов — **на русском языке**
- Стиль: кратко, что сделано (пример: `"Блог в меню"`, `"Удалил googleshopping"`)

### Код-стайл
- PHP: без строгой типизации, используется `$_` суперглобальный массив для языковых переменных
- Языковые файлы — ассоциативный массив `$_['key'] = 'значение';`
- Контроллеры — классы в `Controller*` namespace
- Модели — классы в `Model*` namespace
- Шаблоны — `.twig` файлы
- Формат языковых переменных в шаблонах: `{{ text_yes }}`, `{{ button_save }}`
- Формат языковых констант: `$_['text_yes']`, `$_['button_save']` и т.д.

### OpenCart MVC (паттерн)
- URL-роутинг: `index.php?route=common/home` загружает `controller/common/home.php`
- Контроллер вызывает `$this->load->model('catalog/product')` для загрузки модели
- Контроллер вызывает `$this->load->language('product/product')` для языкового файла
- Шаблоны рендерятся через `$this->response->setOutput($this->load->view(...))`

### Модификации (OCMOD)
- OCMOD-модификации лежат в `public/system/modification.xml`
- Изменённые файлы попадают в `storage/modification/` — не трогать вручную

### Composer
- Зависимости: Twig 3.0
- Установка: `composer install` в `storage/`

## Работа с расширениями

Расширения (модули, темы, платёжные шлюзы и т.д.) устанавливаются через админ-панель или вручную:
- Модули: `public/admin/controller/extension/module/`, `public/store/controller/extension/module/`
- Темы: `public/store/view/theme/`
- Языковые файлы расширений: `public/admin/language/ru-ru/extension/`

## Модальные окна и UI

### Модалки (modal.create)
Система модальных окон реализована в `public/store/view/theme/dominik/assets/js/script.js` (объект `modal`, строка 64).

**Вызов модалки с HTML-контентом:**
```js
modal.create({
    modal: '<p>Содержимое окна</p>',  // HTML-контент (обязателен)
    title: 'Заголовок окна',           // опционально
    width: 400,                        // опционально, ширина в px
    align: 'top',                      // опционально, прижать к верху
    class: {                           // опционально, CSS-классы
        'modal-body': 'p-0',
        'modal-title': 'text-primary'
    },
    callback: {                        // опционально
        show: function() { ... }       // колбек при показе
    }
});
```

**Загрузка контента через AJAX (modal.load):**
```js
modal.load(url, data);  // ожидает JSON-ответ с ключом 'modal'
```

### Выбор города в шапке
Выбор города реализован через:
- **Контроллер:** `public/store/controller/common/city.php`
  - `index()` — отдаёт HTML-список зон (городов) для страны магазина
  - `save()` — сохраняет `city_id` в сессию (`session->data['city_id']`), возвращает JSON с именем города
- **Шаблон списка:** `public/store/view/theme/dominik/template/common/city_list.twig`
- **Логика в хедере:** `public/store/controller/common/header.php` (строки с `model_localisation_zone`)
  - Берёт `config_country_id` и `config_zone_id` из настроек магазина
  - Если в сессии есть `city_id` — используется он, иначе `config_zone_id`
  - Передаёт `current_city_name` и `city_list_url` в шаблон
- **Кнопка в шапке:** `public/store/view/theme/dominik/template/common/header.twig` — после `{{ service_menu }}`
- **JS-функция:** `citySelect(el)` в `script.js` — загружает список городов через AJAX, создаёт модалку, при клике сохраняет выбор в сессию и обновляет название на кнопке

## Полезные команды

```bash
# Очистка кэша
rm -rf storage/cache/*

# Установка зависимостей
cd storage && composer install

# Просмотр логов
tail -f storage/logs/error.log
```
