repository = $repository; $this->formHandler = new FormRequestHandler(); } public function list(): string { $sortableColumns = ['o', 'name', 'status', 'start']; $filterDefinitions = [ [ 'key' => 'name', 'label' => 'Jezyk', 'type' => 'text', ], [ 'key' => 'status', 'label' => 'Aktywny', 'type' => 'select', 'options' => [ '' => '- aktywny -', '1' => 'tak', '0' => 'nie', ], ], [ 'key' => 'start', 'label' => 'Domyslny', 'type' => 'select', 'options' => [ '' => '- domyslny -', '1' => 'tak', '0' => 'nie', ], ], ]; $listRequest = \admin\Support\TableListRequestFactory::fromRequest( $filterDefinitions, $sortableColumns, 'o' ); $sortDir = $listRequest['sortDir']; if (trim((string)\S::get('sort')) === '') { $sortDir = 'ASC'; } $result = $this->repository->listForAdmin( $listRequest['filters'], $listRequest['sortColumn'], $sortDir, $listRequest['page'], $listRequest['perPage'] ); $rows = []; $lp = ($listRequest['page'] - 1) * $listRequest['perPage'] + 1; foreach ($result['items'] as $item) { $id = (string)($item['id'] ?? ''); $name = trim((string)($item['name'] ?? '')); $rows[] = [ 'lp' => $lp++ . '.', 'start' => ((int)($item['start'] ?? 0) === 1) ? 'tak' : 'nie', 'status' => ((int)($item['status'] ?? 0) === 1) ? 'tak' : 'nie', 'name' => '' . htmlspecialchars($name, ENT_QUOTES, 'UTF-8') . '', '_actions' => [ [ 'label' => 'Edytuj', 'url' => '/admin/languages/language_edit/id=' . $id, 'class' => 'btn btn-xs btn-primary', ], [ 'label' => 'Usun', 'url' => '/admin/languages/language_delete/id=' . $id, 'class' => 'btn btn-xs btn-danger', 'confirm' => 'Na pewno chcesz usunac wybrany jezyk?', ], ], ]; } $total = (int)$result['total']; $totalPages = max(1, (int)ceil($total / $listRequest['perPage'])); $viewModel = new \admin\ViewModels\Common\PaginatedTableViewModel( [ ['key' => 'lp', 'label' => 'Lp.', 'class' => 'text-center', 'sortable' => false], ['key' => 'start', 'sort_key' => 'start', 'label' => 'Domyslny', 'class' => 'text-center', 'sortable' => true, 'raw' => true], ['key' => 'status', 'sort_key' => 'status', 'label' => 'Aktywny', 'class' => 'text-center', 'sortable' => true, 'raw' => true], ['key' => 'name', 'sort_key' => 'name', 'label' => 'Jezyk', 'sortable' => true, 'raw' => true], ], $rows, $listRequest['viewFilters'], [ 'column' => $listRequest['sortColumn'], 'dir' => $sortDir, ], [ 'page' => $listRequest['page'], 'per_page' => $listRequest['perPage'], 'total' => $total, 'total_pages' => $totalPages, ], array_merge($listRequest['queryFilters'], [ 'sort' => $listRequest['sortColumn'], 'dir' => $sortDir, 'per_page' => $listRequest['perPage'], ]), $listRequest['perPageOptions'], $sortableColumns, '/admin/languages/view_list/', 'Brak danych w tabeli.', '/admin/languages/language_edit/', 'Dodaj jezyk' ); return \Tpl::view('languages/languages-list', [ 'viewModel' => $viewModel, ]); } public function view_list(): string { return $this->list(); } public function language_edit(): string { $languageId = trim((string)\S::get('id')); $language = $this->repository->languageDetails($languageId) ?? []; $validationErrors = $_SESSION['form_errors'][$this->getLanguageFormId()] ?? null; if ($validationErrors) { unset($_SESSION['form_errors'][$this->getLanguageFormId()]); } return \Tpl::view('languages/language-edit', [ 'form' => $this->buildLanguageFormViewModel($language, $this->repository->maxOrder(), $validationErrors), ]); } public function language_save(): void { $legacyValues = \S::get('values'); if ($legacyValues) { $values = json_decode((string)$legacyValues, true); $response = ['status' => 'error', 'msg' => 'Podczas zapisywania jezyka wystapil blad.']; if (is_array($values)) { $savedId = $this->repository->saveLanguage( (string)($values['id'] ?? ''), (string)($values['name'] ?? ''), $values['status'] ?? 0, $values['start'] ?? 0, (int)($values['o'] ?? 0) ); if ($savedId) { $response = ['status' => 'ok', 'msg' => 'Jezyk zostal zapisany.', 'id' => $savedId]; } } echo json_encode($response); exit; } $languageId = trim((string)\S::get('id')); $language = $this->repository->languageDetails($languageId) ?? []; $viewModel = $this->buildLanguageFormViewModel($language, $this->repository->maxOrder()); $result = $this->formHandler->handleSubmit($viewModel, $_POST); if (!$result['success']) { $_SESSION['form_errors'][$this->getLanguageFormId()] = $result['errors']; echo json_encode(['success' => false, 'errors' => $result['errors']]); exit; } $data = $result['data']; $requestId = strtolower(trim((string)\S::get('id'))); $idFromData = strtolower(trim((string)($data['id'] ?? ''))); $id = $idFromData !== '' ? $idFromData : $requestId; if (!preg_match('/^[a-z]{2}$/', $id)) { echo json_encode([ 'success' => false, 'errors' => ['id' => 'ID jezyka musi miec 2 litery (np. pl, en).'], ]); exit; } $savedId = $this->repository->saveLanguage( $id, trim((string)($data['name'] ?? '')), $data['status'] ?? 0, $data['start'] ?? 0, (int)($data['o'] ?? 0) ); if ($savedId) { echo json_encode([ 'success' => true, 'id' => $savedId, 'message' => 'Jezyk zostal zapisany.', ]); exit; } echo json_encode([ 'success' => false, 'errors' => ['general' => 'Podczas zapisywania jezyka wystapil blad.'], ]); exit; } public function language_delete(): void { if ($this->repository->deleteLanguage((string)\S::get('id'))) { \S::alert('Jezyk zostal usuniety.'); } header('Location: /admin/languages/view_list/'); exit; } public function translation_list(): string { $sortableColumns = ['text', 'id']; $filterDefinitions = [ [ 'key' => 'text', 'label' => 'Tekst', 'type' => 'text', ], ]; $listRequest = \admin\Support\TableListRequestFactory::fromRequest( $filterDefinitions, $sortableColumns, 'text' ); $sortDir = $listRequest['sortDir']; if (trim((string)\S::get('sort')) === '') { $sortDir = 'ASC'; } $result = $this->repository->listTranslationsForAdmin( $listRequest['filters'], $listRequest['sortColumn'], $sortDir, $listRequest['page'], $listRequest['perPage'] ); $rows = []; $lp = ($listRequest['page'] - 1) * $listRequest['perPage'] + 1; foreach ($result['items'] as $item) { $id = (int)($item['id'] ?? 0); $text = trim((string)($item['text'] ?? '')); $rows[] = [ 'lp' => $lp++ . '.', 'text' => '' . htmlspecialchars($text, ENT_QUOTES, 'UTF-8') . '', '_actions' => [ [ 'label' => 'Edytuj', 'url' => '/admin/languages/translation_edit/id=' . $id, 'class' => 'btn btn-xs btn-primary', ], [ 'label' => 'Usun', 'url' => '/admin/languages/translation_delete/id=' . $id, 'class' => 'btn btn-xs btn-danger', 'confirm' => 'Na pewno chcesz usunac wybrane tlumaczenie?', ], ], ]; } $total = (int)$result['total']; $totalPages = max(1, (int)ceil($total / $listRequest['perPage'])); $viewModel = new \admin\ViewModels\Common\PaginatedTableViewModel( [ ['key' => 'lp', 'label' => 'Lp.', 'class' => 'text-center', 'sortable' => false], ['key' => 'text', 'sort_key' => 'text', 'label' => 'Tekst', 'sortable' => true, 'raw' => true], ], $rows, $listRequest['viewFilters'], [ 'column' => $listRequest['sortColumn'], 'dir' => $sortDir, ], [ 'page' => $listRequest['page'], 'per_page' => $listRequest['perPage'], 'total' => $total, 'total_pages' => $totalPages, ], array_merge($listRequest['queryFilters'], [ 'sort' => $listRequest['sortColumn'], 'dir' => $sortDir, 'per_page' => $listRequest['perPage'], ]), $listRequest['perPageOptions'], $sortableColumns, '/admin/languages/translation_list/', 'Brak danych w tabeli.', '/admin/languages/translation_edit/', 'Dodaj tlumaczenie' ); return \Tpl::view('languages/translations-list', [ 'viewModel' => $viewModel, ]); } public function translation_edit(): string { $translationId = (int)\S::get('id'); $translation = $this->repository->translationDetails($translationId) ?? []; $languages = $this->repository->languagesList(); $validationErrors = $_SESSION['form_errors'][$this->getTranslationFormId()] ?? null; if ($validationErrors) { unset($_SESSION['form_errors'][$this->getTranslationFormId()]); } return \Tpl::view('languages/translation-edit', [ 'form' => $this->buildTranslationFormViewModel($translation, $languages, $validationErrors), ]); } public function translation_save(): void { $legacyValues = \S::get('values'); if ($legacyValues) { $values = json_decode((string)$legacyValues, true); $response = ['status' => 'error', 'msg' => 'Podczas zapisywania tlumaczenia wystapil blad.']; if (is_array($values)) { $languagesMap = $this->extractLegacyTranslations($values, $this->repository->languagesList()); $savedId = $this->repository->saveTranslation( (int)($values['id'] ?? 0), (string)($values['text'] ?? ''), $languagesMap ); if ($savedId) { $this->clearLanguageSessions($this->repository->languagesList()); $response = ['status' => 'ok', 'msg' => 'Tlumaczenie zostalo zapisane.', 'id' => $savedId]; } } echo json_encode($response); exit; } $translationId = (int)\S::get('id'); $translation = $this->repository->translationDetails($translationId) ?? []; $languages = $this->repository->languagesList(); $viewModel = $this->buildTranslationFormViewModel($translation, $languages); $result = $this->formHandler->handleSubmit($viewModel, $_POST); if (!$result['success']) { $_SESSION['form_errors'][$this->getTranslationFormId()] = $result['errors']; echo json_encode(['success' => false, 'errors' => $result['errors']]); exit; } $data = $result['data']; $languagesMap = []; foreach ($languages as $language) { $langId = (string)($language['id'] ?? ''); $key = 'lang_' . $langId; $languagesMap[$langId] = (string)($data[$key] ?? ''); } $savedId = $this->repository->saveTranslation( $translationId, (string)($data['text'] ?? ''), $languagesMap ); if ($savedId) { $this->clearLanguageSessions($languages); echo json_encode([ 'success' => true, 'id' => $savedId, 'message' => 'Tlumaczenie zostalo zapisane.', ]); exit; } echo json_encode([ 'success' => false, 'errors' => ['general' => 'Podczas zapisywania tlumaczenia wystapil blad.'], ]); exit; } public function translation_delete(): void { if ($this->repository->deleteTranslation((int)\S::get('id'))) { \S::alert('Tlumaczenie zostalo usuniete.'); } header('Location: /admin/languages/translation_list/'); exit; } private function buildLanguageFormViewModel(array $language, int $maxOrder, ?array $errors = null): FormEditViewModel { $languageId = strtolower(trim((string)($language['id'] ?? ''))); $isNew = $languageId === ''; $data = [ 'id' => $languageId, 'name' => (string)($language['name'] ?? ''), 'status' => (int)($language['status'] ?? 0), 'start' => (int)($language['start'] ?? 0), 'o' => (int)($language['o'] ?? ($maxOrder + 1)), ]; $fields = []; if ($isNew) { $fields[] = FormField::text('id', [ 'label' => 'ID (2 znaki)', 'required' => true, 'attributes' => ['maxlength' => 2], ]); } $fields[] = FormField::text('name', [ 'label' => 'Jezyk', 'required' => true, ]); $fields[] = FormField::switch('status', [ 'label' => 'Aktywny', ]); $fields[] = FormField::switch('start', [ 'label' => 'Domyslny', ]); $fields[] = FormField::hidden('o', $data['o']); $actionUrl = '/admin/languages/language_save/' . ($isNew ? '' : ('id=' . $languageId)); $actions = [ FormAction::save($actionUrl, '/admin/languages/view_list/'), FormAction::cancel('/admin/languages/view_list/'), ]; return new FormEditViewModel( $this->getLanguageFormId(), $isNew ? 'Nowy jezyk' : 'Edycja jezyka', $data, $fields, [], $actions, 'POST', $actionUrl, '/admin/languages/view_list/', true, $isNew ? [] : ['id' => $languageId], null, $errors ); } private function buildTranslationFormViewModel(array $translation, array $languages, ?array $errors = null): FormEditViewModel { $translationId = (int)($translation['id'] ?? 0); $isNew = $translationId <= 0; $data = [ 'id' => $translationId, 'text' => (string)($translation['text'] ?? ''), ]; $fields = [ FormField::text('text', [ 'label' => 'Tekst', 'required' => true, ]), ]; foreach ($languages as $language) { $langId = (string)($language['id'] ?? ''); $fieldName = 'lang_' . $langId; $data[$fieldName] = (string)($translation[$langId] ?? ''); $fields[] = FormField::text($fieldName, [ 'label' => (string)($language['name'] ?? $langId), ]); } $actionUrl = '/admin/languages/translation_save/' . ($isNew ? '' : ('id=' . $translationId)); $actions = [ FormAction::save($actionUrl, '/admin/languages/translation_list/'), FormAction::cancel('/admin/languages/translation_list/'), ]; return new FormEditViewModel( $this->getTranslationFormId(), $isNew ? 'Nowe tlumaczenie' : 'Edycja tlumaczenia', $data, $fields, [], $actions, 'POST', $actionUrl, '/admin/languages/translation_list/', true, $isNew ? [] : ['id' => $translationId], null, $errors ); } private function extractLegacyTranslations(array $values, array $languages): array { $result = []; foreach ($languages as $language) { $langId = (string)($language['id'] ?? ''); $result[$langId] = (string)($values[$langId] ?? ''); } return $result; } private function clearLanguageSessions(array $languages): void { foreach ($languages as $language) { if (!isset($language['id'])) { continue; } \S::delete_session('lang-' . (string)$language['id']); } } private function getLanguageFormId(): string { return 'languages-language-edit'; } private function getTranslationFormId(): string { return 'languages-translation-edit'; } }