# Changelog: Category Access Plugin - ng-helpers Integration

**Дата последнего обновления:** 29 января 2026 г.
**Версия ng-helpers:** v0.2.2
**Версия плагина:** 0.04
**PHP совместимость:** 7.0+

---

## Версия 0.04 - Исправление формата logger (ng-helpers v0.2.2)

### Исправленные функции

#### logger() - Правильный 3-параметровый формат

- **Было:** `logger('category_access', 'Access denied: ...')`
- **Стало:** `logger('Access denied: ...', 'warning', 'category_access.log')`

**Изменения во всех вызовах:**

1. **Запрет доступа к новости** (строка ~79):
   - Уровень: `warning` (было неявно)
   - Добавлен sanitize для имени пользователя

2. **Полный запрет доступа** (строка ~95):
   - Уровень: `warning`
   - Файл: `category_access.log`

3. **Частичный запрет** (строка ~104):
   - Уровень: `info` (менее критично)
   - Файл: `category_access.log`

4. **Запрет доступа к конкретной новости** (строка ~118):
   - Уровень: `warning`
   - Файл: `category_access.log`

### Добавленные функции

#### array_get() - Безопасный доступ к массивам

- **Локации:**
  - Строка ~79: `$userROW['name']` → `array_get($userROW, 'name', 'unknown')`
  - Строка ~64: `$userROW['name']` → `array_get($userROW, 'name', '')`

- **Преимущества:**
  - Устранены undefined index notices
  - Безопасная обработка отсутствующих ключей
  - Default значения для критических данных

#### sanitize() - Очистка данных для логов

- **Использование:**
  ```php
  logger('Access denied: ... user=' . sanitize($userName, 'string') . ...', 'warning', 'category_access.log');
  ```
- **Преимущества:**
  - Защита от injection в логах
  - Безопасное логирование имён пользователей
  - Предотвращение log poisoning

---

## Версия 0.03 - Первичная интеграция

### 1. logger (Категория: Debugging)

- **Назначение:** Логирование попыток доступа к закрытым категориям
- **Использование:**

  ```php
  // При запрете доступа к новости
  logger('category_access', 'Access denied: newsID=' . $newsID . ', user=' . $userName . ', catid=' . $SQLnews['catid'] . ', IP=' . get_ip());

  // При показе полного запрета
  logger('category_access', 'Full access denied notification shown, IP=' . get_ip());

  // При частичном запрете
  logger('category_access', 'Partial access: hidden=' . $this->hiddenCount . ' items, IP=' . get_ip());

  // При запрете доступа к конкретной новости
  logger('category_access', 'News access denied: newsID=' . $newsID . ', IP=' . get_ip());
  ```

- **Преимущества:**
  - Полный аудит попыток доступа к закрытым материалам
  - Отслеживание пользователей, пытающихся получить доступ
  - IP tracking для безопасности
  - Статистика использования закрытых категорий
  - Выявление подозрительной активности

### 2. get_ip (Категория: Network)

- **Назначение:** Отслеживание IP адресов для всех попыток доступа
- **Использование:**
  ```php
  logger('category_access', 'Access denied: ..., IP=' . get_ip());
  ```
- **Преимущества:**
  - Поддержка прокси и CloudFlare
  - Аудит с IP tracking
  - Выявление попыток обхода ограничений
  - Анализ географии запросов

### 3. sanitize (Категория: Security)

- **Назначение:** Импортирован для будущих улучшений безопасности
- **Использование:**
  ```php
  // Потенциально для валидации пользовательских данных
  ```
- **Преимущества:**
  - Готовность к будущим улучшениям
  - Безопасная обработка данных

---

## Безопасность

### Улучшения:

1. **Access logging:** Полный аудит попыток доступа
2. **IP tracking:** Отслеживание для всех запретов
3. **User tracking:** Логирование имени пользователя
4. **Category tracking:** Запись ID категорий

### Предотвращение:

- Попытки обхода ограничений доступа
- Подозрительная активность (массовые запросы)
- Анализ IP для выявления ботов
- Мониторинг доступа к премиум контенту

---

## Логирование

### Записи в логах:

```
[2026-01-12 19:30:10] Access denied: newsID=1523, user=guest, catid=5, IP=192.168.1.100
[2026-01-12 19:30:11] Full access denied notification shown, IP=192.168.1.100

[2026-01-12 19:35:20] Access denied: newsID=1420, user=john_doe, catid=3,7, IP=192.168.1.101
[2026-01-12 19:35:20] Partial access: hidden=3 items, IP=192.168.1.101

[2026-01-12 19:40:10] News access denied: newsID=1350, IP=192.168.1.102
```

### Что отслеживается:

- **Запрет доступа:** newsID, имя пользователя (или guest), catid, IP
- **Полный запрет:** Когда показывается страница "Доступ запрещён"
- **Частичный запрет:** Количество скрытых материалов, IP
- **Запрет новости:** Конкретная новость, к которой запрещён доступ

---

## Производительность

### Влияние ng-helpers:

- **logger():** < 0.5ms (запись в файл)
- **get_ip():** < 0.01ms

### Общее влияние:

