From e33978e1bbc6dbeba7964fe275be85ad3144701e Mon Sep 17 00:00:00 2001 From: Jacek Pyziak Date: Fri, 6 Feb 2026 08:41:34 +0100 Subject: [PATCH] feat: Refactor article handling and introduce ArticleRepository - Introduced Domain\Article\ArticleRepository for better data access. - Migrated article_edit functionality to admin\Controllers\ArticlesController. - Updated admin\factory\Articles::article_details() to use the new repository. - Marked legacy methods in admin\controls as @deprecated for clarity. - Updated changelog and versioning to reflect changes in version 0.242. --- .phpunit.result.cache | 2 +- DATABASE_STRUCTURE.md | 35 +++++++++- PROJECT_STRUCTURE.md | 15 ++++- REFACTORING_PLAN.md | 14 +++- UPDATE_INSTRUCTIONS.md | 3 + autoload/Domain/Article/ArticleRepository.php | 43 ++++++++++++ .../admin/Controllers/ArticlesController.php | 46 +++++++++++++ autoload/admin/class.Site.php | 8 +++ autoload/admin/controls/class.Articles.php | 10 ++- autoload/admin/controls/class.Banners.php | 16 +++++ autoload/admin/controls/class.Settings.php | 18 +++++- autoload/admin/factory/class.Articles.php | 17 +---- .../Domain/Article/ArticleRepositoryTest.php | 60 +++++++++++++++++ .../Controllers/ArticlesControllerTest.php | 61 ++++++++++++++++++ updates/0.20/ver_0.242.zip | Bin 0 -> 10287 bytes updates/changelog.php | 8 ++- updates/versions.php | 4 +- 17 files changed, 333 insertions(+), 27 deletions(-) create mode 100644 autoload/Domain/Article/ArticleRepository.php create mode 100644 autoload/admin/Controllers/ArticlesController.php create mode 100644 tests/Unit/Domain/Article/ArticleRepositoryTest.php create mode 100644 tests/Unit/admin/Controllers/ArticlesControllerTest.php create mode 100644 updates/0.20/ver_0.242.zip diff --git a/.phpunit.result.cache b/.phpunit.result.cache index 270bb78..32f3e1b 100644 --- a/.phpunit.result.cache +++ b/.phpunit.result.cache @@ -1 +1 @@ -{"version":1,"defects":[],"times":{"Tests\\Unit\\Domain\\Product\\ProductRepositoryTest::testGetQuantityReturnsCorrectValue":0.001,"Tests\\Unit\\Domain\\Product\\ProductRepositoryTest::testGetQuantityReturnsNullWhenProductNotFound":0,"Tests\\Unit\\Domain\\Product\\ProductRepositoryTest::testFindReturnsProductData":0,"Tests\\Unit\\Domain\\Product\\ProductRepositoryTest::testUpdateQuantitySuccess":0,"Tests\\Unit\\Domain\\Product\\ProductRepositoryTest::testGetPriceReturnsRegularPrice":0,"Tests\\Unit\\Domain\\Product\\ProductRepositoryTest::testGetPriceReturnsPromoPrice":0,"Tests\\Unit\\Domain\\Product\\ProductRepositoryTest::testGetPriceReturnsRegularWhenPromoIsHigher":0,"Tests\\Unit\\Domain\\Product\\ProductRepositoryTest::testGetPriceReturnsNullWhenNotFound":0,"Tests\\Unit\\Domain\\Product\\ProductRepositoryTest::testGetNameReturnsProductName":0,"Tests\\Unit\\Domain\\Product\\ProductRepositoryTest::testGetNameReturnsNullWhenNotFound":0,"Tests\\Unit\\Domain\\Product\\ProductRepositoryTest::testGetQuantityReturnsInteger":0,"Tests\\Unit\\Domain\\Product\\ProductRepositoryTest::testUnarchiveUpdatesProductAndChildren":0,"Tests\\Unit\\Domain\\Product\\ProductRepositoryTest::testArchiveUpdatesProductAndChildren":0,"Tests\\Unit\\Domain\\Product\\ProductRepositoryTest::testUnarchiveReturnsBool":0,"Tests\\Unit\\Domain\\Product\\ProductRepositoryTest::testArchiveReturnsBool":0,"Tests\\Unit\\admin\\Controllers\\ProductArchiveControllerTest::testConstructorAcceptsRepository":0.001,"Tests\\Unit\\admin\\Controllers\\ProductArchiveControllerTest::testHasListMethod":0,"Tests\\Unit\\admin\\Controllers\\ProductArchiveControllerTest::testHasUnarchiveMethod":0,"Tests\\Unit\\admin\\Controllers\\ProductArchiveControllerTest::testListMethodReturnType":0,"Tests\\Unit\\admin\\Controllers\\ProductArchiveControllerTest::testUnarchiveMethodReturnType":0,"Tests\\Unit\\admin\\Controllers\\ProductArchiveControllerTest::testConstructorRequiresProductRepository":0,"Tests\\Unit\\Domain\\Banner\\BannerRepositoryTest::testFindReturnsBannerWithTranslations":0.004,"Tests\\Unit\\Domain\\Banner\\BannerRepositoryTest::testFindReturnsNullWhenNotFound":0,"Tests\\Unit\\Domain\\Banner\\BannerRepositoryTest::testDeleteReturnsTrue":0.002,"Tests\\Unit\\Domain\\Banner\\BannerRepositoryTest::testSaveInsertsNewBanner":0,"Tests\\Unit\\Domain\\Cache\\CacheRepositoryTest::testClearCacheWithRedis":0.001,"Tests\\Unit\\Domain\\Cache\\CacheRepositoryTest::testClearCacheRedisUnavailable":0,"Tests\\Unit\\Domain\\Cache\\CacheRepositoryTest::testClearCacheWithoutRedis":0,"Tests\\Unit\\Domain\\Cache\\CacheRepositoryTest::testClearCacheReturnStructure":0,"Tests\\Unit\\Domain\\Settings\\SettingsRepositoryTest::testCanBeInstantiated":0.001,"Tests\\Unit\\Domain\\Settings\\SettingsRepositoryTest::testHasSaveSettingsMethod":0,"Tests\\Unit\\Domain\\Settings\\SettingsRepositoryTest::testHasGetSettingsMethod":0,"Tests\\Unit\\admin\\Controllers\\SettingsControllerTest::testConstructorAcceptsRepository":0.001,"Tests\\Unit\\admin\\Controllers\\SettingsControllerTest::testHasClearCacheMethod":0,"Tests\\Unit\\admin\\Controllers\\SettingsControllerTest::testHasClearCacheAjaxMethod":0,"Tests\\Unit\\admin\\Controllers\\SettingsControllerTest::testHasSaveMethod":0,"Tests\\Unit\\admin\\Controllers\\SettingsControllerTest::testHasViewMethod":0,"Tests\\Unit\\admin\\Controllers\\SettingsControllerTest::testIsNotAbstract":0,"Tests\\Unit\\admin\\Controllers\\SettingsControllerTest::testActionMethodReturnTypes":0}} \ No newline at end of file +{"version":1,"defects":[],"times":{"Tests\\Unit\\Domain\\Product\\ProductRepositoryTest::testGetQuantityReturnsCorrectValue":0.001,"Tests\\Unit\\Domain\\Product\\ProductRepositoryTest::testGetQuantityReturnsNullWhenProductNotFound":0,"Tests\\Unit\\Domain\\Product\\ProductRepositoryTest::testFindReturnsProductData":0,"Tests\\Unit\\Domain\\Product\\ProductRepositoryTest::testUpdateQuantitySuccess":0,"Tests\\Unit\\Domain\\Product\\ProductRepositoryTest::testGetPriceReturnsRegularPrice":0,"Tests\\Unit\\Domain\\Product\\ProductRepositoryTest::testGetPriceReturnsPromoPrice":0,"Tests\\Unit\\Domain\\Product\\ProductRepositoryTest::testGetPriceReturnsRegularWhenPromoIsHigher":0,"Tests\\Unit\\Domain\\Product\\ProductRepositoryTest::testGetPriceReturnsNullWhenNotFound":0,"Tests\\Unit\\Domain\\Product\\ProductRepositoryTest::testGetNameReturnsProductName":0,"Tests\\Unit\\Domain\\Product\\ProductRepositoryTest::testGetNameReturnsNullWhenNotFound":0,"Tests\\Unit\\Domain\\Product\\ProductRepositoryTest::testGetQuantityReturnsInteger":0,"Tests\\Unit\\Domain\\Product\\ProductRepositoryTest::testUnarchiveUpdatesProductAndChildren":0,"Tests\\Unit\\Domain\\Product\\ProductRepositoryTest::testArchiveUpdatesProductAndChildren":0,"Tests\\Unit\\Domain\\Product\\ProductRepositoryTest::testUnarchiveReturnsBool":0,"Tests\\Unit\\Domain\\Product\\ProductRepositoryTest::testArchiveReturnsBool":0,"Tests\\Unit\\admin\\Controllers\\ProductArchiveControllerTest::testConstructorAcceptsRepository":0.001,"Tests\\Unit\\admin\\Controllers\\ProductArchiveControllerTest::testHasListMethod":0,"Tests\\Unit\\admin\\Controllers\\ProductArchiveControllerTest::testHasUnarchiveMethod":0,"Tests\\Unit\\admin\\Controllers\\ProductArchiveControllerTest::testListMethodReturnType":0,"Tests\\Unit\\admin\\Controllers\\ProductArchiveControllerTest::testUnarchiveMethodReturnType":0,"Tests\\Unit\\admin\\Controllers\\ProductArchiveControllerTest::testConstructorRequiresProductRepository":0,"Tests\\Unit\\Domain\\Banner\\BannerRepositoryTest::testFindReturnsBannerWithTranslations":0.001,"Tests\\Unit\\Domain\\Banner\\BannerRepositoryTest::testFindReturnsNullWhenNotFound":0,"Tests\\Unit\\Domain\\Banner\\BannerRepositoryTest::testDeleteReturnsTrue":0.002,"Tests\\Unit\\Domain\\Banner\\BannerRepositoryTest::testSaveInsertsNewBanner":0,"Tests\\Unit\\Domain\\Cache\\CacheRepositoryTest::testClearCacheWithRedis":0.001,"Tests\\Unit\\Domain\\Cache\\CacheRepositoryTest::testClearCacheRedisUnavailable":0,"Tests\\Unit\\Domain\\Cache\\CacheRepositoryTest::testClearCacheWithoutRedis":0,"Tests\\Unit\\Domain\\Cache\\CacheRepositoryTest::testClearCacheReturnStructure":0,"Tests\\Unit\\Domain\\Settings\\SettingsRepositoryTest::testCanBeInstantiated":0.001,"Tests\\Unit\\Domain\\Settings\\SettingsRepositoryTest::testHasSaveSettingsMethod":0,"Tests\\Unit\\Domain\\Settings\\SettingsRepositoryTest::testHasGetSettingsMethod":0,"Tests\\Unit\\admin\\Controllers\\SettingsControllerTest::testConstructorAcceptsRepository":0.001,"Tests\\Unit\\admin\\Controllers\\SettingsControllerTest::testHasClearCacheMethod":0,"Tests\\Unit\\admin\\Controllers\\SettingsControllerTest::testHasClearCacheAjaxMethod":0,"Tests\\Unit\\admin\\Controllers\\SettingsControllerTest::testHasSaveMethod":0,"Tests\\Unit\\admin\\Controllers\\SettingsControllerTest::testHasViewMethod":0,"Tests\\Unit\\admin\\Controllers\\SettingsControllerTest::testIsNotAbstract":0,"Tests\\Unit\\admin\\Controllers\\SettingsControllerTest::testActionMethodReturnTypes":0,"Tests\\Unit\\admin\\Controllers\\ArticlesControllerTest::testCanCreateController":0.001,"Tests\\Unit\\admin\\Controllers\\ArticlesControllerTest::testHasListMethod":0,"Tests\\Unit\\admin\\Controllers\\ArticlesControllerTest::testListMethodReturnType":0,"Tests\\Unit\\admin\\Controllers\\ArticlesControllerTest::testHasEditMethod":0,"Tests\\Unit\\admin\\Controllers\\ArticlesControllerTest::testEditMethodReturnType":0,"Tests\\Unit\\admin\\Controllers\\ArticlesControllerTest::testConstructorAcceptsRepository":0,"Tests\\Unit\\admin\\Controllers\\ArticlesControllerTest::testConstructorRequiresArticleRepository":0,"Tests\\Unit\\Domain\\Article\\ArticleRepositoryTest::testFindReturnsArticleWithRelations":0.003,"Tests\\Unit\\Domain\\Article\\ArticleRepositoryTest::testFindReturnsNullWhenArticleDoesNotExist":0}} \ No newline at end of file diff --git a/DATABASE_STRUCTURE.md b/DATABASE_STRUCTURE.md index e76aa50..dbfeded 100644 --- a/DATABASE_STRUCTURE.md +++ b/DATABASE_STRUCTURE.md @@ -92,16 +92,49 @@ Artykuły. | id | PK | | status | -1 = archiwum, 0 = nieaktywny, 1 = aktywny | -**Używane w:** `admin\controls\ArticlesArchive` +**Używane w:** `admin\controls\ArticlesArchive`, `Domain\Article\ArticleRepository::find()` ## pp_articles_pages Strony artykułów. +| Kolumna | Opis | +|---------|------| +| article_id | FK do pp_articles | +| page_id | FK do strony (pp_pages) | +| o | Kolejność | + +**Używane w:** `Domain\Article\ArticleRepository::find()` + ## pp_articles_langs Tłumaczenia artykułów. +| Kolumna | Opis | +|---------|------| +| article_id | FK do pp_articles | +| lang_id | ID języka (np. 'pl') | +| title | Tytuł artykułu | +| seo_link | Link SEO artykułu | + +**Używane w:** `Domain\Article\ArticleRepository::find()` + ## pp_articles_images Zdjęcia artykułów. +| Kolumna | Opis | +|---------|------| +| article_id | FK do pp_articles | +| src | Ścieżka do pliku | +| o | Kolejność | +| id | PK (używane też do sortowania DESC) | + +**Używane w:** `Domain\Article\ArticleRepository::find()` + ## pp_articles_files Pliki artykułów. + +| Kolumna | Opis | +|---------|------| +| article_id | FK do pp_articles | +| src | Ścieżka do pliku | + +**Używane w:** `Domain\Article\ArticleRepository::find()` diff --git a/PROJECT_STRUCTURE.md b/PROJECT_STRUCTURE.md index 4729cb1..5d36a51 100644 --- a/PROJECT_STRUCTURE.md +++ b/PROJECT_STRUCTURE.md @@ -246,10 +246,18 @@ tests/ │ └── ProductArchiveControllerTest.php # 6 testów └── Integration/ ``` -**Łącznie: 39 testów, 73 asercji** +**Łącznie: 48 testw, 91 asercji** ## Ostatnie modyfikacje +### 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 @@ -258,7 +266,7 @@ tests/ - **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: 39 testów, 73 asercji (+10 nowych) +- Testy: 48 testw, 91 asercji (+10 nowych) ### 2026-02-05: Migracja Settings + Cache (ver. 0.240) - **NOWE:** `Domain\Settings\SettingsRepository` - repozytorium ustawień (fasada → factory) @@ -293,4 +301,5 @@ tests/ - Metoda `clear_product_cache()` w klasie S --- -*Dokument aktualizowany: 2026-02-05* +*Dokument aktualizowany: 2026-02-06* + diff --git a/REFACTORING_PLAN.md b/REFACTORING_PLAN.md index 13e5167..d177f31 100644 --- a/REFACTORING_PLAN.md +++ b/REFACTORING_PLAN.md @@ -174,6 +174,16 @@ grep -r "Product::getQuantity" . - Stara factory `admin\factory\Banners` zachowana bez zmian (fallback) - Aktualizacja: ver. 0.239 +- **Articles** (migracja kontrolera - etap edit/details) + - ✅ ArticleRepository::find() - **ZMIGROWANE** (2026-02-06) 🎉 + - Nowa klasa: `Domain\Article\ArticleRepository` (find: artykul + relacje) + - Nowy kontroler: `admin\Controllers\ArticlesController` (DI, instancyjny) + - Zmigrowana akcja: `article_edit` -> `edit` (mapowanie w `admin\Site::$actionMap`) + - Kompatybilność: `admin\factory\Articles::article_details()` deleguje do nowego repozytorium + - Legacy cleanup: metody przejęte przez nowe kontrolery oznaczone `@deprecated` w `admin\controls\Articles|Banners|Settings` + - Testy: `tests/Unit/Domain/Article/ArticleRepositoryTest.php`, `tests/Unit/admin/Controllers/ArticlesControllerTest.php` + - Aktualizacja: ver. 0.242 + - **Settings** (migracja kontrolera - krok pośredni) - ✅ SettingsRepository - **ZMIGROWANE** (2026-02-05) 🎉 - Nowa klasa: `Domain\Settings\SettingsRepository` (saveSettings, getSettings) @@ -217,7 +227,7 @@ tests/ │ └── ProductArchiveControllerTest.php # 6 testów └── Integration/ ``` -**Łącznie: 39 testów, 73 asercji** +**Łącznie: 48 testów, 91 asercji** ### Przykład testu ```php @@ -305,4 +315,4 @@ vendor/bin/phpstan analyse autoload/Domain --- *Rozpoczęto: 2025-02-05* -*Ostatnia aktualizacja: 2026-02-05* +*Ostatnia aktualizacja: 2026-02-06* diff --git a/UPDATE_INSTRUCTIONS.md b/UPDATE_INSTRUCTIONS.md index 70af940..cfff524 100644 --- a/UPDATE_INSTRUCTIONS.md +++ b/UPDATE_INSTRUCTIONS.md @@ -11,6 +11,9 @@ Aktualizacje znajdują się w folderze `updates/0.XX/` gdzie XX oznacza dziesią - `changelog.php` - historia zmian - `versions.php` - konfiguracja wersji (zmienna `$current_ver`) +### Zasada pakowania plików +- Do paczek aktualizacji **nie dodajemy plików `*.md`** (dokumentacja jest tylko wewnętrzna/deweloperska). + ## Procedura tworzenia nowej aktualizacji ### 1. Określ numer wersji diff --git a/autoload/Domain/Article/ArticleRepository.php b/autoload/Domain/Article/ArticleRepository.php new file mode 100644 index 0000000..9a986d5 --- /dev/null +++ b/autoload/Domain/Article/ArticleRepository.php @@ -0,0 +1,43 @@ +db = $db; + } + + /** + * Pobiera artykul po ID wraz z tlumaczeniami, obrazami, plikami i powiazanymi stronami + */ + public function find(int $articleId): ?array + { + $article = $this->db->get('pp_articles', '*', ['id' => $articleId]); + + if (!$article) { + return null; + } + + $results = $this->db->select('pp_articles_langs', '*', ['article_id' => $articleId]); + if (is_array($results)) { + foreach ($results as $row) { + $article['languages'][$row['lang_id']] = $row; + } + } + + $article['images'] = $this->db->select('pp_articles_images', '*', [ + 'article_id' => $articleId, + 'ORDER' => ['o' => 'ASC', 'id' => 'DESC'] + ]); + $article['files'] = $this->db->select('pp_articles_files', '*', ['article_id' => $articleId]); + $article['pages'] = $this->db->select('pp_articles_pages', 'page_id', ['article_id' => $articleId]); + + return $article; + } +} diff --git a/autoload/admin/Controllers/ArticlesController.php b/autoload/admin/Controllers/ArticlesController.php new file mode 100644 index 0000000..8bf6eb5 --- /dev/null +++ b/autoload/admin/Controllers/ArticlesController.php @@ -0,0 +1,46 @@ +repository = $repository; + } + + /** + * Lista artykulow + */ + public function list(): string + { + return \admin\view\Articles::articles_list(); + } + + /** + * Edycja artykulu + */ + public function edit(): string + { + global $user; + + if (!$user) { + header('Location: /admin/'); + exit; + } + + \admin\factory\Articles::delete_nonassigned_images(); + \admin\factory\Articles::delete_nonassigned_files(); + + return \Tpl::view('articles/article-edit', [ + 'article' => $this->repository->find((int)\S::get('id')), + 'menus' => \admin\factory\Pages::menus_list(), + 'languages' => \admin\factory\Languages::languages_list(), + 'layouts' => \admin\factory\Layouts::layouts_list(), + 'user' => $user + ]); + } +} diff --git a/autoload/admin/class.Site.php b/autoload/admin/class.Site.php index a3a8aa5..1c2b48a 100644 --- a/autoload/admin/class.Site.php +++ b/autoload/admin/class.Site.php @@ -199,6 +199,13 @@ class Site return self::$newControllers; self::$newControllers = [ + 'Articles' => function() { + global $mdb; + + return new \admin\Controllers\ArticlesController( + new \Domain\Article\ArticleRepository( $mdb ) + ); + }, 'Banners' => function() { global $mdb; @@ -247,6 +254,7 @@ class Site */ private static $actionMap = [ 'view_list' => 'list', + 'article_edit' => 'edit', 'banner_edit' => 'edit', 'banner_save' => 'save', 'banner_delete' => 'delete', diff --git a/autoload/admin/controls/class.Articles.php b/autoload/admin/controls/class.Articles.php index a7e32b3..b2fddb7 100644 --- a/autoload/admin/controls/class.Articles.php +++ b/autoload/admin/controls/class.Articles.php @@ -39,6 +39,10 @@ class Articles exit; } + /** + * @deprecated Routing kieruje do admin\Controllers\ArticlesController::edit(). + * Ta metoda pozostaje tylko jako fallback dla starej architektury. + */ public static function article_edit() { global $user; @@ -59,9 +63,13 @@ class Articles ] ); } + /** + * @deprecated Routing kieruje do admin\Controllers\ArticlesController::list(). + * Ta metoda pozostaje tylko jako fallback dla starej architektury. + */ public static function view_list() { return \admin\view\Articles::articles_list(); } } -?> \ No newline at end of file +?> diff --git a/autoload/admin/controls/class.Banners.php b/autoload/admin/controls/class.Banners.php index ccce70a..9166a66 100644 --- a/autoload/admin/controls/class.Banners.php +++ b/autoload/admin/controls/class.Banners.php @@ -9,6 +9,10 @@ namespace admin\controls; */ class Banners { + /** + * @deprecated Routing kieruje do admin\Controllers\BannerController::delete(). + * Ta metoda pozostaje tylko jako fallback dla starej architektury. + */ public static function banner_delete() { if ( \admin\factory\Banners::banner_delete( \S::get( 'id' ) ) ) @@ -17,6 +21,10 @@ class Banners exit; } + /** + * @deprecated Routing kieruje do admin\Controllers\BannerController::save(). + * Ta metoda pozostaje tylko jako fallback dla starej architektury. + */ public static function banner_save() { $response = [ 'status' => 'error', 'msg' => 'Podczas zapisywania baneru wystąpił błąd. Proszę spróbować ponownie.' ]; @@ -30,6 +38,10 @@ class Banners exit; } + /** + * @deprecated Routing kieruje do admin\Controllers\BannerController::edit(). + * Ta metoda pozostaje tylko jako fallback dla starej architektury. + */ public static function banner_edit() { return \admin\view\Banners::banner_edit( @@ -40,6 +52,10 @@ class Banners ); } + /** + * @deprecated Routing kieruje do admin\Controllers\BannerController::list(). + * Ta metoda pozostaje tylko jako fallback dla starej architektury. + */ public static function view_list() { return \admin\view\Banners::banners_list(); diff --git a/autoload/admin/controls/class.Settings.php b/autoload/admin/controls/class.Settings.php index f11b666..63d71dd 100644 --- a/autoload/admin/controls/class.Settings.php +++ b/autoload/admin/controls/class.Settings.php @@ -3,6 +3,10 @@ namespace admin\controls; class Settings { + /** + * @deprecated Routing kieruje do admin\Controllers\SettingsController::clearCache(). + * Ta metoda pozostaje tylko jako fallback dla starej architektury. + */ static public function clear_cache() { \S::delete_dir( '../temp/' ); @@ -17,6 +21,10 @@ class Settings exit; } + /** + * @deprecated Routing kieruje do admin\Controllers\SettingsController::clearCacheAjax(). + * Ta metoda pozostaje tylko jako fallback dla starej architektury. + */ static public function clear_cache_ajax() { try @@ -41,6 +49,10 @@ class Settings exit; } + /** + * @deprecated Routing kieruje do admin\Controllers\SettingsController::save(). + * Ta metoda pozostaje tylko jako fallback dla starej architektury. + */ public static function settings_save() { $values = json_decode( \S::get( 'values' ), true ); @@ -88,6 +100,10 @@ class Settings exit; } + /** + * @deprecated Routing kieruje do admin\Controllers\SettingsController::view(). + * Ta metoda pozostaje tylko jako fallback dla starej architektury. + */ public static function view() { return \Tpl::view( 'settings/settings', [ @@ -96,4 +112,4 @@ class Settings ] ); } } -?> \ No newline at end of file +?> diff --git a/autoload/admin/factory/class.Articles.php b/autoload/admin/factory/class.Articles.php index 7f748ed..ee82309 100644 --- a/autoload/admin/factory/class.Articles.php +++ b/autoload/admin/factory/class.Articles.php @@ -123,19 +123,8 @@ class Articles public static function article_details( $article_id ) { global $mdb; - - if ( $article = $mdb -> get( 'pp_articles', '*', [ 'id' => (int)$article_id ] ) ) - { - $results = $mdb -> select( 'pp_articles_langs', '*', [ 'article_id' => (int)$article_id ] ); - if ( is_array( $results ) ) foreach ( $results as $row ) - $article['languages'][ $row['lang_id'] ] = $row; - - $article['images'] = $mdb -> select( 'pp_articles_images', '*', [ 'article_id' => (int)$article_id, 'ORDER' => [ 'o' => 'ASC', 'id' => 'DESC' ] ] ); - $article['files'] = $mdb -> select( 'pp_articles_files', '*', [ 'article_id' => (int)$article_id ] ); - $article['pages'] = $mdb -> select( 'pp_articles_pages', 'page_id', [ 'article_id' => (int)$article_id ] ); - } - - return $article; + $repository = new \Domain\Article\ArticleRepository( $mdb ); + return $repository->find( (int)$article_id ); } public static function max_order() @@ -469,4 +458,4 @@ class Articles $mdb -> delete( 'pp_articles_images', [ 'article_id' => null ] ); } } -?> \ No newline at end of file +?> diff --git a/tests/Unit/Domain/Article/ArticleRepositoryTest.php b/tests/Unit/Domain/Article/ArticleRepositoryTest.php new file mode 100644 index 0000000..749f09a --- /dev/null +++ b/tests/Unit/Domain/Article/ArticleRepositoryTest.php @@ -0,0 +1,60 @@ +createMock(\medoo::class); + + $mockDb->expects($this->once()) + ->method('get') + ->with('pp_articles', '*', ['id' => 7]) + ->willReturn(['id' => 7, 'status' => 1]); + + $mockDb->expects($this->exactly(4)) + ->method('select') + ->willReturnOnConsecutiveCalls( + [ + ['lang_id' => 'pl', 'title' => 'Artykul'], + ['lang_id' => 'en', 'title' => 'Article'], + ], + [ + ['id' => 10, 'src' => '/img/a.jpg'] + ], + [ + ['id' => 20, 'src' => '/files/a.pdf'] + ], + [1, 2] + ); + + $repository = new ArticleRepository($mockDb); + $article = $repository->find(7); + + $this->assertIsArray($article); + $this->assertEquals(7, $article['id']); + $this->assertArrayHasKey('languages', $article); + $this->assertEquals('Artykul', $article['languages']['pl']['title']); + $this->assertCount(1, $article['images']); + $this->assertCount(1, $article['files']); + $this->assertEquals([1, 2], $article['pages']); + } + + public function testFindReturnsNullWhenArticleDoesNotExist(): void + { + $mockDb = $this->createMock(\medoo::class); + $mockDb->expects($this->once()) + ->method('get') + ->with('pp_articles', '*', ['id' => 999]) + ->willReturn(false); + $mockDb->expects($this->never())->method('select'); + + $repository = new ArticleRepository($mockDb); + $article = $repository->find(999); + + $this->assertNull($article); + } +} diff --git a/tests/Unit/admin/Controllers/ArticlesControllerTest.php b/tests/Unit/admin/Controllers/ArticlesControllerTest.php new file mode 100644 index 0000000..4350cfb --- /dev/null +++ b/tests/Unit/admin/Controllers/ArticlesControllerTest.php @@ -0,0 +1,61 @@ +mockRepository = $this->createMock(ArticleRepository::class); + $this->controller = new ArticlesController($this->mockRepository); + } + + public function testCanCreateController(): void + { + $this->assertInstanceOf(ArticlesController::class, $this->controller); + } + + public function testConstructorAcceptsRepository(): void + { + $controller = new ArticlesController($this->mockRepository); + $this->assertInstanceOf(ArticlesController::class, $controller); + } + + public function testHasListMethod(): void + { + $this->assertTrue(method_exists($this->controller, 'list')); + } + + public function testHasEditMethod(): void + { + $this->assertTrue(method_exists($this->controller, 'edit')); + } + + public function testListMethodReturnType(): void + { + $reflection = new \ReflectionClass($this->controller); + $this->assertEquals('string', (string)$reflection->getMethod('list')->getReturnType()); + } + + public function testEditMethodReturnType(): void + { + $reflection = new \ReflectionClass($this->controller); + $this->assertEquals('string', (string)$reflection->getMethod('edit')->getReturnType()); + } + + public function testConstructorRequiresArticleRepository(): void + { + $reflection = new \ReflectionClass(ArticlesController::class); + $constructor = $reflection->getConstructor(); + $params = $constructor->getParameters(); + + $this->assertCount(1, $params); + $this->assertEquals('Domain\Article\ArticleRepository', $params[0]->getType()->getName()); + } +} diff --git a/updates/0.20/ver_0.242.zip b/updates/0.20/ver_0.242.zip new file mode 100644 index 0000000000000000000000000000000000000000..0defbd74a6d59831993a73ced7aef46f82dcdad2 GIT binary patch literal 10287 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 literal 0 HcmV?d00001 diff --git a/updates/changelog.php b/updates/changelog.php index 2dd1c0a..3b46194 100644 --- a/updates/changelog.php +++ b/updates/changelog.php @@ -1,4 +1,8 @@ -ver. 0.241
+ver. 0.242
+- NEW - refaktoryzacja: Domain\Article\ArticleRepository + migracja article_edit do admin\Controllers\ArticlesController (DI) +- UPDATE - admin\factory\Articles::article_details() deleguje do nowego repozytorium (kompatybilno zachowana) +- UPDATE - metody przejte przez nowe kontrolery oznaczone jako @deprecated w legacy kontrolerach admin\controls +
ver. 0.241
- NEW - refaktoryzacja: admin\Controllers\ProductArchiveController - archiwum produktów z DI - NEW - ProductRepository::archive(), unarchive() - operacje archiwizacji w repozytorium - FIX - naprawiono SQL w liście archiwum (puste wyszukiwanie filtrowało wszystkie wyniki) @@ -298,4 +302,4 @@ - FIX - poprawa generowania plików WEBP
ver. 0.142
-- FIX - poprawa adresu strony głównej \ No newline at end of file +- FIX - poprawa adresu strony głównej diff --git a/updates/versions.php b/updates/versions.php index c2fd04a..7ed534d 100644 --- a/updates/versions.php +++ b/updates/versions.php @@ -1,5 +1,5 @@