From 29b329e422bd381f03600cf1987fc781471fc738 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96mer=20Faruk=20Demirel?= Date: Sun, 21 Dec 2025 17:39:19 +0300 Subject: [PATCH 1/2] ci: remove unnecessary migrations --- Makefile | 5 ----- 1 file changed, 5 deletions(-) diff --git a/Makefile b/Makefile index 521a350..f1a9446 100644 --- a/Makefile +++ b/Makefile @@ -15,8 +15,6 @@ DC_RUN_ARGS = $(ENV_FILE) $(DC_PROFILES) $(DC_FILE) HOST_UID=$(shell id -u) HOST_GID=$(shell id -g) -PACKAGE_DIRS := $(wildcard packages/*/database/migrations) - .PHONY : help migrate up down shell\:app stop-all ps update build restart down-up images\:list images\:clean logs\:app logs containers\:health command\:app .DEFAULT_GOAL : help @@ -27,9 +25,6 @@ help: ## Show this help migrate: ## Run all migrations php artisan migrate - @for dir in $(PACKAGE_DIRS); do \ - php artisan migrate --path=/$$dir; \ - done test: ## Run tests using pgsql and redis @docker run -d --rm \ From 5a6b6a0e24cbafc2ad572ced48e7f8912ce16414 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96mer=20Faruk=20Demirel?= Date: Sun, 21 Dec 2025 17:47:39 +0300 Subject: [PATCH 2/2] refactor!: migrate packages structure to laravel-modules --- .github/workflows/docs.yml | 2 +- .php-cs-fixer.php | 4 +- app/Filament/Pages/Settings/SiteSettings.php | 2 +- app/Filament/Resources/ArticleResource.php | 2 +- .../Widgets/ArticleStatsOverview.php | 2 +- .../Widgets/RecentArticles.php | 2 +- app/Filament/Resources/CategoryResource.php | 2 +- app/Filament/Resources/CommentResource.php | 2 +- .../Widgets/CommentStatsOverview.php | 2 +- .../Resources/CourseChapterResource.php | 2 +- .../Resources/CourseLessonResource.php | 2 +- app/Filament/Resources/CourseResource.php | 2 +- app/Filament/Resources/DislikeResource.php | 2 +- app/Filament/Resources/EntryResource.php | 2 +- .../Widgets/EntryStatsOverview.php | 2 +- .../EntryResource/Widgets/RecentEntries.php | 2 +- app/Filament/Resources/FollowResource.php | 2 +- app/Filament/Resources/LikeResource.php | 2 +- app/Filament/Resources/NewsResource.php | 2 +- app/Filament/Resources/PageResource.php | 2 +- app/Filament/Resources/SaveResource.php | 2 +- app/Filament/Resources/TagResource.php | 2 +- app/Jobs/GenerateSitemapJob.php | 12 +- app/Models/User.php | 10 +- app/Services/SeoService.php | 24 +- bootstrap/providers.php | 13 +- composer.json | 49 +-- composer.lock | 147 ++++++++- config/ide-helper.php | 2 +- config/modules.php | 285 ++++++++++++++++++ database/seeders/DatabaseSeeder.php | 2 +- lang/en.json | 5 +- lang/tr.json | 5 +- .../Commands/ScheduleArticleCommand.php | 6 +- .../Article/app}/Data/ArticleData.php | 10 +- .../app}/Events/ArticlePublishedEvent.php | 4 +- .../Http/Controllers/ArticleController.php | 6 +- .../Controllers/ArticleCrudController.php | 14 +- .../app}/Http/Requests/CreateRequest.php | 4 +- .../app}/Http/Requests/EditRequest.php | 4 +- .../Listeners/ArticlePublishedListener.php | 6 +- .../Article/app}/Models/Article.php | 28 +- .../ArticlePublishedNotification.php | 4 +- .../app}/Observers/ArticleObserver.php | 12 +- .../Article/app}/Policies/ArticlePolicy.php | 4 +- .../app/Providers/ArticleServiceProvider.php | 155 ++++++++++ .../app/Providers/EventServiceProvider.php | 35 +++ .../app/Providers/RouteServiceProvider.php | 49 +++ .../Article/app}/Services/ArticleService.php | 8 +- modules/Article/composer.json | 28 ++ .../database/factories/ArticleFactory.php | 6 +- ...025_08_15_144713_create_articles_table.php | 0 ...8_15_145320_create_article_pivot_table.php | 0 .../database/seeders/ArticleSeeder.php | 4 +- .../Article}/lang/en/messages.php | 0 .../Article}/lang/tr/messages.php | 0 modules/Article/module.json | 14 + modules/Article/package.json | 15 + modules/Article/routes/api.php | 18 ++ modules/Article/routes/web.php | 15 + .../Commands/ScheduleArticleCommandTest.php | 8 +- .../Database/Seeders/ArticleSeederTest.php | 8 +- .../Controllers/ArticleControllerTest.php | 14 +- .../Controllers/ArticleCrudControllerTest.php | 12 +- .../Http/Requests/CreateRequestTest.php | 8 +- .../Feature/Http/Requests/EditRequestTest.php | 8 +- .../Article/tests/TestCase.php | 2 +- .../tests/Unit/Data/ArticleDataTest.php | 14 +- .../Unit/Database/ArticleFactoryTest.php | 6 +- .../Unit/Events/ArticlePublishedEventTest.php | 8 +- .../ArticlePublishedListenerTest.php | 12 +- .../Article/tests/Unit/Models/ArticleTest.php | 10 +- .../ArticlePublishedNotificationTest.php | 8 +- .../Unit/Observers/ArticleObserverTest.php | 12 +- .../tests/Unit/Policies/ArticlePolicyTest.php | 8 +- .../Unit/Services/ArticleServiceTest.php | 10 +- modules/Article/vite.config.js | 57 ++++ .../Category/app}/Data/CategoryData.php | 4 +- .../app}/Data/CategoryProfileData.php | 4 +- .../Http/Controllers/CategoryController.php | 4 +- .../Category/app}/Models/Category.php | 14 +- .../Category/app}/Models/CategoryProfile.php | 8 +- .../app}/Observers/CategoryObserver.php | 4 +- .../Observers/CategoryProfileObserver.php | 4 +- .../Category/app}/Policies/CategoryPolicy.php | 2 +- .../app/Providers/CategoryServiceProvider.php | 107 +++++++ .../app/Providers/RouteServiceProvider.php | 34 +++ .../app}/Services/CategoryService.php | 18 +- modules/Category/composer.json | 28 ++ .../database/factories/CategoryFactory.php | 6 +- .../factories/CategoryProfileFactory.php | 8 +- ...5_08_15_145151_create_categories_table.php | 0 ..._103855_create_category_profiles_table.php | 0 .../database/seeders/CategorySeeder.php | 6 +- modules/Category/module.json | 14 + modules/Category/package.json | 15 + modules/Category/routes/web.php | 7 + .../Database/Seeders/CategorySeederTest.php | 10 +- .../Controllers/CategoryControllerTest.php | 12 +- .../Category/tests/TestCase.php | 2 +- .../tests/Unit/Data/CategoryDataTest.php | 8 +- .../Unit/Data/CategoryProfileDataTest.php | 8 +- .../Factories/CategoryFactoryTest.php | 6 +- .../Factories/CategoryProfileFactoryTest.php | 8 +- .../tests/Unit/Models/CategoryProfileTest.php | 8 +- .../tests/Unit/Models/CategoryTest.php | 10 +- .../Unit/Observers/CategoryObserverTest.php | 8 +- .../Observers/CategoryProfileObserverTest.php | 10 +- .../Unit/Policies/CategoryPolicyTest.php | 6 +- .../Unit/Services/CategoryServiceTest.php | 18 +- modules/Category/vite.config.js | 57 ++++ .../Commands/ScheduleCourseCommand.php | 6 +- .../Commands/ScheduleLessonCommand.php | 6 +- .../Course/app}/Data/CourseData.php | 10 +- .../Course/app}/Data/CourseLessonData.php | 4 +- .../app}/Events/CoursePublishedEvent.php | 4 +- .../app}/Events/LessonPublishedEvent.php | 4 +- .../Http/Controllers/CourseController.php | 4 +- .../Listeners/CoursePublishedListener.php | 6 +- .../Listeners/LessonPublishedListener.php | 6 +- .../Course/app}/Models/Course.php | 28 +- .../Course/app}/Models/CourseChapter.php | 8 +- .../Course/app}/Models/CourseLesson.php | 16 +- .../CoursePublishedNotification.php | 4 +- .../LessonPublishedNotification.php | 4 +- .../app}/Observers/CourseChapterObserver.php | 4 +- .../app}/Observers/CourseLessonObserver.php | 4 +- .../Course/app}/Observers/CourseObserver.php | 12 +- .../app}/Policies/CourseChapterPolicy.php | 4 +- .../app}/Policies/CourseLessonPolicy.php | 4 +- .../Course/app}/Policies/CoursePolicy.php | 4 +- .../app/Providers/CourseServiceProvider.php | 174 +++++++++++ .../app/Providers/EventServiceProvider.php | 40 +++ .../app/Providers/RouteServiceProvider.php | 34 +++ .../Course/app}/Services/CourseService.php | 14 +- modules/Course/composer.json | 28 ++ .../factories/CourseChapterFactory.php | 8 +- .../database/factories/CourseFactory.php | 6 +- .../factories/CourseLessonFactory.php | 8 +- ...2025_11_09_084042_create_courses_table.php | 0 ...09_084732_create_course_chapters_table.php | 0 ..._09_084905_create_course_lessons_table.php | 0 ...11_09_192116_create_course_pivot_table.php | 0 .../Course/database/seeders/CourseSeeder.php | 14 + .../Course}/lang/en/messages.php | 0 .../Course}/lang/tr/messages.php | 0 modules/Course/module.json | 11 + modules/Course/package.json | 15 + modules/Course/resources/assets/.gitkeep | 0 modules/Course/resources/assets/js/app.js | 0 modules/Course/resources/assets/sass/app.scss | 0 .../views/components/layouts/master.blade.php | 30 ++ .../Course/resources/views/index.blade.php | 5 + modules/Course/routes/web.php | 9 + modules/Course/vite.config.js | 57 ++++ .../Entry/app}/Data/EntryData.php | 6 +- .../app}/Http/Controllers/EntryController.php | 6 +- .../Http/Controllers/EntryCrudController.php | 8 +- .../app}/Http/Requests/CreateRequest.php | 2 +- .../Entry/app}/Models/Entry.php | 24 +- .../Entry/app}/Observers/EntryObserver.php | 8 +- .../Entry/app}/Policies/EntryPolicy.php | 4 +- .../app/Providers/EntryServiceProvider.php | 109 +++++++ .../app/Providers/RouteServiceProvider.php | 49 +++ .../Entry/app}/Services/EntryService.php | 8 +- modules/Entry/composer.json | 28 ++ .../Entry/database/factories/EntryFactory.php | 6 +- ...2025_10_03_095727_create_entries_table.php | 0 .../Entry/database/seeders/EntrySeeder.php | 12 +- modules/Entry/module.json | 14 + modules/Entry/package.json | 15 + modules/Entry/routes/api.php | 14 + modules/Entry/routes/web.php | 8 + modules/Entry/vite.config.js | 57 ++++ .../News/app}/Data/NewsData.php | 12 +- .../src => modules/News/app}/Models/News.php | 12 +- .../News/app}/Observers/NewsObserver.php | 8 +- .../News/app}/Policies/NewsPolicy.php | 4 +- .../app/Providers/NewsServiceProvider.php | 84 ++++++ .../News/app}/Services/NewsService.php | 8 +- modules/News/composer.json | 28 ++ .../News/database/factories/NewsFactory.php | 6 +- .../2025_08_17_132322_create_news_table.php | 0 ...5_08_17_132432_create_news_pivot_table.php | 0 ...4927_drop_timestampts_from_news_pivots.php | 0 ...2_06_194559_drop_image_from_news_table.php | 0 .../News/database/seeders/NewsSeeder.php | 4 +- modules/News/module.json | 14 + modules/News/package.json | 15 + modules/News/resources/assets/js/app.js | 0 modules/News/resources/assets/sass/app.scss | 0 .../views/components/layouts/master.blade.php | 30 ++ modules/News/resources/views/index.blade.php | 5 + modules/News/vite.config.js | 57 ++++ .../Console/Commands/SchedulePageCommand.php | 6 +- .../Page/app}/Data/PageData.php | 6 +- .../Page/app}/Events/PagePublishedEvent.php | 4 +- .../app}/Http/Controllers/PageController.php | 4 +- .../app}/Listeners/PagePublishedListener.php | 6 +- .../src => modules/Page/app}/Models/Page.php | 8 +- .../PagePublishedNotification.php | 4 +- .../Page/app}/Observers/PageObserver.php | 4 +- .../Page/app}/Policies/PagePolicy.php | 4 +- .../app/Providers/EventServiceProvider.php | 35 +++ .../app/Providers/PageServiceProvider.php | 124 ++++++++ .../app/Providers/RouteServiceProvider.php | 34 +++ .../Page/app}/Services/PageService.php | 8 +- modules/Page/composer.json | 28 ++ .../Page/database/factories/PageFactory.php | 6 +- .../2025_09_04_100152_create_pages_table.php | 0 .../Page/database/seeders/PageSeeder.php | 4 +- .../Page}/lang/en/messages.php | 0 .../Page}/lang/tr/messages.php | 0 modules/Page/module.json | 14 + modules/Page/package.json | 15 + modules/Page/routes/web.php | 8 + modules/Page/vite.config.js | 57 ++++ .../React/app}/Data/CommentData.php | 8 +- .../React/app}/Events/FollowedEvent.php | 4 +- .../src => modules/React/app}/Helpers.php | 2 +- .../app}/Http/Controllers/ReactController.php | 6 +- .../React/app}/Http/Requests/ReactRequest.php | 4 +- .../React/app}/Listeners/FollowedListener.php | 12 +- .../React/app}/Models/Comment.php | 12 +- .../React/app}/Models/Dislike.php | 8 +- .../React/app}/Models/Follow.php | 8 +- .../src => modules/React/app}/Models/Like.php | 8 +- .../src => modules/React/app}/Models/Save.php | 8 +- .../React/app}/Observers/CommentObserver.php | 8 +- .../React/app}/Observers/DislikeObserver.php | 8 +- .../React/app}/Observers/FollowObserver.php | 8 +- .../React/app}/Observers/LikeObserver.php | 8 +- .../React/app}/Observers/SaveObserver.php | 8 +- .../React/app}/Policies/CommentPolicy.php | 4 +- .../React/app}/Policies/DislikePolicy.php | 4 +- .../React/app}/Policies/FollowPolicy.php | 2 +- .../React/app}/Policies/LikePolicy.php | 4 +- .../React/app}/Policies/SavePolicy.php | 4 +- .../app/Providers/EventServiceProvider.php | 35 +++ .../app/Providers/ReactServiceProvider.php | 142 +++++++++ .../app/Providers/RouteServiceProvider.php | 35 +++ .../React/app}/Services/ReactService.php | 14 +- .../React/app}/Traits/CanFollow.php | 6 +- .../React/app}/Traits/HasComments.php | 6 +- .../React/app}/Traits/HasDislikes.php | 6 +- .../React/app}/Traits/HasFollowers.php | 6 +- .../React/app}/Traits/HasLikes.php | 6 +- .../React/app}/Traits/HasSaves.php | 6 +- modules/React/composer.json | 28 ++ .../database/factories/CommentFactory.php | 6 +- .../database/factories/DislikeFactory.php | 6 +- .../database/factories/FollowFactory.php | 6 +- .../React/database/factories/LikeFactory.php | 6 +- .../React/database/factories/SaveFactory.php | 6 +- ...025_09_18_075116_create_comments_table.php | 0 .../2025_10_15_071629_create_likes_table.php | 0 ...025_10_16_072117_create_dislikes_table.php | 0 .../2025_10_16_072145_create_saves_table.php | 0 ...2025_10_16_111600_create_follows_table.php | 0 modules/React/lang/en/messages.php | 7 + modules/React/lang/tr/messages.php | 7 + modules/React/module.json | 14 + modules/React/package.json | 15 + {packages => modules}/React/routes/api.php | 17 +- modules/React/vite.config.js | 57 ++++ .../Recommend/app}/Classes/GorseFeedback.php | 2 +- .../Recommend/app}/Classes/GorseItem.php | 2 +- .../Recommend/app}/Classes/GorseUser.php | 2 +- .../Recommend/app}/Classes/RowAffected.php | 2 +- .../Commands/UploadRecommendations.php | 24 +- .../app}/Http/Controllers/FeedController.php | 6 +- .../app}/Http/Requests/FeedRequest.php | 2 +- .../Providers/RecommendServiceProvider.php | 104 +++++++ .../app/Providers/RouteServiceProvider.php | 34 +++ .../Recommend/app}/Services/FeedService.php | 14 +- .../Recommend/app}/Services/GorseService.php | 10 +- modules/Recommend/composer.json | 28 ++ .../Recommend/config/recommend.php | 0 modules/Recommend/module.json | 14 + modules/Recommend/package.json | 15 + modules/Recommend/routes/api.php | 9 + modules/Recommend/vite.config.js | 57 ++++ .../Http/Controllers/SearchController.php | 4 +- .../app/Providers/RouteServiceProvider.php | 49 +++ .../app/Providers/SearchServiceProvider.php | 36 +++ .../Search/app}/Services/SearchService.php | 2 +- modules/Search/composer.json | 28 ++ modules/Search/module.json | 14 + modules/Search/package.json | 15 + modules/Search/routes/api.php | 7 + modules/Search/routes/web.php | 7 + modules/Search/vite.config.js | 57 ++++ .../src => modules/Tag/app}/Data/TagData.php | 4 +- .../Tag/app}/Data/TagProfileData.php | 6 +- .../app}/Http/Controllers/TagController.php | 4 +- .../src => modules/Tag/app}/Models/Tag.php | 14 +- .../Tag/app}/Models/TagProfile.php | 10 +- .../Tag/app}/Observers/TagObserver.php | 4 +- .../Tag/app}/Observers/TagProfileObserver.php | 4 +- .../Tag/app}/Policies/TagPolicy.php | 2 +- .../app/Providers/RouteServiceProvider.php | 34 +++ .../Tag/app/Providers/TagServiceProvider.php | 108 +++++++ .../Tag/app}/Services/TagService.php | 14 +- modules/Tag/composer.json | 28 ++ .../Tag/database/factories/TagFactory.php | 6 +- .../database/factories/TagProfileFactory.php | 10 +- .../2025_08_15_145209_create_tags_table.php | 0 ...08_25_093825_create_tag_profiles_table.php | 0 ...3612_create_tag_profile_category_table.php | 0 .../Tag/database/seeders/TagSeeder.php | 6 +- modules/Tag/module.json | 14 + modules/Tag/package.json | 15 + modules/Tag/routes/web.php | 7 + .../Database/Seeders/TagSeederTest.php | 10 +- .../Http/Controllers/TagControllerTest.php | 10 +- {packages => modules}/Tag/tests/TestCase.php | 2 +- .../Tag/tests/Unit/Data/TagDataTest.php | 8 +- .../tests/Unit/Data/TagProfileDataTest.php | 12 +- .../Database/Factories/TagFactoryTest.php | 6 +- .../Factories/TagProfileFactoryTest.php | 10 +- .../Tag/tests/Unit/Models/TagProfileTest.php | 10 +- .../Tag/tests/Unit/Models/TagTest.php | 10 +- .../tests/Unit/Observers/TagObserverTest.php | 8 +- .../Unit/Observers/TagProfileObserverTest.php | 8 +- .../Tag/tests/Unit/Policies/TagPolicyTest.php | 6 +- .../tests/Unit/Services/TagServiceTest.php | 16 +- modules/Tag/vite.config.js | 57 ++++ .../User/app}/Data/UserData.php | 4 +- .../User/app}/Data/UserProfileData.php | 4 +- .../app}/Http/Controllers/AuthController.php | 12 +- .../Controllers/NotificationController.php | 2 +- .../app}/Http/Controllers/UserController.php | 14 +- .../Requests/Auth/ForgotPasswordRequest.php | 2 +- .../app}/Http/Requests/Auth/LoginRequest.php | 2 +- .../app}/Http/Requests/Auth/LogoutRequest.php | 2 +- .../Http/Requests/Auth/RegisterRequest.php | 2 +- .../Requests/Auth/ResetPasswordRequest.php | 2 +- .../Http/Requests/ProfileUpdateRequest.php | 2 +- .../User/app}/Jobs/DeleteAccountJob.php | 4 +- .../User/app}/Listeners/AuthListener.php | 6 +- .../src => modules/User/app}/Models/User.php | 16 +- .../User/app}/Models/UserProfile.php | 8 +- .../User/app}/Observers/UserObserver.php | 8 +- .../app}/Observers/UserProfileObserver.php | 4 +- .../User/app}/Policies/RolePolicy.php | 4 +- .../User/app}/Policies/UserPolicy.php | 4 +- .../app/Providers/EventServiceProvider.php | 51 ++++ .../app/Providers/RouteServiceProvider.php | 47 +++ .../app/Providers/UserServiceProvider.php | 115 +++++++ .../User/app}/Services/SessionService.php | 2 +- .../User/app}/Services/UserService.php | 10 +- modules/User/composer.json | 28 ++ .../User/database/factories/UserFactory.php | 2 +- .../database/factories/UserProfileFactory.php | 6 +- .../0001_01_01_000000_create_users_table.php | 0 ...8_20_154902_create_user_profiles_table.php | 0 .../User/database/seeders/UserSeeder.php | 6 +- modules/User/module.json | 11 + modules/User/package.json | 15 + modules/User/routes/api.php | 38 +++ modules/User/routes/web.php | 21 ++ modules/User/vite.config.js | 57 ++++ modules_statuses.json | 13 + packages/Article/routes/api.php | 20 -- packages/Article/routes/web.php | 20 -- packages/Article/src/ArticleProvider.php | 126 -------- packages/Category/routes/web.php | 8 - packages/Category/src/CategoryProvider.php | 92 ------ packages/Course/routes/api.php | 1 - packages/Course/routes/web.php | 11 - packages/Course/src/CourseProvider.php | 147 --------- packages/Entry/routes/api.php | 16 - packages/Entry/routes/web.php | 13 - packages/Entry/src/EntryProvider.php | 89 ------ packages/News/src/NewsProvider.php | 63 ---- packages/Page/routes/web.php | 8 - packages/Page/src/PageProvider.php | 104 ------- packages/React/src/ReactProvider.php | 108 ------- packages/Recommend/routes/api.php | 10 - packages/Recommend/src/RecommendProvider.php | 42 --- packages/Search/routes/api.php | 7 - packages/Search/routes/web.php | 10 - packages/Search/src/SearchProvider.php | 24 -- packages/Tag/routes/web.php | 8 - packages/Tag/src/TagProvider.php | 92 ------ packages/User/routes/api.php | 41 --- packages/User/routes/web.php | 22 -- packages/User/src/UserProvider.php | 104 ------- phpstan.neon | 2 +- phpunit.xml | 6 +- stubs/nwidart-stubs/action-invoke.stub | 8 + stubs/nwidart-stubs/action.stub | 8 + stubs/nwidart-stubs/assets/js/app.stub | 0 stubs/nwidart-stubs/assets/sass/app.stub | 0 stubs/nwidart-stubs/cast.stub | 25 ++ stubs/nwidart-stubs/channel.stub | 16 + stubs/nwidart-stubs/class-invoke.stub | 8 + stubs/nwidart-stubs/class.stub | 8 + stubs/nwidart-stubs/command.stub | 53 ++++ stubs/nwidart-stubs/component-class.stub | 22 ++ stubs/nwidart-stubs/component-view.stub | 3 + stubs/nwidart-stubs/composer.stub | 28 ++ stubs/nwidart-stubs/controller-api.stub | 59 ++++ stubs/nwidart-stubs/controller-plain.stub | 7 + stubs/nwidart-stubs/controller.invokable.stub | 17 ++ stubs/nwidart-stubs/controller.stub | 56 ++++ stubs/nwidart-stubs/enum.stub | 5 + stubs/nwidart-stubs/event-provider.stub | 27 ++ stubs/nwidart-stubs/event.stub | 31 ++ .../exception-render-report.stub | 20 ++ stubs/nwidart-stubs/exception-render.stub | 15 + stubs/nwidart-stubs/exception-report.stub | 13 + stubs/nwidart-stubs/exception.stub | 7 + stubs/nwidart-stubs/factory.stub | 22 ++ stubs/nwidart-stubs/helper-invoke.stub | 8 + stubs/nwidart-stubs/helper.stub | 8 + stubs/nwidart-stubs/interface.stub | 5 + stubs/nwidart-stubs/job-queued.stub | 24 ++ stubs/nwidart-stubs/job.stub | 21 ++ stubs/nwidart-stubs/json.stub | 11 + stubs/nwidart-stubs/listener-duck.stub | 19 ++ stubs/nwidart-stubs/listener-queued-duck.stub | 21 ++ stubs/nwidart-stubs/listener-queued.stub | 22 ++ stubs/nwidart-stubs/listener.stub | 20 ++ stubs/nwidart-stubs/mail.stub | 26 ++ stubs/nwidart-stubs/middleware.stub | 17 ++ stubs/nwidart-stubs/migration/add.stub | 28 ++ stubs/nwidart-stubs/migration/create.stub | 28 ++ stubs/nwidart-stubs/migration/delete.stub | 28 ++ stubs/nwidart-stubs/migration/drop.stub | 28 ++ stubs/nwidart-stubs/migration/plain.stub | 18 ++ stubs/nwidart-stubs/model.stub | 22 ++ stubs/nwidart-stubs/notification.stub | 45 +++ stubs/nwidart-stubs/observer.stub | 33 ++ stubs/nwidart-stubs/package.stub | 15 + stubs/nwidart-stubs/policy.plain.stub | 15 + stubs/nwidart-stubs/provider.stub | 21 ++ stubs/nwidart-stubs/repository-invoke.stub | 8 + stubs/nwidart-stubs/repository.stub | 8 + stubs/nwidart-stubs/request.stub | 24 ++ stubs/nwidart-stubs/resource-collection.stub | 17 ++ stubs/nwidart-stubs/resource.stub | 17 ++ stubs/nwidart-stubs/route-provider.stub | 59 ++++ stubs/nwidart-stubs/routes/api.stub | 8 + stubs/nwidart-stubs/routes/web.stub | 8 + stubs/nwidart-stubs/rule.implicit.stub | 19 ++ stubs/nwidart-stubs/rule.stub | 14 + stubs/nwidart-stubs/scaffold/config.stub | 5 + stubs/nwidart-stubs/scaffold/provider.stub | 156 ++++++++++ stubs/nwidart-stubs/scope.stub | 15 + stubs/nwidart-stubs/seeder.stub | 16 + stubs/nwidart-stubs/service-invoke.stub | 8 + stubs/nwidart-stubs/service.stub | 8 + stubs/nwidart-stubs/tests/feature.stub | 18 ++ stubs/nwidart-stubs/tests/unit.stub | 16 + stubs/nwidart-stubs/trait.stub | 5 + stubs/nwidart-stubs/view.stub | 3 + stubs/nwidart-stubs/views/index.stub | 5 + stubs/nwidart-stubs/views/master.stub | 30 ++ stubs/nwidart-stubs/vite.stub | 57 ++++ tests/TestCase.php | 11 +- vite-module-loader.js | 51 ++++ 462 files changed, 6137 insertions(+), 2041 deletions(-) create mode 100644 config/modules.php rename {packages/Article/src => modules/Article/app}/Console/Commands/ScheduleArticleCommand.php (86%) rename {packages/Article/src => modules/Article/app}/Data/ArticleData.php (93%) rename {packages/Article/src => modules/Article/app}/Events/ArticlePublishedEvent.php (91%) rename {packages/Article/src => modules/Article/app}/Http/Controllers/ArticleController.php (89%) rename {packages/Article/src => modules/Article/app}/Http/Controllers/ArticleCrudController.php (94%) rename {packages/Article/src => modules/Article/app}/Http/Requests/CreateRequest.php (96%) rename {packages/Article/src => modules/Article/app}/Http/Requests/EditRequest.php (96%) rename {packages/Article/src => modules/Article/app}/Listeners/ArticlePublishedListener.php (87%) rename {packages/Article/src => modules/Article/app}/Models/Article.php (92%) rename {packages/Article/src => modules/Article/app}/Notifications/ArticlePublishedNotification.php (94%) rename {packages/Article/src => modules/Article/app}/Observers/ArticleObserver.php (89%) rename {packages/Article/src => modules/Article/app}/Policies/ArticlePolicy.php (97%) create mode 100644 modules/Article/app/Providers/ArticleServiceProvider.php create mode 100644 modules/Article/app/Providers/EventServiceProvider.php create mode 100644 modules/Article/app/Providers/RouteServiceProvider.php rename {packages/Article/src => modules/Article/app}/Services/ArticleService.php (90%) create mode 100644 modules/Article/composer.json rename {packages => modules}/Article/database/factories/ArticleFactory.php (87%) rename {packages => modules}/Article/database/migrations/2025_08_15_144713_create_articles_table.php (100%) rename {packages => modules}/Article/database/migrations/2025_08_15_145320_create_article_pivot_table.php (100%) rename {packages => modules}/Article/database/seeders/ArticleSeeder.php (66%) rename {packages/Article/resources => modules/Article}/lang/en/messages.php (100%) rename {packages/Article/resources => modules/Article}/lang/tr/messages.php (100%) create mode 100644 modules/Article/module.json create mode 100644 modules/Article/package.json create mode 100644 modules/Article/routes/api.php create mode 100644 modules/Article/routes/web.php rename {packages => modules}/Article/tests/Feature/Console/Commands/ScheduleArticleCommandTest.php (94%) rename {packages => modules}/Article/tests/Feature/Database/Seeders/ArticleSeederTest.php (53%) rename {packages => modules}/Article/tests/Feature/Http/Controllers/ArticleControllerTest.php (94%) rename {packages => modules}/Article/tests/Feature/Http/Controllers/ArticleCrudControllerTest.php (97%) rename {packages => modules}/Article/tests/Feature/Http/Requests/CreateRequestTest.php (98%) rename {packages => modules}/Article/tests/Feature/Http/Requests/EditRequestTest.php (98%) rename {packages => modules}/Article/tests/TestCase.php (93%) rename {packages => modules}/Article/tests/Unit/Data/ArticleDataTest.php (96%) rename {packages => modules}/Article/tests/Unit/Database/ArticleFactoryTest.php (93%) rename {packages => modules}/Article/tests/Unit/Events/ArticlePublishedEventTest.php (79%) rename {packages => modules}/Article/tests/Unit/Listeners/ArticlePublishedListenerTest.php (70%) rename {packages => modules}/Article/tests/Unit/Models/ArticleTest.php (95%) rename {packages => modules}/Article/tests/Unit/Notifications/ArticlePublishedNotificationTest.php (80%) rename {packages => modules}/Article/tests/Unit/Observers/ArticleObserverTest.php (88%) rename {packages => modules}/Article/tests/Unit/Policies/ArticlePolicyTest.php (98%) rename {packages => modules}/Article/tests/Unit/Services/ArticleServiceTest.php (80%) create mode 100644 modules/Article/vite.config.js rename {packages/Category/src => modules/Category/app}/Data/CategoryData.php (91%) rename {packages/Category/src => modules/Category/app}/Data/CategoryProfileData.php (88%) rename {packages/Category/src => modules/Category/app}/Http/Controllers/CategoryController.php (93%) rename {packages/Category/src => modules/Category/app}/Models/Category.php (87%) rename {packages/Category/src => modules/Category/app}/Models/CategoryProfile.php (89%) rename {packages/Category/src => modules/Category/app}/Observers/CategoryObserver.php (91%) rename {packages/Category/src => modules/Category/app}/Observers/CategoryProfileObserver.php (86%) rename {packages/Category/src => modules/Category/app}/Policies/CategoryPolicy.php (98%) create mode 100644 modules/Category/app/Providers/CategoryServiceProvider.php create mode 100644 modules/Category/app/Providers/RouteServiceProvider.php rename {packages/Category/src => modules/Category/app}/Services/CategoryService.php (90%) create mode 100644 modules/Category/composer.json rename {packages => modules}/Category/database/factories/CategoryFactory.php (73%) rename {packages => modules}/Category/database/factories/CategoryProfileFactory.php (68%) rename {packages => modules}/Category/database/migrations/2025_08_15_145151_create_categories_table.php (100%) rename {packages => modules}/Category/database/migrations/2025_08_25_103855_create_category_profiles_table.php (100%) rename {packages => modules}/Category/database/seeders/CategorySeeder.php (67%) create mode 100644 modules/Category/module.json create mode 100644 modules/Category/package.json create mode 100644 modules/Category/routes/web.php rename {packages => modules}/Category/tests/Feature/Database/Seeders/CategorySeederTest.php (78%) rename {packages => modules}/Category/tests/Feature/Http/Controllers/CategoryControllerTest.php (92%) rename {packages => modules}/Category/tests/TestCase.php (74%) rename {packages => modules}/Category/tests/Unit/Data/CategoryDataTest.php (95%) rename {packages => modules}/Category/tests/Unit/Data/CategoryProfileDataTest.php (82%) rename {packages => modules}/Category/tests/Unit/Database/Factories/CategoryFactoryTest.php (91%) rename {packages => modules}/Category/tests/Unit/Database/Factories/CategoryProfileFactoryTest.php (87%) rename {packages => modules}/Category/tests/Unit/Models/CategoryProfileTest.php (95%) rename {packages => modules}/Category/tests/Unit/Models/CategoryTest.php (94%) rename {packages => modules}/Category/tests/Unit/Observers/CategoryObserverTest.php (92%) rename {packages => modules}/Category/tests/Unit/Observers/CategoryProfileObserverTest.php (79%) rename {packages => modules}/Category/tests/Unit/Policies/CategoryPolicyTest.php (97%) rename {packages => modules}/Category/tests/Unit/Services/CategoryServiceTest.php (90%) create mode 100644 modules/Category/vite.config.js rename {packages/Course/src => modules/Course/app}/Console/Commands/ScheduleCourseCommand.php (86%) rename {packages/Course/src => modules/Course/app}/Console/Commands/ScheduleLessonCommand.php (86%) rename {packages/Course/src => modules/Course/app}/Data/CourseData.php (92%) rename {packages/Course/src => modules/Course/app}/Data/CourseLessonData.php (94%) rename {packages/Course/src => modules/Course/app}/Events/CoursePublishedEvent.php (91%) rename {packages/Course/src => modules/Course/app}/Events/LessonPublishedEvent.php (91%) rename {packages/Course/src => modules/Course/app}/Http/Controllers/CourseController.php (95%) rename {packages/Course/src => modules/Course/app}/Listeners/CoursePublishedListener.php (88%) rename {packages/Course/src => modules/Course/app}/Listeners/LessonPublishedListener.php (88%) rename {packages/Course/src => modules/Course/app}/Models/Course.php (92%) rename {packages/Course/src => modules/Course/app}/Models/CourseChapter.php (90%) rename {packages/Course/src => modules/Course/app}/Models/CourseLesson.php (92%) rename {packages/Course/src => modules/Course/app}/Notifications/CoursePublishedNotification.php (94%) rename {packages/Course/src => modules/Course/app}/Notifications/LessonPublishedNotification.php (94%) rename {packages/Course/src => modules/Course/app}/Observers/CourseChapterObserver.php (90%) rename {packages/Course/src => modules/Course/app}/Observers/CourseLessonObserver.php (91%) rename {packages/Course/src => modules/Course/app}/Observers/CourseObserver.php (89%) rename {packages/Course/src => modules/Course/app}/Policies/CourseChapterPolicy.php (97%) rename {packages/Course/src => modules/Course/app}/Policies/CourseLessonPolicy.php (97%) rename {packages/Course/src => modules/Course/app}/Policies/CoursePolicy.php (97%) create mode 100644 modules/Course/app/Providers/CourseServiceProvider.php create mode 100644 modules/Course/app/Providers/EventServiceProvider.php create mode 100644 modules/Course/app/Providers/RouteServiceProvider.php rename {packages/Course/src => modules/Course/app}/Services/CourseService.php (94%) create mode 100644 modules/Course/composer.json rename {packages => modules}/Course/database/factories/CourseChapterFactory.php (67%) rename {packages => modules}/Course/database/factories/CourseFactory.php (87%) rename {packages => modules}/Course/database/factories/CourseLessonFactory.php (79%) rename {packages => modules}/Course/database/migrations/2025_11_09_084042_create_courses_table.php (100%) rename {packages => modules}/Course/database/migrations/2025_11_09_084732_create_course_chapters_table.php (100%) rename {packages => modules}/Course/database/migrations/2025_11_09_084905_create_course_lessons_table.php (100%) rename {packages => modules}/Course/database/migrations/2025_11_09_192116_create_course_pivot_table.php (100%) create mode 100755 modules/Course/database/seeders/CourseSeeder.php rename {packages/Course/resources => modules/Course}/lang/en/messages.php (100%) rename {packages/Course/resources => modules/Course}/lang/tr/messages.php (100%) create mode 100644 modules/Course/module.json create mode 100644 modules/Course/package.json create mode 100644 modules/Course/resources/assets/.gitkeep create mode 100644 modules/Course/resources/assets/js/app.js create mode 100644 modules/Course/resources/assets/sass/app.scss create mode 100644 modules/Course/resources/views/components/layouts/master.blade.php create mode 100644 modules/Course/resources/views/index.blade.php create mode 100644 modules/Course/routes/web.php create mode 100644 modules/Course/vite.config.js rename {packages/Entry/src => modules/Entry/app}/Data/EntryData.php (94%) rename {packages/Entry/src => modules/Entry/app}/Http/Controllers/EntryController.php (89%) rename {packages/Entry/src => modules/Entry/app}/Http/Controllers/EntryCrudController.php (85%) rename {packages/Entry/src => modules/Entry/app}/Http/Requests/CreateRequest.php (97%) rename {packages/Entry/src => modules/Entry/app}/Models/Entry.php (89%) rename {packages/Entry/src => modules/Entry/app}/Observers/EntryObserver.php (88%) rename {packages/Entry/src => modules/Entry/app}/Policies/EntryPolicy.php (97%) create mode 100644 modules/Entry/app/Providers/EntryServiceProvider.php create mode 100644 modules/Entry/app/Providers/RouteServiceProvider.php rename {packages/Entry/src => modules/Entry/app}/Services/EntryService.php (89%) create mode 100644 modules/Entry/composer.json rename {packages => modules}/Entry/database/factories/EntryFactory.php (79%) rename {packages => modules}/Entry/database/migrations/2025_10_03_095727_create_entries_table.php (100%) rename {packages => modules}/Entry/database/seeders/EntrySeeder.php (67%) create mode 100644 modules/Entry/module.json create mode 100644 modules/Entry/package.json create mode 100644 modules/Entry/routes/api.php create mode 100644 modules/Entry/routes/web.php create mode 100644 modules/Entry/vite.config.js rename {packages/News/src => modules/News/app}/Data/NewsData.php (88%) rename {packages/News/src => modules/News/app}/Models/News.php (95%) rename {packages/News/src => modules/News/app}/Observers/NewsObserver.php (93%) rename {packages/News/src => modules/News/app}/Policies/NewsPolicy.php (97%) create mode 100644 modules/News/app/Providers/NewsServiceProvider.php rename {packages/News/src => modules/News/app}/Services/NewsService.php (90%) create mode 100644 modules/News/composer.json rename {packages => modules}/News/database/factories/NewsFactory.php (84%) rename {packages => modules}/News/database/migrations/2025_08_17_132322_create_news_table.php (100%) rename {packages => modules}/News/database/migrations/2025_08_17_132432_create_news_pivot_table.php (100%) rename {packages => modules}/News/database/migrations/2025_10_21_184927_drop_timestampts_from_news_pivots.php (100%) rename {packages => modules}/News/database/migrations/2025_12_06_194559_drop_image_from_news_table.php (100%) rename {packages => modules}/News/database/seeders/NewsSeeder.php (68%) create mode 100644 modules/News/module.json create mode 100644 modules/News/package.json create mode 100644 modules/News/resources/assets/js/app.js create mode 100644 modules/News/resources/assets/sass/app.scss create mode 100644 modules/News/resources/views/components/layouts/master.blade.php create mode 100644 modules/News/resources/views/index.blade.php create mode 100644 modules/News/vite.config.js rename {packages/Page/src => modules/Page/app}/Console/Commands/SchedulePageCommand.php (87%) rename {packages/Page/src => modules/Page/app}/Data/PageData.php (93%) rename {packages/Page/src => modules/Page/app}/Events/PagePublishedEvent.php (92%) rename {packages/Page/src => modules/Page/app}/Http/Controllers/PageController.php (92%) rename {packages/Page/src => modules/Page/app}/Listeners/PagePublishedListener.php (88%) rename {packages/Page/src => modules/Page/app}/Models/Page.php (95%) rename {packages/Page/src => modules/Page/app}/Notifications/PagePublishedNotification.php (95%) rename {packages/Page/src => modules/Page/app}/Observers/PageObserver.php (93%) rename {packages/Page/src => modules/Page/app}/Policies/PagePolicy.php (97%) create mode 100644 modules/Page/app/Providers/EventServiceProvider.php create mode 100644 modules/Page/app/Providers/PageServiceProvider.php create mode 100644 modules/Page/app/Providers/RouteServiceProvider.php rename {packages/Page/src => modules/Page/app}/Services/PageService.php (90%) create mode 100644 modules/Page/composer.json rename {packages => modules}/Page/database/factories/PageFactory.php (84%) rename {packages => modules}/Page/database/migrations/2025_09_04_100152_create_pages_table.php (100%) rename {packages => modules}/Page/database/seeders/PageSeeder.php (68%) rename {packages/Page/resources => modules/Page}/lang/en/messages.php (100%) rename {packages/Page/resources => modules/Page}/lang/tr/messages.php (100%) create mode 100644 modules/Page/module.json create mode 100644 modules/Page/package.json create mode 100644 modules/Page/routes/web.php create mode 100644 modules/Page/vite.config.js rename {packages/React/src => modules/React/app}/Data/CommentData.php (92%) rename {packages/React/src => modules/React/app}/Events/FollowedEvent.php (92%) rename {packages/React/src => modules/React/app}/Helpers.php (93%) rename {packages/React/src => modules/React/app}/Http/Controllers/ReactController.php (97%) rename {packages/React/src => modules/React/app}/Http/Requests/ReactRequest.php (94%) rename {packages/React/src => modules/React/app}/Listeners/FollowedListener.php (80%) rename {packages/React/src => modules/React/app}/Models/Comment.php (91%) rename {packages/React/src => modules/React/app}/Models/Dislike.php (86%) rename {packages/React/src => modules/React/app}/Models/Follow.php (86%) rename {packages/React/src => modules/React/app}/Models/Like.php (86%) rename {packages/React/src => modules/React/app}/Models/Save.php (86%) rename {packages/React/src => modules/React/app}/Observers/CommentObserver.php (85%) rename {packages/React/src => modules/React/app}/Observers/DislikeObserver.php (85%) rename {packages/React/src => modules/React/app}/Observers/FollowObserver.php (86%) rename {packages/React/src => modules/React/app}/Observers/LikeObserver.php (84%) rename {packages/React/src => modules/React/app}/Observers/SaveObserver.php (84%) rename {packages/React/src => modules/React/app}/Policies/CommentPolicy.php (97%) rename {packages/React/src => modules/React/app}/Policies/DislikePolicy.php (97%) rename {packages/React/src => modules/React/app}/Policies/FollowPolicy.php (98%) rename {packages/React/src => modules/React/app}/Policies/LikePolicy.php (97%) rename {packages/React/src => modules/React/app}/Policies/SavePolicy.php (97%) create mode 100644 modules/React/app/Providers/EventServiceProvider.php create mode 100644 modules/React/app/Providers/ReactServiceProvider.php create mode 100644 modules/React/app/Providers/RouteServiceProvider.php rename {packages/React/src => modules/React/app}/Services/ReactService.php (98%) rename {packages/React/src => modules/React/app}/Traits/CanFollow.php (95%) rename {packages/React/src => modules/React/app}/Traits/HasComments.php (95%) rename {packages/React/src => modules/React/app}/Traits/HasDislikes.php (95%) rename {packages/React/src => modules/React/app}/Traits/HasFollowers.php (91%) rename {packages/React/src => modules/React/app}/Traits/HasLikes.php (95%) rename {packages/React/src => modules/React/app}/Traits/HasSaves.php (94%) create mode 100644 modules/React/composer.json rename {packages => modules}/React/database/factories/CommentFactory.php (84%) rename {packages => modules}/React/database/factories/DislikeFactory.php (82%) rename {packages => modules}/React/database/factories/FollowFactory.php (82%) rename {packages => modules}/React/database/factories/LikeFactory.php (82%) rename {packages => modules}/React/database/factories/SaveFactory.php (82%) rename {packages => modules}/React/database/migrations/2025_09_18_075116_create_comments_table.php (100%) rename {packages => modules}/React/database/migrations/2025_10_15_071629_create_likes_table.php (100%) rename {packages => modules}/React/database/migrations/2025_10_16_072117_create_dislikes_table.php (100%) rename {packages => modules}/React/database/migrations/2025_10_16_072145_create_saves_table.php (100%) rename {packages => modules}/React/database/migrations/2025_10_16_111600_create_follows_table.php (100%) create mode 100644 modules/React/lang/en/messages.php create mode 100644 modules/React/lang/tr/messages.php create mode 100644 modules/React/module.json create mode 100644 modules/React/package.json rename {packages => modules}/React/routes/api.php (60%) create mode 100644 modules/React/vite.config.js rename {packages/Recommend/src => modules/Recommend/app}/Classes/GorseFeedback.php (97%) rename {packages/Recommend/src => modules/Recommend/app}/Classes/GorseItem.php (98%) rename {packages/Recommend/src => modules/Recommend/app}/Classes/GorseUser.php (98%) rename {packages/Recommend/src => modules/Recommend/app}/Classes/RowAffected.php (93%) rename {packages/Recommend/src => modules/Recommend/app}/Console/Commands/UploadRecommendations.php (89%) rename {packages/Recommend/src => modules/Recommend/app}/Http/Controllers/FeedController.php (93%) rename {packages/Recommend/src => modules/Recommend/app}/Http/Requests/FeedRequest.php (94%) create mode 100644 modules/Recommend/app/Providers/RecommendServiceProvider.php create mode 100644 modules/Recommend/app/Providers/RouteServiceProvider.php rename {packages/Recommend/src => modules/Recommend/app}/Services/FeedService.php (96%) rename {packages/Recommend/src => modules/Recommend/app}/Services/GorseService.php (97%) create mode 100644 modules/Recommend/composer.json rename {packages => modules}/Recommend/config/recommend.php (100%) create mode 100644 modules/Recommend/module.json create mode 100644 modules/Recommend/package.json create mode 100644 modules/Recommend/routes/api.php create mode 100644 modules/Recommend/vite.config.js rename {packages/Search/src => modules/Search/app}/Http/Controllers/SearchController.php (93%) create mode 100644 modules/Search/app/Providers/RouteServiceProvider.php create mode 100644 modules/Search/app/Providers/SearchServiceProvider.php rename {packages/Search/src => modules/Search/app}/Services/SearchService.php (98%) create mode 100644 modules/Search/composer.json create mode 100644 modules/Search/module.json create mode 100644 modules/Search/package.json create mode 100644 modules/Search/routes/api.php create mode 100644 modules/Search/routes/web.php create mode 100644 modules/Search/vite.config.js rename {packages/Tag/src => modules/Tag/app}/Data/TagData.php (92%) rename {packages/Tag/src => modules/Tag/app}/Data/TagProfileData.php (90%) rename {packages/Tag/src => modules/Tag/app}/Http/Controllers/TagController.php (94%) rename {packages/Tag/src => modules/Tag/app}/Models/Tag.php (87%) rename {packages/Tag/src => modules/Tag/app}/Models/TagProfile.php (90%) rename {packages/Tag/src => modules/Tag/app}/Observers/TagObserver.php (91%) rename {packages/Tag/src => modules/Tag/app}/Observers/TagProfileObserver.php (81%) rename {packages/Tag/src => modules/Tag/app}/Policies/TagPolicy.php (98%) create mode 100644 modules/Tag/app/Providers/RouteServiceProvider.php create mode 100644 modules/Tag/app/Providers/TagServiceProvider.php rename {packages/Tag/src => modules/Tag/app}/Services/TagService.php (93%) create mode 100644 modules/Tag/composer.json rename {packages => modules}/Tag/database/factories/TagFactory.php (75%) rename {packages => modules}/Tag/database/factories/TagProfileFactory.php (86%) rename {packages => modules}/Tag/database/migrations/2025_08_15_145209_create_tags_table.php (100%) rename {packages => modules}/Tag/database/migrations/2025_08_25_093825_create_tag_profiles_table.php (100%) rename {packages => modules}/Tag/database/migrations/2025_10_20_053612_create_tag_profile_category_table.php (100%) rename {packages => modules}/Tag/database/seeders/TagSeeder.php (69%) create mode 100644 modules/Tag/module.json create mode 100644 modules/Tag/package.json create mode 100644 modules/Tag/routes/web.php rename {packages => modules}/Tag/tests/Feature/Database/Seeders/TagSeederTest.php (79%) rename {packages => modules}/Tag/tests/Feature/Http/Controllers/TagControllerTest.php (93%) rename {packages => modules}/Tag/tests/TestCase.php (77%) rename {packages => modules}/Tag/tests/Unit/Data/TagDataTest.php (95%) rename {packages => modules}/Tag/tests/Unit/Data/TagProfileDataTest.php (92%) rename {packages => modules}/Tag/tests/Unit/Database/Factories/TagFactoryTest.php (91%) rename {packages => modules}/Tag/tests/Unit/Database/Factories/TagProfileFactoryTest.php (93%) rename {packages => modules}/Tag/tests/Unit/Models/TagProfileTest.php (95%) rename {packages => modules}/Tag/tests/Unit/Models/TagTest.php (94%) rename {packages => modules}/Tag/tests/Unit/Observers/TagObserverTest.php (93%) rename {packages => modules}/Tag/tests/Unit/Observers/TagProfileObserverTest.php (81%) rename {packages => modules}/Tag/tests/Unit/Policies/TagPolicyTest.php (98%) rename {packages => modules}/Tag/tests/Unit/Services/TagServiceTest.php (91%) create mode 100644 modules/Tag/vite.config.js rename {packages/User/src => modules/User/app}/Data/UserData.php (94%) rename {packages/User/src => modules/User/app}/Data/UserProfileData.php (93%) rename {packages/User/src => modules/User/app}/Http/Controllers/AuthController.php (83%) rename {packages/User/src => modules/User/app}/Http/Controllers/NotificationController.php (97%) rename {packages/User/src => modules/User/app}/Http/Controllers/UserController.php (96%) rename {packages/User/src => modules/User/app}/Http/Requests/Auth/ForgotPasswordRequest.php (98%) rename {packages/User/src => modules/User/app}/Http/Requests/Auth/LoginRequest.php (98%) rename {packages/User/src => modules/User/app}/Http/Requests/Auth/LogoutRequest.php (95%) rename {packages/User/src => modules/User/app}/Http/Requests/Auth/RegisterRequest.php (99%) rename {packages/User/src => modules/User/app}/Http/Requests/Auth/ResetPasswordRequest.php (98%) rename {packages/User/src => modules/User/app}/Http/Requests/ProfileUpdateRequest.php (94%) rename {packages/User/src => modules/User/app}/Jobs/DeleteAccountJob.php (90%) rename {packages/User/src => modules/User/app}/Listeners/AuthListener.php (87%) rename {packages/User/src => modules/User/app}/Models/User.php (95%) rename {packages/User/src => modules/User/app}/Models/UserProfile.php (94%) rename {packages/User/src => modules/User/app}/Observers/UserObserver.php (92%) rename {packages/User/src => modules/User/app}/Observers/UserProfileObserver.php (87%) rename {packages/User/src => modules/User/app}/Policies/RolePolicy.php (97%) rename {packages/User/src => modules/User/app}/Policies/UserPolicy.php (97%) create mode 100644 modules/User/app/Providers/EventServiceProvider.php create mode 100644 modules/User/app/Providers/RouteServiceProvider.php create mode 100644 modules/User/app/Providers/UserServiceProvider.php rename {packages/User/src => modules/User/app}/Services/SessionService.php (99%) rename {packages/User/src => modules/User/app}/Services/UserService.php (90%) create mode 100644 modules/User/composer.json rename {packages => modules}/User/database/factories/UserFactory.php (95%) rename {packages => modules}/User/database/factories/UserProfileFactory.php (80%) rename {packages => modules}/User/database/migrations/0001_01_01_000000_create_users_table.php (100%) rename {packages => modules}/User/database/migrations/2025_08_20_154902_create_user_profiles_table.php (100%) rename {packages => modules}/User/database/seeders/UserSeeder.php (88%) create mode 100644 modules/User/module.json create mode 100644 modules/User/package.json create mode 100755 modules/User/routes/api.php create mode 100755 modules/User/routes/web.php create mode 100644 modules/User/vite.config.js create mode 100644 modules_statuses.json delete mode 100644 packages/Article/routes/api.php delete mode 100644 packages/Article/routes/web.php delete mode 100644 packages/Article/src/ArticleProvider.php delete mode 100644 packages/Category/routes/web.php delete mode 100644 packages/Category/src/CategoryProvider.php delete mode 100644 packages/Course/routes/api.php delete mode 100644 packages/Course/routes/web.php delete mode 100644 packages/Course/src/CourseProvider.php delete mode 100644 packages/Entry/routes/api.php delete mode 100644 packages/Entry/routes/web.php delete mode 100644 packages/Entry/src/EntryProvider.php delete mode 100644 packages/News/src/NewsProvider.php delete mode 100644 packages/Page/routes/web.php delete mode 100644 packages/Page/src/PageProvider.php delete mode 100644 packages/React/src/ReactProvider.php delete mode 100644 packages/Recommend/routes/api.php delete mode 100644 packages/Recommend/src/RecommendProvider.php delete mode 100644 packages/Search/routes/api.php delete mode 100644 packages/Search/routes/web.php delete mode 100644 packages/Search/src/SearchProvider.php delete mode 100644 packages/Tag/routes/web.php delete mode 100644 packages/Tag/src/TagProvider.php delete mode 100755 packages/User/routes/api.php delete mode 100755 packages/User/routes/web.php delete mode 100644 packages/User/src/UserProvider.php create mode 100644 stubs/nwidart-stubs/action-invoke.stub create mode 100644 stubs/nwidart-stubs/action.stub create mode 100644 stubs/nwidart-stubs/assets/js/app.stub create mode 100644 stubs/nwidart-stubs/assets/sass/app.stub create mode 100644 stubs/nwidart-stubs/cast.stub create mode 100644 stubs/nwidart-stubs/channel.stub create mode 100644 stubs/nwidart-stubs/class-invoke.stub create mode 100644 stubs/nwidart-stubs/class.stub create mode 100644 stubs/nwidart-stubs/command.stub create mode 100644 stubs/nwidart-stubs/component-class.stub create mode 100644 stubs/nwidart-stubs/component-view.stub create mode 100644 stubs/nwidart-stubs/composer.stub create mode 100644 stubs/nwidart-stubs/controller-api.stub create mode 100644 stubs/nwidart-stubs/controller-plain.stub create mode 100644 stubs/nwidart-stubs/controller.invokable.stub create mode 100644 stubs/nwidart-stubs/controller.stub create mode 100644 stubs/nwidart-stubs/enum.stub create mode 100644 stubs/nwidart-stubs/event-provider.stub create mode 100644 stubs/nwidart-stubs/event.stub create mode 100644 stubs/nwidart-stubs/exception-render-report.stub create mode 100644 stubs/nwidart-stubs/exception-render.stub create mode 100644 stubs/nwidart-stubs/exception-report.stub create mode 100644 stubs/nwidart-stubs/exception.stub create mode 100644 stubs/nwidart-stubs/factory.stub create mode 100644 stubs/nwidart-stubs/helper-invoke.stub create mode 100644 stubs/nwidart-stubs/helper.stub create mode 100644 stubs/nwidart-stubs/interface.stub create mode 100644 stubs/nwidart-stubs/job-queued.stub create mode 100644 stubs/nwidart-stubs/job.stub create mode 100644 stubs/nwidart-stubs/json.stub create mode 100644 stubs/nwidart-stubs/listener-duck.stub create mode 100644 stubs/nwidart-stubs/listener-queued-duck.stub create mode 100644 stubs/nwidart-stubs/listener-queued.stub create mode 100644 stubs/nwidart-stubs/listener.stub create mode 100644 stubs/nwidart-stubs/mail.stub create mode 100644 stubs/nwidart-stubs/middleware.stub create mode 100644 stubs/nwidart-stubs/migration/add.stub create mode 100644 stubs/nwidart-stubs/migration/create.stub create mode 100644 stubs/nwidart-stubs/migration/delete.stub create mode 100644 stubs/nwidart-stubs/migration/drop.stub create mode 100644 stubs/nwidart-stubs/migration/plain.stub create mode 100644 stubs/nwidart-stubs/model.stub create mode 100644 stubs/nwidart-stubs/notification.stub create mode 100644 stubs/nwidart-stubs/observer.stub create mode 100644 stubs/nwidart-stubs/package.stub create mode 100644 stubs/nwidart-stubs/policy.plain.stub create mode 100644 stubs/nwidart-stubs/provider.stub create mode 100644 stubs/nwidart-stubs/repository-invoke.stub create mode 100644 stubs/nwidart-stubs/repository.stub create mode 100644 stubs/nwidart-stubs/request.stub create mode 100644 stubs/nwidart-stubs/resource-collection.stub create mode 100644 stubs/nwidart-stubs/resource.stub create mode 100644 stubs/nwidart-stubs/route-provider.stub create mode 100644 stubs/nwidart-stubs/routes/api.stub create mode 100644 stubs/nwidart-stubs/routes/web.stub create mode 100644 stubs/nwidart-stubs/rule.implicit.stub create mode 100644 stubs/nwidart-stubs/rule.stub create mode 100644 stubs/nwidart-stubs/scaffold/config.stub create mode 100644 stubs/nwidart-stubs/scaffold/provider.stub create mode 100644 stubs/nwidart-stubs/scope.stub create mode 100644 stubs/nwidart-stubs/seeder.stub create mode 100644 stubs/nwidart-stubs/service-invoke.stub create mode 100644 stubs/nwidart-stubs/service.stub create mode 100644 stubs/nwidart-stubs/tests/feature.stub create mode 100644 stubs/nwidart-stubs/tests/unit.stub create mode 100644 stubs/nwidart-stubs/trait.stub create mode 100644 stubs/nwidart-stubs/view.stub create mode 100644 stubs/nwidart-stubs/views/index.stub create mode 100644 stubs/nwidart-stubs/views/master.stub create mode 100644 stubs/nwidart-stubs/vite.stub create mode 100644 vite-module-loader.js diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index eaf80ba..1859d39 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -44,4 +44,4 @@ jobs: - name: Generate PHPDocs run: | - php phpDocumentor.phar -d app,packages -t docs + php phpDocumentor.phar -d app,modules -t docs diff --git a/.php-cs-fixer.php b/.php-cs-fixer.php index dddcdeb..467584e 100644 --- a/.php-cs-fixer.php +++ b/.php-cs-fixer.php @@ -4,7 +4,7 @@ use PhpCsFixer\Finder; $finder = Finder::create() - ->in(['app', 'routes', 'database', 'packages']) + ->in(['app', 'routes', 'database', 'modules']) ->name('*.php') ->ignoreDotFiles(true) ->ignoreVCS(true); @@ -55,7 +55,7 @@ ], 'cast_spaces' => true, 'class_attributes_separation' => [ - 'elements' =>['const' => 'one', 'method' => 'one', 'property' => 'one', 'trait_import' => 'none', 'case' => 'none'] + 'elements' => ['const' => 'one', 'method' => 'one', 'property' => 'one', 'trait_import' => 'none', 'case' => 'none'] ], 'class_definition' => ['single_line' => false], 'concat_space' => [ diff --git a/app/Filament/Pages/Settings/SiteSettings.php b/app/Filament/Pages/Settings/SiteSettings.php index a5eb82f..e577e6a 100755 --- a/app/Filament/Pages/Settings/SiteSettings.php +++ b/app/Filament/Pages/Settings/SiteSettings.php @@ -3,7 +3,7 @@ namespace App\Filament\Pages\Settings; use Filament\Forms; -use Packages\Page\Models\Page; +use Modules\Page\Models\Page; use Spatie\Permission\Models\Role as SpatieRole; class SiteSettings diff --git a/app/Filament/Resources/ArticleResource.php b/app/Filament/Resources/ArticleResource.php index 04dc689..c4c728a 100755 --- a/app/Filament/Resources/ArticleResource.php +++ b/app/Filament/Resources/ArticleResource.php @@ -13,7 +13,7 @@ use Filament\Tables; use Filament\Tables\Table; use Illuminate\Support\Carbon; -use Packages\Article\Models\Article; +use Modules\Article\Models\Article; use Rmsramos\Activitylog\RelationManagers\ActivitylogRelationManager; class ArticleResource extends Resource diff --git a/app/Filament/Resources/ArticleResource/Widgets/ArticleStatsOverview.php b/app/Filament/Resources/ArticleResource/Widgets/ArticleStatsOverview.php index 2041b57..d696d4a 100644 --- a/app/Filament/Resources/ArticleResource/Widgets/ArticleStatsOverview.php +++ b/app/Filament/Resources/ArticleResource/Widgets/ArticleStatsOverview.php @@ -5,7 +5,7 @@ use BezhanSalleh\FilamentShield\Traits\HasWidgetShield; use Filament\Widgets\StatsOverviewWidget as BaseWidget; use Filament\Widgets\StatsOverviewWidget\Stat; -use Packages\Article\Models\Article; +use Modules\Article\Models\Article; class ArticleStatsOverview extends BaseWidget { diff --git a/app/Filament/Resources/ArticleResource/Widgets/RecentArticles.php b/app/Filament/Resources/ArticleResource/Widgets/RecentArticles.php index 909be56..cf9c483 100644 --- a/app/Filament/Resources/ArticleResource/Widgets/RecentArticles.php +++ b/app/Filament/Resources/ArticleResource/Widgets/RecentArticles.php @@ -7,7 +7,7 @@ use Filament\Tables\Actions\Action; use Filament\Widgets\TableWidget as BaseWidget; use Illuminate\Database\Eloquent\Builder; -use Packages\Article\Models\Article; +use Modules\Article\Models\Article; class RecentArticles extends BaseWidget { diff --git a/app/Filament/Resources/CategoryResource.php b/app/Filament/Resources/CategoryResource.php index fc163e2..9c8461c 100755 --- a/app/Filament/Resources/CategoryResource.php +++ b/app/Filament/Resources/CategoryResource.php @@ -9,7 +9,7 @@ use Filament\Resources\Resource; use Filament\Tables; use Filament\Tables\Table; -use Packages\Category\Models\Category; +use Modules\Category\Models\Category; use Rmsramos\Activitylog\RelationManagers\ActivitylogRelationManager; class CategoryResource extends Resource diff --git a/app/Filament/Resources/CommentResource.php b/app/Filament/Resources/CommentResource.php index fe2d417..21b8af3 100644 --- a/app/Filament/Resources/CommentResource.php +++ b/app/Filament/Resources/CommentResource.php @@ -10,7 +10,7 @@ use Filament\Resources\Resource; use Filament\Tables; use Filament\Tables\Table; -use Packages\React\Models\Comment; +use Modules\React\Models\Comment; use Rmsramos\Activitylog\RelationManagers\ActivitylogRelationManager; class CommentResource extends Resource diff --git a/app/Filament/Resources/CommentResource/Widgets/CommentStatsOverview.php b/app/Filament/Resources/CommentResource/Widgets/CommentStatsOverview.php index 84e6107..16383a3 100644 --- a/app/Filament/Resources/CommentResource/Widgets/CommentStatsOverview.php +++ b/app/Filament/Resources/CommentResource/Widgets/CommentStatsOverview.php @@ -5,7 +5,7 @@ use BezhanSalleh\FilamentShield\Traits\HasWidgetShield; use Filament\Widgets\StatsOverviewWidget as BaseWidget; use Filament\Widgets\StatsOverviewWidget\Stat; -use Packages\React\Models\Comment; +use Modules\React\Models\Comment; class CommentStatsOverview extends BaseWidget { diff --git a/app/Filament/Resources/CourseChapterResource.php b/app/Filament/Resources/CourseChapterResource.php index 02a7978..c8e2a54 100644 --- a/app/Filament/Resources/CourseChapterResource.php +++ b/app/Filament/Resources/CourseChapterResource.php @@ -10,7 +10,7 @@ use Filament\Resources\Resource; use Filament\Tables; use Filament\Tables\Table; -use Packages\Course\Models\CourseChapter; +use Modules\Course\Models\CourseChapter; class CourseChapterResource extends Resource { diff --git a/app/Filament/Resources/CourseLessonResource.php b/app/Filament/Resources/CourseLessonResource.php index 72c8fea..68d234f 100644 --- a/app/Filament/Resources/CourseLessonResource.php +++ b/app/Filament/Resources/CourseLessonResource.php @@ -10,7 +10,7 @@ use Filament\Resources\Resource; use Filament\Tables; use Filament\Tables\Table; -use Packages\Course\Models\CourseLesson; +use Modules\Course\Models\CourseLesson; class CourseLessonResource extends Resource { diff --git a/app/Filament/Resources/CourseResource.php b/app/Filament/Resources/CourseResource.php index dee6132..d766b0f 100644 --- a/app/Filament/Resources/CourseResource.php +++ b/app/Filament/Resources/CourseResource.php @@ -14,7 +14,7 @@ use Filament\Support\Enums\FontWeight; use Filament\Tables; use Filament\Tables\Table; -use Packages\Course\Models\Course; +use Modules\Course\Models\Course; class CourseResource extends Resource { diff --git a/app/Filament/Resources/DislikeResource.php b/app/Filament/Resources/DislikeResource.php index b89ae83..e57bfdd 100644 --- a/app/Filament/Resources/DislikeResource.php +++ b/app/Filament/Resources/DislikeResource.php @@ -4,7 +4,7 @@ use BezhanSalleh\FilamentShield\Traits\HasPanelShield; use Filament\Resources\Resource; -use Packages\React\Models\Dislike; +use Modules\React\Models\Dislike; class DislikeResource extends Resource { diff --git a/app/Filament/Resources/EntryResource.php b/app/Filament/Resources/EntryResource.php index 8840cf0..3f91507 100644 --- a/app/Filament/Resources/EntryResource.php +++ b/app/Filament/Resources/EntryResource.php @@ -11,7 +11,7 @@ use Filament\Resources\Resource; use Filament\Tables; use Filament\Tables\Table; -use Packages\Entry\Models\Entry; +use Modules\Entry\Models\Entry; use Rmsramos\Activitylog\RelationManagers\ActivitylogRelationManager; class EntryResource extends Resource diff --git a/app/Filament/Resources/EntryResource/Widgets/EntryStatsOverview.php b/app/Filament/Resources/EntryResource/Widgets/EntryStatsOverview.php index 4452bf4..a2f1611 100644 --- a/app/Filament/Resources/EntryResource/Widgets/EntryStatsOverview.php +++ b/app/Filament/Resources/EntryResource/Widgets/EntryStatsOverview.php @@ -5,7 +5,7 @@ use BezhanSalleh\FilamentShield\Traits\HasWidgetShield; use Filament\Widgets\StatsOverviewWidget as BaseWidget; use Filament\Widgets\StatsOverviewWidget\Stat; -use Packages\Entry\Models\Entry; +use Modules\Entry\Models\Entry; class EntryStatsOverview extends BaseWidget { diff --git a/app/Filament/Resources/EntryResource/Widgets/RecentEntries.php b/app/Filament/Resources/EntryResource/Widgets/RecentEntries.php index de69c6a..a51b2e6 100644 --- a/app/Filament/Resources/EntryResource/Widgets/RecentEntries.php +++ b/app/Filament/Resources/EntryResource/Widgets/RecentEntries.php @@ -7,7 +7,7 @@ use Filament\Tables\Actions\Action; use Filament\Widgets\TableWidget as BaseWidget; use Illuminate\Database\Eloquent\Builder; -use Packages\Entry\Models\Entry; +use Modules\Entry\Models\Entry; class RecentEntries extends BaseWidget { diff --git a/app/Filament/Resources/FollowResource.php b/app/Filament/Resources/FollowResource.php index 0fecab8..23c3eb9 100644 --- a/app/Filament/Resources/FollowResource.php +++ b/app/Filament/Resources/FollowResource.php @@ -4,7 +4,7 @@ use BezhanSalleh\FilamentShield\Traits\HasPanelShield; use Filament\Resources\Resource; -use Packages\React\Models\Follow; +use Modules\React\Models\Follow; class FollowResource extends Resource { diff --git a/app/Filament/Resources/LikeResource.php b/app/Filament/Resources/LikeResource.php index 975002b..0c2ac70 100644 --- a/app/Filament/Resources/LikeResource.php +++ b/app/Filament/Resources/LikeResource.php @@ -4,7 +4,7 @@ use BezhanSalleh\FilamentShield\Traits\HasPanelShield; use Filament\Resources\Resource; -use Packages\React\Models\Like; +use Modules\React\Models\Like; class LikeResource extends Resource { diff --git a/app/Filament/Resources/NewsResource.php b/app/Filament/Resources/NewsResource.php index 65f179d..91be406 100755 --- a/app/Filament/Resources/NewsResource.php +++ b/app/Filament/Resources/NewsResource.php @@ -13,7 +13,7 @@ use Filament\Tables; use Filament\Tables\Table; use Illuminate\Support\Carbon; -use Packages\News\Models\News; +use Modules\News\Models\News; use Rmsramos\Activitylog\RelationManagers\ActivitylogRelationManager; class NewsResource extends Resource diff --git a/app/Filament/Resources/PageResource.php b/app/Filament/Resources/PageResource.php index 34d0319..c5c56ed 100755 --- a/app/Filament/Resources/PageResource.php +++ b/app/Filament/Resources/PageResource.php @@ -13,7 +13,7 @@ use Filament\Tables; use Filament\Tables\Table; use Illuminate\Support\Carbon; -use Packages\Page\Models\Page; +use Modules\Page\Models\Page; use Rmsramos\Activitylog\RelationManagers\ActivitylogRelationManager; class PageResource extends Resource diff --git a/app/Filament/Resources/SaveResource.php b/app/Filament/Resources/SaveResource.php index bb5d882..7c5609d 100644 --- a/app/Filament/Resources/SaveResource.php +++ b/app/Filament/Resources/SaveResource.php @@ -4,7 +4,7 @@ use BezhanSalleh\FilamentShield\Traits\HasPanelShield; use Filament\Resources\Resource; -use Packages\React\Models\Save; +use Modules\React\Models\Save; class SaveResource extends Resource { diff --git a/app/Filament/Resources/TagResource.php b/app/Filament/Resources/TagResource.php index 98b0963..4721a8b 100755 --- a/app/Filament/Resources/TagResource.php +++ b/app/Filament/Resources/TagResource.php @@ -9,7 +9,7 @@ use Filament\Resources\Resource; use Filament\Tables; use Filament\Tables\Table; -use Packages\Tag\Models\Tag; +use Modules\Tag\Models\Tag; use Rmsramos\Activitylog\RelationManagers\ActivitylogRelationManager; class TagResource extends Resource diff --git a/app/Jobs/GenerateSitemapJob.php b/app/Jobs/GenerateSitemapJob.php index b27c44f..8240039 100755 --- a/app/Jobs/GenerateSitemapJob.php +++ b/app/Jobs/GenerateSitemapJob.php @@ -45,42 +45,42 @@ public function handle(): void ->setLastModificationDate($user->updated_at)); } - foreach (\Packages\Article\Models\Article::where('status', 'PUBLISHED')->get() as $article) { + foreach (\Modules\Article\Models\Article::where('status', 'PUBLISHED')->get() as $article) { $totalItems += 1; $sitemap->add(Url::create(route('article.view', ['slug' => $article->slug])) ->setPriority(0.7) ->setLastModificationDate($article->updated_at)); } - foreach (\Packages\Entry\Models\Entry::get() as $entry) { + foreach (\Modules\Entry\Models\Entry::get() as $entry) { $totalItems += 1; $sitemap->add(Url::create(route('entry.view', ['slug' => $entry->slug])) ->setPriority(0.6) ->setLastModificationDate($entry->created_at)); } - foreach (\Packages\News\Models\News::where('status', 'PUBLISHED')->get() as $news) { + foreach (\Modules\News\Models\News::where('status', 'PUBLISHED')->get() as $news) { $totalItems += 1; $sitemap->add(Url::create(route('news.view', ['slug' => $news->slug])) ->setPriority(0.6) ->setLastModificationDate($news->updated_at)); } - foreach (\Packages\Page\Models\Page::where('status', 'PUBLISHED')->get() as $page) { + foreach (\Modules\Page\Models\Page::where('status', 'PUBLISHED')->get() as $page) { $totalItems += 1; $sitemap->add(Url::create(route('page.view', ['slug' => $page->slug])) ->setPriority(0.5) ->setLastModificationDate($page->updated_at)); } - foreach (\Packages\Tag\Models\Tag::all() as $tag) { + foreach (\Modules\Tag\Models\Tag::all() as $tag) { $totalItems += 1; $sitemap->add(Url::create(route('tag.view', ['slug' => $tag->slug])) ->setPriority(0.4) ->setLastModificationDate($tag->updated_at)); } - foreach (\Packages\Category\Models\Category::all() as $cat) { + foreach (\Modules\Category\Models\Category::all() as $cat) { $totalItems += 1; $sitemap->add(Url::create(route('category.view', ['slug' => $cat->slug])) ->setPriority(0.4) diff --git a/app/Models/User.php b/app/Models/User.php index e7732fa..78b7abf 100755 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -2,7 +2,7 @@ namespace App\Models; -use Packages\User\Models\User as BaseUser; +use Modules\User\Models\User as BaseUser; /** * @property int $id @@ -21,9 +21,9 @@ * @property-read mixed $breezy_session * @property-read \Illuminate\Database\Eloquent\Collection $breezySessions * @property-read int|null $breezy_sessions_count - * @property-read \Illuminate\Database\Eloquent\Collection $followers + * @property-read \Illuminate\Database\Eloquent\Collection $followers * @property-read int|null $followers_count - * @property-read \Illuminate\Database\Eloquent\Collection $followings + * @property-read \Illuminate\Database\Eloquent\Collection $followings * @property-read int|null $followings_count * @property-read \Spatie\MediaLibrary\MediaCollections\Models\Collections\MediaCollection $media * @property-read int|null $media_count @@ -31,13 +31,13 @@ * @property-read int|null $notifications_count * @property-read \Illuminate\Database\Eloquent\Collection $permissions * @property-read int|null $permissions_count - * @property-read \Packages\User\Models\UserProfile|null $profile + * @property-read \Modules\User\Models\UserProfile|null $profile * @property-read \Illuminate\Database\Eloquent\Collection $roles * @property-read int|null $roles_count * @property-read mixed $two_factor_recovery_codes * @property-read mixed $two_factor_secret * - * @method static \Packages\User\Database\Factories\UserFactory factory($count = null, $state = []) + * @method static \Modules\User\Database\Factories\UserFactory factory($count = null, $state = []) * @method static \Illuminate\Database\Eloquent\Builder|User newModelQuery() * @method static \Illuminate\Database\Eloquent\Builder|User newQuery() * @method static \Illuminate\Database\Eloquent\Builder|User onlyTrashed() diff --git a/app/Services/SeoService.php b/app/Services/SeoService.php index 5db2bac..f4bdfc8 100755 --- a/app/Services/SeoService.php +++ b/app/Services/SeoService.php @@ -8,18 +8,18 @@ use Honeystone\Seo\Contracts\BuildsMetadata; use Honeystone\Seo\OpenGraph\ArticleProperties; use Honeystone\Seo\OpenGraph\ProfileProperties; -use Packages\Article\Data\ArticleData; -use Packages\Category\Data\CategoryData; -use Packages\Category\Data\CategoryProfileData; -use Packages\Course\Data\CourseData; -use Packages\Course\Data\CourseLessonData; -use Packages\Entry\Data\EntryData; -use Packages\News\Data\NewsData; -use Packages\Page\Data\PageData; -use Packages\Tag\Data\TagData; -use Packages\Tag\Data\TagProfileData; -use Packages\User\Data\UserData; -use Packages\User\Data\UserProfileData; +use Modules\Article\Data\ArticleData; +use Modules\Category\Data\CategoryData; +use Modules\Category\Data\CategoryProfileData; +use Modules\Course\Data\CourseData; +use Modules\Course\Data\CourseLessonData; +use Modules\Entry\Data\EntryData; +use Modules\News\Data\NewsData; +use Modules\Page\Data\PageData; +use Modules\Tag\Data\TagData; +use Modules\Tag\Data\TagProfileData; +use Modules\User\Data\UserData; +use Modules\User\Data\UserProfileData; use Spatie\SchemaOrg\Schema; class SeoService diff --git a/bootstrap/providers.php b/bootstrap/providers.php index 7d38a54..dc65e0d 100755 --- a/bootstrap/providers.php +++ b/bootstrap/providers.php @@ -2,16 +2,5 @@ return [ App\Providers\AppServiceProvider::class, - App\Providers\Filament\AdminPanelProvider::class, - Packages\User\UserProvider::class, - Packages\Article\ArticleProvider::class, - Packages\Category\CategoryProvider::class, - Packages\News\NewsProvider::class, - Packages\Page\PageProvider::class, - Packages\Recommend\RecommendProvider::class, - Packages\Tag\TagProvider::class, - Packages\Entry\EntryProvider::class, - Packages\React\ReactProvider::class, - Packages\Search\SearchProvider::class, - Packages\Course\CourseProvider::class + App\Providers\Filament\AdminPanelProvider::class ]; diff --git a/composer.json b/composer.json index 5d4edb6..7427576 100755 --- a/composer.json +++ b/composer.json @@ -26,6 +26,7 @@ "league/flysystem-aws-s3-v3": "^3.0", "marcogermani87/filament-cookie-consent": "^1.1", "meilisearch/meilisearch-php": "^1.16", + "nwidart/laravel-modules": "^12.0", "rmsramos/activitylog": "^2.0", "spatie/laravel-activitylog": "^4.10", "spatie/laravel-data": "^4.17", @@ -55,48 +56,12 @@ "psr-4": { "App\\": "app/", "Database\\Factories\\": "database/factories/", - "Database\\Seeders\\": "database/seeders/", - "Packages\\User\\": "packages/User/src/", - "Packages\\User\\Database\\Factories\\": "packages/User/database/factories/", - "Packages\\User\\Database\\Seeders\\": "packages/User/database/seeders/", - "Packages\\Article\\": "packages/Article/src/", - "Packages\\Article\\Database\\Factories\\": "packages/Article/database/factories/", - "Packages\\Article\\Database\\Seeders\\": "packages/Article/database/seeders/", - "Packages\\Category\\": "packages/Category/src/", - "Packages\\Category\\Database\\Factories\\": "packages/Category/database/factories/", - "Packages\\Category\\Database\\Seeders\\": "packages/Category/database/seeders/", - "Packages\\Tag\\": "packages/Tag/src/", - "Packages\\Tag\\Database\\Factories\\": "packages/Tag/database/factories/", - "Packages\\Tag\\Database\\Seeders\\": "packages/Tag/database/seeders/", - "Packages\\Page\\": "packages/Page/src/", - "Packages\\Page\\Database\\Factories\\": "packages/Page/database/factories/", - "Packages\\Page\\Database\\Seeders\\": "packages/Page/database/seeders/", - "Packages\\News\\": "packages/News/src/", - "Packages\\News\\Database\\Factories\\": "packages/News/database/factories/", - "Packages\\News\\Database\\Seeders\\": "packages/News/database/seeders/", - "Packages\\Recommend\\": "packages/Recommend/src/", - "Packages\\Recommend\\Database\\Factories\\": "packages/Recommend/database/factories/", - "Packages\\Recommend\\Database\\Seeders\\": "packages/Recommend/database/seeders/", - "Packages\\Entry\\": "packages/Entry/src/", - "Packages\\Entry\\Database\\Factories\\": "packages/Entry/database/factories/", - "Packages\\Entry\\Database\\Seeders\\": "packages/Entry/database/seeders/", - "Packages\\React\\": "packages/React/src/", - "Packages\\React\\Database\\Factories\\": "packages/React/database/factories/", - "Packages\\React\\Database\\Seeders\\": "packages/React/database/seeders/", - "Packages\\Search\\": "packages/Search/src/", - "Packages\\Search\\Database\\Factories\\": "packages/Search/database/factories/", - "Packages\\Search\\Database\\Seeders\\": "packages/Search/database/seeders/", - "Packages\\Course\\": "packages/Course/src/", - "Packages\\Course\\Database\\Factories\\": "packages/Course/database/factories/", - "Packages\\Course\\Database\\Seeders\\": "packages/Course/database/seeders/" + "Database\\Seeders\\": "database/seeders/" } }, "autoload-dev": { "psr-4": { - "Tests\\": "tests/", - "Packages\\Tag\\Tests\\": "packages/Tag/tests/", - "Packages\\Category\\Tests\\": "packages/Category/tests/", - "Packages\\Article\\Tests\\": "packages/Article/tests/" + "Tests\\": "tests/" } }, "scripts": { @@ -138,6 +103,11 @@ "laravel/telescope", "barryvdh/laravel-debugbar" ] + }, + "merge-plugin": { + "include": [ + "modules/*/composer.json" + ] } }, "config": { @@ -147,7 +117,8 @@ "allow-plugins": { "dealerdirect/phpcodesniffer-composer-installer": true, "pestphp/pest-plugin": true, - "php-http/discovery": true + "php-http/discovery": true, + "wikimedia/composer-merge-plugin": true } }, "minimum-stability": "stable", diff --git a/composer.lock b/composer.lock index aa7e130..a967635 100755 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "ab7da0eeb6abcb645a66ff91c67744b0", + "content-hash": "898c7af4e415c97ef44c8bdb50b17e45", "packages": [ { "name": "amphp/amp", @@ -6340,6 +6340,95 @@ ], "time": "2025-05-08T08:14:37+00:00" }, + { + "name": "nwidart/laravel-modules", + "version": "v12.0.4", + "source": { + "type": "git", + "url": "https://github.com/nWidart/laravel-modules.git", + "reference": "6e1f50de63366206b06ec53bbc823282977ddd06" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nWidart/laravel-modules/zipball/6e1f50de63366206b06ec53bbc823282977ddd06", + "reference": "6e1f50de63366206b06ec53bbc823282977ddd06", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-json": "*", + "ext-simplexml": "*", + "php": ">=8.2", + "wikimedia/composer-merge-plugin": "^2.1" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^v3.52", + "laravel/framework": "^v12.0", + "laravel/pint": "^1.16", + "mockery/mockery": "^1.6", + "orchestra/testbench": "^v10.0", + "phpstan/phpstan": "^2.0", + "phpunit/phpunit": "^11.5.3|^12.0.", + "spatie/phpunit-snapshot-assertions": "^5.0" + }, + "type": "library", + "extra": { + "laravel": { + "aliases": { + "Module": "Nwidart\\Modules\\Facades\\Module" + }, + "providers": [ + "Nwidart\\Modules\\LaravelModulesServiceProvider" + ] + }, + "branch-alias": { + "dev-master": "12.x-dev" + } + }, + "autoload": { + "files": [ + "src/helpers.php" + ], + "psr-4": { + "Nwidart\\Modules\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Widart", + "email": "n.widart@gmail.com", + "homepage": "https://nicolaswidart.com", + "role": "Developer" + } + ], + "description": "Laravel Module management", + "keywords": [ + "laravel", + "module", + "modules", + "nwidart", + "rad" + ], + "support": { + "issues": "https://github.com/nWidart/laravel-modules/issues", + "source": "https://github.com/nWidart/laravel-modules/tree/v12.0.4" + }, + "funding": [ + { + "url": "https://github.com/dcblogdev", + "type": "github" + }, + { + "url": "https://github.com/nwidart", + "type": "github" + } + ], + "time": "2025-06-29T09:23:53+00:00" + }, { "name": "openspout/openspout", "version": "v4.30.1", @@ -12508,6 +12597,62 @@ "source": "https://github.com/webmozarts/assert/tree/1.11.0" }, "time": "2022-06-03T18:03:27+00:00" + }, + { + "name": "wikimedia/composer-merge-plugin", + "version": "v2.1.0", + "source": { + "type": "git", + "url": "https://github.com/wikimedia/composer-merge-plugin.git", + "reference": "a03d426c8e9fb2c9c569d9deeb31a083292788bc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/wikimedia/composer-merge-plugin/zipball/a03d426c8e9fb2c9c569d9deeb31a083292788bc", + "reference": "a03d426c8e9fb2c9c569d9deeb31a083292788bc", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^1.1||^2.0", + "php": ">=7.2.0" + }, + "require-dev": { + "composer/composer": "^1.1||^2.0", + "ext-json": "*", + "mediawiki/mediawiki-phan-config": "0.11.1", + "php-parallel-lint/php-parallel-lint": "~1.3.1", + "phpspec/prophecy": "~1.15.0", + "phpunit/phpunit": "^8.5||^9.0", + "squizlabs/php_codesniffer": "~3.7.1" + }, + "type": "composer-plugin", + "extra": { + "class": "Wikimedia\\Composer\\Merge\\V2\\MergePlugin", + "branch-alias": { + "dev-master": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "Wikimedia\\Composer\\Merge\\V2\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bryan Davis", + "email": "bd808@wikimedia.org" + } + ], + "description": "Composer plugin to merge multiple composer.json files", + "support": { + "issues": "https://github.com/wikimedia/composer-merge-plugin/issues", + "source": "https://github.com/wikimedia/composer-merge-plugin/tree/v2.1.0" + }, + "time": "2023-04-15T19:07:00+00:00" } ], "packages-dev": [ diff --git a/config/ide-helper.php b/config/ide-helper.php index 28f341c..70974c2 100644 --- a/config/ide-helper.php +++ b/config/ide-helper.php @@ -142,7 +142,7 @@ 'model_locations' => [ 'app', - 'packages/*/src/Models', + 'modules/*/app/Models', ], /* diff --git a/config/modules.php b/config/modules.php new file mode 100644 index 0000000..fb5da0c --- /dev/null +++ b/config/modules.php @@ -0,0 +1,285 @@ + 'Modules', + + /* + |-------------------------------------------------------------------------- + | Module Stubs + |-------------------------------------------------------------------------- + | + | Default module stubs. + | + */ + 'stubs' => [ + 'enabled' => true, + 'path' => base_path('stubs/nwidart-stubs'), + 'files' => [ + 'routes/web' => 'routes/web.php', + 'routes/api' => 'routes/api.php', + 'views/index' => 'resources/views/index.blade.php', + 'views/master' => 'resources/views/components/layouts/master.blade.php', + 'scaffold/config' => 'config/config.php', + 'composer' => 'composer.json', + 'assets/js/app' => 'resources/assets/js/app.js', + 'assets/sass/app' => 'resources/assets/sass/app.scss', + 'vite' => 'vite.config.js', + 'package' => 'package.json', + ], + 'replacements' => [ + 'routes/web' => ['LOWER_NAME', 'STUDLY_NAME', 'PLURAL_LOWER_NAME', 'KEBAB_NAME', 'MODULE_NAMESPACE', 'CONTROLLER_NAMESPACE'], + 'routes/api' => ['LOWER_NAME', 'STUDLY_NAME', 'PLURAL_LOWER_NAME', 'KEBAB_NAME', 'MODULE_NAMESPACE', 'CONTROLLER_NAMESPACE'], + 'vite' => ['LOWER_NAME', 'STUDLY_NAME', 'KEBAB_NAME'], + 'json' => ['LOWER_NAME', 'STUDLY_NAME', 'KEBAB_NAME', 'MODULE_NAMESPACE', 'PROVIDER_NAMESPACE'], + 'views/index' => ['LOWER_NAME'], + 'views/master' => ['LOWER_NAME', 'STUDLY_NAME', 'KEBAB_NAME'], + 'scaffold/config' => ['STUDLY_NAME'], + 'scaffold/provider' => ['SEEDERS_PATH' => fn () => database_path('seeders')], + 'route-provider' => ['STUDLY_NAME', 'LOWER_NAME'], + 'composer' => [ + 'LOWER_NAME', + 'STUDLY_NAME', + 'VENDOR', + 'AUTHOR_NAME', + 'AUTHOR_EMAIL', + 'MODULE_NAMESPACE', + 'PROVIDER_NAMESPACE', + 'APP_FOLDER_NAME', + 'APP_NAME' => fn () => config('app.name'), + ], + ], + 'gitkeep' => false, + ], + 'paths' => [ + /* + |-------------------------------------------------------------------------- + | Modules path + |-------------------------------------------------------------------------- + | + | This path is used to save the generated module. + | This path will also be added automatically to the list of scanned folders. + | + */ + 'modules' => base_path('modules'), + + /* + |-------------------------------------------------------------------------- + | Modules assets path + |-------------------------------------------------------------------------- + | + | Here you may update the modules' assets path. + | + */ + 'assets' => public_path('modules'), + + /* + |-------------------------------------------------------------------------- + | The migrations' path + |-------------------------------------------------------------------------- + | + | Where you run the 'module:publish-migration' command, where do you publish the + | the migration files? + | + */ + 'migration' => base_path('database/migrations'), + + /* + |-------------------------------------------------------------------------- + | The app path + |-------------------------------------------------------------------------- + | + | app folder name + | for example can change it to 'src' or 'App' + */ + 'app_folder' => 'app/', + + /* + |-------------------------------------------------------------------------- + | Generator path + |-------------------------------------------------------------------------- + | Customise the paths where the folders will be generated. + | Setting the generate key to false will not generate that folder + */ + 'generator' => [ + // app/ + 'actions' => ['path' => 'app/Actions', 'generate' => false], + 'casts' => ['path' => 'app/Casts', 'generate' => false], + 'channels' => ['path' => 'app/Broadcasting', 'generate' => false], + 'class' => ['path' => 'app/Classes', 'generate' => false], + 'command' => ['path' => 'app/Console', 'generate' => false], + 'component-class' => ['path' => 'app/View/Components', 'generate' => false], + 'emails' => ['path' => 'app/Emails', 'generate' => false], + 'event' => ['path' => 'app/Events', 'generate' => true], + 'enums' => ['path' => 'app/Enums', 'generate' => false], + 'exceptions' => ['path' => 'app/Exceptions', 'generate' => false], + 'jobs' => ['path' => 'app/Jobs', 'generate' => true], + 'helpers' => ['path' => 'app/Helpers', 'generate' => false], + 'interfaces' => ['path' => 'app/Interfaces', 'generate' => false], + 'listener' => ['path' => 'app/Listeners', 'generate' => true], + 'model' => ['path' => 'app/Models', 'generate' => true], + 'notifications' => ['path' => 'app/Notifications', 'generate' => true], + 'observer' => ['path' => 'app/Observers', 'generate' => true], + 'policies' => ['path' => 'app/Policies', 'generate' => true], + 'provider' => ['path' => 'app/Providers', 'generate' => true], + 'repository' => ['path' => 'app/Repositories', 'generate' => false], + 'resource' => ['path' => 'app/Transformers', 'generate' => false], + 'route-provider' => ['path' => 'app/Providers', 'generate' => true], + 'rules' => ['path' => 'app/Rules', 'generate' => false], + 'services' => ['path' => 'app/Services', 'generate' => false], + 'scopes' => ['path' => 'app/Models/Scopes', 'generate' => false], + 'traits' => ['path' => 'app/Traits', 'generate' => false], + + // app/Http/ + 'controller' => ['path' => 'app/Http/Controllers', 'generate' => true], + 'filter' => ['path' => 'app/Http/Middleware', 'generate' => false], + 'request' => ['path' => 'app/Http/Requests', 'generate' => false], + + // config/ + 'config' => ['path' => 'config', 'generate' => true], + + // database/ + 'factory' => ['path' => 'database/factories', 'generate' => true], + 'migration' => ['path' => 'database/migrations', 'generate' => true], + 'seeder' => ['path' => 'database/seeders', 'generate' => true], + + // lang/ + 'lang' => ['path' => 'lang', 'generate' => true], + + // resource/ + 'assets' => ['path' => 'resources/assets', 'generate' => true], + 'component-view' => ['path' => 'resources/views/components', 'generate' => false], + 'views' => ['path' => 'resources/views', 'generate' => false], + + // routes/ + 'routes' => ['path' => 'routes', 'generate' => true], + + // tests/ + 'test-feature' => ['path' => 'tests/Feature', 'generate' => true], + 'test-unit' => ['path' => 'tests/Unit', 'generate' => true], + ], + ], + + /* + |-------------------------------------------------------------------------- + | Auto Discover of Modules + |-------------------------------------------------------------------------- + | + | Here you configure auto discover of module + | This is useful for simplify module providers. + | + */ + 'auto-discover' => [ + /* + |-------------------------------------------------------------------------- + | Migrations + |-------------------------------------------------------------------------- + | + | This option for register migration automatically. + | + */ + 'migrations' => true, + + /* + |-------------------------------------------------------------------------- + | Translations + |-------------------------------------------------------------------------- + | + | This option for register lang file automatically. + | + */ + 'translations' => false, + + ], + + /* + |-------------------------------------------------------------------------- + | Package commands + |-------------------------------------------------------------------------- + | + | Here you can define which commands will be visible and used in your + | application. You can add your own commands to merge section. + | + */ + 'commands' => ConsoleServiceProvider::defaultCommands() + ->merge([ + // New commands go here + ])->toArray(), + + /* + |-------------------------------------------------------------------------- + | Scan Path + |-------------------------------------------------------------------------- + | + | Here you define which folder will be scanned. By default will scan vendor + | directory. This is useful if you host the package in packagist website. + | + */ + 'scan' => [ + 'enabled' => false, + 'paths' => [ + base_path('vendor/*/*'), + ], + ], + + /* + |-------------------------------------------------------------------------- + | Composer File Template + |-------------------------------------------------------------------------- + | + | Here is the config for the composer.json file, generated by this package + | + */ + 'composer' => [ + 'vendor' => env('MODULE_VENDOR', '4byte'), + 'author' => [ + 'name' => env('MODULE_AUTHOR_NAME', '4Byte'), + 'email' => env('MODULE_AUTHOR_EMAIL', 'info@4byte.dev'), + ], + 'composer-output' => false, + ], + + /* + |-------------------------------------------------------------------------- + | Choose what laravel-modules will register as custom namespaces. + | Setting one to false will require you to register that part + | in your own Service Provider class. + |-------------------------------------------------------------------------- + */ + 'register' => [ + 'translations' => true, + /** + * load files on boot or register method + */ + 'files' => 'register', + ], + + /* + |-------------------------------------------------------------------------- + | Activators + |-------------------------------------------------------------------------- + | + | You can define new types of activators here, file, database, etc. The only + | required parameter is 'class'. + | The file activator will store the activation status in storage/installed_modules + */ + 'activators' => [ + 'file' => [ + 'class' => FileActivator::class, + 'statuses-file' => base_path('modules_statuses.json'), + ], + ], + + 'activator' => 'file', +]; diff --git a/database/seeders/DatabaseSeeder.php b/database/seeders/DatabaseSeeder.php index 93cd9c1..7b8d448 100755 --- a/database/seeders/DatabaseSeeder.php +++ b/database/seeders/DatabaseSeeder.php @@ -3,7 +3,7 @@ namespace Database\Seeders; use Illuminate\Database\Seeder; -use Packages\User\Database\Seeders\UserSeeder; +use Modules\User\Database\Seeders\UserSeeder; class DatabaseSeeder extends Seeder { diff --git a/lang/en.json b/lang/en.json index 1321c9b..cef75e0 100644 --- a/lang/en.json +++ b/lang/en.json @@ -4,8 +4,5 @@ "Mail Verification": "Mail Verification", "Reset Password": "Reset Password", "Create Article": "Create Article", - "Edit Article": "Edit Article", - "You have a new follower!": "You have a new follower!", - "user_follow": "\":username\" has started following you.", - "View Profile": "View Profile" + "Edit Article": "Edit Article" } \ No newline at end of file diff --git a/lang/tr.json b/lang/tr.json index 8bc216d..4d4a9a1 100644 --- a/lang/tr.json +++ b/lang/tr.json @@ -4,8 +4,5 @@ "Mail Verification": "Mail Doğrulama", "Reset Password": "Şifreni Sıfırla", "Create Article": "Makale Yaz", - "Edit Article": "Makale Düzenle", - "You have a new follower!": "Yeni bir takipçin var!", - "user_follow": "\":username\" seni takip etmeye başladı.", - "View Profile": "Profili Görüntüle" + "Edit Article": "Makale Düzenle" } \ No newline at end of file diff --git a/packages/Article/src/Console/Commands/ScheduleArticleCommand.php b/modules/Article/app/Console/Commands/ScheduleArticleCommand.php similarity index 86% rename from packages/Article/src/Console/Commands/ScheduleArticleCommand.php rename to modules/Article/app/Console/Commands/ScheduleArticleCommand.php index af53746..72845f8 100755 --- a/packages/Article/src/Console/Commands/ScheduleArticleCommand.php +++ b/modules/Article/app/Console/Commands/ScheduleArticleCommand.php @@ -1,10 +1,10 @@ $categories * @property-read int|null $categories_count - * @property-read \Illuminate\Database\Eloquent\Collection $comments + * @property-read \Illuminate\Database\Eloquent\Collection $comments * @property-read int|null $comments_count - * @property-read \Illuminate\Database\Eloquent\Collection $dislikes + * @property-read \Illuminate\Database\Eloquent\Collection $dislikes * @property-read int|null $dislikes_count - * @property-read \Illuminate\Database\Eloquent\Collection $likes + * @property-read \Illuminate\Database\Eloquent\Collection $likes * @property-read int|null $likes_count * @property-read \Spatie\MediaLibrary\MediaCollections\Models\Collections\MediaCollection $media * @property-read int|null $media_count - * @property-read \Illuminate\Database\Eloquent\Collection $saves + * @property-read \Illuminate\Database\Eloquent\Collection $saves * @property-read int|null $saves_count * @property-read \Illuminate\Database\Eloquent\Collection $tags * @property-read int|null $tags_count * @property-read User $user * - * @method static \Packages\Article\Database\Factories\ArticleFactory factory($count = null, $state = []) + * @method static \Modules\Article\Database\Factories\ArticleFactory factory($count = null, $state = []) * @method static \Illuminate\Database\Eloquent\Builder|Article newModelQuery() * @method static \Illuminate\Database\Eloquent\Builder|Article newQuery() * @method static \Illuminate\Database\Eloquent\Builder|Article query() @@ -75,7 +75,7 @@ class Article extends Model implements HasMedia use HasComments; use HasDislikes; - /** @use HasFactory<\Packages\Article\Database\Factories\ArticleFactory> */ + /** @use HasFactory<\Modules\Article\Database\Factories\ArticleFactory> */ use HasFactory; use HasLikes; diff --git a/packages/Article/src/Notifications/ArticlePublishedNotification.php b/modules/Article/app/Notifications/ArticlePublishedNotification.php similarity index 94% rename from packages/Article/src/Notifications/ArticlePublishedNotification.php rename to modules/Article/app/Notifications/ArticlePublishedNotification.php index 5c9b7a1..47e21ea 100755 --- a/packages/Article/src/Notifications/ArticlePublishedNotification.php +++ b/modules/Article/app/Notifications/ArticlePublishedNotification.php @@ -1,12 +1,12 @@ status != "PUBLISHED") return; + if ($article->status != "PUBLISHED") { + return; + } $gorseItem = new GorseItem( 'article:' . $article->id, ['article', "user:{$article->user_id}"], diff --git a/packages/Article/src/Policies/ArticlePolicy.php b/modules/Article/app/Policies/ArticlePolicy.php similarity index 97% rename from packages/Article/src/Policies/ArticlePolicy.php rename to modules/Article/app/Policies/ArticlePolicy.php index 7cddf09..462b8f9 100755 --- a/packages/Article/src/Policies/ArticlePolicy.php +++ b/modules/Article/app/Policies/ArticlePolicy.php @@ -1,10 +1,10 @@ registerPolicies(); + $this->registerObservers(); + $this->registerCommands(); + $this->registerTranslations(); + $this->registerPublishableResources(); + $this->loadMigrationsFrom(module_path($this->name, 'database/migrations')); + $this->loadFactoriesFrom(module_path($this->name, 'database/factories')); + $this->registerSearch(); + $this->registerReact(); + $this->registerFeed(); + } + + /** + * Register the service provider. + */ + public function register(): void + { + $this->app->register(EventServiceProvider::class); + $this->app->register(RouteServiceProvider::class); + } + + /** + * Get the services provided by the provider. + * + * @return array + */ + public function provides(): array + { + return [ + ArticleService::class, + ]; + } + + /** + * Register model policies. + */ + protected function registerPolicies(): void + { + Gate::policy(Article::class, ArticlePolicy::class); + } + + /** + * Register model observers. + */ + protected function registerObservers(): void + { + Article::observe(ArticleObserver::class); + } + + /** + * Register commands in the format of Command::class. + */ + protected function registerCommands(): void + { + $this->commands([ + ScheduleArticleCommand::class, + ]); + } + + /** + * Register translations. + */ + protected function registerTranslations(): void + { + $langPath = resource_path('lang/modules/' . $this->nameLower); + + if (is_dir($langPath)) { + $this->loadTranslationsFrom($langPath, $this->nameLower); + $this->loadJsonTranslationsFrom($langPath); + } else { + $this->loadTranslationsFrom(module_path($this->name, 'lang'), $this->nameLower); + $this->loadJsonTranslationsFrom(module_path($this->name, 'lang')); + } + } + + /** + * Register console publishes. + */ + protected function registerPublishableResources(): void + { + if ($this->app->runningInConsole()) { + $this->publishes([ + module_path($this->name, 'database/seeders') => database_path("seeders/{$this->name}"), + module_path($this->name, 'database/migrations') => database_path('migrations/'), + ], $this->nameLower); + } + } + + /** + * Register to React for make it searchable. + */ + protected function registerSearch(): void + { + SearchService::registerHandler( + index: 'articles', + callback: fn ($hit) => app(ArticleService::class)->getData($hit['id']), + searchableAttributes: ['title'], + filterableAttributes: ['id'], + sortableAttributes: ['updated_at'] + ); + } + + /** + * Register to React. + */ + protected function registerReact(): void + { + ReactService::registerHandler( + name: $this->nameLower, + class: Article::class, + callback: fn ($slug) => app(ArticleService::class)->getId($slug) + ); + } + + /** + * Register to Feed. + */ + protected function registerFeed(): void + { + FeedService::registerHandler( + name: $this->nameLower, + isFilter: false, + callback: fn ($slug) => app(ArticleService::class)->getData($slug) + ); + } +} diff --git a/modules/Article/app/Providers/EventServiceProvider.php b/modules/Article/app/Providers/EventServiceProvider.php new file mode 100644 index 0000000..4a673c2 --- /dev/null +++ b/modules/Article/app/Providers/EventServiceProvider.php @@ -0,0 +1,35 @@ +> + */ + protected $listen = [ + ArticlePublishedEvent::class => [ + ArticlePublishedListener::class, + ], + ]; + + /** + * Indicates if events should be discovered. + * + * @var bool + */ + protected static $shouldDiscoverEvents = true; + + /** + * Configure the proper event listeners for email verification. + */ + protected function configureEmailVerification(): void + { + } +} diff --git a/modules/Article/app/Providers/RouteServiceProvider.php b/modules/Article/app/Providers/RouteServiceProvider.php new file mode 100644 index 0000000..89ed6bd --- /dev/null +++ b/modules/Article/app/Providers/RouteServiceProvider.php @@ -0,0 +1,49 @@ +mapWebRoutes(); + $this->mapApiRoutes(); + } + + /** + * Define the "web" routes for the application. + * + * These routes all receive session state, CSRF protection, etc. + */ + protected function mapWebRoutes(): void + { + Route::middleware('web') + ->prefix('makale') + ->name("{$this->nameLower}.") + ->group(module_path($this->name, '/routes/web.php')); + } + + /** + * Define the "api" routes for the application. + * + * These routes are typically stateless. + */ + protected function mapApiRoutes(): void + { + Route::middleware(['web', 'auth', BatchLogsActivity::class]) + ->prefix('api/article') + ->name('api.article.') + ->group(module_path($this->name, '/routes/api.php')); + } +} diff --git a/packages/Article/src/Services/ArticleService.php b/modules/Article/app/Services/ArticleService.php similarity index 90% rename from packages/Article/src/Services/ArticleService.php rename to modules/Article/app/Services/ArticleService.php index c4e2f69..fea4d13 100755 --- a/packages/Article/src/Services/ArticleService.php +++ b/modules/Article/app/Services/ArticleService.php @@ -1,11 +1,11 @@ + * @extends \Illuminate\Database\Eloquent\Factories\Factory<\Modules\Article\Models\Article> */ class ArticleFactory extends Factory { diff --git a/packages/Article/database/migrations/2025_08_15_144713_create_articles_table.php b/modules/Article/database/migrations/2025_08_15_144713_create_articles_table.php similarity index 100% rename from packages/Article/database/migrations/2025_08_15_144713_create_articles_table.php rename to modules/Article/database/migrations/2025_08_15_144713_create_articles_table.php diff --git a/packages/Article/database/migrations/2025_08_15_145320_create_article_pivot_table.php b/modules/Article/database/migrations/2025_08_15_145320_create_article_pivot_table.php similarity index 100% rename from packages/Article/database/migrations/2025_08_15_145320_create_article_pivot_table.php rename to modules/Article/database/migrations/2025_08_15_145320_create_article_pivot_table.php diff --git a/packages/Article/database/seeders/ArticleSeeder.php b/modules/Article/database/seeders/ArticleSeeder.php similarity index 66% rename from packages/Article/database/seeders/ArticleSeeder.php rename to modules/Article/database/seeders/ArticleSeeder.php index 3adecb0..dc99624 100755 --- a/packages/Article/database/seeders/ArticleSeeder.php +++ b/modules/Article/database/seeders/ArticleSeeder.php @@ -1,9 +1,9 @@ name('crud.') + ->controller(ArticleCrudController::class) + ->group(function () { + Route::post('/create', 'create') + ->name('create') + ->can('create', Article::class); + + Route::post('/{article:slug}/edit', 'edit') + ->name('edit') + ->can('update,article'); + }); diff --git a/modules/Article/routes/web.php b/modules/Article/routes/web.php new file mode 100644 index 0000000..0bee9fd --- /dev/null +++ b/modules/Article/routes/web.php @@ -0,0 +1,15 @@ +middleware('auth')->name('crud.')->group(function () { + Route::get('/yaz', 'createView')->name('create.view')->can('create', Article::class); + Route::get('/{article:slug}/duzenle', 'editView')->name('edit.view')->can('update,article'); +}); + +Route::controller(ArticleController::class)->group(function () { + Route::get('/{slug}', 'view')->name('view'); +}); diff --git a/packages/Article/tests/Feature/Console/Commands/ScheduleArticleCommandTest.php b/modules/Article/tests/Feature/Console/Commands/ScheduleArticleCommandTest.php similarity index 94% rename from packages/Article/tests/Feature/Console/Commands/ScheduleArticleCommandTest.php rename to modules/Article/tests/Feature/Console/Commands/ScheduleArticleCommandTest.php index d6df9d4..3430db7 100644 --- a/packages/Article/tests/Feature/Console/Commands/ScheduleArticleCommandTest.php +++ b/modules/Article/tests/Feature/Console/Commands/ScheduleArticleCommandTest.php @@ -1,11 +1,11 @@ assertTrue(Cache::has("article:{$article->id}")); } - public function test_it_can_get_article_id_by_slug(): void + public function test_it_can_get_article_id_by_slug(): void { $article = Article::factory()->create([ 'status' => 'PUBLISHED', diff --git a/modules/Article/vite.config.js b/modules/Article/vite.config.js new file mode 100644 index 0000000..d1c3ad7 --- /dev/null +++ b/modules/Article/vite.config.js @@ -0,0 +1,57 @@ +import { defineConfig } from 'vite'; +import laravel from 'laravel-vite-plugin'; +import { readdirSync, statSync } from 'fs'; +import { join,relative,dirname } from 'path'; +import { fileURLToPath } from 'url'; + +export default defineConfig({ + build: { + outDir: '../../public/build-article', + emptyOutDir: true, + manifest: true, + }, + plugins: [ + laravel({ + publicDirectory: '../../public', + buildDirectory: 'build-article', + input: [ + __dirname + '/resources/assets/sass/app.scss', + __dirname + '/resources/assets/js/app.js' + ], + refresh: true, + }), + ], +}); +// Scen all resources for assets file. Return array +//function getFilePaths(dir) { +// const filePaths = []; +// +// function walkDirectory(currentPath) { +// const files = readdirSync(currentPath); +// for (const file of files) { +// const filePath = join(currentPath, file); +// const stats = statSync(filePath); +// if (stats.isFile() && !file.startsWith('.')) { +// const relativePath = 'Modules/Article/'+relative(__dirname, filePath); +// filePaths.push(relativePath); +// } else if (stats.isDirectory()) { +// walkDirectory(filePath); +// } +// } +// } +// +// walkDirectory(dir); +// return filePaths; +//} + +//const __filename = fileURLToPath(import.meta.url); +//const __dirname = dirname(__filename); + +//const assetsDir = join(__dirname, 'resources/assets'); +//export const paths = getFilePaths(assetsDir); + + +//export const paths = [ +// 'Modules/Article/resources/assets/sass/app.scss', +// 'Modules/Article/resources/assets/js/app.js', +//]; diff --git a/packages/Category/src/Data/CategoryData.php b/modules/Category/app/Data/CategoryData.php similarity index 91% rename from packages/Category/src/Data/CategoryData.php rename to modules/Category/app/Data/CategoryData.php index f2d4ceb..46b8c9d 100755 --- a/packages/Category/src/Data/CategoryData.php +++ b/modules/Category/app/Data/CategoryData.php @@ -1,9 +1,9 @@ $articles * @property-read int|null $articles_count - * @property-read \Illuminate\Database\Eloquent\Collection $followers + * @property-read \Illuminate\Database\Eloquent\Collection $followers * @property-read int|null $followers_count * @property-read CategoryProfile|null $profile * - * @method static \Packages\Category\Database\Factories\CategoryFactory factory($count = null, $state = []) + * @method static \Modules\Category\Database\Factories\CategoryFactory factory($count = null, $state = []) * @method static \Illuminate\Database\Eloquent\Builder|Category newModelQuery() * @method static \Illuminate\Database\Eloquent\Builder|Category newQuery() * @method static \Illuminate\Database\Eloquent\Builder|Category query() @@ -41,7 +41,7 @@ */ class Category extends Model { - /** @use HasFactory<\Packages\Category\Database\Factories\CategoryFactory> */ + /** @use HasFactory<\Modules\Category\Database\Factories\CategoryFactory> */ use HasFactory; use HasFollowers; diff --git a/packages/Category/src/Models/CategoryProfile.php b/modules/Category/app/Models/CategoryProfile.php similarity index 89% rename from packages/Category/src/Models/CategoryProfile.php rename to modules/Category/app/Models/CategoryProfile.php index d7a1e3a..372fc4b 100755 --- a/packages/Category/src/Models/CategoryProfile.php +++ b/modules/Category/app/Models/CategoryProfile.php @@ -1,11 +1,11 @@ |CategoryProfile newModelQuery() * @method static \Illuminate\Database\Eloquent\Builder|CategoryProfile newQuery() * @method static \Illuminate\Database\Eloquent\Builder|CategoryProfile query() @@ -36,7 +36,7 @@ */ class CategoryProfile extends Model { - /** @use HasFactory<\Packages\Category\Database\Factories\CategoryProfileFactory> */ + /** @use HasFactory<\Modules\Category\Database\Factories\CategoryProfileFactory> */ use HasFactory; use LogsActivity; diff --git a/packages/Category/src/Observers/CategoryObserver.php b/modules/Category/app/Observers/CategoryObserver.php similarity index 91% rename from packages/Category/src/Observers/CategoryObserver.php rename to modules/Category/app/Observers/CategoryObserver.php index 79fe28f..c6af863 100755 --- a/packages/Category/src/Observers/CategoryObserver.php +++ b/modules/Category/app/Observers/CategoryObserver.php @@ -1,9 +1,9 @@ registerPolicies(); + $this->registerObservers(); + $this->loadMigrationsFrom(module_path($this->name, 'database/migrations')); + $this->loadFactoriesFrom(module_path($this->name, 'database/factories')); + $this->registerPublishableResources(); + } + + /** + * Register the service provider. + */ + public function register(): void + { + $this->app->register(RouteServiceProvider::class); + } + + /** + * Get the services provided by the provider. + * + * @return array + */ + public function provides(): array + { + return [ + CategoryService::class, + ]; + } + + /** + * Register model policies. + */ + protected function registerPolicies(): void + { + Gate::policy(Category::class, CategoryPolicy::class); + } + + /** + * Register model observers. + */ + protected function registerObservers(): void + { + Category::observe(CategoryObserver::class); + } + + /** + * Register console publishes. + */ + protected function registerPublishableResources(): void + { + if ($this->app->runningInConsole()) { + $this->publishes([ + module_path($this->name, 'database/seeders') => database_path("seeders/{$this->name}"), + module_path($this->name, 'database/migrations') => database_path('migrations/'), + ], $this->nameLower); + } + } + + /** + * Register to React. + */ + protected function registerReact(): void + { + ReactService::registerHandler( + name: $this->nameLower, + class: Category::class, + callback: fn ($slug) => app(CategoryService::class)->getId($slug) + ); + } + + /** + * Register to Feed. + */ + protected function registerFeed(): void + { + FeedService::registerHandler( + name: $this->nameLower, + isFilter: true, + callback: fn ($slug) => app(CategoryService::class)->getId($slug) + ); + } +} diff --git a/modules/Category/app/Providers/RouteServiceProvider.php b/modules/Category/app/Providers/RouteServiceProvider.php new file mode 100644 index 0000000..1dd0811 --- /dev/null +++ b/modules/Category/app/Providers/RouteServiceProvider.php @@ -0,0 +1,34 @@ +mapWebRoutes(); + } + + /** + * Define the "web" routes for the application. + * + * These routes all receive session state, CSRF protection, etc. + */ + protected function mapWebRoutes(): void + { + Route::middleware('web') + ->prefix('kategori') + ->name("{$this->nameLower}.") + ->group(module_path($this->name, '/routes/web.php')); + } +} diff --git a/packages/Category/src/Services/CategoryService.php b/modules/Category/app/Services/CategoryService.php similarity index 90% rename from packages/Category/src/Services/CategoryService.php rename to modules/Category/app/Services/CategoryService.php index 1fbe3e5..6a2e161 100755 --- a/packages/Category/src/Services/CategoryService.php +++ b/modules/Category/app/Services/CategoryService.php @@ -1,17 +1,17 @@ + * @extends \Illuminate\Database\Eloquent\Factories\Factory<\Modules\Category\Models\Category> */ class CategoryFactory extends Factory { diff --git a/packages/Category/database/factories/CategoryProfileFactory.php b/modules/Category/database/factories/CategoryProfileFactory.php similarity index 68% rename from packages/Category/database/factories/CategoryProfileFactory.php rename to modules/Category/database/factories/CategoryProfileFactory.php index 8104b64..b7a1f8a 100755 --- a/packages/Category/database/factories/CategoryProfileFactory.php +++ b/modules/Category/database/factories/CategoryProfileFactory.php @@ -1,13 +1,13 @@ + * @extends \Illuminate\Database\Eloquent\Factories\Factory<\Modules\Category\Models\CategoryProfile> */ class CategoryProfileFactory extends Factory { diff --git a/packages/Category/database/migrations/2025_08_15_145151_create_categories_table.php b/modules/Category/database/migrations/2025_08_15_145151_create_categories_table.php similarity index 100% rename from packages/Category/database/migrations/2025_08_15_145151_create_categories_table.php rename to modules/Category/database/migrations/2025_08_15_145151_create_categories_table.php diff --git a/packages/Category/database/migrations/2025_08_25_103855_create_category_profiles_table.php b/modules/Category/database/migrations/2025_08_25_103855_create_category_profiles_table.php similarity index 100% rename from packages/Category/database/migrations/2025_08_25_103855_create_category_profiles_table.php rename to modules/Category/database/migrations/2025_08_25_103855_create_category_profiles_table.php diff --git a/packages/Category/database/seeders/CategorySeeder.php b/modules/Category/database/seeders/CategorySeeder.php similarity index 67% rename from packages/Category/database/seeders/CategorySeeder.php rename to modules/Category/database/seeders/CategorySeeder.php index b612f55..513a776 100755 --- a/packages/Category/database/seeders/CategorySeeder.php +++ b/modules/Category/database/seeders/CategorySeeder.php @@ -1,10 +1,10 @@ group(function () { + Route::get('/{slug}', 'view')->name('view'); +}); diff --git a/packages/Category/tests/Feature/Database/Seeders/CategorySeederTest.php b/modules/Category/tests/Feature/Database/Seeders/CategorySeederTest.php similarity index 78% rename from packages/Category/tests/Feature/Database/Seeders/CategorySeederTest.php rename to modules/Category/tests/Feature/Database/Seeders/CategorySeederTest.php index edafe22..e54d1d5 100644 --- a/packages/Category/tests/Feature/Database/Seeders/CategorySeederTest.php +++ b/modules/Category/tests/Feature/Database/Seeders/CategorySeederTest.php @@ -1,11 +1,11 @@ $chapters * @property-read int|null $chapters_count - * @property-read \Illuminate\Database\Eloquent\Collection $comments + * @property-read \Illuminate\Database\Eloquent\Collection $comments * @property-read int|null $comments_count - * @property-read \Illuminate\Database\Eloquent\Collection $dislikes + * @property-read \Illuminate\Database\Eloquent\Collection $dislikes * @property-read int|null $dislikes_count * @property-read \Illuminate\Database\Eloquent\Collection $lessons * @property-read int|null $lessons_count - * @property-read \Illuminate\Database\Eloquent\Collection $likes + * @property-read \Illuminate\Database\Eloquent\Collection $likes * @property-read int|null $likes_count * @property-read \Spatie\MediaLibrary\MediaCollections\Models\Collections\MediaCollection $media * @property-read int|null $media_count - * @property-read \Illuminate\Database\Eloquent\Collection $saves + * @property-read \Illuminate\Database\Eloquent\Collection $saves * @property-read int|null $saves_count * @property-read \Illuminate\Database\Eloquent\Collection $tags * @property-read int|null $tags_count * @property-read User $user * - * @method static \Packages\Course\Database\Factories\CourseFactory factory($count = null, $state = []) + * @method static \Modules\Course\Database\Factories\CourseFactory factory($count = null, $state = []) * @method static \Illuminate\Database\Eloquent\Builder|Course newModelQuery() * @method static \Illuminate\Database\Eloquent\Builder|Course newQuery() * @method static \Illuminate\Database\Eloquent\Builder|Course query() @@ -79,7 +79,7 @@ class Course extends Model implements HasMedia use HasComments; use HasDislikes; - /** @use HasFactory<\Packages\Course\Database\Factories\CourseFactory> */ + /** @use HasFactory<\Modules\Course\Database\Factories\CourseFactory> */ use HasFactory; use HasLikes; diff --git a/packages/Course/src/Models/CourseChapter.php b/modules/Course/app/Models/CourseChapter.php similarity index 90% rename from packages/Course/src/Models/CourseChapter.php rename to modules/Course/app/Models/CourseChapter.php index 9d414a1..d24cc53 100644 --- a/packages/Course/src/Models/CourseChapter.php +++ b/modules/Course/app/Models/CourseChapter.php @@ -1,12 +1,12 @@ $lessons * @property-read int|null $lessons_count * - * @method static \Packages\Course\Database\Factories\CourseChapterFactory factory($count = null, $state = []) + * @method static \Modules\Course\Database\Factories\CourseChapterFactory factory($count = null, $state = []) * @method static \Illuminate\Database\Eloquent\Builder|CourseChapter newModelQuery() * @method static \Illuminate\Database\Eloquent\Builder|CourseChapter newQuery() * @method static \Illuminate\Database\Eloquent\Builder|CourseChapter query() @@ -37,7 +37,7 @@ */ class CourseChapter extends Model { - /** @use HasFactory<\Packages\Course\Database\Factories\CourseChapterFactory> */ + /** @use HasFactory<\Modules\Course\Database\Factories\CourseChapterFactory> */ use HasFactory; use LogsActivity; diff --git a/packages/Course/src/Models/CourseLesson.php b/modules/Course/app/Models/CourseLesson.php similarity index 92% rename from packages/Course/src/Models/CourseLesson.php rename to modules/Course/app/Models/CourseLesson.php index ddb3e4b..a1c1954 100644 --- a/packages/Course/src/Models/CourseLesson.php +++ b/modules/Course/app/Models/CourseLesson.php @@ -1,15 +1,15 @@ $activities * @property-read int|null $activities_count * @property-read CourseChapter $chapter - * @property-read \Illuminate\Database\Eloquent\Collection $comments + * @property-read \Illuminate\Database\Eloquent\Collection $comments * @property-read int|null $comments_count * @property-read \Spatie\MediaLibrary\MediaCollections\Models\Collections\MediaCollection $media * @property-read int|null $media_count - * @property-read \Illuminate\Database\Eloquent\Collection $saves + * @property-read \Illuminate\Database\Eloquent\Collection $saves * @property-read int|null $saves_count * @property-read User $user * - * @method static \Packages\Course\Database\Factories\CourseLessonFactory factory($count = null, $state = []) + * @method static \Modules\Course\Database\Factories\CourseLessonFactory factory($count = null, $state = []) * @method static \Illuminate\Database\Eloquent\Builder|CourseLesson newModelQuery() * @method static \Illuminate\Database\Eloquent\Builder|CourseLesson newQuery() * @method static \Illuminate\Database\Eloquent\Builder|CourseLesson query() @@ -62,7 +62,7 @@ class CourseLesson extends Model implements HasMedia { use HasComments; - /** @use HasFactory<\Packages\Course\Database\Factories\CourseLessonFactory> */ + /** @use HasFactory<\Modules\Course\Database\Factories\CourseLessonFactory> */ use HasFactory; use HasSaves; diff --git a/packages/Course/src/Notifications/CoursePublishedNotification.php b/modules/Course/app/Notifications/CoursePublishedNotification.php similarity index 94% rename from packages/Course/src/Notifications/CoursePublishedNotification.php rename to modules/Course/app/Notifications/CoursePublishedNotification.php index ddd9b5c..422a666 100755 --- a/packages/Course/src/Notifications/CoursePublishedNotification.php +++ b/modules/Course/app/Notifications/CoursePublishedNotification.php @@ -1,12 +1,12 @@ status != "PUBLISHED") return; + if ($course->status != "PUBLISHED") { + return; + } $gorseItem = new GorseItem( 'course:' . $course->id, ['course', "user:{$course->user_id}"], diff --git a/packages/Course/src/Policies/CourseChapterPolicy.php b/modules/Course/app/Policies/CourseChapterPolicy.php similarity index 97% rename from packages/Course/src/Policies/CourseChapterPolicy.php rename to modules/Course/app/Policies/CourseChapterPolicy.php index fcef7d0..274a92c 100755 --- a/packages/Course/src/Policies/CourseChapterPolicy.php +++ b/modules/Course/app/Policies/CourseChapterPolicy.php @@ -1,10 +1,10 @@ registerPolicies(); + $this->registerObservers(); + $this->registerCommands(); + $this->registerTranslations(); + $this->registerPublishableResources(); + $this->loadMigrationsFrom(module_path($this->name, 'database/migrations')); + $this->loadFactoriesFrom(module_path($this->name, 'database/factories')); + $this->registerSearch(); + $this->registerReact(); + $this->registerFeed(); + } + + /** + * Register the service provider. + */ + public function register(): void + { + $this->app->register(EventServiceProvider::class); + $this->app->register(RouteServiceProvider::class); + } + + /** + * Register translations. + */ + public function registerTranslations(): void + { + $langPath = resource_path('lang/modules/' . $this->nameLower); + + if (is_dir($langPath)) { + $this->loadTranslationsFrom($langPath, $this->nameLower); + $this->loadJsonTranslationsFrom($langPath); + } else { + $this->loadTranslationsFrom(module_path($this->name, 'lang'), $this->nameLower); + $this->loadJsonTranslationsFrom(module_path($this->name, 'lang')); + } + } + + /** + * Get the services provided by the provider. + * + * @return array + */ + public function provides(): array + { + return [ + CourseService::class, + ]; + } + + /** + * Register model policies. + */ + protected function registerPolicies(): void + { + Gate::policy(Course::class, CoursePolicy::class); + Gate::policy(CourseChapter::class, CourseChapterPolicy::class); + Gate::policy(CourseLesson::class, CourseLessonPolicy::class); + } + + /** + * Register model observers. + */ + protected function registerObservers(): void + { + Course::observe(CourseObserver::class); + CourseLesson::observe(CourseLessonObserver::class); + CourseChapter::observe(CourseChapterObserver::class); + } + + /** + * Register commands in the format of Command::class. + */ + protected function registerCommands(): void + { + $this->commands([ + ScheduleCourseCommand::class, + ScheduleLessonCommand::class, + ]); + } + + /** + * Register console publishes. + */ + protected function registerPublishableResources(): void + { + if ($this->app->runningInConsole()) { + $this->publishes([ + module_path($this->name, 'database/seeders') => database_path("seeders/{$this->name}"), + module_path($this->name, 'database/migrations') => database_path('migrations/'), + ], $this->nameLower); + } + } + + /** + * Register to React for make it searchable. + */ + protected function registerSearch(): void + { + SearchService::registerHandler( + index: 'courses', + callback: fn ($hit) => app(CourseService::class)->getData($hit['id']), + searchableAttributes: ['title'], + filterableAttributes: ['id'], + sortableAttributes: ['updated_at'] + ); + SearchService::registerHandler( + index: 'lessons', + callback: fn ($hit) => app(CourseService::class)->getLessonByChapter($hit['chapter_id'], $hit['id']), + searchableAttributes: ['title'], + filterableAttributes: ['id', 'chapter_id'], + sortableAttributes: ['updated_at'] + ); + } + + /** + * Register to React. + */ + protected function registerReact(): void + { + ReactService::registerHandler( + name: $this->nameLower, + class: Course::class, + callback: fn ($slug) => app(CourseService::class)->getId($slug) + ); + } + + /** + * Register to Feed. + */ + protected function registerFeed(): void + { + FeedService::registerHandler( + name: $this->nameLower, + isFilter: false, + callback: fn ($slug) => app(CourseService::class)->getData($slug) + ); + } +} diff --git a/modules/Course/app/Providers/EventServiceProvider.php b/modules/Course/app/Providers/EventServiceProvider.php new file mode 100644 index 0000000..381c7eb --- /dev/null +++ b/modules/Course/app/Providers/EventServiceProvider.php @@ -0,0 +1,40 @@ +> + */ + protected $listen = [ + CoursePublishedEvent::class => [ + CoursePublishedListener::class, + ], + LessonPublishedEvent::class => [ + LessonPublishedListener::class, + ], + ]; + + /** + * Indicates if events should be discovered. + * + * @var bool + */ + protected static $shouldDiscoverEvents = true; + + /** + * Configure the proper event listeners for email verification. + */ + protected function configureEmailVerification(): void + { + } +} diff --git a/modules/Course/app/Providers/RouteServiceProvider.php b/modules/Course/app/Providers/RouteServiceProvider.php new file mode 100644 index 0000000..6422612 --- /dev/null +++ b/modules/Course/app/Providers/RouteServiceProvider.php @@ -0,0 +1,34 @@ +mapWebRoutes(); + } + + /** + * Define the "web" routes for the application. + * + * These routes all receive session state, CSRF protection, etc. + */ + protected function mapWebRoutes(): void + { + Route::middleware('web') + ->prefix('egitim') + ->name("{$this->nameLower}.") + ->group(module_path($this->name, '/routes/web.php')); + } +} diff --git a/packages/Course/src/Services/CourseService.php b/modules/Course/app/Services/CourseService.php similarity index 94% rename from packages/Course/src/Services/CourseService.php rename to modules/Course/app/Services/CourseService.php index 6e74661..ade69e8 100644 --- a/packages/Course/src/Services/CourseService.php +++ b/modules/Course/app/Services/CourseService.php @@ -1,14 +1,14 @@ + * @extends \Illuminate\Database\Eloquent\Factories\Factory<\Modules\Course\Models\CourseChapter> */ class CourseChapterFactory extends Factory { diff --git a/packages/Course/database/factories/CourseFactory.php b/modules/Course/database/factories/CourseFactory.php similarity index 87% rename from packages/Course/database/factories/CourseFactory.php rename to modules/Course/database/factories/CourseFactory.php index 64ee455..7fdc1ca 100644 --- a/packages/Course/database/factories/CourseFactory.php +++ b/modules/Course/database/factories/CourseFactory.php @@ -1,14 +1,14 @@ + * @extends \Illuminate\Database\Eloquent\Factories\Factory<\Modules\Course\Models\Course> */ class CourseFactory extends Factory { diff --git a/packages/Course/database/factories/CourseLessonFactory.php b/modules/Course/database/factories/CourseLessonFactory.php similarity index 79% rename from packages/Course/database/factories/CourseLessonFactory.php rename to modules/Course/database/factories/CourseLessonFactory.php index 4c35a6b..4bac0ab 100644 --- a/packages/Course/database/factories/CourseLessonFactory.php +++ b/modules/Course/database/factories/CourseLessonFactory.php @@ -1,15 +1,15 @@ + * @extends \Illuminate\Database\Eloquent\Factories\Factory<\Modules\Course\Models\CourseLesson> */ class CourseLessonFactory extends Factory { diff --git a/packages/Course/database/migrations/2025_11_09_084042_create_courses_table.php b/modules/Course/database/migrations/2025_11_09_084042_create_courses_table.php similarity index 100% rename from packages/Course/database/migrations/2025_11_09_084042_create_courses_table.php rename to modules/Course/database/migrations/2025_11_09_084042_create_courses_table.php diff --git a/packages/Course/database/migrations/2025_11_09_084732_create_course_chapters_table.php b/modules/Course/database/migrations/2025_11_09_084732_create_course_chapters_table.php similarity index 100% rename from packages/Course/database/migrations/2025_11_09_084732_create_course_chapters_table.php rename to modules/Course/database/migrations/2025_11_09_084732_create_course_chapters_table.php diff --git a/packages/Course/database/migrations/2025_11_09_084905_create_course_lessons_table.php b/modules/Course/database/migrations/2025_11_09_084905_create_course_lessons_table.php similarity index 100% rename from packages/Course/database/migrations/2025_11_09_084905_create_course_lessons_table.php rename to modules/Course/database/migrations/2025_11_09_084905_create_course_lessons_table.php diff --git a/packages/Course/database/migrations/2025_11_09_192116_create_course_pivot_table.php b/modules/Course/database/migrations/2025_11_09_192116_create_course_pivot_table.php similarity index 100% rename from packages/Course/database/migrations/2025_11_09_192116_create_course_pivot_table.php rename to modules/Course/database/migrations/2025_11_09_192116_create_course_pivot_table.php diff --git a/modules/Course/database/seeders/CourseSeeder.php b/modules/Course/database/seeders/CourseSeeder.php new file mode 100755 index 0000000..597639e --- /dev/null +++ b/modules/Course/database/seeders/CourseSeeder.php @@ -0,0 +1,14 @@ +create(); + } +} diff --git a/packages/Course/resources/lang/en/messages.php b/modules/Course/lang/en/messages.php similarity index 100% rename from packages/Course/resources/lang/en/messages.php rename to modules/Course/lang/en/messages.php diff --git a/packages/Course/resources/lang/tr/messages.php b/modules/Course/lang/tr/messages.php similarity index 100% rename from packages/Course/resources/lang/tr/messages.php rename to modules/Course/lang/tr/messages.php diff --git a/modules/Course/module.json b/modules/Course/module.json new file mode 100644 index 0000000..cdb66a7 --- /dev/null +++ b/modules/Course/module.json @@ -0,0 +1,11 @@ +{ + "name": "Course", + "alias": "course", + "description": "Course module for 4Byte", + "keywords": [], + "priority": 0, + "providers": [ + "Modules\\Course\\Providers\\CourseServiceProvider" + ], + "files": [] +} \ No newline at end of file diff --git a/modules/Course/package.json b/modules/Course/package.json new file mode 100644 index 0000000..d6fbfc8 --- /dev/null +++ b/modules/Course/package.json @@ -0,0 +1,15 @@ +{ + "private": true, + "type": "module", + "scripts": { + "dev": "vite", + "build": "vite build" + }, + "devDependencies": { + "axios": "^1.1.2", + "laravel-vite-plugin": "^0.7.5", + "sass": "^1.69.5", + "postcss": "^8.3.7", + "vite": "^4.0.0" + } +} diff --git a/modules/Course/resources/assets/.gitkeep b/modules/Course/resources/assets/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/modules/Course/resources/assets/js/app.js b/modules/Course/resources/assets/js/app.js new file mode 100644 index 0000000..e69de29 diff --git a/modules/Course/resources/assets/sass/app.scss b/modules/Course/resources/assets/sass/app.scss new file mode 100644 index 0000000..e69de29 diff --git a/modules/Course/resources/views/components/layouts/master.blade.php b/modules/Course/resources/views/components/layouts/master.blade.php new file mode 100644 index 0000000..99de260 --- /dev/null +++ b/modules/Course/resources/views/components/layouts/master.blade.php @@ -0,0 +1,30 @@ + + + + + + + + + + Course Module - {{ config('app.name', 'Laravel') }} + + + + + + + + + + {{-- Vite CSS --}} + {{-- {{ module_vite('build-course', 'resources/assets/sass/app.scss') }} --}} + + + + {{ $slot }} + + {{-- Vite JS --}} + {{-- {{ module_vite('build-course', 'resources/assets/js/app.js') }} --}} + + diff --git a/modules/Course/resources/views/index.blade.php b/modules/Course/resources/views/index.blade.php new file mode 100644 index 0000000..ac303c7 --- /dev/null +++ b/modules/Course/resources/views/index.blade.php @@ -0,0 +1,5 @@ + +

Hello World

+ +

Module: {!! config('course.name') !!}

+
diff --git a/modules/Course/routes/web.php b/modules/Course/routes/web.php new file mode 100644 index 0000000..2a2d7a7 --- /dev/null +++ b/modules/Course/routes/web.php @@ -0,0 +1,9 @@ +group(function () { + Route::get('/{slug}', 'view')->name('view'); + Route::get('/{slug}/{page}', 'page')->name('page'); +}); diff --git a/modules/Course/vite.config.js b/modules/Course/vite.config.js new file mode 100644 index 0000000..a9bf84c --- /dev/null +++ b/modules/Course/vite.config.js @@ -0,0 +1,57 @@ +import { defineConfig } from 'vite'; +import laravel from 'laravel-vite-plugin'; +import { readdirSync, statSync } from 'fs'; +import { join,relative,dirname } from 'path'; +import { fileURLToPath } from 'url'; + +export default defineConfig({ + build: { + outDir: '../../public/build-course', + emptyOutDir: true, + manifest: true, + }, + plugins: [ + laravel({ + publicDirectory: '../../public', + buildDirectory: 'build-course', + input: [ + __dirname + '/resources/assets/sass/app.scss', + __dirname + '/resources/assets/js/app.js' + ], + refresh: true, + }), + ], +}); +// Scen all resources for assets file. Return array +//function getFilePaths(dir) { +// const filePaths = []; +// +// function walkDirectory(currentPath) { +// const files = readdirSync(currentPath); +// for (const file of files) { +// const filePath = join(currentPath, file); +// const stats = statSync(filePath); +// if (stats.isFile() && !file.startsWith('.')) { +// const relativePath = 'Modules/Course/'+relative(__dirname, filePath); +// filePaths.push(relativePath); +// } else if (stats.isDirectory()) { +// walkDirectory(filePath); +// } +// } +// } +// +// walkDirectory(dir); +// return filePaths; +//} + +//const __filename = fileURLToPath(import.meta.url); +//const __dirname = dirname(__filename); + +//const assetsDir = join(__dirname, 'resources/assets'); +//export const paths = getFilePaths(assetsDir); + + +//export const paths = [ +// 'Modules/Course/resources/assets/sass/app.scss', +// 'Modules/Course/resources/assets/js/app.js', +//]; diff --git a/packages/Entry/src/Data/EntryData.php b/modules/Entry/app/Data/EntryData.php similarity index 94% rename from packages/Entry/src/Data/EntryData.php rename to modules/Entry/app/Data/EntryData.php index e12586e..3a17886 100644 --- a/packages/Entry/src/Data/EntryData.php +++ b/modules/Entry/app/Data/EntryData.php @@ -1,12 +1,12 @@ $activities * @property-read int|null $activities_count - * @property-read \Illuminate\Database\Eloquent\Collection $comments + * @property-read \Illuminate\Database\Eloquent\Collection $comments * @property-read int|null $comments_count - * @property-read \Illuminate\Database\Eloquent\Collection $dislikes + * @property-read \Illuminate\Database\Eloquent\Collection $dislikes * @property-read int|null $dislikes_count - * @property-read \Illuminate\Database\Eloquent\Collection $likes + * @property-read \Illuminate\Database\Eloquent\Collection $likes * @property-read int|null $likes_count * @property-read \Spatie\MediaLibrary\MediaCollections\Models\Collections\MediaCollection $media * @property-read int|null $media_count - * @property-read \Illuminate\Database\Eloquent\Collection $saves + * @property-read \Illuminate\Database\Eloquent\Collection $saves * @property-read int|null $saves_count * @property-read User $user * - * @method static \Packages\Entry\Database\Factories\EntryFactory factory($count = null, $state = []) + * @method static \Modules\Entry\Database\Factories\EntryFactory factory($count = null, $state = []) * @method static \Illuminate\Database\Eloquent\Builder|Entry newModelQuery() * @method static \Illuminate\Database\Eloquent\Builder|Entry newQuery() * @method static \Illuminate\Database\Eloquent\Builder|Entry query() @@ -57,7 +57,7 @@ class Entry extends Model implements HasMedia use HasComments; use HasDislikes; - /** @use HasFactory<\Packages\Entry\Database\Factories\EntryFactory> */ + /** @use HasFactory<\Modules\Entry\Database\Factories\EntryFactory> */ use HasFactory; use HasLikes; diff --git a/packages/Entry/src/Observers/EntryObserver.php b/modules/Entry/app/Observers/EntryObserver.php similarity index 88% rename from packages/Entry/src/Observers/EntryObserver.php rename to modules/Entry/app/Observers/EntryObserver.php index 1acb845..acc67e4 100755 --- a/packages/Entry/src/Observers/EntryObserver.php +++ b/modules/Entry/app/Observers/EntryObserver.php @@ -1,12 +1,12 @@ registerPolicies(); + $this->registerObservers(); + $this->registerPublishableResources(); + $this->loadMigrationsFrom(module_path($this->name, 'database/migrations')); + $this->loadFactoriesFrom(module_path($this->name, 'database/factories')); + $this->registerReact(); + $this->registerFeed(); + } + + /** + * Register the service provider. + */ + public function register(): void + { + $this->app->register(RouteServiceProvider::class); + } + + /** + * Get the services provided by the provider. + * + * @return array + */ + public function provides(): array + { + return [ + EntryService::class, + ]; + } + + /** + * Register model policies. + */ + protected function registerPolicies(): void + { + Gate::policy(Entry::class, EntryPolicy::class); + } + + /** + * Register model observers. + */ + protected function registerObservers(): void + { + Entry::observe(EntryObserver::class); + } + + /** + * Register console publishes. + */ + protected function registerPublishableResources(): void + { + if ($this->app->runningInConsole()) { + $this->publishes([ + module_path($this->name, 'database/seeders') => database_path("seeders/{$this->name}"), + module_path($this->name, 'database/migrations') => database_path('migrations/'), + ], $this->nameLower); + } + } + + /** + * Register to React. + */ + protected function registerReact(): void + { + ReactService::registerHandler( + name: $this->nameLower, + class: Entry::class, + callback: fn ($slug) => app(EntryService::class)->getId($slug) + ); + } + + /** + * Register to Feed. + */ + protected function registerFeed(): void + { + FeedService::registerHandler( + name: $this->nameLower, + isFilter: false, + callback: fn ($slug) => app(EntryService::class)->getData($slug) + ); + } +} diff --git a/modules/Entry/app/Providers/RouteServiceProvider.php b/modules/Entry/app/Providers/RouteServiceProvider.php new file mode 100644 index 0000000..0a8658a --- /dev/null +++ b/modules/Entry/app/Providers/RouteServiceProvider.php @@ -0,0 +1,49 @@ +mapApiRoutes(); + $this->mapWebRoutes(); + } + + /** + * Define the "web" routes for the application. + * + * These routes all receive session state, CSRF protection, etc. + */ + protected function mapWebRoutes(): void + { + Route::middleware('web') + ->prefix($this->nameLower) + ->name("{$this->nameLower}.") + ->group(module_path($this->name, '/routes/web.php')); + } + + /** + * Define the "api" routes for the application. + * + * These routes are typically stateless. + */ + protected function mapApiRoutes(): void + { + Route::middleware(['web', 'auth', BatchLogsActivity::class]) + ->prefix("api/{$this->nameLower}") + ->name("api.{$this->nameLower}.") + ->group(module_path($this->name, '/routes/api.php')); + } +} diff --git a/packages/Entry/src/Services/EntryService.php b/modules/Entry/app/Services/EntryService.php similarity index 89% rename from packages/Entry/src/Services/EntryService.php rename to modules/Entry/app/Services/EntryService.php index 018f6c9..c0898e6 100755 --- a/packages/Entry/src/Services/EntryService.php +++ b/modules/Entry/app/Services/EntryService.php @@ -1,11 +1,11 @@ + * @extends \Illuminate\Database\Eloquent\Factories\Factory<\Modules\Entry\Models\Entry> */ class EntryFactory extends Factory { diff --git a/packages/Entry/database/migrations/2025_10_03_095727_create_entries_table.php b/modules/Entry/database/migrations/2025_10_03_095727_create_entries_table.php similarity index 100% rename from packages/Entry/database/migrations/2025_10_03_095727_create_entries_table.php rename to modules/Entry/database/migrations/2025_10_03_095727_create_entries_table.php diff --git a/packages/Entry/database/seeders/EntrySeeder.php b/modules/Entry/database/seeders/EntrySeeder.php similarity index 67% rename from packages/Entry/database/seeders/EntrySeeder.php rename to modules/Entry/database/seeders/EntrySeeder.php index 6b25070..d50bff3 100755 --- a/packages/Entry/database/seeders/EntrySeeder.php +++ b/modules/Entry/database/seeders/EntrySeeder.php @@ -1,13 +1,13 @@ name('crud.') + ->controller(EntryCrudController::class) + ->group(function () { + Route::post('/create', 'create') + ->name('create') + ->can('create', Entry::class); + }); diff --git a/modules/Entry/routes/web.php b/modules/Entry/routes/web.php new file mode 100644 index 0000000..f19bcbb --- /dev/null +++ b/modules/Entry/routes/web.php @@ -0,0 +1,8 @@ +group(function () { + Route::get('/{slug}', 'view')->name('view'); +}); diff --git a/modules/Entry/vite.config.js b/modules/Entry/vite.config.js new file mode 100644 index 0000000..185a0e4 --- /dev/null +++ b/modules/Entry/vite.config.js @@ -0,0 +1,57 @@ +import { defineConfig } from 'vite'; +import laravel from 'laravel-vite-plugin'; +import { readdirSync, statSync } from 'fs'; +import { join,relative,dirname } from 'path'; +import { fileURLToPath } from 'url'; + +export default defineConfig({ + build: { + outDir: '../../public/build-entry', + emptyOutDir: true, + manifest: true, + }, + plugins: [ + laravel({ + publicDirectory: '../../public', + buildDirectory: 'build-entry', + input: [ + __dirname + '/resources/assets/sass/app.scss', + __dirname + '/resources/assets/js/app.js' + ], + refresh: true, + }), + ], +}); +// Scen all resources for assets file. Return array +//function getFilePaths(dir) { +// const filePaths = []; +// +// function walkDirectory(currentPath) { +// const files = readdirSync(currentPath); +// for (const file of files) { +// const filePath = join(currentPath, file); +// const stats = statSync(filePath); +// if (stats.isFile() && !file.startsWith('.')) { +// const relativePath = 'Modules/Entry/'+relative(__dirname, filePath); +// filePaths.push(relativePath); +// } else if (stats.isDirectory()) { +// walkDirectory(filePath); +// } +// } +// } +// +// walkDirectory(dir); +// return filePaths; +//} + +//const __filename = fileURLToPath(import.meta.url); +//const __dirname = dirname(__filename); + +//const assetsDir = join(__dirname, 'resources/assets'); +//export const paths = getFilePaths(assetsDir); + + +//export const paths = [ +// 'Modules/Entry/resources/assets/sass/app.scss', +// 'Modules/Entry/resources/assets/js/app.js', +//]; diff --git a/packages/News/src/Data/NewsData.php b/modules/News/app/Data/NewsData.php similarity index 88% rename from packages/News/src/Data/NewsData.php rename to modules/News/app/Data/NewsData.php index 59d4c13..fa51a40 100755 --- a/packages/News/src/Data/NewsData.php +++ b/modules/News/app/Data/NewsData.php @@ -1,14 +1,14 @@ |News newModelQuery() * @method static \Illuminate\Database\Eloquent\Builder|News newQuery() * @method static \Illuminate\Database\Eloquent\Builder|News query() @@ -59,7 +59,7 @@ */ class News extends Model implements HasMedia { - /** @use HasFactory<\Packages\News\Database\Factories\NewsFactory> */ + /** @use HasFactory<\Modules\News\Database\Factories\NewsFactory> */ use HasFactory; use InteractsWithMedia; diff --git a/packages/News/src/Observers/NewsObserver.php b/modules/News/app/Observers/NewsObserver.php similarity index 93% rename from packages/News/src/Observers/NewsObserver.php rename to modules/News/app/Observers/NewsObserver.php index 7d48409..106144a 100755 --- a/packages/News/src/Observers/NewsObserver.php +++ b/modules/News/app/Observers/NewsObserver.php @@ -1,12 +1,12 @@ registerPublishableResources(); + $this->loadMigrationsFrom(module_path($this->name, 'database/migrations')); + $this->loadFactoriesFrom(module_path($this->name, 'database/factories')); + } + + /** + * Get the services provided by the provider. + * + * @return array + */ + public function provides(): array + { + return [ + NewsService::class, + ]; + } + + /** + * Register model policies. + */ + protected function registerPolicies(): void + { + Gate::policy(News::class, NewsPolicy::class); + } + + /** + * Register model observers. + */ + protected function registerObservers(): void + { + News::observe(NewsObserver::class); + } + + /** + * Register console publishes. + */ + protected function registerPublishableResources(): void + { + if ($this->app->runningInConsole()) { + $this->publishes([ + module_path($this->name, 'database/seeders') => database_path("seeders/{$this->name}"), + module_path($this->name, 'database/migrations') => database_path('migrations/'), + ], $this->nameLower); + } + } + + /** + * Register to Feed. + */ + protected function registerFeed(): void + { + FeedService::registerHandler( + name: $this->nameLower, + isFilter: false, + callback: fn ($slug) => app(NewsService::class)->getData($slug) + ); + } +} diff --git a/packages/News/src/Services/NewsService.php b/modules/News/app/Services/NewsService.php similarity index 90% rename from packages/News/src/Services/NewsService.php rename to modules/News/app/Services/NewsService.php index e686499..7236ec4 100755 --- a/packages/News/src/Services/NewsService.php +++ b/modules/News/app/Services/NewsService.php @@ -1,11 +1,11 @@ + * @extends \Illuminate\Database\Eloquent\Factories\Factory<\Modules\News\Models\News> */ class NewsFactory extends Factory { diff --git a/packages/News/database/migrations/2025_08_17_132322_create_news_table.php b/modules/News/database/migrations/2025_08_17_132322_create_news_table.php similarity index 100% rename from packages/News/database/migrations/2025_08_17_132322_create_news_table.php rename to modules/News/database/migrations/2025_08_17_132322_create_news_table.php diff --git a/packages/News/database/migrations/2025_08_17_132432_create_news_pivot_table.php b/modules/News/database/migrations/2025_08_17_132432_create_news_pivot_table.php similarity index 100% rename from packages/News/database/migrations/2025_08_17_132432_create_news_pivot_table.php rename to modules/News/database/migrations/2025_08_17_132432_create_news_pivot_table.php diff --git a/packages/News/database/migrations/2025_10_21_184927_drop_timestampts_from_news_pivots.php b/modules/News/database/migrations/2025_10_21_184927_drop_timestampts_from_news_pivots.php similarity index 100% rename from packages/News/database/migrations/2025_10_21_184927_drop_timestampts_from_news_pivots.php rename to modules/News/database/migrations/2025_10_21_184927_drop_timestampts_from_news_pivots.php diff --git a/packages/News/database/migrations/2025_12_06_194559_drop_image_from_news_table.php b/modules/News/database/migrations/2025_12_06_194559_drop_image_from_news_table.php similarity index 100% rename from packages/News/database/migrations/2025_12_06_194559_drop_image_from_news_table.php rename to modules/News/database/migrations/2025_12_06_194559_drop_image_from_news_table.php diff --git a/packages/News/database/seeders/NewsSeeder.php b/modules/News/database/seeders/NewsSeeder.php similarity index 68% rename from packages/News/database/seeders/NewsSeeder.php rename to modules/News/database/seeders/NewsSeeder.php index da01b8b..526cc41 100755 --- a/packages/News/database/seeders/NewsSeeder.php +++ b/modules/News/database/seeders/NewsSeeder.php @@ -1,9 +1,9 @@ + + + + + + + + + News Module - {{ config('app.name', 'Laravel') }} + + + + + + + + + + {{-- Vite CSS --}} + {{-- {{ module_vite('build-news', 'resources/assets/sass/app.scss') }} --}} + + + + {{ $slot }} + + {{-- Vite JS --}} + {{-- {{ module_vite('build-news', 'resources/assets/js/app.js') }} --}} + + diff --git a/modules/News/resources/views/index.blade.php b/modules/News/resources/views/index.blade.php new file mode 100644 index 0000000..5b4cbfb --- /dev/null +++ b/modules/News/resources/views/index.blade.php @@ -0,0 +1,5 @@ + +

Hello World

+ +

Module: {!! config('news.name') !!}

+
diff --git a/modules/News/vite.config.js b/modules/News/vite.config.js new file mode 100644 index 0000000..1fa993f --- /dev/null +++ b/modules/News/vite.config.js @@ -0,0 +1,57 @@ +import { defineConfig } from 'vite'; +import laravel from 'laravel-vite-plugin'; +import { readdirSync, statSync } from 'fs'; +import { join,relative,dirname } from 'path'; +import { fileURLToPath } from 'url'; + +export default defineConfig({ + build: { + outDir: '../../public/build-news', + emptyOutDir: true, + manifest: true, + }, + plugins: [ + laravel({ + publicDirectory: '../../public', + buildDirectory: 'build-news', + input: [ + __dirname + '/resources/assets/sass/app.scss', + __dirname + '/resources/assets/js/app.js' + ], + refresh: true, + }), + ], +}); +// Scen all resources for assets file. Return array +//function getFilePaths(dir) { +// const filePaths = []; +// +// function walkDirectory(currentPath) { +// const files = readdirSync(currentPath); +// for (const file of files) { +// const filePath = join(currentPath, file); +// const stats = statSync(filePath); +// if (stats.isFile() && !file.startsWith('.')) { +// const relativePath = 'Modules/News/'+relative(__dirname, filePath); +// filePaths.push(relativePath); +// } else if (stats.isDirectory()) { +// walkDirectory(filePath); +// } +// } +// } +// +// walkDirectory(dir); +// return filePaths; +//} + +//const __filename = fileURLToPath(import.meta.url); +//const __dirname = dirname(__filename); + +//const assetsDir = join(__dirname, 'resources/assets'); +//export const paths = getFilePaths(assetsDir); + + +//export const paths = [ +// 'Modules/News/resources/assets/sass/app.scss', +// 'Modules/News/resources/assets/js/app.js', +//]; diff --git a/packages/Page/src/Console/Commands/SchedulePageCommand.php b/modules/Page/app/Console/Commands/SchedulePageCommand.php similarity index 87% rename from packages/Page/src/Console/Commands/SchedulePageCommand.php rename to modules/Page/app/Console/Commands/SchedulePageCommand.php index 55de884..e427935 100755 --- a/packages/Page/src/Console/Commands/SchedulePageCommand.php +++ b/modules/Page/app/Console/Commands/SchedulePageCommand.php @@ -1,10 +1,10 @@ |Page newModelQuery() * @method static \Illuminate\Database\Eloquent\Builder|Page newQuery() * @method static \Illuminate\Database\Eloquent\Builder|Page query() @@ -51,7 +51,7 @@ */ class Page extends Model implements HasMedia { - /** @use HasFactory<\Packages\Page\Database\Factories\PageFactory> */ + /** @use HasFactory<\Modules\Page\Database\Factories\PageFactory> */ use HasFactory; use InteractsWithMedia; diff --git a/packages/Page/src/Notifications/PagePublishedNotification.php b/modules/Page/app/Notifications/PagePublishedNotification.php similarity index 95% rename from packages/Page/src/Notifications/PagePublishedNotification.php rename to modules/Page/app/Notifications/PagePublishedNotification.php index 96addb2..83c5f62 100755 --- a/packages/Page/src/Notifications/PagePublishedNotification.php +++ b/modules/Page/app/Notifications/PagePublishedNotification.php @@ -1,12 +1,12 @@ > + */ + protected $listen = [ + PagePublishedEvent::class => [ + PagePublishedListener::class, + ], + ]; + + /** + * Indicates if events should be discovered. + * + * @var bool + */ + protected static $shouldDiscoverEvents = true; + + /** + * Configure the proper event listeners for email verification. + */ + protected function configureEmailVerification(): void + { + } +} diff --git a/modules/Page/app/Providers/PageServiceProvider.php b/modules/Page/app/Providers/PageServiceProvider.php new file mode 100644 index 0000000..daa77f7 --- /dev/null +++ b/modules/Page/app/Providers/PageServiceProvider.php @@ -0,0 +1,124 @@ +registerCommands(); + $this->registerTranslations(); + $this->registerPublishableResources(); + $this->loadMigrationsFrom(module_path($this->name, 'database/migrations')); + $this->loadFactoriesFrom(module_path($this->name, 'database/factories')); + } + + /** + * Register the service provider. + */ + public function register(): void + { + $this->app->register(EventServiceProvider::class); + $this->app->register(RouteServiceProvider::class); + } + + /** + * Register translations. + */ + public function registerTranslations(): void + { + $langPath = resource_path('lang/modules/' . $this->nameLower); + + if (is_dir($langPath)) { + $this->loadTranslationsFrom($langPath, $this->nameLower); + $this->loadJsonTranslationsFrom($langPath); + } else { + $this->loadTranslationsFrom(module_path($this->name, 'lang'), $this->nameLower); + $this->loadJsonTranslationsFrom(module_path($this->name, 'lang')); + } + } + + /** + * Get the services provided by the provider. + * + * @return array + */ + public function provides(): array + { + return [ + PageService::class, + ]; + } + + /** + * Register model policies. + */ + protected function registerPolicies(): void + { + Gate::policy(Page::class, PagePolicy::class); + } + + /** + * Register model observers. + */ + protected function registerObservers(): void + { + Page::observe(PageObserver::class); + } + + /** + * Register commands in the format of Command::class. + */ + protected function registerCommands(): void + { + $this->commands([ + SchedulePageCommand::class, + ]); + } + + /** + * Register console publishes. + */ + protected function registerPublishableResources(): void + { + if ($this->app->runningInConsole()) { + $this->publishes([ + module_path($this->name, 'database/seeders') => database_path("seeders/{$this->name}"), + module_path($this->name, 'database/migrations') => database_path('migrations/'), + ], $this->nameLower); + } + } + + /** + * Register to React for make it searchable. + */ + protected function registerSearch(): void + { + SearchService::registerHandler( + index: 'pages', + callback: fn ($hit) => app(PageService::class)->getData($hit['id']), + searchableAttributes: ['title'], + filterableAttributes: ['id'], + sortableAttributes: ['updated_at'] + ); + } +} diff --git a/modules/Page/app/Providers/RouteServiceProvider.php b/modules/Page/app/Providers/RouteServiceProvider.php new file mode 100644 index 0000000..ba06eed --- /dev/null +++ b/modules/Page/app/Providers/RouteServiceProvider.php @@ -0,0 +1,34 @@ +mapWebRoutes(); + } + + /** + * Define the "web" routes for the application. + * + * These routes all receive session state, CSRF protection, etc. + */ + protected function mapWebRoutes(): void + { + Route::middleware('web') + ->prefix('sayfa') + ->name("{$this->nameLower}.") + ->group(module_path($this->name, '/routes/web.php')); + } +} diff --git a/packages/Page/src/Services/PageService.php b/modules/Page/app/Services/PageService.php similarity index 90% rename from packages/Page/src/Services/PageService.php rename to modules/Page/app/Services/PageService.php index 23de26e..c7c9c67 100755 --- a/packages/Page/src/Services/PageService.php +++ b/modules/Page/app/Services/PageService.php @@ -1,11 +1,11 @@ + * @extends \Illuminate\Database\Eloquent\Factories\Factory<\Modules\Page\Models\Page> */ class PageFactory extends Factory { diff --git a/packages/Page/database/migrations/2025_09_04_100152_create_pages_table.php b/modules/Page/database/migrations/2025_09_04_100152_create_pages_table.php similarity index 100% rename from packages/Page/database/migrations/2025_09_04_100152_create_pages_table.php rename to modules/Page/database/migrations/2025_09_04_100152_create_pages_table.php diff --git a/packages/Page/database/seeders/PageSeeder.php b/modules/Page/database/seeders/PageSeeder.php similarity index 68% rename from packages/Page/database/seeders/PageSeeder.php rename to modules/Page/database/seeders/PageSeeder.php index ebf985e..b7287a2 100644 --- a/packages/Page/database/seeders/PageSeeder.php +++ b/modules/Page/database/seeders/PageSeeder.php @@ -1,9 +1,9 @@ group(function () { + Route::get('/{slug}', 'view')->name('view'); +}); diff --git a/modules/Page/vite.config.js b/modules/Page/vite.config.js new file mode 100644 index 0000000..949e3a2 --- /dev/null +++ b/modules/Page/vite.config.js @@ -0,0 +1,57 @@ +import { defineConfig } from 'vite'; +import laravel from 'laravel-vite-plugin'; +import { readdirSync, statSync } from 'fs'; +import { join,relative,dirname } from 'path'; +import { fileURLToPath } from 'url'; + +export default defineConfig({ + build: { + outDir: '../../public/build-page', + emptyOutDir: true, + manifest: true, + }, + plugins: [ + laravel({ + publicDirectory: '../../public', + buildDirectory: 'build-page', + input: [ + __dirname + '/resources/assets/sass/app.scss', + __dirname + '/resources/assets/js/app.js' + ], + refresh: true, + }), + ], +}); +// Scen all resources for assets file. Return array +//function getFilePaths(dir) { +// const filePaths = []; +// +// function walkDirectory(currentPath) { +// const files = readdirSync(currentPath); +// for (const file of files) { +// const filePath = join(currentPath, file); +// const stats = statSync(filePath); +// if (stats.isFile() && !file.startsWith('.')) { +// const relativePath = 'Modules/Page/'+relative(__dirname, filePath); +// filePaths.push(relativePath); +// } else if (stats.isDirectory()) { +// walkDirectory(filePath); +// } +// } +// } +// +// walkDirectory(dir); +// return filePaths; +//} + +//const __filename = fileURLToPath(import.meta.url); +//const __dirname = dirname(__filename); + +//const assetsDir = join(__dirname, 'resources/assets'); +//export const paths = getFilePaths(assetsDir); + + +//export const paths = [ +// 'Modules/Page/resources/assets/sass/app.scss', +// 'Modules/Page/resources/assets/js/app.js', +//]; diff --git a/packages/React/src/Data/CommentData.php b/modules/React/app/Data/CommentData.php similarity index 92% rename from packages/React/src/Data/CommentData.php rename to modules/React/app/Data/CommentData.php index a6215c8..989dee7 100755 --- a/packages/React/src/Data/CommentData.php +++ b/modules/React/app/Data/CommentData.php @@ -1,12 +1,12 @@ notify( Notification::make() - ->title(__('You have a new follower!')) + ->title(__('react::messages.follower_title')) ->success() - ->body(__('user_follow', ['username' => $follow->follower->username])) + ->body(__('react::messages.follower_body', ['username' => $follow->follower->username])) ->actions([ Action::make('view') - ->label(__('View Profile')) + ->label(__('react::messages.view_profile')) ->url(route('user.view', ['username' => $follow->follower->username])) ->markAsRead() ->openUrlInNewTab() diff --git a/packages/React/src/Models/Comment.php b/modules/React/app/Models/Comment.php similarity index 91% rename from packages/React/src/Models/Comment.php rename to modules/React/app/Models/Comment.php index e1dcc3c..776a3da 100644 --- a/packages/React/src/Models/Comment.php +++ b/modules/React/app/Models/Comment.php @@ -1,6 +1,6 @@ |Comment newModelQuery() * @method static \Illuminate\Database\Eloquent\Builder|Comment newQuery() * @method static \Illuminate\Database\Eloquent\Builder|Comment query() @@ -51,7 +51,7 @@ */ class Comment extends Model { - /** @use HasFactory<\Packages\React\Database\Factories\CommentFactory> */ + /** @use HasFactory<\Modules\React\Database\Factories\CommentFactory> */ use HasFactory; use HasLikes; diff --git a/packages/React/src/Models/Dislike.php b/modules/React/app/Models/Dislike.php similarity index 86% rename from packages/React/src/Models/Dislike.php rename to modules/React/app/Models/Dislike.php index f892ce6..df3e055 100644 --- a/packages/React/src/Models/Dislike.php +++ b/modules/React/app/Models/Dislike.php @@ -1,13 +1,13 @@ |Dislike newModelQuery() * @method static \Illuminate\Database\Eloquent\Builder|Dislike newQuery() * @method static \Illuminate\Database\Eloquent\Builder|Dislike query() @@ -29,7 +29,7 @@ */ class Dislike extends Model { - /** @use HasFactory<\Packages\React\Database\Factories\DislikeFactory> */ + /** @use HasFactory<\Modules\React\Database\Factories\DislikeFactory> */ use HasFactory; public $timestamps = false; diff --git a/packages/React/src/Models/Follow.php b/modules/React/app/Models/Follow.php similarity index 86% rename from packages/React/src/Models/Follow.php rename to modules/React/app/Models/Follow.php index 0268808..45ae114 100644 --- a/packages/React/src/Models/Follow.php +++ b/modules/React/app/Models/Follow.php @@ -1,13 +1,13 @@ |Follow newModelQuery() * @method static \Illuminate\Database\Eloquent\Builder|Follow newQuery() * @method static \Illuminate\Database\Eloquent\Builder|Follow query() @@ -29,7 +29,7 @@ */ class Follow extends Model { - /** @use HasFactory<\Packages\React\Database\Factories\FollowFactory> */ + /** @use HasFactory<\Modules\React\Database\Factories\FollowFactory> */ use HasFactory; public $timestamps = false; diff --git a/packages/React/src/Models/Like.php b/modules/React/app/Models/Like.php similarity index 86% rename from packages/React/src/Models/Like.php rename to modules/React/app/Models/Like.php index b7bc13f..bac94e7 100644 --- a/packages/React/src/Models/Like.php +++ b/modules/React/app/Models/Like.php @@ -1,13 +1,13 @@ |Like newModelQuery() * @method static \Illuminate\Database\Eloquent\Builder|Like newQuery() * @method static \Illuminate\Database\Eloquent\Builder|Like query() @@ -29,7 +29,7 @@ */ class Like extends Model { - /** @use HasFactory<\Packages\React\Database\Factories\LikeFactory> */ + /** @use HasFactory<\Modules\React\Database\Factories\LikeFactory> */ use HasFactory; public $timestamps = false; diff --git a/packages/React/src/Models/Save.php b/modules/React/app/Models/Save.php similarity index 86% rename from packages/React/src/Models/Save.php rename to modules/React/app/Models/Save.php index 5157790..629bd7f 100644 --- a/packages/React/src/Models/Save.php +++ b/modules/React/app/Models/Save.php @@ -1,13 +1,13 @@ |Save newModelQuery() * @method static \Illuminate\Database\Eloquent\Builder|Save newQuery() * @method static \Illuminate\Database\Eloquent\Builder|Save query() @@ -29,7 +29,7 @@ */ class Save extends Model { - /** @use HasFactory<\Packages\React\Database\Factories\SaveFactory> */ + /** @use HasFactory<\Modules\React\Database\Factories\SaveFactory> */ use HasFactory; public $timestamps = false; diff --git a/packages/React/src/Observers/CommentObserver.php b/modules/React/app/Observers/CommentObserver.php similarity index 85% rename from packages/React/src/Observers/CommentObserver.php rename to modules/React/app/Observers/CommentObserver.php index 5170a55..75c676f 100644 --- a/packages/React/src/Observers/CommentObserver.php +++ b/modules/React/app/Observers/CommentObserver.php @@ -1,11 +1,11 @@ > + */ + protected $listen = [ + FollowedEvent::class => [ + FollowedListener::class, + ], + ]; + + /** + * Indicates if events should be discovered. + * + * @var bool + */ + protected static $shouldDiscoverEvents = true; + + /** + * Configure the proper event listeners for email verification. + */ + protected function configureEmailVerification(): void + { + } +} diff --git a/modules/React/app/Providers/ReactServiceProvider.php b/modules/React/app/Providers/ReactServiceProvider.php new file mode 100644 index 0000000..bfd3db0 --- /dev/null +++ b/modules/React/app/Providers/ReactServiceProvider.php @@ -0,0 +1,142 @@ +registerTranslations(); + $this->registerPublishableResources(); + $this->loadMigrationsFrom(module_path($this->name, 'database/migrations')); + $this->loadFactoriesFrom(module_path($this->name, 'database/factories')); + } + + /** + * Register the service provider. + */ + public function register(): void + { + $this->app->register(EventServiceProvider::class); + $this->app->register(RouteServiceProvider::class); + } + + /** + * Register translations. + */ + public function registerTranslations(): void + { + $langPath = resource_path('lang/modules/' . $this->nameLower); + + if (is_dir($langPath)) { + $this->loadTranslationsFrom($langPath, $this->nameLower); + $this->loadJsonTranslationsFrom($langPath); + } else { + $this->loadTranslationsFrom(module_path($this->name, 'lang'), $this->nameLower); + $this->loadJsonTranslationsFrom(module_path($this->name, 'lang')); + } + } + + /** + * Get the services provided by the provider. + * + * @return array + */ + public function provides(): array + { + return [ + ReactService::class, + ]; + } + + /** + * Register model policies. + */ + protected function registerPolicies(): void + { + Gate::policy(Like::class, LikePolicy::class); + Gate::policy(Dislike::class, DislikePolicy::class); + Gate::policy(Save::class, SavePolicy::class); + Gate::policy(Comment::class, CommentPolicy::class); + Gate::policy(Follow::class, FollowPolicy::class); + } + + /** + * Register model observers. + */ + protected function registerObservers(): void + { + Like::observe(LikeObserver::class); + Dislike::observe(DislikeObserver::class); + Save::observe(SaveObserver::class); + Comment::observe(CommentObserver::class); + Follow::observe(FollowObserver::class); + } + + /** + * Register console publishes. + */ + protected function registerPublishableResources(): void + { + if ($this->app->runningInConsole()) { + $this->publishes([ + module_path($this->name, 'database/seeders') => database_path("seeders/{$this->name}"), + module_path($this->name, 'database/migrations') => database_path('migrations/'), + ], $this->nameLower); + } + } + + /** + * Register to React. + */ + protected function registerReact(): void + { + ReactService::registerHandler( + name: 'comment', + class: Comment::class, + callback: fn ($slug) => $slug + ); + } + + /** + * Register to Feed. + */ + protected function registerFeed(): void + { + FeedService::registerHandler( + name: 'comment', + isFilter: false, + callback: fn ($slug) => app(ReactService::class)->getComment($slug) + ); + } +} diff --git a/modules/React/app/Providers/RouteServiceProvider.php b/modules/React/app/Providers/RouteServiceProvider.php new file mode 100644 index 0000000..f3c2b88 --- /dev/null +++ b/modules/React/app/Providers/RouteServiceProvider.php @@ -0,0 +1,35 @@ +mapApiRoutes(); + } + + /** + * Define the "api" routes for the application. + * + * These routes are typically stateless. + */ + protected function mapApiRoutes(): void + { + Route::middleware(['web', 'auth', BatchLogsActivity::class]) + ->prefix("api/{$this->nameLower}") + ->name("api.{$this->nameLower}.") + ->group(module_path($this->name, '/routes/api.php')); + } +} diff --git a/packages/React/src/Services/ReactService.php b/modules/React/app/Services/ReactService.php similarity index 98% rename from packages/React/src/Services/ReactService.php rename to modules/React/app/Services/ReactService.php index 46435d7..03a0008 100644 --- a/packages/React/src/Services/ReactService.php +++ b/modules/React/app/Services/ReactService.php @@ -1,18 +1,18 @@ + * @extends \Illuminate\Database\Eloquent\Factories\Factory<\Modules\React\Models\Comment> */ class CommentFactory extends Factory { diff --git a/packages/React/database/factories/DislikeFactory.php b/modules/React/database/factories/DislikeFactory.php similarity index 82% rename from packages/React/database/factories/DislikeFactory.php rename to modules/React/database/factories/DislikeFactory.php index 27bea60..17937c2 100644 --- a/packages/React/database/factories/DislikeFactory.php +++ b/modules/React/database/factories/DislikeFactory.php @@ -1,14 +1,14 @@ + * @extends \Illuminate\Database\Eloquent\Factories\Factory<\Modules\React\Models\Dislike> */ class DislikeFactory extends Factory { diff --git a/packages/React/database/factories/FollowFactory.php b/modules/React/database/factories/FollowFactory.php similarity index 82% rename from packages/React/database/factories/FollowFactory.php rename to modules/React/database/factories/FollowFactory.php index 7e7761d..7cffa91 100644 --- a/packages/React/database/factories/FollowFactory.php +++ b/modules/React/database/factories/FollowFactory.php @@ -1,14 +1,14 @@ + * @extends \Illuminate\Database\Eloquent\Factories\Factory<\Modules\React\Models\Follow> */ class FollowFactory extends Factory { diff --git a/packages/React/database/factories/LikeFactory.php b/modules/React/database/factories/LikeFactory.php similarity index 82% rename from packages/React/database/factories/LikeFactory.php rename to modules/React/database/factories/LikeFactory.php index ac586a8..2b01fd8 100644 --- a/packages/React/database/factories/LikeFactory.php +++ b/modules/React/database/factories/LikeFactory.php @@ -1,14 +1,14 @@ + * @extends \Illuminate\Database\Eloquent\Factories\Factory<\Modules\React\Models\Like> */ class LikeFactory extends Factory { diff --git a/packages/React/database/factories/SaveFactory.php b/modules/React/database/factories/SaveFactory.php similarity index 82% rename from packages/React/database/factories/SaveFactory.php rename to modules/React/database/factories/SaveFactory.php index aa50af1..070b8c4 100644 --- a/packages/React/database/factories/SaveFactory.php +++ b/modules/React/database/factories/SaveFactory.php @@ -1,14 +1,14 @@ + * @extends \Illuminate\Database\Eloquent\Factories\Factory<\Modules\React\Models\Save> */ class SaveFactory extends Factory { diff --git a/packages/React/database/migrations/2025_09_18_075116_create_comments_table.php b/modules/React/database/migrations/2025_09_18_075116_create_comments_table.php similarity index 100% rename from packages/React/database/migrations/2025_09_18_075116_create_comments_table.php rename to modules/React/database/migrations/2025_09_18_075116_create_comments_table.php diff --git a/packages/React/database/migrations/2025_10_15_071629_create_likes_table.php b/modules/React/database/migrations/2025_10_15_071629_create_likes_table.php similarity index 100% rename from packages/React/database/migrations/2025_10_15_071629_create_likes_table.php rename to modules/React/database/migrations/2025_10_15_071629_create_likes_table.php diff --git a/packages/React/database/migrations/2025_10_16_072117_create_dislikes_table.php b/modules/React/database/migrations/2025_10_16_072117_create_dislikes_table.php similarity index 100% rename from packages/React/database/migrations/2025_10_16_072117_create_dislikes_table.php rename to modules/React/database/migrations/2025_10_16_072117_create_dislikes_table.php diff --git a/packages/React/database/migrations/2025_10_16_072145_create_saves_table.php b/modules/React/database/migrations/2025_10_16_072145_create_saves_table.php similarity index 100% rename from packages/React/database/migrations/2025_10_16_072145_create_saves_table.php rename to modules/React/database/migrations/2025_10_16_072145_create_saves_table.php diff --git a/packages/React/database/migrations/2025_10_16_111600_create_follows_table.php b/modules/React/database/migrations/2025_10_16_111600_create_follows_table.php similarity index 100% rename from packages/React/database/migrations/2025_10_16_111600_create_follows_table.php rename to modules/React/database/migrations/2025_10_16_111600_create_follows_table.php diff --git a/modules/React/lang/en/messages.php b/modules/React/lang/en/messages.php new file mode 100644 index 0000000..fb1c90a --- /dev/null +++ b/modules/React/lang/en/messages.php @@ -0,0 +1,7 @@ + "You have a new follower!", + "follower_body" => "\":username\" has started following you.", + "view_profile" => "View Profile", +]; diff --git a/modules/React/lang/tr/messages.php b/modules/React/lang/tr/messages.php new file mode 100644 index 0000000..c1b2032 --- /dev/null +++ b/modules/React/lang/tr/messages.php @@ -0,0 +1,7 @@ + "Yeni bir takipçin var!", + "follower_body" => "\":username\" seni takip etmeye başladı.", + "view_profile" => "Profili Görüntüle", +]; diff --git a/modules/React/module.json b/modules/React/module.json new file mode 100644 index 0000000..dec005c --- /dev/null +++ b/modules/React/module.json @@ -0,0 +1,14 @@ +{ + "name": "React", + "alias": "react", + "description": "React module for 4Byte", + "keywords": [ + "4Byte", + "React" + ], + "priority": 0, + "providers": [ + "Modules\\React\\Providers\\ReactServiceProvider" + ], + "files": [] +} \ No newline at end of file diff --git a/modules/React/package.json b/modules/React/package.json new file mode 100644 index 0000000..d6fbfc8 --- /dev/null +++ b/modules/React/package.json @@ -0,0 +1,15 @@ +{ + "private": true, + "type": "module", + "scripts": { + "dev": "vite", + "build": "vite build" + }, + "devDependencies": { + "axios": "^1.1.2", + "laravel-vite-plugin": "^0.7.5", + "sass": "^1.69.5", + "postcss": "^8.3.7", + "vite": "^4.0.0" + } +} diff --git a/packages/React/routes/api.php b/modules/React/routes/api.php similarity index 60% rename from packages/React/routes/api.php rename to modules/React/routes/api.php index b6b4c93..1486636 100644 --- a/packages/React/routes/api.php +++ b/modules/React/routes/api.php @@ -1,15 +1,14 @@ prefix('api/react')->middleware([BatchLogsActivity::class])->controller(ReactController::class)->group(function () { - Route::middleware(['auth'])->group(function () { +Route::controller(ReactController::class)->group(function () { + Route::middleware('auth')->group(function () { Route::post('/{type}/{slug}/like', 'like')->name('like')->can('create', Like::class); Route::post('/{type}/{slug}/dislike', 'dislike')->name('dislike')->can('create', Dislike::class); Route::post('/{type}/{slug}/save', 'save')->name('save')->can('create', Save::class); diff --git a/modules/React/vite.config.js b/modules/React/vite.config.js new file mode 100644 index 0000000..baaf539 --- /dev/null +++ b/modules/React/vite.config.js @@ -0,0 +1,57 @@ +import { defineConfig } from 'vite'; +import laravel from 'laravel-vite-plugin'; +import { readdirSync, statSync } from 'fs'; +import { join,relative,dirname } from 'path'; +import { fileURLToPath } from 'url'; + +export default defineConfig({ + build: { + outDir: '../../public/build-react', + emptyOutDir: true, + manifest: true, + }, + plugins: [ + laravel({ + publicDirectory: '../../public', + buildDirectory: 'build-react', + input: [ + __dirname + '/resources/assets/sass/app.scss', + __dirname + '/resources/assets/js/app.js' + ], + refresh: true, + }), + ], +}); +// Scen all resources for assets file. Return array +//function getFilePaths(dir) { +// const filePaths = []; +// +// function walkDirectory(currentPath) { +// const files = readdirSync(currentPath); +// for (const file of files) { +// const filePath = join(currentPath, file); +// const stats = statSync(filePath); +// if (stats.isFile() && !file.startsWith('.')) { +// const relativePath = 'Modules/React/'+relative(__dirname, filePath); +// filePaths.push(relativePath); +// } else if (stats.isDirectory()) { +// walkDirectory(filePath); +// } +// } +// } +// +// walkDirectory(dir); +// return filePaths; +//} + +//const __filename = fileURLToPath(import.meta.url); +//const __dirname = dirname(__filename); + +//const assetsDir = join(__dirname, 'resources/assets'); +//export const paths = getFilePaths(assetsDir); + + +//export const paths = [ +// 'Modules/React/resources/assets/sass/app.scss', +// 'Modules/React/resources/assets/js/app.js', +//]; diff --git a/packages/Recommend/src/Classes/GorseFeedback.php b/modules/Recommend/app/Classes/GorseFeedback.php similarity index 97% rename from packages/Recommend/src/Classes/GorseFeedback.php rename to modules/Recommend/app/Classes/GorseFeedback.php index a952aa8..b54cd06 100644 --- a/packages/Recommend/src/Classes/GorseFeedback.php +++ b/modules/Recommend/app/Classes/GorseFeedback.php @@ -1,6 +1,6 @@ registerCommands(); + $this->registerConfig(); + } + + /** + * Register the service provider. + */ + public function register(): void + { + $this->app->register(RouteServiceProvider::class); + } + + /** + * Get the services provided by the provider. + * + * @return array + */ + public function provides(): array + { + return [ + FeedService::class, + GorseService::class, + ]; + } + + /** + * Register commands in the format of Command::class. + */ + protected function registerCommands(): void + { + $this->commands([ + UploadRecommendations::class, + ]); + } + + /** + * Register config. + */ + protected function registerConfig(): void + { + $configPath = module_path($this->name, config('modules.paths.generator.config.path')); + + if (is_dir($configPath)) { + $iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($configPath)); + + foreach ($iterator as $file) { + if ($file->isFile() && $file->getExtension() === 'php') { + $config = str_replace($configPath . DIRECTORY_SEPARATOR, '', $file->getPathname()); + $config_key = str_replace([DIRECTORY_SEPARATOR, '.php'], ['.', ''], $config); + $segments = explode('.', $this->nameLower . '.' . $config_key); + + // Remove duplicated adjacent segments + $normalized = []; + foreach ($segments as $segment) { + if (end($normalized) !== $segment) { + $normalized[] = $segment; + } + } + + $key = $config === 'config.php' ? $this->nameLower : implode('.', $normalized); + + $this->publishes([$file->getPathname() => config_path($config)], 'config'); + $this->merge_config_from($file->getPathname(), $key); + } + } + } + } + + /** + * Merge config from the given path recursively. + */ + protected function merge_config_from(string $path, string $key): void + { + $existing = config($key, []); + $module_config = require $path; + + config([$key => array_replace_recursive($existing, $module_config)]); + } +} diff --git a/modules/Recommend/app/Providers/RouteServiceProvider.php b/modules/Recommend/app/Providers/RouteServiceProvider.php new file mode 100644 index 0000000..ef0a36c --- /dev/null +++ b/modules/Recommend/app/Providers/RouteServiceProvider.php @@ -0,0 +1,34 @@ +mapApiRoutes(); + } + + /** + * Define the "api" routes for the application. + * + * These routes are typically stateless. + */ + protected function mapApiRoutes(): void + { + Route::middleware(['web', 'auth']) + ->prefix('api/feed') + ->name('api.feed.') + ->group(module_path($this->name, '/routes/api.php')); + } +} diff --git a/packages/Recommend/src/Services/FeedService.php b/modules/Recommend/app/Services/FeedService.php similarity index 96% rename from packages/Recommend/src/Services/FeedService.php rename to modules/Recommend/app/Services/FeedService.php index 569b62c..8fc460e 100755 --- a/packages/Recommend/src/Services/FeedService.php +++ b/modules/Recommend/app/Services/FeedService.php @@ -1,16 +1,16 @@ + * @return array */ public function articles(): array { diff --git a/packages/Recommend/src/Services/GorseService.php b/modules/Recommend/app/Services/GorseService.php similarity index 97% rename from packages/Recommend/src/Services/GorseService.php rename to modules/Recommend/app/Services/GorseService.php index 6273c79..0a25856 100755 --- a/packages/Recommend/src/Services/GorseService.php +++ b/modules/Recommend/app/Services/GorseService.php @@ -1,13 +1,13 @@ group(function () { + Route::get('/', 'data')->name('data'); + Route::get('/feed', 'feed')->name('feed'); +}); diff --git a/modules/Recommend/vite.config.js b/modules/Recommend/vite.config.js new file mode 100644 index 0000000..976b6c4 --- /dev/null +++ b/modules/Recommend/vite.config.js @@ -0,0 +1,57 @@ +import { defineConfig } from 'vite'; +import laravel from 'laravel-vite-plugin'; +import { readdirSync, statSync } from 'fs'; +import { join,relative,dirname } from 'path'; +import { fileURLToPath } from 'url'; + +export default defineConfig({ + build: { + outDir: '../../public/build-recommend', + emptyOutDir: true, + manifest: true, + }, + plugins: [ + laravel({ + publicDirectory: '../../public', + buildDirectory: 'build-recommend', + input: [ + __dirname + '/resources/assets/sass/app.scss', + __dirname + '/resources/assets/js/app.js' + ], + refresh: true, + }), + ], +}); +// Scen all resources for assets file. Return array +//function getFilePaths(dir) { +// const filePaths = []; +// +// function walkDirectory(currentPath) { +// const files = readdirSync(currentPath); +// for (const file of files) { +// const filePath = join(currentPath, file); +// const stats = statSync(filePath); +// if (stats.isFile() && !file.startsWith('.')) { +// const relativePath = 'Modules/Recommend/'+relative(__dirname, filePath); +// filePaths.push(relativePath); +// } else if (stats.isDirectory()) { +// walkDirectory(filePath); +// } +// } +// } +// +// walkDirectory(dir); +// return filePaths; +//} + +//const __filename = fileURLToPath(import.meta.url); +//const __dirname = dirname(__filename); + +//const assetsDir = join(__dirname, 'resources/assets'); +//export const paths = getFilePaths(assetsDir); + + +//export const paths = [ +// 'Modules/Recommend/resources/assets/sass/app.scss', +// 'Modules/Recommend/resources/assets/js/app.js', +//]; diff --git a/packages/Search/src/Http/Controllers/SearchController.php b/modules/Search/app/Http/Controllers/SearchController.php similarity index 93% rename from packages/Search/src/Http/Controllers/SearchController.php rename to modules/Search/app/Http/Controllers/SearchController.php index 0c45175..ba3ad77 100644 --- a/packages/Search/src/Http/Controllers/SearchController.php +++ b/modules/Search/app/Http/Controllers/SearchController.php @@ -1,6 +1,6 @@ mapWebRoutes(); + $this->mapApiRoutes(); + } + + /** + * Define the "web" routes for the application. + * + * These routes all receive session state, CSRF protection, etc. + */ + protected function mapWebRoutes(): void + { + Route::middleware('web') + ->prefix('ara') + ->name("{$this->nameLower}.") + ->group(module_path($this->name, '/routes/web.php')); + } + + /** + * Define the "api" routes for the application. + * + * These routes are typically stateless. + */ + protected function mapApiRoutes(): void + { + Route::middleware(['web', 'auth', BatchLogsActivity::class]) + ->prefix("api/{$this->nameLower}") + ->name("api.{$this->nameLower}.") + ->group(module_path($this->name, '/routes/api.php')); + } +} diff --git a/modules/Search/app/Providers/SearchServiceProvider.php b/modules/Search/app/Providers/SearchServiceProvider.php new file mode 100644 index 0000000..349ea84 --- /dev/null +++ b/modules/Search/app/Providers/SearchServiceProvider.php @@ -0,0 +1,36 @@ +app->register(RouteServiceProvider::class); + } + + /** + * Get the services provided by the provider. + * + * @return array + */ + public function provides(): array + { + return [ + SearchService::class, + ]; + } +} diff --git a/packages/Search/src/Services/SearchService.php b/modules/Search/app/Services/SearchService.php similarity index 98% rename from packages/Search/src/Services/SearchService.php rename to modules/Search/app/Services/SearchService.php index badfc27..32f6496 100644 --- a/packages/Search/src/Services/SearchService.php +++ b/modules/Search/app/Services/SearchService.php @@ -1,6 +1,6 @@ group(function () { + Route::get('/', 'search'); +}); diff --git a/modules/Search/routes/web.php b/modules/Search/routes/web.php new file mode 100644 index 0000000..47a44fd --- /dev/null +++ b/modules/Search/routes/web.php @@ -0,0 +1,7 @@ +group(function () { + Route::get('/', 'view')->name('view'); +}); diff --git a/modules/Search/vite.config.js b/modules/Search/vite.config.js new file mode 100644 index 0000000..c3e152d --- /dev/null +++ b/modules/Search/vite.config.js @@ -0,0 +1,57 @@ +import { defineConfig } from 'vite'; +import laravel from 'laravel-vite-plugin'; +import { readdirSync, statSync } from 'fs'; +import { join,relative,dirname } from 'path'; +import { fileURLToPath } from 'url'; + +export default defineConfig({ + build: { + outDir: '../../public/build-search', + emptyOutDir: true, + manifest: true, + }, + plugins: [ + laravel({ + publicDirectory: '../../public', + buildDirectory: 'build-search', + input: [ + __dirname + '/resources/assets/sass/app.scss', + __dirname + '/resources/assets/js/app.js' + ], + refresh: true, + }), + ], +}); +// Scen all resources for assets file. Return array +//function getFilePaths(dir) { +// const filePaths = []; +// +// function walkDirectory(currentPath) { +// const files = readdirSync(currentPath); +// for (const file of files) { +// const filePath = join(currentPath, file); +// const stats = statSync(filePath); +// if (stats.isFile() && !file.startsWith('.')) { +// const relativePath = 'Modules/Search/'+relative(__dirname, filePath); +// filePaths.push(relativePath); +// } else if (stats.isDirectory()) { +// walkDirectory(filePath); +// } +// } +// } +// +// walkDirectory(dir); +// return filePaths; +//} + +//const __filename = fileURLToPath(import.meta.url); +//const __dirname = dirname(__filename); + +//const assetsDir = join(__dirname, 'resources/assets'); +//export const paths = getFilePaths(assetsDir); + + +//export const paths = [ +// 'Modules/Search/resources/assets/sass/app.scss', +// 'Modules/Search/resources/assets/js/app.js', +//]; diff --git a/packages/Tag/src/Data/TagData.php b/modules/Tag/app/Data/TagData.php similarity index 92% rename from packages/Tag/src/Data/TagData.php rename to modules/Tag/app/Data/TagData.php index 13b3024..5469b78 100755 --- a/packages/Tag/src/Data/TagData.php +++ b/modules/Tag/app/Data/TagData.php @@ -1,9 +1,9 @@ $articles * @property-read int|null $articles_count - * @property-read \Illuminate\Database\Eloquent\Collection $followers + * @property-read \Illuminate\Database\Eloquent\Collection $followers * @property-read int|null $followers_count * @property-read TagProfile|null $profile * - * @method static \Packages\Tag\Database\Factories\TagFactory factory($count = null, $state = []) + * @method static \Modules\Tag\Database\Factories\TagFactory factory($count = null, $state = []) * @method static \Illuminate\Database\Eloquent\Builder|Tag newModelQuery() * @method static \Illuminate\Database\Eloquent\Builder|Tag newQuery() * @method static \Illuminate\Database\Eloquent\Builder|Tag query() @@ -41,7 +41,7 @@ */ class Tag extends Model { - /** @use HasFactory<\Packages\Tag\Database\Factories\TagFactory> */ + /** @use HasFactory<\Modules\Tag\Database\Factories\TagFactory> */ use HasFactory; use HasFollowers; diff --git a/packages/Tag/src/Models/TagProfile.php b/modules/Tag/app/Models/TagProfile.php similarity index 90% rename from packages/Tag/src/Models/TagProfile.php rename to modules/Tag/app/Models/TagProfile.php index 2d439bd..e2676df 100755 --- a/packages/Tag/src/Models/TagProfile.php +++ b/modules/Tag/app/Models/TagProfile.php @@ -1,13 +1,13 @@ |TagProfile newModelQuery() * @method static \Illuminate\Database\Eloquent\Builder|TagProfile newQuery() * @method static \Illuminate\Database\Eloquent\Builder|TagProfile query() @@ -40,7 +40,7 @@ */ class TagProfile extends Model { - /** @use HasFactory<\Packages\Tag\Database\Factories\TagProfileFactory> */ + /** @use HasFactory<\Modules\Tag\Database\Factories\TagProfileFactory> */ use HasFactory; use LogsActivity; diff --git a/packages/Tag/src/Observers/TagObserver.php b/modules/Tag/app/Observers/TagObserver.php similarity index 91% rename from packages/Tag/src/Observers/TagObserver.php rename to modules/Tag/app/Observers/TagObserver.php index a4d89c7..1ac5324 100755 --- a/packages/Tag/src/Observers/TagObserver.php +++ b/modules/Tag/app/Observers/TagObserver.php @@ -1,9 +1,9 @@ mapWebRoutes(); + } + + /** + * Define the "web" routes for the application. + * + * These routes all receive session state, CSRF protection, etc. + */ + protected function mapWebRoutes(): void + { + Route::middleware('web') + ->prefix('etiket') + ->name("{$this->nameLower}.") + ->group(module_path($this->name, '/routes/web.php')); + } +} diff --git a/modules/Tag/app/Providers/TagServiceProvider.php b/modules/Tag/app/Providers/TagServiceProvider.php new file mode 100644 index 0000000..72961bc --- /dev/null +++ b/modules/Tag/app/Providers/TagServiceProvider.php @@ -0,0 +1,108 @@ +registerPublishableResources(); + $this->loadMigrationsFrom(module_path($this->name, 'database/migrations')); + $this->loadFactoriesFrom(module_path($this->name, 'database/factories')); + } + + /** + * Register the service provider. + */ + public function register(): void + { + $this->app->register(RouteServiceProvider::class); + } + + /** + * Get the services provided by the provider. + * + * @return array + */ + public function provides(): array + { + return [ + TagService::class, + ]; + } + + /** + * Register model policies. + */ + protected function registerPolicies(): void + { + Gate::policy(Tag::class, TagPolicy::class); + } + + /** + * Register model observers. + */ + protected function registerObservers(): void + { + Tag::observe(TagObserver::class); + TagProfile::observe(TagProfileObserver::class); + } + + /** + * Register console publishes. + */ + protected function registerPublishableResources(): void + { + if ($this->app->runningInConsole()) { + $this->publishes([ + module_path($this->name, 'database/seeders') => database_path("seeders/{$this->name}"), + module_path($this->name, 'database/migrations') => database_path('migrations/'), + ], $this->nameLower); + } + } + + /** + * Register to React. + */ + protected function registerReact(): void + { + ReactService::registerHandler( + name: $this->nameLower, + class: Tag::class, + callback: fn ($slug) => app(TagService::class)->getId($slug) + ); + } + + /** + * Register to Feed. + */ + protected function registerFeed(): void + { + FeedService::registerHandler( + name: $this->nameLower, + isFilter: true, + callback: fn ($slug) => app(TagService::class)->getId($slug) + ); + } +} diff --git a/packages/Tag/src/Services/TagService.php b/modules/Tag/app/Services/TagService.php similarity index 93% rename from packages/Tag/src/Services/TagService.php rename to modules/Tag/app/Services/TagService.php index 899207a..fd42c94 100755 --- a/packages/Tag/src/Services/TagService.php +++ b/modules/Tag/app/Services/TagService.php @@ -1,15 +1,15 @@ + * @extends \Illuminate\Database\Eloquent\Factories\Factory<\Modules\Tag\Models\Tag> */ class TagFactory extends Factory { diff --git a/packages/Tag/database/factories/TagProfileFactory.php b/modules/Tag/database/factories/TagProfileFactory.php similarity index 86% rename from packages/Tag/database/factories/TagProfileFactory.php rename to modules/Tag/database/factories/TagProfileFactory.php index 5870fee..14dd0b9 100644 --- a/packages/Tag/database/factories/TagProfileFactory.php +++ b/modules/Tag/database/factories/TagProfileFactory.php @@ -1,14 +1,14 @@ + * @extends \Illuminate\Database\Eloquent\Factories\Factory<\Modules\Tag\Models\TagProfile> */ class TagProfileFactory extends Factory { diff --git a/packages/Tag/database/migrations/2025_08_15_145209_create_tags_table.php b/modules/Tag/database/migrations/2025_08_15_145209_create_tags_table.php similarity index 100% rename from packages/Tag/database/migrations/2025_08_15_145209_create_tags_table.php rename to modules/Tag/database/migrations/2025_08_15_145209_create_tags_table.php diff --git a/packages/Tag/database/migrations/2025_08_25_093825_create_tag_profiles_table.php b/modules/Tag/database/migrations/2025_08_25_093825_create_tag_profiles_table.php similarity index 100% rename from packages/Tag/database/migrations/2025_08_25_093825_create_tag_profiles_table.php rename to modules/Tag/database/migrations/2025_08_25_093825_create_tag_profiles_table.php diff --git a/packages/Tag/database/migrations/2025_10_20_053612_create_tag_profile_category_table.php b/modules/Tag/database/migrations/2025_10_20_053612_create_tag_profile_category_table.php similarity index 100% rename from packages/Tag/database/migrations/2025_10_20_053612_create_tag_profile_category_table.php rename to modules/Tag/database/migrations/2025_10_20_053612_create_tag_profile_category_table.php diff --git a/packages/Tag/database/seeders/TagSeeder.php b/modules/Tag/database/seeders/TagSeeder.php similarity index 69% rename from packages/Tag/database/seeders/TagSeeder.php rename to modules/Tag/database/seeders/TagSeeder.php index a49a189..8a1c1d4 100755 --- a/packages/Tag/database/seeders/TagSeeder.php +++ b/modules/Tag/database/seeders/TagSeeder.php @@ -1,10 +1,10 @@ group(function () { + Route::get('/{slug}', 'view')->name('view'); +}); diff --git a/packages/Tag/tests/Feature/Database/Seeders/TagSeederTest.php b/modules/Tag/tests/Feature/Database/Seeders/TagSeederTest.php similarity index 79% rename from packages/Tag/tests/Feature/Database/Seeders/TagSeederTest.php rename to modules/Tag/tests/Feature/Database/Seeders/TagSeederTest.php index 893c182..0184d59 100644 --- a/packages/Tag/tests/Feature/Database/Seeders/TagSeederTest.php +++ b/modules/Tag/tests/Feature/Database/Seeders/TagSeederTest.php @@ -1,11 +1,11 @@ user(); - /** @var \Packages\User\Models\UserProfile $profileModel */ + /** @var \Modules\User\Models\UserProfile $profileModel */ $profileModel = $user->profile; $account = [ 'name' => $user->name, @@ -194,7 +194,7 @@ public function updateProfile(Request $request): HttpResponse ]); $user = $request->user(); - /** @var \Packages\User\Models\UserProfile $profile */ + /** @var \Modules\User\Models\UserProfile $profile */ $profile = $user->profile; if ($request->hasFile('cover')) { diff --git a/packages/User/src/Http/Requests/Auth/ForgotPasswordRequest.php b/modules/User/app/Http/Requests/Auth/ForgotPasswordRequest.php similarity index 98% rename from packages/User/src/Http/Requests/Auth/ForgotPasswordRequest.php rename to modules/User/app/Http/Requests/Auth/ForgotPasswordRequest.php index 83173de..a3abe94 100755 --- a/packages/User/src/Http/Requests/Auth/ForgotPasswordRequest.php +++ b/modules/User/app/Http/Requests/Auth/ForgotPasswordRequest.php @@ -1,6 +1,6 @@ user instanceof User ? $event->user : null; diff --git a/packages/User/src/Models/User.php b/modules/User/app/Models/User.php similarity index 95% rename from packages/User/src/Models/User.php rename to modules/User/app/Models/User.php index 7677020..8140afd 100644 --- a/packages/User/src/Models/User.php +++ b/modules/User/app/Models/User.php @@ -1,6 +1,6 @@ $breezySessions * @property-read int|null $breezy_sessions_count - * @property-read \Illuminate\Database\Eloquent\Collection $followers + * @property-read \Illuminate\Database\Eloquent\Collection $followers * @property-read int|null $followers_count - * @property-read \Illuminate\Database\Eloquent\Collection $followings + * @property-read \Illuminate\Database\Eloquent\Collection $followings * @property-read int|null $followings_count * @property-read \Spatie\MediaLibrary\MediaCollections\Models\Collections\MediaCollection $media * @property-read int|null $media_count @@ -54,7 +54,7 @@ * @property-read mixed $two_factor_recovery_codes * @property-read mixed $two_factor_secret * - * @method static \Packages\User\Database\Factories\UserFactory factory($count = null, $state = []) + * @method static \Modules\User\Database\Factories\UserFactory factory($count = null, $state = []) * @method static \Illuminate\Database\Eloquent\Builder|User newModelQuery() * @method static \Illuminate\Database\Eloquent\Builder|User newQuery() * @method static \Illuminate\Database\Eloquent\Builder|User onlyTrashed() @@ -82,7 +82,7 @@ class User extends Authenticatable implements FilamentUser, HasMedia, HasAvatar { use CanFollow; - /** @use HasFactory<\Packages\User\Database\Factories\UserFactory> */ + /** @use HasFactory<\Modules\User\Database\Factories\UserFactory> */ use HasFactory; use HasFollowers; diff --git a/packages/User/src/Models/UserProfile.php b/modules/User/app/Models/UserProfile.php similarity index 94% rename from packages/User/src/Models/UserProfile.php rename to modules/User/app/Models/UserProfile.php index 3cf19d6..b63fbec 100755 --- a/packages/User/src/Models/UserProfile.php +++ b/modules/User/app/Models/UserProfile.php @@ -1,11 +1,11 @@ |UserProfile newModelQuery() * @method static \Illuminate\Database\Eloquent\Builder|UserProfile newQuery() * @method static \Illuminate\Database\Eloquent\Builder|UserProfile query() @@ -47,7 +47,7 @@ */ class UserProfile extends Model implements HasMedia { - /** @use HasFactory<\Packages\User\Database\Factories\UserProfileFactory> */ + /** @use HasFactory<\Modules\User\Database\Factories\UserProfileFactory> */ use HasFactory; use InteractsWithMedia; diff --git a/packages/User/src/Observers/UserObserver.php b/modules/User/app/Observers/UserObserver.php similarity index 92% rename from packages/User/src/Observers/UserObserver.php rename to modules/User/app/Observers/UserObserver.php index 90bc660..87a3d78 100755 --- a/packages/User/src/Observers/UserObserver.php +++ b/modules/User/app/Observers/UserObserver.php @@ -1,12 +1,12 @@ > + */ + protected $listen = [ + Login::class => [ + AuthListener::class, + ], + Logout::class => [ + AuthListener::class, + ], + Registered::class => [ + AuthListener::class, + ], + PasswordReset::class => [ + AuthListener::class, + ], + PasswordResetLinkSent::class => [ + AuthListener::class, + ], + ]; + + /** + * Indicates if events should be discovered. + * + * @var bool + */ + protected static $shouldDiscoverEvents = true; + + /** + * Configure the proper event listeners for email verification. + */ + protected function configureEmailVerification(): void + { + } +} diff --git a/modules/User/app/Providers/RouteServiceProvider.php b/modules/User/app/Providers/RouteServiceProvider.php new file mode 100644 index 0000000..699e39c --- /dev/null +++ b/modules/User/app/Providers/RouteServiceProvider.php @@ -0,0 +1,47 @@ +mapWebRoutes(); + $this->mapApiRoutes(); + } + + /** + * Define the "web" routes for the application. + * + * These routes all receive session state, CSRF protection, etc. + */ + protected function mapWebRoutes(): void + { + Route::middleware('web') + ->group(module_path($this->name, '/routes/web.php')); + } + + /** + * Define the "api" routes for the application. + * + * These routes are typically stateless. + */ + protected function mapApiRoutes(): void + { + Route::middleware(['web', 'auth', BatchLogsActivity::class]) + ->prefix('api') + ->name('api.') + ->group(module_path($this->name, '/routes/api.php')); + } +} diff --git a/modules/User/app/Providers/UserServiceProvider.php b/modules/User/app/Providers/UserServiceProvider.php new file mode 100644 index 0000000..25ed570 --- /dev/null +++ b/modules/User/app/Providers/UserServiceProvider.php @@ -0,0 +1,115 @@ +registerPublishableResources(); + $this->loadMigrationsFrom(module_path($this->name, 'database/migrations')); + $this->loadFactoriesFrom(module_path($this->name, 'database/factories')); + } + + /** + * Register the service provider. + */ + public function register(): void + { + $this->app->register(EventServiceProvider::class); + $this->app->register(RouteServiceProvider::class); + } + + /** + * Get the services provided by the provider. + * + * @return array + */ + public function provides(): array + { + return [ + UserService::class, + ]; + } + + /** + * Register model policies. + */ + protected function registerPolicies(): void + { + Gate::policy(User::class, UserPolicy::class); + } + + /** + * Register model observers. + */ + protected function registerObservers(): void + { + User::observe(UserObserver::class); + UserProfile::observe(UserProfileObserver::class); + } + + /** + * Register console publishes. + */ + protected function registerPublishableResources(): void + { + if ($this->app->runningInConsole()) { + $this->publishes([ + module_path($this->name, 'database/seeders') => database_path("seeders/{$this->name}"), + module_path($this->name, 'database/migrations') => database_path('migrations/'), + ], $this->nameLower); + } + } + + protected function registerSearch(): void + { + SearchService::registerHandler( + index: 'users', + callback: fn ($hit) => app(UserService::class)->getData($hit['id']), + searchableAttributes: ['name', 'username'], + filterableAttributes: ['id'], + sortableAttributes: ['created_at'] + ); + } + + protected function registerReact(): void + { + ReactService::registerHandler( + name: $this->nameLower, + class: User::class, + callback: fn ($slug) => app(UserService::class)->getId($slug) + ); + } + + protected function registerFeed(): void + { + FeedService::registerHandler( + name: $this->nameLower, + isFilter: true, + callback: fn ($slug) => app(UserService::class)->getId($slug) + ); + } +} diff --git a/packages/User/src/Services/SessionService.php b/modules/User/app/Services/SessionService.php similarity index 99% rename from packages/User/src/Services/SessionService.php rename to modules/User/app/Services/SessionService.php index d0c753d..ff440d6 100644 --- a/packages/User/src/Services/SessionService.php +++ b/modules/User/app/Services/SessionService.php @@ -1,6 +1,6 @@ + * @extends \Illuminate\Database\Eloquent\Factories\Factory<\Modules\User\Models\UserProfile> */ class UserProfileFactory extends Factory { diff --git a/packages/User/database/migrations/0001_01_01_000000_create_users_table.php b/modules/User/database/migrations/0001_01_01_000000_create_users_table.php similarity index 100% rename from packages/User/database/migrations/0001_01_01_000000_create_users_table.php rename to modules/User/database/migrations/0001_01_01_000000_create_users_table.php diff --git a/packages/User/database/migrations/2025_08_20_154902_create_user_profiles_table.php b/modules/User/database/migrations/2025_08_20_154902_create_user_profiles_table.php similarity index 100% rename from packages/User/database/migrations/2025_08_20_154902_create_user_profiles_table.php rename to modules/User/database/migrations/2025_08_20_154902_create_user_profiles_table.php diff --git a/packages/User/database/seeders/UserSeeder.php b/modules/User/database/seeders/UserSeeder.php similarity index 88% rename from packages/User/database/seeders/UserSeeder.php rename to modules/User/database/seeders/UserSeeder.php index 75cf251..f1cf6e9 100755 --- a/packages/User/database/seeders/UserSeeder.php +++ b/modules/User/database/seeders/UserSeeder.php @@ -1,11 +1,11 @@ name('user.')->group(function () { + Route::get('/{username}/preview', [UserController::class, 'preview'])->name('preview'); +}); + +Route::prefix('auth')->name('auth.')->group(function () { + Route::post('/login', [AuthController::class, 'login'])->name('login'); + Route::post('/register', [AuthController::class, 'register'])->name('register'); + Route::post('/forgot-password', [AuthController::class, 'forgotPassword'])->name('forgot-password'); + Route::post('/reset-password', [AuthController::class, 'resetPassword'])->name('reset-password.request'); +}); + +Route::middleware('auth')->group(function () { + Route::post('/auth/logout', [AuthController::class, 'logout'])->name('auth.logout'); + + Route::prefix('user/me/settings')->name('user.settings.')->group(function () { + Route::post('/account', [UserController::class, 'updateAccount'])->name('account')->can('update-account'); + Route::post('/profile', [UserController::class, 'updateProfile'])->name('profile')->can('update-profile'); + Route::post('/password', [UserController::class, 'updatePassword'])->name('password')->can('update-password'); + Route::post('/logout-other-sessions', [UserController::class, 'logOutOtherSessions'])->name('logout-other-sessions')->can('delete-sessions'); + Route::post('/delete-account', [UserController::class, 'deleteAccount'])->name('delete-account')->can('delete-account'); + }); + + Route::post('/user/me/verification/resend', [UserController::class, 'verificationResend'])->name('user.verification.resend'); + + Route::prefix('notifications')->name('notification.')->controller(NotificationController::class)->group(function () { + Route::get('/', 'list')->name('list')->can('view-notification'); + Route::get('/count', 'count')->name('count')->can('view-notification'); + Route::post('/mark-as-read', 'read')->name('read')->can('view-notification'); + Route::post('/mark-all-as-read', 'readAll')->name('read-all')->can('view-notification'); + }); +}); diff --git a/modules/User/routes/web.php b/modules/User/routes/web.php new file mode 100755 index 0000000..5b29413 --- /dev/null +++ b/modules/User/routes/web.php @@ -0,0 +1,21 @@ +name('user.view'); + +Route::middleware('auth') + ->prefix('user') + ->name('user.') + ->controller(UserController::class) + ->group(function () { + Route::get('/me/settings', 'settingsView')->name('settings.view'); + Route::get('/me/verification', 'verificationView')->name('verification.view'); + Route::middleware('signed') + ->get('/me/verification/verify/{id}/{hash}', 'verificationVerify') + ->name('verification.verify'); + }); + +Route::get('/auth/reset-password', [AuthController::class, 'viewResetPassword'])->name('auth.reset-password.view'); diff --git a/modules/User/vite.config.js b/modules/User/vite.config.js new file mode 100644 index 0000000..f397306 --- /dev/null +++ b/modules/User/vite.config.js @@ -0,0 +1,57 @@ +import { defineConfig } from 'vite'; +import laravel from 'laravel-vite-plugin'; +import { readdirSync, statSync } from 'fs'; +import { join,relative,dirname } from 'path'; +import { fileURLToPath } from 'url'; + +export default defineConfig({ + build: { + outDir: '../../public/build-user', + emptyOutDir: true, + manifest: true, + }, + plugins: [ + laravel({ + publicDirectory: '../../public', + buildDirectory: 'build-user', + input: [ + __dirname + '/resources/assets/sass/app.scss', + __dirname + '/resources/assets/js/app.js' + ], + refresh: true, + }), + ], +}); +// Scen all resources for assets file. Return array +//function getFilePaths(dir) { +// const filePaths = []; +// +// function walkDirectory(currentPath) { +// const files = readdirSync(currentPath); +// for (const file of files) { +// const filePath = join(currentPath, file); +// const stats = statSync(filePath); +// if (stats.isFile() && !file.startsWith('.')) { +// const relativePath = 'Modules/User/'+relative(__dirname, filePath); +// filePaths.push(relativePath); +// } else if (stats.isDirectory()) { +// walkDirectory(filePath); +// } +// } +// } +// +// walkDirectory(dir); +// return filePaths; +//} + +//const __filename = fileURLToPath(import.meta.url); +//const __dirname = dirname(__filename); + +//const assetsDir = join(__dirname, 'resources/assets'); +//export const paths = getFilePaths(assetsDir); + + +//export const paths = [ +// 'Modules/User/resources/assets/sass/app.scss', +// 'Modules/User/resources/assets/js/app.js', +//]; diff --git a/modules_statuses.json b/modules_statuses.json new file mode 100644 index 0000000..6ac07c6 --- /dev/null +++ b/modules_statuses.json @@ -0,0 +1,13 @@ +{ + "Article": true, + "Category": true, + "Course": true, + "Entry": true, + "News": true, + "Page": true, + "React": true, + "Recommend": true, + "Search": true, + "Tag": true, + "User": true +} \ No newline at end of file diff --git a/packages/Article/routes/api.php b/packages/Article/routes/api.php deleted file mode 100644 index df37336..0000000 --- a/packages/Article/routes/api.php +++ /dev/null @@ -1,20 +0,0 @@ -prefix('api/article')->middleware([BatchLogsActivity::class])->group(function () { - Route::middleware('auth')->group(function () { - Route::prefix('crud')->name('crud.')->controller(ArticleCrudController::class)->group(function () { - Route::post('/create', 'create') - ->name('create') - ->can('create', Article::class); - - Route::post('/{article:slug}/edit', 'edit') - ->name('edit') - ->can('update,article'); - }); - }); -}); diff --git a/packages/Article/routes/web.php b/packages/Article/routes/web.php deleted file mode 100644 index c8adf51..0000000 --- a/packages/Article/routes/web.php +++ /dev/null @@ -1,20 +0,0 @@ -prefix('makale')->name('article.')->group(function () { - Route::controller(ArticleCrudController::class)->middleware('auth')->name('crud.')->group(function () { - Route::get('/yaz', 'createView')->name('create.view')->can('create', Article::class); - Route::get('/{article:slug}/duzenle', 'editView')->name('edit.view')->can('update,article'); - }); - - Route::controller(ArticleController::class)->group(function () { - Route::get('/{slug}', 'view')->name('view'); - }); -}); - -require __DIR__ . '/api.php'; diff --git a/packages/Article/src/ArticleProvider.php b/packages/Article/src/ArticleProvider.php deleted file mode 100644 index bd245b2..0000000 --- a/packages/Article/src/ArticleProvider.php +++ /dev/null @@ -1,126 +0,0 @@ -loadPolicies(); - $this->loadObservers(); - $this->loadEvents(); - $this->loadCommands(); - $this->loadRoutes(); - $this->loadFactories(); - $this->loadSeeders(); - $this->loadTranslations(); - $this->loadMigrations(); - $this->configureSearch(); - $this->configureReact(); - $this->configureFeed(); - } - - public function loadPolicies(): void - { - Gate::policy(Article::class, ArticlePolicy::class); - } - - public function loadObservers(): void - { - Article::observe(ArticleObserver::class); - } - - public function loadEvents(): void - { - Event::listen(ArticlePublishedEvent::class, ArticlePublishedListener::class); - } - - public function loadCommands(): void - { - $this->commands([ - ScheduleArticleCommand::class, - ]); - } - - public function loadRoutes(): void - { - Route::middleware('web') - ->namespace('Packages\Article\Http\Controllers') - ->group(__DIR__ . '/../routes/web.php'); - } - - protected function loadFactories(): void - { - $this->loadFactoriesFrom(__DIR__ . '/../database/factories'); - } - - protected function loadSeeders(): void - { - if ($this->app->runningInConsole()) { - $this->publishes([ - __DIR__ . '/../database/seeders' => database_path('seeders/packages/article'), - ], 'article-seeders'); - } - } - - protected function loadTranslations(): void - { - $this->loadTranslationsFrom(__DIR__ . '/../resources/lang', 'article'); - } - - protected function loadMigrations(): void - { - $this->loadMigrationsFrom(__DIR__ . '/../database/migrations'); - if ($this->app->runningInConsole()) { - $this->publishes([ - __DIR__ . '/../database/migrations' => database_path('migrations/'), - ], 'migrations'); - } - } - - protected function configureSearch(): void - { - SearchService::registerHandler( - index: 'articles', - callback: fn ($hit) => app(Services\ArticleService::class)->getData($hit['id']), - searchableAttributes: ['title'], - filterableAttributes: ['id'], - sortableAttributes: ['updated_at'] - ); - } - - protected function configureReact(): void - { - ReactService::registerHandler( - name: 'article', - class: Article::class, - callback: fn ($slug) => app(Services\ArticleService::class)->getId($slug) - ); - } - - protected function configureFeed(): void - { - FeedService::registerHandler( - name: 'article', - isFilter: false, - callback: fn ($slug) => app(Services\ArticleService::class)->getData($slug) - ); - } -} diff --git a/packages/Category/routes/web.php b/packages/Category/routes/web.php deleted file mode 100644 index ba5c3df..0000000 --- a/packages/Category/routes/web.php +++ /dev/null @@ -1,8 +0,0 @@ -prefix('kategori')->name('category.')->controller(CategoryController::class)->group(function () { - Route::get('/{slug}', 'view')->name('view'); -}); diff --git a/packages/Category/src/CategoryProvider.php b/packages/Category/src/CategoryProvider.php deleted file mode 100644 index 2a0f8fa..0000000 --- a/packages/Category/src/CategoryProvider.php +++ /dev/null @@ -1,92 +0,0 @@ -loadPolicies(); - $this->loadObservers(); - $this->loadRoutes(); - $this->loadFactories(); - $this->loadSeeders(); - $this->loadMigrations(); - $this->configureReact(); - $this->configureFeed(); - } - - public function loadPolicies(): void - { - Gate::policy(Category::class, CategoryPolicy::class); - } - - public function loadObservers(): void - { - Category::observe(CategoryObserver::class); - CategoryProfile::observe(CategoryProfileObserver::class); - } - - public function loadRoutes(): void - { - Route::middleware('web') - ->namespace('Packages\Category\Http\Controllers') - ->group(__DIR__ . '/../routes/web.php'); - } - - protected function loadFactories(): void - { - $this->loadFactoriesFrom(__DIR__ . '/../database/factories'); - } - - protected function loadSeeders(): void - { - if ($this->app->runningInConsole()) { - $this->publishes([ - __DIR__ . '/../database/seeders' => database_path('seeders/packages/category'), - ], 'category-seeders'); - } - } - - protected function loadMigrations(): void - { - $this->loadMigrationsFrom(__DIR__ . '/../database/migrations'); - if ($this->app->runningInConsole()) { - $this->publishes([ - __DIR__ . '/../database/migrations' => database_path('migrations/'), - ], 'migrations'); - } - } - - protected function configureReact(): void - { - ReactService::registerHandler( - name: 'category', - class: Category::class, - callback: fn ($slug) => app(Services\CategoryService::class)->getId($slug) - ); - } - - protected function configureFeed(): void - { - FeedService::registerHandler( - name: 'category', - isFilter: true, - callback: fn ($slug) => app(Services\CategoryService::class)->getId($slug) - ); - } -} diff --git a/packages/Course/routes/api.php b/packages/Course/routes/api.php deleted file mode 100644 index b3d9bbc..0000000 --- a/packages/Course/routes/api.php +++ /dev/null @@ -1 +0,0 @@ -prefix('egitim')->name('course.')->controller(CourseController::class)->group(function () { - Route::get('/{slug}', 'view')->name('view'); - Route::get('/{slug}/{page}', 'page')->name('page'); -}); - -require __DIR__ . '/api.php'; diff --git a/packages/Course/src/CourseProvider.php b/packages/Course/src/CourseProvider.php deleted file mode 100644 index e9fe84a..0000000 --- a/packages/Course/src/CourseProvider.php +++ /dev/null @@ -1,147 +0,0 @@ -loadPolicies(); - $this->loadObservers(); - $this->loadEvents(); - $this->loadCommands(); - $this->loadRoutes(); - $this->loadFactories(); - $this->loadSeeders(); - $this->loadTranslations(); - $this->loadMigrations(); - $this->configureSearch(); - $this->configureFeed(); - } - - public function loadPolicies(): void - { - Gate::policy(Course::class, CoursePolicy::class); - Gate::policy(CourseChapter::class, CourseChapterPolicy::class); - Gate::policy(CourseLesson::class, CourseLessonPolicy::class); - } - - public function loadObservers(): void - { - Course::observe(CourseObserver::class); - CourseLesson::observe(CourseLessonObserver::class); - CourseChapter::observe(CourseChapterObserver::class); - } - - public function loadEvents(): void - { - Event::listen(CoursePublishedEvent::class, CoursePublishedListener::class); - Event::listen(LessonPublishedEvent::class, LessonPublishedListener::class); - } - - public function loadCommands(): void - { - $this->commands([ - ScheduleCourseCommand::class, - ScheduleLessonCommand::class, - ]); - } - - public function loadRoutes(): void - { - Route::middleware('web') - ->namespace('Packages\Course\Http\Controllers') - ->group(__DIR__ . '/../routes/web.php'); - } - - protected function loadFactories(): void - { - $this->loadFactoriesFrom(__DIR__ . '/../database/factories'); - } - - protected function loadSeeders(): void - { - if ($this->app->runningInConsole()) { - $this->publishes([ - __DIR__ . '/../database/seeders' => database_path('seeders/packages/course'), - ], 'seeders'); - } - } - - protected function loadTranslations(): void - { - $this->loadTranslationsFrom(__DIR__ . '/../resources/lang', 'course'); - } - - protected function loadMigrations(): void - { - $this->loadMigrationsFrom(__DIR__ . '/../database/migrations'); - if ($this->app->runningInConsole()) { - $this->publishes([ - __DIR__ . '/../database/migrations' => database_path('migrations/'), - ], 'migrations'); - } - } - - protected function configureSearch(): void - { - SearchService::registerHandler( - index: 'courses', - callback: fn ($hit) => app(Services\CourseService::class)->getData($hit['id']), - searchableAttributes: ['title'], - filterableAttributes: ['id'], - sortableAttributes: ['updated_at'] - ); - SearchService::registerHandler( - index: 'lessons', - callback: fn ($hit) => app(Services\CourseService::class)->getLessonByChapter($hit['chapter_id'], $hit['id']), - searchableAttributes: ['title'], - filterableAttributes: ['id', 'chapter_id'], - sortableAttributes: ['updated_at'] - ); - } - - protected function configureReact(): void - { - ReactService::registerHandler( - name: 'course', - class: Course::class, - callback: fn ($slug) => app(Services\CourseService::class)->getId($slug) - ); - } - - protected function configureFeed(): void - { - FeedService::registerHandler( - name: 'course', - isFilter: false, - callback: fn ($slug) => app(Services\CourseService::class)->getData($slug) - ); - } -} diff --git a/packages/Entry/routes/api.php b/packages/Entry/routes/api.php deleted file mode 100644 index aae77fa..0000000 --- a/packages/Entry/routes/api.php +++ /dev/null @@ -1,16 +0,0 @@ -prefix('api/entry')->middleware([BatchLogsActivity::class])->group(function () { - Route::middleware('auth')->group(function () { - Route::prefix('crud')->name('crud.')->controller(EntryCrudController::class)->group(function () { - Route::post('/create', 'create') - ->name('create') - ->can('create', Entry::class); - }); - }); -}); diff --git a/packages/Entry/routes/web.php b/packages/Entry/routes/web.php deleted file mode 100644 index da192d5..0000000 --- a/packages/Entry/routes/web.php +++ /dev/null @@ -1,13 +0,0 @@ -prefix('entry')->name('entry.')->group(function () { - Route::controller(EntryController::class)->group(function () { - Route::get('/{slug}', 'view')->name('view'); - }); -}); - -require __DIR__ . '/api.php'; diff --git a/packages/Entry/src/EntryProvider.php b/packages/Entry/src/EntryProvider.php deleted file mode 100644 index c544de6..0000000 --- a/packages/Entry/src/EntryProvider.php +++ /dev/null @@ -1,89 +0,0 @@ -loadPolicies(); - $this->loadObservers(); - $this->loadRoutes(); - $this->loadFactories(); - $this->loadSeeders(); - $this->loadMigrations(); - $this->configureReact(); - $this->configureFeed(); - } - - public function loadPolicies(): void - { - Gate::policy(Entry::class, EntryPolicy::class); - } - - public function loadObservers(): void - { - Entry::observe(EntryObserver::class); - } - - public function loadRoutes(): void - { - Route::middleware('web') - ->namespace('Packages\Entry\Http\Controllers') - ->group(__DIR__ . '/../routes/web.php'); - } - - protected function loadFactories(): void - { - $this->loadFactoriesFrom(__DIR__ . '/../database/factories'); - } - - protected function loadSeeders(): void - { - if ($this->app->runningInConsole()) { - $this->publishes([ - __DIR__ . '/../database/seeders' => database_path('seeders/packages/entry'), - ], 'entry-seeders'); - } - } - - protected function loadMigrations(): void - { - $this->loadMigrationsFrom(__DIR__ . '/../database/migrations'); - if ($this->app->runningInConsole()) { - $this->publishes([ - __DIR__ . '/../database/migrations' => database_path('migrations/'), - ], 'migrations'); - } - } - - protected function configureReact(): void - { - ReactService::registerHandler( - name: 'entry', - class: Entry::class, - callback: fn ($slug) => app(Services\EntryService::class)->getId($slug) - ); - } - - protected function configureFeed(): void - { - FeedService::registerHandler( - name: 'entry', - isFilter: false, - callback: fn ($slug) => app(Services\EntryService::class)->getData($slug) - ); - } -} diff --git a/packages/News/src/NewsProvider.php b/packages/News/src/NewsProvider.php deleted file mode 100644 index c214dc4..0000000 --- a/packages/News/src/NewsProvider.php +++ /dev/null @@ -1,63 +0,0 @@ -loadPolicies(); - $this->loadObservers(); - $this->loadSeeders(); - $this->loadMigrations(); - $this->configureFeed(); - } - - public function loadPolicies(): void - { - Gate::policy(News::class, NewsPolicy::class); - } - - public function loadObservers(): void - { - News::observe(NewsObserver::class); - } - - protected function loadSeeders(): void - { - if ($this->app->runningInConsole()) { - $this->publishes([ - __DIR__ . '/../database/seeders' => database_path('seeders/packages/news'), - ], 'news-seeders'); - } - } - - protected function loadMigrations(): void - { - $this->loadMigrationsFrom(__DIR__ . '/../database/migrations'); - if ($this->app->runningInConsole()) { - $this->publishes([ - __DIR__ . '/../database/migrations' => database_path('migrations/'), - ], 'migrations'); - } - } - - protected function configureFeed(): void - { - FeedService::registerHandler( - name: 'news', - isFilter: false, - callback: fn ($slug) => app(Services\NewsService::class)->getData($slug) - ); - } -} diff --git a/packages/Page/routes/web.php b/packages/Page/routes/web.php deleted file mode 100644 index 1a6c669..0000000 --- a/packages/Page/routes/web.php +++ /dev/null @@ -1,8 +0,0 @@ -name('page.')->prefix('sayfa')->controller(PageController::class)->group(function () { - Route::get('/{slug}', 'view')->name('view'); -}); diff --git a/packages/Page/src/PageProvider.php b/packages/Page/src/PageProvider.php deleted file mode 100644 index 1f1f71f..0000000 --- a/packages/Page/src/PageProvider.php +++ /dev/null @@ -1,104 +0,0 @@ -loadPolicies(); - $this->loadObservers(); - $this->loadEvents(); - $this->loadCommands(); - $this->loadRoutes(); - $this->loadFactories(); - $this->loadSeeders(); - $this->loadTranslations(); - $this->loadMigrations(); - $this->configureSearch(); - } - - public function loadPolicies(): void - { - Gate::policy(Page::class, PagePolicy::class); - } - - public function loadObservers(): void - { - Page::observe(PageObserver::class); - } - - public function loadEvents(): void - { - Event::listen(PagePublishedEvent::class, PagePublishedListener::class); - } - - public function loadCommands(): void - { - $this->commands([ - SchedulePageCommand::class, - ]); - } - - public function loadRoutes(): void - { - Route::middleware('web') - ->namespace('Packages\Page\Http\Controllers') - ->group(__DIR__ . '/../routes/web.php'); - } - - protected function loadFactories(): void - { - $this->loadFactoriesFrom(__DIR__ . '/../database/factories'); - } - - protected function loadSeeders(): void - { - if ($this->app->runningInConsole()) { - $this->publishes([ - __DIR__ . '/../database/seeders' => database_path('seeders/packages/page'), - ], 'page-seeders'); - } - } - - protected function loadTranslations(): void - { - $this->loadTranslationsFrom(__DIR__ . '/../resources/lang', 'page'); - } - - protected function loadMigrations(): void - { - $this->loadMigrationsFrom(__DIR__ . '/../database/migrations'); - if ($this->app->runningInConsole()) { - $this->publishes([ - __DIR__ . '/../database/migrations' => database_path('migrations/'), - ], 'migrations'); - } - } - - protected function configureSearch(): void - { - SearchService::registerHandler( - index: 'pages', - callback: fn ($hit) => app(Services\PageService::class)->getData($hit['id']), - searchableAttributes: ['title'], - filterableAttributes: ['id'], - sortableAttributes: ['updated_at'] - ); - } -} diff --git a/packages/React/src/ReactProvider.php b/packages/React/src/ReactProvider.php deleted file mode 100644 index 53b1537..0000000 --- a/packages/React/src/ReactProvider.php +++ /dev/null @@ -1,108 +0,0 @@ -loadPolicies(); - $this->loadObservers(); - $this->loadRoutes(); - $this->loadEvents(); - $this->loadFactories(); - $this->loadMigrations(); - $this->configureReact(); - $this->configureFeed(); - } - - public function loadPolicies(): void - { - Gate::policy(Like::class, LikePolicy::class); - Gate::policy(Dislike::class, DislikePolicy::class); - Gate::policy(Save::class, SavePolicy::class); - Gate::policy(Comment::class, CommentPolicy::class); - Gate::policy(Follow::class, FollowPolicy::class); - } - - public function loadObservers(): void - { - Like::observe(LikeObserver::class); - Dislike::observe(DislikeObserver::class); - Save::observe(SaveObserver::class); - Comment::observe(CommentObserver::class); - Follow::observe(FollowObserver::class); - } - - public function loadRoutes(): void - { - Route::middleware('web') - ->namespace('Packages\React\Http\Controllers') - ->group(__DIR__ . '/../routes/api.php'); - } - - public function loadEvents(): void - { - Event::listen(FollowedEvent::class, FollowedListener::class); - } - - protected function loadFactories(): void - { - $this->loadFactoriesFrom(__DIR__ . '/../database/factories'); - } - - protected function loadMigrations(): void - { - $this->loadMigrationsFrom(__DIR__ . '/../database/migrations'); - if ($this->app->runningInConsole()) { - $this->publishes([ - __DIR__ . '/../database/migrations' => database_path('migrations/'), - ], 'migrations'); - } - } - - protected function configureReact(): void - { - ReactService::registerHandler( - name: 'comment', - class: Comment::class, - callback: fn ($slug) => $slug - ); - } - - protected function configureFeed(): void - { - FeedService::registerHandler( - name: 'article', - isFilter: false, - callback: fn ($slug) => app(ReactService::class)->getComment($slug) - ); - } -} diff --git a/packages/Recommend/routes/api.php b/packages/Recommend/routes/api.php deleted file mode 100644 index 7ad5aef..0000000 --- a/packages/Recommend/routes/api.php +++ /dev/null @@ -1,10 +0,0 @@ -prefix('api/feed')->middleware(BatchLogsActivity::class)->controller(FeedController::class)->group(function () { - Route::get('/', 'data')->name('data'); - Route::get('/feed', 'feed')->name('feed'); -}); diff --git a/packages/Recommend/src/RecommendProvider.php b/packages/Recommend/src/RecommendProvider.php deleted file mode 100644 index 79d6544..0000000 --- a/packages/Recommend/src/RecommendProvider.php +++ /dev/null @@ -1,42 +0,0 @@ -loadRoutes(); - $this->loadConfig(); - $this->loadCommands(); - } - - public function loadRoutes(): void - { - Route::middleware('web') - ->namespace('Packages\Recommend\Http\Controllers') - ->group(__DIR__ . '/../routes/api.php'); - } - - public function loadConfig(): void - { - $this->publishes([ - __DIR__ . '/../config/recommend.php' => config_path('recommend.php'), - ]); - $this->mergeConfigFrom(__DIR__ . '/../config/recommend.php', 'recommend'); - } - - public function loadCommands(): void - { - $this->commands([ - UploadRecommendations::class, - ]); - } -} diff --git a/packages/Search/routes/api.php b/packages/Search/routes/api.php deleted file mode 100644 index ee88977..0000000 --- a/packages/Search/routes/api.php +++ /dev/null @@ -1,7 +0,0 @@ -prefix('api/search')->controller(SearchController::class)->group(function () { - Route::get('/', 'search'); -}); diff --git a/packages/Search/routes/web.php b/packages/Search/routes/web.php deleted file mode 100644 index 97d8565..0000000 --- a/packages/Search/routes/web.php +++ /dev/null @@ -1,10 +0,0 @@ -prefix('ara')->name('search.')->controller(SearchController::class)->group(function () { - Route::get('/', 'view')->name('view'); -}); - -require __DIR__ . '/api.php'; diff --git a/packages/Search/src/SearchProvider.php b/packages/Search/src/SearchProvider.php deleted file mode 100644 index 5ff5669..0000000 --- a/packages/Search/src/SearchProvider.php +++ /dev/null @@ -1,24 +0,0 @@ -loadRoutes(); - } - - public function loadRoutes(): void - { - Route::middleware('web') - ->namespace('Packages\Search\Http\Controllers') - ->group(__DIR__ . '/../routes/web.php'); - } -} diff --git a/packages/Tag/routes/web.php b/packages/Tag/routes/web.php deleted file mode 100644 index 4958c7f..0000000 --- a/packages/Tag/routes/web.php +++ /dev/null @@ -1,8 +0,0 @@ -prefix('etiket')->controller(TagController::class)->name('tag.')->group(function () { - Route::get('/{slug}', 'view')->name('view'); -}); diff --git a/packages/Tag/src/TagProvider.php b/packages/Tag/src/TagProvider.php deleted file mode 100644 index 81826ca..0000000 --- a/packages/Tag/src/TagProvider.php +++ /dev/null @@ -1,92 +0,0 @@ -loadPolicies(); - $this->loadObservers(); - $this->loadRoutes(); - $this->loadFactories(); - $this->loadSeeders(); - $this->loadMigrations(); - $this->configureReact(); - $this->configureFeed(); - } - - public function loadPolicies(): void - { - Gate::policy(Tag::class, TagPolicy::class); - } - - public function loadObservers(): void - { - Tag::observe(TagObserver::class); - TagProfile::observe(TagProfileObserver::class); - } - - public function loadRoutes(): void - { - Route::middleware('web') - ->namespace('Packages\Tag\Http\Controllers') - ->group(__DIR__ . '/../routes/web.php'); - } - - protected function loadFactories(): void - { - $this->loadFactoriesFrom(__DIR__ . '/../database/factories'); - } - - protected function loadSeeders(): void - { - if ($this->app->runningInConsole()) { - $this->publishes([ - __DIR__ . '/../database/seeders' => database_path('seeders/packages/tag'), - ], 'seeders'); - } - } - - protected function loadMigrations(): void - { - $this->loadMigrationsFrom(__DIR__ . '/../database/migrations'); - if ($this->app->runningInConsole()) { - $this->publishes([ - __DIR__ . '/../database/migrations' => database_path('migrations/'), - ], 'migrations'); - } - } - - protected function configureReact(): void - { - ReactService::registerHandler( - name: 'tag', - class: Tag::class, - callback: fn ($slug) => app(Services\TagService::class)->getId($slug) - ); - } - - protected function configureFeed(): void - { - FeedService::registerHandler( - name: 'tag', - isFilter: true, - callback: fn ($slug) => app(Services\TagService::class)->getId($slug) - ); - } -} diff --git a/packages/User/routes/api.php b/packages/User/routes/api.php deleted file mode 100755 index b530e19..0000000 --- a/packages/User/routes/api.php +++ /dev/null @@ -1,41 +0,0 @@ -prefix('api')->middleware(BatchLogsActivity::class)->group(function () { - Route::prefix('user')->name('user.')->group(function () { - Route::get('/{username}/preview', [UserController::class, 'preview'])->name('preview'); - }); - - Route::prefix('auth')->name('auth.')->group(function () { - Route::post('/login', [AuthController::class, 'login'])->name('login'); - Route::post('/register', [AuthController::class, 'register'])->name('register'); - Route::post('/forgot-password', [AuthController::class, 'forgotPassword'])->name('forgot-password'); - Route::post('/reset-password', [AuthController::class, 'resetPassword'])->name('reset-password.request'); - }); - - Route::middleware('auth')->group(function () { - Route::post('/auth/logout', [AuthController::class, 'logout'])->name('auth.logout'); - - Route::prefix('user/me/settings')->name('user.settings.')->group(function () { - Route::post('/account', [UserController::class, 'updateAccount'])->name('account')->can('update-account'); - Route::post('/profile', [UserController::class, 'updateProfile'])->name('profile')->can('update-profile'); - Route::post('/password', [UserController::class, 'updatePassword'])->name('password')->can('update-password'); - Route::post('/logout-other-sessions', [UserController::class, 'logOutOtherSessions'])->name('logout-other-sessions')->can('delete-sessions'); - Route::post('/delete-account', [UserController::class, 'deleteAccount'])->name('delete-account')->can('delete-account'); - }); - - Route::post('/user/me/verification/resend', [UserController::class, 'verificationResend'])->name('user.verification.resend'); - - Route::prefix('notifications')->name('notification.')->controller(NotificationController::class)->group(function () { - Route::get('/', 'list')->name('list')->can('view-notification'); - Route::get('/count', 'count')->name('count')->can('view-notification'); - Route::post('/mark-as-read', 'read')->name('read')->can('view-notification'); - Route::post('/mark-all-as-read', 'readAll')->name('read-all')->can('view-notification'); - }); - }); -}); diff --git a/packages/User/routes/web.php b/packages/User/routes/web.php deleted file mode 100755 index 1ec19e7..0000000 --- a/packages/User/routes/web.php +++ /dev/null @@ -1,22 +0,0 @@ -group(function () { - Route::get('/@{username}', [UserController::class, 'view'])->name('user.view'); - - Route::name('user.')->prefix('user')->controller(UserController::class)->middleware('auth')->group(function () { - Route::get('/me/settings', 'settingsView')->name('settings.view'); - Route::get('/me/verification', 'verificationView')->name('verification.view'); - Route::middleware('signed') - ->get('/me/verification/verify/{id}/{hash}', 'verificationVerify') - ->name('verification.verify'); - }); - - Route::get('/auth/reset-password', [AuthController::class, 'viewResetPassword'])->name('auth.reset-password.view'); -}); - -require __DIR__ . '/api.php'; diff --git a/packages/User/src/UserProvider.php b/packages/User/src/UserProvider.php deleted file mode 100644 index d3e629a..0000000 --- a/packages/User/src/UserProvider.php +++ /dev/null @@ -1,104 +0,0 @@ -loadPolicies(); - $this->loadObservers(); - $this->loadRoutes(); - $this->loadFactories(); - $this->loadSeeders(); - $this->loadMigrations(); - $this->configureReact(); - $this->configureFeed(); - } - - public function loadPolicies(): void - { - Gate::policy(User::class, UserPolicy::class); - } - - public function loadObservers(): void - { - User::observe(UserObserver::class); - UserProfile::observe(UserProfileObserver::class); - } - - public function loadRoutes(): void - { - Route::middleware('web') - ->namespace('Packages\User\Http\Controllers') - ->group(__DIR__ . '/../routes/web.php'); - } - - protected function loadFactories(): void - { - $this->loadFactoriesFrom(__DIR__ . '/../database/factories'); - } - - protected function loadSeeders(): void - { - if ($this->app->runningInConsole()) { - $this->publishes([ - __DIR__ . '/../database/seeders' => database_path('seeders/packages/user'), - ], 'seeders'); - } - } - - protected function loadMigrations(): void - { - $this->loadMigrationsFrom(__DIR__ . '/../database/migrations'); - if ($this->app->runningInConsole()) { - $this->publishes([ - __DIR__ . '/../database/migrations' => database_path('migrations/'), - ], 'migrations'); - } - } - - protected function configureSearch(): void - { - SearchService::registerHandler( - index: 'users', - callback: fn ($hit) => app(Services\UserService::class)->getData($hit['id']), - searchableAttributes: ['name', 'username'], - filterableAttributes: ['id'], - sortableAttributes: ['created_at'] - ); - } - - protected function configureReact(): void - { - ReactService::registerHandler( - name: 'user', - class: User::class, - callback: fn ($slug) => app(Services\UserService::class)->getId($slug) - ); - } - - protected function configureFeed(): void - { - FeedService::registerHandler( - name: 'user', - isFilter: true, - callback: fn ($slug) => app(Services\UserService::class)->getId($slug) - ); - } -} diff --git a/phpstan.neon b/phpstan.neon index 39a36de..c736ac4 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -8,4 +8,4 @@ parameters: paths: - app/ - tests/ - - packages/ + - modules/ diff --git a/phpunit.xml b/phpunit.xml index 8479fd4..92a899f 100755 --- a/phpunit.xml +++ b/phpunit.xml @@ -5,10 +5,8 @@ colors="true" > - - packages/Tag/tests - packages/Category/tests - packages/Article/tests + + Modules/**/tests diff --git a/stubs/nwidart-stubs/action-invoke.stub b/stubs/nwidart-stubs/action-invoke.stub new file mode 100644 index 0000000..ae29efc --- /dev/null +++ b/stubs/nwidart-stubs/action-invoke.stub @@ -0,0 +1,8 @@ + + + diff --git a/stubs/nwidart-stubs/composer.stub b/stubs/nwidart-stubs/composer.stub new file mode 100644 index 0000000..eab071c --- /dev/null +++ b/stubs/nwidart-stubs/composer.stub @@ -0,0 +1,28 @@ +{ + "name": "$VENDOR$/$LOWER_NAME$", + "description": "$STUDLY_NAME$ module for $APP_NAME$", + "authors": [ + { + "name": "$AUTHOR_NAME$", + "email": "$AUTHOR_EMAIL$" + } + ], + "extra": { + "laravel": { + "providers": [], + "aliases": {} + } + }, + "autoload": { + "psr-4": { + "$MODULE_NAMESPACE$\\$STUDLY_NAME$\\": "$APP_FOLDER_NAME$", + "$MODULE_NAMESPACE$\\$STUDLY_NAME$\\Database\\Factories\\": "database/factories/", + "$MODULE_NAMESPACE$\\$STUDLY_NAME$\\Database\\Seeders\\": "database/seeders/" + } + }, + "autoload-dev": { + "psr-4": { + "$MODULE_NAMESPACE$\\$STUDLY_NAME$\\Tests\\": "tests/" + } + } +} diff --git a/stubs/nwidart-stubs/controller-api.stub b/stubs/nwidart-stubs/controller-api.stub new file mode 100644 index 0000000..025095d --- /dev/null +++ b/stubs/nwidart-stubs/controller-api.stub @@ -0,0 +1,59 @@ +json([]); + } + + /** + * Store a newly created resource in storage. + */ + public function store(Request $request) + { + // + + return response()->json([]); + } + + /** + * Show the specified resource. + */ + public function show($id) + { + // + + return response()->json([]); + } + + /** + * Update the specified resource in storage. + */ + public function update(Request $request, $id) + { + // + + return response()->json([]); + } + + /** + * Remove the specified resource from storage. + */ + public function destroy($id) + { + // + + return response()->json([]); + } +} diff --git a/stubs/nwidart-stubs/controller-plain.stub b/stubs/nwidart-stubs/controller-plain.stub new file mode 100644 index 0000000..9702ba7 --- /dev/null +++ b/stubs/nwidart-stubs/controller-plain.stub @@ -0,0 +1,7 @@ +json([]); + } +} diff --git a/stubs/nwidart-stubs/controller.stub b/stubs/nwidart-stubs/controller.stub new file mode 100644 index 0000000..79f1b77 --- /dev/null +++ b/stubs/nwidart-stubs/controller.stub @@ -0,0 +1,56 @@ +> + */ + protected $listen = []; + + /** + * Indicates if events should be discovered. + * + * @var bool + */ + protected static $shouldDiscoverEvents = true; + + /** + * Configure the proper event listeners for email verification. + */ + protected function configureEmailVerification(): void {} +} diff --git a/stubs/nwidart-stubs/event.stub b/stubs/nwidart-stubs/event.stub new file mode 100644 index 0000000..048d7f8 --- /dev/null +++ b/stubs/nwidart-stubs/event.stub @@ -0,0 +1,31 @@ +view('view.name'); + } +} diff --git a/stubs/nwidart-stubs/middleware.stub b/stubs/nwidart-stubs/middleware.stub new file mode 100644 index 0000000..bdd192d --- /dev/null +++ b/stubs/nwidart-stubs/middleware.stub @@ -0,0 +1,17 @@ +id(); + $FIELDS$ + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('$TABLE$'); + } +}; diff --git a/stubs/nwidart-stubs/migration/delete.stub b/stubs/nwidart-stubs/migration/delete.stub new file mode 100644 index 0000000..788cdee --- /dev/null +++ b/stubs/nwidart-stubs/migration/delete.stub @@ -0,0 +1,28 @@ +id(); + $FIELDS$ + $table->timestamps(); + }); + } +}; diff --git a/stubs/nwidart-stubs/migration/plain.stub b/stubs/nwidart-stubs/migration/plain.stub new file mode 100644 index 0000000..d94404c --- /dev/null +++ b/stubs/nwidart-stubs/migration/plain.stub @@ -0,0 +1,18 @@ +line('The introduction to the notification.') + ->action('Notification Action', 'https://laravel.com') + ->line('Thank you for using our application!'); + } + + /** + * Get the array representation of the notification. + */ + public function toArray($notifiable): array + { + return []; + } +} diff --git a/stubs/nwidart-stubs/observer.stub b/stubs/nwidart-stubs/observer.stub new file mode 100644 index 0000000..e74fe90 --- /dev/null +++ b/stubs/nwidart-stubs/observer.stub @@ -0,0 +1,33 @@ +mapWebRoutes(); + $this->mapApiRoutes(); + } + + /** + * Define the "web" routes for the application. + * + * These routes all receive session state, CSRF protection, etc. + */ + protected function mapWebRoutes(): void + { + Route::middleware('web') + ->prefix($this->nameLower) + ->name("{$this->nameLower}.") + ->group(module_path($this->name, '$WEB_ROUTES_PATH$')); + } + + /** + * Define the "api" routes for the application. + * + * These routes are typically stateless. + */ + protected function mapApiRoutes(): void + { + Route::middleware(['web', 'auth', BatchLogsActivity::class]) + ->prefix("api/{$this->nameLower}") + ->name("api.{$this->nameLower}.") + ->group(module_path($this->name, '$API_ROUTES_PATH$')); + } +} diff --git a/stubs/nwidart-stubs/routes/api.stub b/stubs/nwidart-stubs/routes/api.stub new file mode 100644 index 0000000..bd71ff0 --- /dev/null +++ b/stubs/nwidart-stubs/routes/api.stub @@ -0,0 +1,8 @@ +prefix('v1')->group(function () { + Route::apiResource('$PLURAL_LOWER_NAME$', $STUDLY_NAME$Controller::class)->names('$LOWER_NAME$'); +}); diff --git a/stubs/nwidart-stubs/routes/web.stub b/stubs/nwidart-stubs/routes/web.stub new file mode 100644 index 0000000..2da42a1 --- /dev/null +++ b/stubs/nwidart-stubs/routes/web.stub @@ -0,0 +1,8 @@ +group(function () { + Route::resource('$PLURAL_LOWER_NAME$', $STUDLY_NAME$Controller::class)->names('$LOWER_NAME$'); +}); diff --git a/stubs/nwidart-stubs/rule.implicit.stub b/stubs/nwidart-stubs/rule.implicit.stub new file mode 100644 index 0000000..635cbd2 --- /dev/null +++ b/stubs/nwidart-stubs/rule.implicit.stub @@ -0,0 +1,19 @@ + '$STUDLY_NAME$', +]; diff --git a/stubs/nwidart-stubs/scaffold/provider.stub b/stubs/nwidart-stubs/scaffold/provider.stub new file mode 100644 index 0000000..e8ccd84 --- /dev/null +++ b/stubs/nwidart-stubs/scaffold/provider.stub @@ -0,0 +1,156 @@ +registerCommands(); + $this->registerCommandSchedules(); + $this->registerTranslations(); + $this->registerConfig(); + $this->registerPublishableResources(); + $this->loadMigrationsFrom(module_path($this->name, '$MIGRATIONS_PATH$')); + $this->loadFactoriesFrom(module_path($this->name, '$FACTORIES_PATH$')); + } + + /** + * Register the service provider. + */ + public function register(): void + { + $this->app->register(EventServiceProvider::class); + $this->app->register(RouteServiceProvider::class); + } + + /** + * Register model policies + */ + protected function registerPolicies(): void + { + // + } + + /** + * Register model observers + */ + protected function registerObservers(): void + { + // + } + + /** + * Register commands in the format of Command::class + */ + protected function registerCommands(): void + { + // $this->commands([]); + } + + /** + * Register command Schedules. + */ + protected function registerCommandSchedules(): void + { + // $this->app->booted(function () { + // $schedule = $this->app->make(Schedule::class); + // $schedule->command('inspire')->hourly(); + // }); + } + + /** + * Register translations. + */ + public function registerTranslations(): void + { + $langPath = resource_path('lang/modules/'.$this->nameLower); + + if (is_dir($langPath)) { + $this->loadTranslationsFrom($langPath, $this->nameLower); + $this->loadJsonTranslationsFrom($langPath); + } else { + $this->loadTranslationsFrom(module_path($this->name, '$PATH_LANG$'), $this->nameLower); + $this->loadJsonTranslationsFrom(module_path($this->name, '$PATH_LANG$')); + } + } + + /** + * Register console publishes + */ + protected function registerPublishableResources(): void + { + if ($this->app->runningInConsole()) { + $this->publishes([ + module_path($this->name, '$SEEDERS_PATH$') => database_path("seeders/{$this->name}"), + module_path($this->name, '$MIGRATIONS_PATH$') => database_path('migrations/'), + ], $this->nameLower); + } + } + + /** + * Register config. + */ + protected function registerConfig(): void + { + $configPath = module_path($this->name, config('modules.paths.generator.config.path')); + + if (is_dir($configPath)) { + $iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($configPath)); + + foreach ($iterator as $file) { + if ($file->isFile() && $file->getExtension() === 'php') { + $config = str_replace($configPath.DIRECTORY_SEPARATOR, '', $file->getPathname()); + $config_key = str_replace([DIRECTORY_SEPARATOR, '.php'], ['.', ''], $config); + $segments = explode('.', $this->nameLower.'.'.$config_key); + + // Remove duplicated adjacent segments + $normalized = []; + foreach ($segments as $segment) { + if (end($normalized) !== $segment) { + $normalized[] = $segment; + } + } + + $key = ($config === 'config.php') ? $this->nameLower : implode('.', $normalized); + + $this->publishes([$file->getPathname() => config_path($config)], 'config'); + $this->merge_config_from($file->getPathname(), $key); + } + } + } + } + + /** + * Merge config from the given path recursively. + */ + protected function merge_config_from(string $path, string $key): void + { + $existing = config($key, []); + $module_config = require $path; + + config([$key => array_replace_recursive($existing, $module_config)]); + } + + /** + * Get the services provided by the provider. + */ + public function provides(): array + { + return []; + } +} diff --git a/stubs/nwidart-stubs/scope.stub b/stubs/nwidart-stubs/scope.stub new file mode 100644 index 0000000..2bbe73f --- /dev/null +++ b/stubs/nwidart-stubs/scope.stub @@ -0,0 +1,15 @@ +call([]); + } +} diff --git a/stubs/nwidart-stubs/service-invoke.stub b/stubs/nwidart-stubs/service-invoke.stub new file mode 100644 index 0000000..ae29efc --- /dev/null +++ b/stubs/nwidart-stubs/service-invoke.stub @@ -0,0 +1,8 @@ +get('/'); + + $response->assertStatus(200); + } +} diff --git a/stubs/nwidart-stubs/tests/unit.stub b/stubs/nwidart-stubs/tests/unit.stub new file mode 100644 index 0000000..938e5da --- /dev/null +++ b/stubs/nwidart-stubs/tests/unit.stub @@ -0,0 +1,16 @@ +assertTrue(true); + } +} diff --git a/stubs/nwidart-stubs/trait.stub b/stubs/nwidart-stubs/trait.stub new file mode 100644 index 0000000..86f1151 --- /dev/null +++ b/stubs/nwidart-stubs/trait.stub @@ -0,0 +1,5 @@ + + + diff --git a/stubs/nwidart-stubs/views/index.stub b/stubs/nwidart-stubs/views/index.stub new file mode 100644 index 0000000..4cc0542 --- /dev/null +++ b/stubs/nwidart-stubs/views/index.stub @@ -0,0 +1,5 @@ + +

Hello World

+ +

Module: {!! config('$LOWER_NAME$.name') !!}

+
diff --git a/stubs/nwidart-stubs/views/master.stub b/stubs/nwidart-stubs/views/master.stub new file mode 100644 index 0000000..b97cddf --- /dev/null +++ b/stubs/nwidart-stubs/views/master.stub @@ -0,0 +1,30 @@ + + + + + + + + + + $STUDLY_NAME$ Module - {{ config('app.name', 'Laravel') }} + + + + + + + + + + {{-- Vite CSS --}} + {{-- {{ module_vite('build-$LOWER_NAME$', 'resources/assets/sass/app.scss') }} --}} + + + + {{ $slot }} + + {{-- Vite JS --}} + {{-- {{ module_vite('build-$LOWER_NAME$', 'resources/assets/js/app.js') }} --}} + + diff --git a/stubs/nwidart-stubs/vite.stub b/stubs/nwidart-stubs/vite.stub new file mode 100644 index 0000000..f1b0312 --- /dev/null +++ b/stubs/nwidart-stubs/vite.stub @@ -0,0 +1,57 @@ +import { defineConfig } from 'vite'; +import laravel from 'laravel-vite-plugin'; +import { readdirSync, statSync } from 'fs'; +import { join,relative,dirname } from 'path'; +import { fileURLToPath } from 'url'; + +export default defineConfig({ + build: { + outDir: '../../public/build-$LOWER_NAME$', + emptyOutDir: true, + manifest: true, + }, + plugins: [ + laravel({ + publicDirectory: '../../public', + buildDirectory: 'build-$LOWER_NAME$', + input: [ + __dirname + '/resources/assets/sass/app.scss', + __dirname + '/resources/assets/js/app.js' + ], + refresh: true, + }), + ], +}); +// Scen all resources for assets file. Return array +//function getFilePaths(dir) { +// const filePaths = []; +// +// function walkDirectory(currentPath) { +// const files = readdirSync(currentPath); +// for (const file of files) { +// const filePath = join(currentPath, file); +// const stats = statSync(filePath); +// if (stats.isFile() && !file.startsWith('.')) { +// const relativePath = 'Modules/$STUDLY_NAME$/'+relative(__dirname, filePath); +// filePaths.push(relativePath); +// } else if (stats.isDirectory()) { +// walkDirectory(filePath); +// } +// } +// } +// +// walkDirectory(dir); +// return filePaths; +//} + +//const __filename = fileURLToPath(import.meta.url); +//const __dirname = dirname(__filename); + +//const assetsDir = join(__dirname, 'resources/assets'); +//export const paths = getFilePaths(assetsDir); + + +//export const paths = [ +// 'Modules/$STUDLY_NAME$/resources/assets/sass/app.scss', +// 'Modules/$STUDLY_NAME$/resources/assets/js/app.js', +//]; diff --git a/tests/TestCase.php b/tests/TestCase.php index f103aba..80b548f 100755 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -5,23 +5,24 @@ use Illuminate\Foundation\Testing\RefreshDatabase; use Illuminate\Foundation\Testing\TestCase as BaseTestCase; use Mockery; -use Packages\Recommend\Services\GorseService; +use Modules\Recommend\Services\GorseService; abstract class TestCase extends BaseTestCase { use RefreshDatabase; - protected function setUp(): void { + protected function setUp(): void + { parent::setUp(); $this->app->bind(GorseService::class, function () { - $userMock = Mockery::mock(\Packages\Recommend\Classes\GorseUser::class); + $userMock = Mockery::mock(\Modules\Recommend\Classes\GorseUser::class); $userMock->shouldIgnoreMissing(); - $rowEffectedMock = Mockery::mock(\Packages\Recommend\Classes\RowAffected::class); + $rowEffectedMock = Mockery::mock(\Modules\Recommend\Classes\RowAffected::class); $rowEffectedMock->shouldIgnoreMissing(); - $gorseItemMock = Mockery::mock(\Packages\Recommend\Classes\GorseItem::class); + $gorseItemMock = Mockery::mock(\Modules\Recommend\Classes\GorseItem::class); $gorseItemMock->shouldIgnoreMissing(); $gorseServiceMock = Mockery::mock(GorseService::class); diff --git a/vite-module-loader.js b/vite-module-loader.js new file mode 100644 index 0000000..56c35b9 --- /dev/null +++ b/vite-module-loader.js @@ -0,0 +1,51 @@ +import fs from 'fs/promises'; +import path from 'path'; +import { pathToFileURL } from 'url'; + +async function collectModuleAssetsPaths(paths, modulesPath) { + modulesPath = path.join(__dirname, modulesPath); + + const moduleStatusesPath = path.join(__dirname, 'modules_statuses.json'); + + try { + // Read module_statuses.json + const moduleStatusesContent = await fs.readFile(moduleStatusesPath, 'utf-8'); + const moduleStatuses = JSON.parse(moduleStatusesContent); + + // Read module directories + const moduleDirectories = await fs.readdir(modulesPath); + + for (const moduleDir of moduleDirectories) { + if (moduleDir === '.DS_Store') { + // Skip .DS_Store directory + continue; + } + + // Check if the module is enabled (status is true) + if (moduleStatuses[moduleDir] === true) { + const viteConfigPath = path.join(modulesPath, moduleDir, 'vite.config.js'); + + try { + await fs.access(viteConfigPath); + // Convert to a file URL for Windows compatibility + const moduleConfigURL = pathToFileURL(viteConfigPath); + + // Import the module-specific Vite configuration + const moduleConfig = await import(moduleConfigURL.href); + + if (moduleConfig.paths && Array.isArray(moduleConfig.paths)) { + paths.push(...moduleConfig.paths); + } + } catch (error) { + // vite.config.js does not exist, skip this module + } + } + } + } catch (error) { + console.error(`Error reading module statuses or module configurations: ${error}`); + } + + return paths; +} + +export default collectModuleAssetsPaths;