Files
shopPRO/PROJECT_STRUCTURE.md

18 KiB
Raw Blame History

Struktura Projektu shopPRO

Dokumentacja struktury projektu shopPRO do szybkiego odniesienia.

System Cache (Redis)

Klasy odpowiedzialne za cache

RedisConnection

  • Plik: autoload/class.RedisConnection.php
  • Opis: Singleton zarządzający połączeniem z Redis
  • Metody:
    • getInstance() - pobiera instancję połączenia
    • getConnection() - zwraca obiekt Redis

CacheHandler

  • Plik: autoload/class.CacheHandler.php
  • Opis: Handler do obsługi cache Redis
  • Metody:
    • get($key) - pobiera wartość z cache
    • set($key, $value, $ttl = 86400) - zapisuje wartość do cache
    • exists($key) - sprawdza czy klucz istnieje
    • delete($key) - usuwa pojedynczy klucz
    • deletePattern($pattern) - usuwa klucze według wzorca

Klasa S (pomocnicza)

  • Plik: autoload/class.S.php
  • Metody cache:
    • clear_redis_cache() - czyści cały cache Redis (flushAll)
    • clear_product_cache(int $product_id) - czyści cache konkretnego produktu

Wzorce kluczy Redis

Produkty

shop\product:{product_id}:{lang_id}:{permutation_hash}
  • Przechowuje zserializowany obiekt produktu
  • TTL: 24 godziny (86400 sekund)
  • Klasa: shop\Product::getFromCache() - autoload/shop/class.Product.php:121

Opcje ilościowe produktu

\shop\Product::get_product_permutation_quantity_options:{product_id}:{permutation}
  • Przechowuje informacje o ilości i komunikatach magazynowych
  • Klasa: shop\Product::get_product_permutation_quantity_options() - autoload/shop/class.Product.php:549

Zestawy produktów

\shop\Product::product_sets_when_add_to_basket:{product_id}
  • Przechowuje produkty często kupowane razem
  • Klasa: shop\Product::product_sets_when_add_to_basket() - autoload/shop/class.Product.php:316

Integracje z systemami zewnętrznymi (CRON)

Plik: cron.php

Sellasist

  • Aktualizacja produktów: Linia 111-149
  • Funkcje: Aktualizacja cen i stanów magazynowych
  • Częstotliwość: Co 10 minut
  • Czyszczenie cache: Linia 146

Apilo

  • Aktualizacja pojedynczego produktu: Linia 152-176

    • Częstotliwość: Co 10 minut
    • Czyszczenie cache: Linia 173
  • Synchronizacja cennika: Linia 179-218

    • Częstotliwość: Co 1 godzinę
    • Czyszczenie cache: Linia 212

Baselinker

  • Aktualizacja produktów: Linia 220-289
  • Funkcje: Ceny, stany magazynowe, wagi
  • Częstotliwość: Co 24 godziny (1440 minut)
  • Czyszczenie cache: Linia 278

Panel Administratora

Routing

  • Główny katalog: admin/
  • Template główny: admin/templates/site/main-layout.php
  • Kontrolery (nowe): autoload/admin/Controllers/
  • Kontrolery legacy (fallback): autoload/admin/controls/

Przycisk "Wyczyść cache"

  • Lokalizacja UI: admin/templates/site/main-layout.php:172
  • JavaScript: admin/templates/site/main-layout.php:235-274
  • Endpoint AJAX: /admin/settings/clear_cache_ajax/
  • Kontroler: autoload/admin/Controllers/SettingsController.php:43-60
  • Działanie:
    1. Pokazuje spinner "Czyszczę cache..."
    2. Czyści katalogi: temp/, thumbs/
    3. Wykonuje flushAll() na Redis
    4. Pokazuje "Cache wyczyszczony!" przez 2 sekundy
    5. Przywraca stan początkowy

Struktura katalogów