- **Минимальное:** < 1ms на проверку доступа
- **Польза:** Значительное улучшение безопасности и аудита

---

## Структура изменений

```
category_access.php
├── import use function Plugins\{logger, get_ip, sanitize};
├── showNews()
│   └── Добавлен logger при запрете доступа (newsID, user, catid, IP)
├── onAfterShow()
│   ├── Добавлен logger для полного запрета
│   └── Добавлен logger для частичного запрета
└── onAfterNewsShow()
    └── Добавлен logger при запрете доступа к новости
```

---

## Обратная совместимость

✅ **Полная обратная совместимость:**

- Все существующие настройки работают
- Логика проверки доступа не изменилась
- Шаблоны совместимы
- Конфигурация не затронута

---

## Особенности плагина Category Access

### Функциональность:

- Ограничение доступа к категориям новостей по группам пользователей
- Типы доступа:
  - **guest** (гости)
  - **admin** (администраторы)
  - **moder** (модераторы)
  - **journ** (журналисты)
  - **coment** (комментаторы)
- Режимы ограничения:
  - **Тип 1:** Доступ только к определённым категориям
  - **Тип 2:** Полный доступ ко всем категориям
- Поддержка родительских категорий (GetParentCategory)
- Персональные разрешения для конкретных пользователей
- Два типа уведомлений:
  - **Полный запрет:** Страница полностью заменяется сообщением
  - **Частичный запрет:** Мягкое уведомление, часть контента скрывается

### Работа:

- Фильтр NewsFilter проверяет доступ для каждой новости
- Счётчик скрытых новостей (hiddenCount)
- Шаблон-заглушка для закрытых новостей
- Уведомления через msg()

---

## Рекомендации по использованию

### 1. Настройка групп доступа

```php
// В конфигурации плагина
guest = 1       // Тип доступа для гостей (1=ограниченный, 2=полный)
admin = 2       // Администраторы: полный доступ
moder = 2       // Модераторы: полный доступ
journ = 1       // Журналисты: ограниченный доступ
coment = 1      // Комментаторы: ограниченный доступ
```

### 2. Настройка категорий

```php
// Список доступных категорий для ограниченных пользователей
categorys = [1, 2, 5, 7]  // ID категорий
```

### 3. Персональные разрешения

```php
// Конкретные пользователи с доступом к определённым категориям
users = [
    'john_doe' => 3,    // Доступ к категории 3
    'jane_smith' => 7   // Доступ к категории 7
]
```

### 4. Мониторинг

- Проверяйте логи `{CACHE_DIR}/logs/category_access.log`
- Отслеживайте попытки доступа к закрытым материалам
- Анализируйте IP адреса для выявления подозрительной активности
- Контролируйте, какие категории чаще всего пытаются просмотреть

---

## Тестирование

Проверено на:

- ✅ PHP 7.0, 7.2, 7.4
- ✅ PHP 8.0, 8.1
- ✅ Ограничение доступа для гостей
- ✅ Полный доступ для администраторов
- ✅ Ограниченный доступ для журналистов
- ✅ Персональные разрешения пользователей
- ✅ Родительские категории (GetParentCategory)
- ✅ Полный запрет (замена страницы)
- ✅ Частичный запрет (скрытие части контента)
- ✅ Логирование всех попыток доступа

---

## SEO и UX преимущества

### Безопасность:

1. **Аудит доступа:** Полное логирование попыток
2. **IP tracking:** Отслеживание подозрительных запросов
3. **User tracking:** Идентификация пользователей
4. **Category tracking:** Контроль закрытых категорий

### UX:

- Мягкие уведомления при частичном запрете
- Понятные сообщения об ограничениях
- Не ломается навигация при частичном запрете

---

## Частые сценарии использования

### 1. Гость пытается просмотреть премиум категорию

```
Гость:
1. Открывает страницу с новостями из закрытой категории
2. Видит сообщение "Доступ к материалам ограничён"
3. Страница заменяется на сообщение

Лог:
- Access denied: newsID=1523, user=guest, catid=5, IP=192.168.1.100
- Full access denied notification shown, IP=192.168.1.100
```

### 2. Журналист просматривает частично закрытую страницу

```
Журналист:
1. Открывает главную страницу с разными категориями
2. Видит новости из доступных категорий
3. Получает уведомление "Доступ к части материалов ограничён"
4. Закрытые новости скрыты

Лог:
- Access denied: newsID=1420, user=john_doe, catid=7, IP=192.168.1.101
- Access denied: newsID=1421, user=john_doe, catid=7, IP=192.168.1.101
- Partial access: hidden=2 items, IP=192.168.1.101
```

### 3. Администратор просматривает всё

```
Администратор:
1. Открывает любую страницу
2. Видит весь контент без ограничений
3. Никаких уведомлений

Лог: (пусто, доступ разрешён)
```

---

## Известные проблемы и ограничения

### 1. Только для новостей

- **Проблема:** Плагин работает только с NewsFilter
- **Решение:** Это feature, не bug. Для других типов контента нужны отдельные фильтры

### 2. Родительские категории

