История коммитов

.
refactor(profile): migrate karma page to new architecture
Add KarmaController (8 routes under /profile/{id}/karma) with GetKarmaListUseCase, GetNewKarmaUseCase, GetVoteContextUseCase, VoteKarmaUseCase, DeleteKarmaVoteUseCase, CleanKarmaUseCase and KarmaListDTO/VoteContextDTO/VoteKarmaCommand. Reuse Johncms\Users\Karma model; extend KarmaRepository and ProfileUserRepository karma counters.

Switch delete to standard csrf_token; non-rights-9 delete/clean -> 403. Update karma links in GetProfileViewUseCase. Remove legacy includes/karma.php and drop karma from $mods.
.
refactor(profile): migrate avatar/photo upload to new architecture
Replace legacy includes/images.php with AvatarController and PhotoController
backed by UploadAvatarUseCase and UploadPhotoUseCase (Intervention ImageManager).

New clean URLs, nested under the edit page:
- GET/POST /profile/{id}/edit/avatar (profile.edit.avatar / .upload)
- GET/POST /profile/{id}/edit/photo (profile.edit.photo / .upload)

Access is guarded by the shared GetEditContextUseCase (equivalent to the legacy
images guard, additionally blocking banned editors like the edit page). File
size validation and image processing live in the use cases; failures surface as
ImageUploadException re-rendering the result page. Avatar (150x150 png) and photo
(1024x960 jpg + 400x300 preview) processing kept 1:1 with legacy.

Avatar/photo upload links in edit.phtml updated to the new URLs.
.
refactor(profile): migrate settings page to new architecture
Replace legacy includes/settings.php with SettingsController covering the three
settings sections (general/forum/mail), backed by UserSettingsUseCase,
ForumSettingsUseCase and MailSettingsUseCase plus their command DTOs.

New clean URLs (all self-only, behind the auth middleware):
- GET/POST /profile/settings (profile.settings / .save)
- POST /profile/settings/reset (profile.settings.reset)
- GET/POST /profile/settings/forum (profile.settings.forum / .save)
- POST /profile/settings/forum/reset (profile.settings.forum.reset)
- GET/POST /profile/settings/mail (profile.settings.mail / .save)

Settings resets moved from GET links to CSRF-less POST submit buttons (aligned
with reset-settings/edit conventions). Validation, clamps and the general PRG
flow are kept 1:1 with legacy; settings are persisted through loaded models so
the UserSettings/Serialize casts apply.

account.phtml link and template reset links updated to the new URLs.
.
refactor(profile): migrate edit profile page to new architecture
Replace legacy includes/edit.php with EditProfileController (form/save/
delete-avatar/delete-photo) backed by GetEditContextUseCase, UpdateProfileUseCase
and DeleteAvatar/DeletePhoto use cases.

New clean URLs:
- GET /profile/{id}/edit (profile.edit)
- POST /profile/{id}/edit (profile.edit.save)
- POST /profile/{id}/edit/delete-avatar (profile.edit.delete-avatar)
- POST /profile/{id}/edit/delete-photo (profile.edit.delete-photo)

Guard (owner or admin over a no-higher user; banned editor blocked) lives in
GetEditContextUseCase; all forbidden cases now return HTTP 403. Avatar/photo
deletion moved from GET to CSRF-protected POST. Validation kept 1:1 with legacy,
including the deferred email-change confirmation flow.

All profile-view links pointing to ?act=edit updated to the new URL.
.
refactor(profile): migrate reset user settings to new architecture
Replace the legacy ?act=reset include with a ResetSettingsController (POST /profile/{id}/reset-settings). Guard (rights>=7 and over a lower-rights user) is folded into GetResetSettingsContextUseCase; ResetUserSettingsUseCase performs the action via ProfileUserRepository::resetSettings, resetting set_user/set_forum through a loaded model so the casts serialize correctly. Convert the legacy edit.phtml link to a POST submit button and drop reset from the legacy dispatcher.
.
refactor(profile): migrate change password page to new architecture
- Add ChangePasswordController (GET form / POST change), URL /profile/{id}/password
- Add GetChangePasswordContextUseCase (guard: owner or admin rights>=7 over lower-rights user)
- Add ChangePasswordUseCase + ChangePasswordCommand with legacy-equivalent validation
- Add ChangePasswordException (own constructor; parent withErrors() returned wrong type)
- Add ProfileUserRepository::updatePassword()
- Update password links in account.phtml and edit.phtml to clean URLs
- Remove legacy includes/password.php and 'password' from $mods
.
refactor(profile): migrate email confirmation page to new architecture
Move the confirm_new_email action from the legacy includes/ dispatcher to a
dedicated controller and use case under the new module architecture.

- Add ConfirmNewEmailController and ConfirmNewEmailUseCase
- Add confirmNewEmail() to ProfileUserRepository(Interface)
- Register public route GET /profile/confirm-email/{id:number}/{code}
(profile.confirm-email), outside the auth group: the link is opened from
an email and the confirmation code is the access boundary
- Simplify confirm_new_email.phtml to a bool $confirmed flag
- Update the confirmation link generated in includes/edit.php
- Remove legacy includes/confirm_new_email.php and drop it from $mods
.
refactor(profile): migrate guestbook page to new architecture
Migrate the legacy profile guestbook to GuestbookController served at
/profile/{id}/guestbook (GET and POST for reply/edit/delete forms).

- Wrap the legacy Johncms\Comments component via output buffering, the
same pattern as downloads FileCommentsController
- Use a clean path script without sub_id_name (Comments::buildUrl adds the
separator); owner can delete and reply
- GetGuestbookContextUseCase loads the profile with the visibility guard
- MarkGuestbookReadUseCase resets comm_old when the owner views their own
guestbook outside of a mod action; add ProfileUserRepository::markGuestbookSeen
- Update act=guestbook links in account/view templates and the
notifications use case to /profile/{id}/guestbook
- Remove legacy includes/guestbook.php and drop 'guestbook' from index.php
.
refactor(profile): migrate account page to new architecture
Migrate the legacy office personal account page to AccountController served
at /profile/account (owner-only, no id — always the current user).

- GetAccountUseCase aggregates account counters into AccountDTO
- AlbumPhotoRepositoryInterface + EloquentAlbumPhotoRepository count the
user's album photos (album module has no models yet, so Capsule::table)
- Reuse mail MailMessageRepositoryInterface and ContactRepositoryInterface
for mailbox and contact counters
- Rename office.phtml to account.phtml and drive it from the DTO
- Update every act=office link across mail, login, admin, themes and the
legacy profile settings templates to /profile/account
- Remove legacy includes/office.php and drop 'office' from index.php
.
refactor(profile): migrate activity page to new architecture
Add ActivityController with messages/topics/comments sub-modes served at
/profile/{id}/activity, /activity/topics and /activity/comments.

- GetActivityUseCase loads the profile, selects the data source by
ActivityType and maps rows for templates
- ProfileActivityRepositoryInterface + EloquentProfileActivityRepository
paginate forum messages, forum topics and guestbook entries using
eager-loaded forum models (topic.section.parentSection)
- ForumActivityPreviewService builds short plain-text post previews
- ActivityDTO and ActivityType enum
- Reuse ForumTopicPathService and GuestbookEntry::post_text
- Update view/statistics links, remove legacy includes/activity.php and
drop 'activity' from the index.php dispatcher