shopPRO/
├── admin/                      # Panel administratora
│   ├── templates/              # Szablony widoków
│   └── layout/                 # Zasoby CSS/JS/ikony
├── autoload/                   # Klasy autoloadowane
│   ├── admin/                  # Klasy panelu admin
│   │   ├── controls/           # Kontrolery
│   │   └── factory/            # Fabryki/helpery
│   ├── front/                  # Klasy frontendu
│   │   └── factory/            # Fabryki/helpery
│   └── shop/                   # Klasy sklepu
├── libraries/                  # Biblioteki zewnętrzne
├── temp/                       # Cache tymczasowy
├── thumbs/                     # Miniatury zdjęć
└── cron.php                    # Zadania CRON

Baza danych

Główne tabele produktów

  • pp_shop_products - produkty główne
  • pp_shop_products_langs - tłumaczenia produktów
  • pp_shop_products_images - zdjęcia produktów
  • pp_shop_products_categories - kategorie produktów
  • pp_shop_products_custom_fields - pola własne produktów

Tabele integracji

  • Kolumny w pp_shop_products:
    • sellasist_product_id, sellasist_get_data_date
    • apilo_product_id, apilo_get_data_date
    • baselinker_product_id, baselinker_get_data_date

Konfiguracja

Redis

  • Konfiguracja: config.php (zmienna $config['redis'])
  • Parametry: host, port, password

Autoload

  • Funkcja: __autoload_my_classes() w cron.php:6
  • Wzorzec: autoload/{namespace}/class.{ClassName}.php

Klasy pomocnicze

\S (autoload/class.S.php)

Główna klasa helper z metodami:

  • seo($val) - generowanie URL SEO
  • normalize_decimal($val, $precision) - normalizacja liczb
  • send_email() - wysyłanie emaili
  • delete_dir($dir) - usuwanie katalogów
  • htacces() - generowanie .htaccess i sitemap.xml

Medoo

  • Plik: libraries/medoo/medoo.php
  • Zmienna: $mdb
  • ORM do operacji na bazie danych

Najważniejsze wzorce

Namespace'y

  • \admin\Controllers\ - nowe kontrolery panelu admin (DI)
  • \admin\controls\ - kontrolery legacy (fallback)
  • \Domain\ - repozytoria/logika domenowa
  • \admin\factory\ - helpery/fabryki admin
  • \front\factory\ - helpery/fabryki frontend
  • \shop\ - klasy sklepu (Product, Order, itp.)

Cachowanie produktów

// Pobranie produktu z cache
$product = \shop\Product::getFromCache($product_id, $lang_id, $permutation_hash);

// Czyszczenie cache produktu
\S::clear_product_cache($product_id);

// Czyszczenie całego cache
\S::clear_redis_cache();

Refaktoryzacja do Domain-Driven Architecture

Nowa struktura (w trakcie migracji)

autoload/
├── Domain/                    # Nowa warstwa biznesowa (namespace \Domain\)
│   ├── Product/
│   │   └── ProductRepository.php   # getQuantity, getPrice, getName, find, updateQuantity, archive, unarchive
│   ├── Banner/
│   │   └── BannerRepository.php    # find, delete, save
│   ├── Settings/
│   │   └── SettingsRepository.php  # saveSettings, getSettings (fasada → factory)
│   └── Cache/
│       └── CacheRepository.php     # clearCache (dirs + Redis)
├── admin/
│   ├── Controllers/                # Nowe kontrolery (namespace \admin\Controllers\)
│   │   ├── BannerController.php         # DI, instancyjny
│   │   ├── SettingsController.php       # DI, instancyjny (clearCache, save, view)
│   │   ├── ProductArchiveController.php # DI, instancyjny (list, unarchive)
│   │   └── UsersController.php          # DI, instancyjny (view_list, user_edit, user_save, user_delete, login_form, twofa)
│   ├── class.Site.php              # Router: nowy kontroler → fallback stary
│   ├── controls/                   # Stare kontrolery (niezależny fallback)
│   ├── factory/                    # Stare helpery (niezależny fallback)
│   └── view/                       # Widoki (statyczne - bez zmian)
├── shop/                           # Legacy - fasady do Domain
└── front/factory/                  # Legacy - stopniowo migrowane