- **Проблема:** Логика GetParentCategory может быть сложной
- **Решение:** Проверяйте настройки категорий, используйте логи

### 3. Персональные разрешения

- **Проблема:** Настройка через массив users может быть неудобной
- **Решение:** Рассмотрите добавление UI в админке

### 4. Кеширование

- **Проблема:** Закрытый контент может кешироваться
- **Решение:** Используйте per-user кеширование или отключите кеш для закрытых категорий

---

## Аналитика доступа

### Метрики из логов:

#### Популярные закрытые категории:

```
Формула: COUNT(Access denied WHERE catid=X)
Пример логов:
- Access denied: catid=5 (15 раз)
- Access denied: catid=7 (8 раз)
- Access denied: catid=3 (23 раза)
Популярная закрытая категория: #3 (23 попытки)
```

#### Активные пользователи:

```
Формула: COUNT(DISTINCT user FROM logs WHERE user != 'guest')
Анализ: Авторизованные пользователи, пытающиеся получить доступ
```

#### География запросов:

```
Формула: COUNT(DISTINCT IP FROM logs)
Анализ: Уникальные IP адреса, пытающиеся получить доступ
```

---

## Расширения функциональности

### 1. Временной доступ (требует доработки)

```php
// Доступ на определённое время
function checkTemporaryAccess($userID, $categoryID) {
    // Проверка временных разрешений
}
```

### 2. Подписки (требует доработки)

```php
// Платные подписки на категории
function checkSubscription($userID, $categoryID) {
    // Проверка активной подписки
}
```

### 3. История доступа (требует доработки)

```sql
CREATE TABLE `prefix_category_access_log` (
    `id` INT AUTO_INCREMENT PRIMARY KEY,
    `user_id` INT,
    `news_id` INT,
    `category_id` INT,
    `ip` VARCHAR(45),
    `timestamp` INT
);
```

---

## Шаблоны

### Шаблон-заглушка (extras_dir/category_access/tpl/):

```html
<!-- Показывается вместо закрытой новости -->
<div class="access-denied">
  <i class="icon-lock"></i>
  <p>Доступ к этому материалу ограничен</p>
  <a href="/register/">Зарегистрируйтесь</a> или
  <a href="/login/">войдите</a> для просмотра
</div>
```

---

## Сообщения об ошибках

### msg() уведомления:

#### Полный запрет:

```php
msg(['type' => 'error', 'text' => 'Доступ к материалам ограничен']);
// Красное уведомление, критическое
```

#### Частичный запрет:

```php
msg(['type' => 'info', 'text' => 'Доступ к части материалов ограничен']);
// Синее уведомление, информационное
```

---

## Интеграция с другими плагинами

### UProfile (опционально):

- Связь ограничений с профилями пользователей
- Дополнительные поля для управления доступом

### Подписки (опционально):

- Платные подписки на категории
- Временные разрешения доступа

---

## Примеры настроек

### Сценарий 1: Премиум контент

```php
// Гости не видят ничего из категории 5
guest = 1
categorys = [1, 2, 3, 4, 6, 7]  // Без категории 5

// Все остальные видят всё
admin = 2
moder = 2
journ = 2
coment = 2
```

### Сценарий 2: Персонализированный доступ

```php
// Журналисты видят только свои категории
journ = 1
categorys = []  // Пусто по умолчанию

// Персональные разрешения
users = [
    'tech_writer' => 3,    // Технологии
    'news_writer' => 5,    // Новости
    'blog_writer' => 7     // Блоги
]
```

### Сценарий 3: Закрытый раздел

```php
// Только администраторы видят категорию 10
guest = 1
categorys = [1, 2, 3, 4, 5, 6, 7, 8, 9]  // Без 10
admin = 2  // Полный доступ
moder = 1  // Ограниченный, без категории 10
```

---

## Мониторинг и отчёты

### Ежедневный отчёт из логов:

```
Дата: 12.01.2026

Попытки доступа: 127
- Гости: 95 (75%)
- Авторизованные: 32 (25%)

Топ закрытых категорий:
1. Категория #5 - 45 попыток
2. Категория #7 - 28 попыток
3. Категория #3 - 23 попытки

Топ IP:
1. 192.168.1.100 - 15 попыток
2. 192.168.1.101 - 12 попыток
3. 192.168.1.102 - 9 попыток

Рекомендации:
- Категория #5 наиболее интересна пользователям
- IP 192.168.1.100 - проверить на подозрительную активность
```

---

## Диагностика проблем

### Пользователь не видит контент:

1. Проверьте группу пользователя (guest, admin, moder, journ, coment)
2. Проверьте настройку типа доступа для этой группы
3. Проверьте список categorys - есть ли там нужная категория
4. Проверьте персональные разрешения users
5. Посмотрите логи - есть ли запись "Access denied"

### Контент доступен всем:

1. Проверьте тип доступа - возможно стоит "2" (полный доступ)
2. Проверьте, что категория правильно настроена в categorys
3. Убедитесь, что плагин активирован

### Частичный запрет не работает:

1. Проверьте hiddenCount в логах
2. Убедитесь, что уведомления включены
3. Проверьте шаблон - возможно msg() блокируется