Aktualny stan migracji (uzupełnienie)

  • Dodane repozytorium: Domain\Dictionaries\DictionariesRepository
  • Dodane kontrolery DI: admin\Controllers\DictionariesController, admin\Controllers\FilemanagerController, admin\Controllers\UsersController
  • Dodane repozytorium: Domain\User\UserRepository
  • Domain\Settings\SettingsRepository działa bezpośrednio na DB (bez delegacji do admin\factory\Settings)

Routing admin (admin\Site::route())

  1. Sprawdź mapę $newControllers → utwórz instancję z DI → wywołaj
  2. Jeśli nowy kontroler nie istnieje (class_exists() = false) → fallback na admin\controls\
  3. Stary kontroler jest NIEZALEŻNY od nowych klas (bezpieczny fallback)

Dependency Injection

Nowe klasy używają Dependency Injection zamiast global variables:

// STARE
global $mdb;
$quantity = $mdb->get('pp_shop_products', 'quantity', ['id' => $id]);

// NOWE
$repository = new \Domain\Product\ProductRepository($mdb);
$quantity = $repository->getQuantity($id);

Testowanie (tylko dla deweloperów)

UWAGA: Pliki testów NIE są częścią aktualizacji dla klientów!

Narzędzia

  • PHPUnit 9.6.34 - framework testowy
  • test.bat - uruchamianie testów
  • composer.json - autoloading PSR-4

Struktura

tests/
├── Unit/
│   ├── Domain/
│   │   ├── Product/ProductRepositoryTest.php    # 11 testów
│   │   ├── Banner/BannerRepositoryTest.php      # 4 testy
│   │   ├── Settings/SettingsRepositoryTest.php  # 3 testy
│   │   └── Cache/CacheRepositoryTest.php        # 4 testy
│   └── admin/
│       └── Controllers/
│           ├── SettingsControllerTest.php        # 7 testów
│           └── ProductArchiveControllerTest.php  # 6 testów
└── Integration/

Aktualnie w suite są też testy modułów Dictionaries, Articles i Users (repozytoria + kontrolery DI). Łącznie: 119 tests, 256 assertions

Ostatnie modyfikacje

2026-02-10: Porządki po migracji i release 0.252 (ver. 0.252)

  • UPDATE: ProductArchiveController i szablony listy archiwum przepięte na nową tabelę (components/table-list)
  • UPDATE: CSS/JS dla list wydzielone do osobnych widoków *-custom-script.php (banery i archiwum produktów)
  • UPDATE: dodano admin\Controllers\FilemanagerController i przepięto filemanager na nowy routing
  • FIX: naprawiono błąd Invalid Key w filemanagerze
  • CLEANUP: usunięto legacy pliki: autoload/admin/controls/class.Archive.php, autoload/admin/controls/class.Filemanager.php, autoload/admin/view/class.FileManager.php, stare szablony admin/templates/product_archive/*
  • RENAME: folder szablonów admin/templates/product_archive/admin/templates/product-archive/
  • Testy: 82 tests, 181 assertions

2026-02-09: Migracja Dictionaries (ver. 0.251)

  • NEW: Domain\Dictionaries\DictionariesRepository (listForAdmin, find, save, delete, allUnits)
  • NEW: admin\Controllers\DictionariesController (lista + formularz na nowych komponentach)
  • UPDATE: migracja słowników na components/table-list i components/form-edit
  • FIX: obsługa lang_id jako string (pl, en) w zapisie tłumaczeń
  • CLEANUP: usunięto legacy klasy Dictionaries (admin\controls, admin\factory, front\factory)
  • Testy: 82 tests, 181 assertions

2026-02-09: Refaktoryzacja Settings (ver. 0.250)

  • UPDATE: Domain\Settings\SettingsRepository ma bezpośredni dostęp do DB (bez delegacji do admin\factory\Settings)
  • UPDATE: przepięto użycia admin\factory\Settings na Domain\Settings\SettingsRepository
  • CLEANUP: usunięto legacy klasy Settings (factory, controls, view)
  • Testy: 82 tests, 181 assertions

2026-02-07: Usuniecie legacy kontrolera Articles (ver. 0.246)

  • UPDATE: usunieto autoload/admin/controls/class.Articles.php
  • UPDATE: admin\Controllers\ArticlesController::galleryOrderSave() uzywa Domain\Article\ArticleRepository::saveGalleryOrder()
  • UPDATE: Domain\Article\ArticleRepository - dodano saveGalleryOrder(int $articleId, string $order): bool
  • UPDATE: admin\factory\Articles::gallery_order_save() deleguje do ArticleRepository::saveGalleryOrder() (backward compatibility)
  • FIX: sortowanie list admin po reloadzie - RewriteRule dla /admin/... ma QSA
  • FIX: generator \S::htacces() komentuje dyrektywy AddHandler|SetHandler|ForceType (kompatybilnosc hostingu)
  • UPDATE: zrodlo generatora libraries/htaccess.conf dostosowane do powyzszych zmian
  • WAZNE (deploy): w paczce aktualizacji dodac ver_X.XXX_files.txt z wpisem: F: ../autoload/admin/controls/class.Articles.php
  • Testy: 65 tests, 131 assertions

2026-02-06: Migracja Articles::article_delete do DI (ver. 0.245)

  • UPDATE: Domain\Article\ArticleRepository - dodano archive() (ustawia status = -1)
  • UPDATE: admin\Controllers\ArticlesController - nowa akcja delete() z DI
  • UPDATE: Router admin\Site - dodano 'article_delete' => 'delete' do $actionMap
  • UPDATE: admin\factory\Articles::articles_set_archive() deleguje do ArticleRepository::archive()
  • UPDATE: admin\controls\Articles::article_delete() oznaczone @deprecated
  • Testy: 59 tests, 123 assertions

2026-02-06: Migracja Articles::article_save do DI (ver. 0.244)

  • UPDATE: Domain\Article\ArticleRepository - dodano save() + prywatne helpery (buildArticleRow, buildLangRow, saveTranslations, savePages, assignTempFiles, assignTempImages, deleteMarkedFiles, deleteMarkedImages, maxPageOrder)
  • UPDATE: admin\Controllers\ArticlesController - nowa akcja save() z DI
  • UPDATE: Router admin\Site - dodano 'article_save' => 'save' do $actionMap
  • UPDATE: admin\factory\Articles::article_save() deleguje do ArticleRepository::save() (backward compatibility)
  • UPDATE: admin\controls\Articles::article_save() oznaczone @deprecated
  • UPDATE: tests/bootstrap.php - dodano stub S::seo()
  • Testy: 57 tests, 119 assertions

2026-02-06: Articles cleanup moved to repository (ver. 0.243)

  • UPDATE: Domain\Article\ArticleRepository - added deleteNonassignedImages() and deleteNonassignedFiles()
  • UPDATE: admin\Controllers\ArticlesController::edit() uses repository cleanup methods
  • UPDATE: admin\factory\Articles::delete_nonassigned_images() and delete_nonassigned_files() delegate to repository (backward compatibility)
  • Testy: 50 tests, 95 assertions

2026-02-06: Migracja Articles::article_edit do DI (ver. 0.242)

  • NOWE: Domain\Article\ArticleRepository - repozytorium artykułów (find())
  • UPDATE: admin\Controllers\ArticlesController - konstruktor DI + edit() używa repozytorium
  • UPDATE: Router admin\Site - factory dla ArticlesController z ArticleRepository
  • UPDATE: admin\factory\Articles::article_details() deleguje do Domain\Article\ArticleRepository
  • UPDATE: Stare kontrolery admin\controls\Articles|Banners|Settings - metody przejęte przez nowe kontrolery oznaczone @deprecated
  • Testy: 48 testów, 91 asercji

2026-02-06: Migracja ProductArchive (ver. 0.241)

  • NOWE: admin\Controllers\ProductArchiveController - kontroler archiwum produktów z DI
  • NOWE: ProductRepository::archive(), unarchive() - operacje archiwizacji w repozytorium
  • RENAME: admin/templates/archive/admin/templates/product_archive/
  • FIX: SQL w ajax_products_list_archive() - puste wyszukiwanie generowało name|ean|sku LIKE '%%' (NULL bitwise OR filtrował wyniki)
  • FIX: Brakujący archive = 1 w branchu bez wyszukiwania
  • CLEANUP: Usunięto zbędny JS z szablonu archiwum (apilo, baselinker, duplikowanie, edycja cen)
  • Stary kontroler admin\controls\Archive zachowany jako fallback
  • Testy: 50 tests, 95 assertions (+10 nowych)

2026-02-05: Migracja Settings + Cache (ver. 0.240)

  • NOWE: Domain\Settings\SettingsRepository - repozytorium ustawień (fasada → factory)
  • NOWE: Domain\Cache\CacheRepository - repozytorium cache (dirs + Redis)
  • NOWE: admin\Controllers\SettingsController - kontroler z DI (clearCache, save, view)
  • FIX: Brakujący id="content" w main-layout.php (komunikaty grid.js)
  • FIX: persist_edit = true w settings.php (komunikat po zapisie)
  • Stary kontroler admin\controls\Settings zachowany jako fallback
  • Testy: 29 testów, 60 asercji (+14 nowych)
  • Bootstrap testów: stuby klas systemowych (S, RedisConnection, Redis, CacheHandler)

2026-02-05: Migracja Banner + Product (ver. 0.239)

  • NOWE: Domain\Banner\BannerRepository - repozytorium banerów (find, delete, save)
  • NOWE: admin\Controllers\BannerController - pierwszy kontroler z DI
  • NOWE: Router z mapą $newControllers + fallback na stare kontrolery
  • NOWE: Autoloader PSR-4 fallback w 9 entry pointach
  • Zmigrowano: get_product_price()ProductRepository::getPrice()
  • Zmigrowano: get_product_name()ProductRepository::getName()
  • Testy: 15 testów, 31 asercji

2025-02-05: Refaktoryzacja - Product Repository (ver. 0.238)

  • NOWE: Domain\Product\ProductRepository - pierwsza klasa w nowej architekturze
  • NOWE: Dependency Injection zamiast global $mdb
  • NOWE: Testy jednostkowe (5 testów, 100% pokrycie)
  • Zmigrowano: get_product_quantity()ProductRepository::getQuantity()
  • Kompatybilność: Stara klasa shop\Product działa jako fasada

2025-02-05: System cache produktów (ver. 0.237)

  • Automatyczne czyszczenie cache produktu po aktualizacji przez CRON
  • AJAX dla przycisku "Wyczyść cache" w panelu admin
  • Metody delete() i deletePattern() w CacheHandler
  • Metoda clear_product_cache() w klasie S

Dokument aktualizowany: 2026-02-12

2026-02-12: Migracja Users (/admin/users) (ver. 0.253)

  • NOWE: Domain\User\UserRepository - repozytorium uzytkownikow (CRUD, check_login, logon, details, 2FA)
  • NOWE: admin\Controllers\UsersController - kontroler DI dla akcji view_list, user_edit, user_save, user_delete, login_form, twofa
  • UPDATE: admin\Site - dodany factory wpis dla modulu Users w mapie nowych kontrolerow
  • UPDATE: admin\factory\Users - fasada deleguje logike do Domain\User\UserRepository
  • UPDATE: admin/ajax/users.php - check_login korzysta bezposrednio z UserRepository
  • CLEANUP: usuniety autoload/admin/controls/class.Users.php (brak fallback - nowy kontroler obsluguje wszystkie akcje)
  • Testy: 119 tests, 256 assertions

Dokument aktualizowany: 2026-02-12

  • UPDATE: widoki Users przeniesione z grid/gridEdit na components/table-list i components/form-edit

Aktualizacja 2026-02-12 (finalizacja Users)

  • Modu<B3> users dzia<69>a na Domain\\User\\UserRepository + admin\\Controllers\\UsersController.
  • Usuni<EA>to legacy klasy: autoload/admin/controls/class.Users.php, autoload/admin/factory/class.Users.php, autoload/admin/view/class.Users.php.
  • Walidacja: przy w<><77>czonym 2FA pole twofa_email jest wymagane.
  • Widoki users przeniesione na components/table-list i components/form-edit.