From 6ef8b0029d54237d678ca392ceab8f50571d8812 Mon Sep 17 00:00:00 2001 From: Jacek Pyziak Date: Fri, 24 Apr 2026 21:35:17 +0200 Subject: [PATCH] feat(02-registration-dictionary-phrases): dictionary-backed registration text Phase 2 complete: - Seed registration dictionary phrases - Update public and admin registration templates to use translations - Document PAUL plan, apply, summary, and changelog --- .paul/PROJECT.md | 12 + .paul/ROADMAP.md | 12 + .paul/STATE.md | 37 ++- .paul/changelog/2026-04-24.md | 20 ++ .../02-01-APPLY.md | 46 ++++ .../02-01-PLAN.md | 170 +++++++++++++ .../02-01-SUMMARY.md | 124 ++++++++++ .../Admin/template/partial/Calc/Reg.tpl | 64 ++--- .../Admin/template/partial/Calc/RegEdit.tpl | 191 ++++++++------- ...-04-24-registration-dictionary-phrases.sql | 226 ++++++++++++++++++ ...-04-24-registration-dictionary-phrases.php | 200 ++++++++++++++++ _rejestracja/template/partial/Index/Index.tpl | 44 ++-- .../template/partial/Index/IndexSent.tpl | 76 +++--- 13 files changed, 1033 insertions(+), 189 deletions(-) create mode 100644 .paul/changelog/2026-04-24.md create mode 100644 .paul/phases/02-registration-dictionary-phrases/02-01-APPLY.md create mode 100644 .paul/phases/02-registration-dictionary-phrases/02-01-PLAN.md create mode 100644 .paul/phases/02-registration-dictionary-phrases/02-01-SUMMARY.md create mode 100644 _rejestracja/sql/2026-04-24-registration-dictionary-phrases.sql create mode 100644 _rejestracja/sql/apply-2026-04-24-registration-dictionary-phrases.php diff --git a/.paul/PROJECT.md b/.paul/PROJECT.md index 91f2258..a593fff 100644 --- a/.paul/PROJECT.md +++ b/.paul/PROJECT.md @@ -15,3 +15,15 @@ The changes must be persisted in the database and visible in the administrator p - Preserve existing pricing/admin content management behavior unless explicitly changed by the plan. - Treat database schema changes as deployment-critical and document them in SQL. +## Validated +- Registration form, persistence, confirmation output, and administrator display were updated for the XXXV conference request - Phase 1. +- New and related registration phrases are dictionary-backed and editable from `/_rejestracja/Admin/Dictionary/Index` after applying the dictionary seed - Phase 2. + +## Key Decisions +| Date | Decision | Impact | +|------|----------|--------| +| 2026-04-24 | Use stable `registration_*` dictionary keys for registration-specific phrases. | Templates can reuse dictionary labels without depending on raw Polish text as keys. | +| 2026-04-24 | Keep form values, participant persistence, pricing logic, and payment status values unchanged while moving labels to dictionary. | Reduces risk to the completed registration flow. | + +--- +*Last updated: 2026-04-24 after Phase 2* diff --git a/.paul/ROADMAP.md b/.paul/ROADMAP.md index 04d2eba..58400ba 100644 --- a/.paul/ROADMAP.md +++ b/.paul/ROADMAP.md @@ -4,6 +4,8 @@ Status: Complete +Progress: 2 of 2 phases complete (100%) + ### Phase 1: Registration Form Update Status: Complete @@ -11,3 +13,13 @@ Goal: Align the public registration form, persisted participant data, confirmati Planned: - `01-01`: Complete - updated registration fields, persistence, pricing/day options, admin display, and PHP migration runner. + +### Phase 2: Registration Dictionary Phrases +Status: Complete +Completed: 2026-04-24 +Plan count: 1/1 + +Goal: Move new and related registration phrases into the editable dictionary so public/admin registration wording can be managed from `/_rejestracja/Admin/Dictionary/Index`. + +Planned: +- `02-01`: Complete - seeded dictionary phrases and updated registration templates to use translations. diff --git a/.paul/STATE.md b/.paul/STATE.md index 3542a1e..d457bf7 100644 --- a/.paul/STATE.md +++ b/.paul/STATE.md @@ -1,26 +1,45 @@ ## Current Position Milestone: v0.1 XXXV Konferencja Registration Update -Phase: 1 of 1 (Registration Form Update) - Complete -Plan: 01-01 complete +Phase: 2 of 2 (Registration Dictionary Phrases) - Complete +Plan: 02-01 complete Status: UNIFY complete, loop closed -Last activity: 2026-04-24 - Created `.paul/phases/01-registration-form-update/01-01-SUMMARY.md` +Last activity: 2026-04-24 21:25:19 +02:00 - Created `.paul/phases/02-registration-dictionary-phrases/02-01-SUMMARY.md` Progress: - Milestone: [##########] 100% -- Phase 1: [##########] 100% +- Phase 2: [##########] 100% ## Loop Position Current loop state: ```text PLAN --> APPLY --> UNIFY - * * * [Loop complete - ready for next request] + * * * [Loop complete - milestone complete] ``` ## Session Continuity -Last session: 2026-04-24 -Stopped at: Plan 01-01 unified -Next action: Apply PHP migration on target server if not already applied, then deploy/test as needed -Resume file: `.paul/phases/01-registration-form-update/01-01-SUMMARY.md` +Last session: 2026-04-24 21:25:19 +02:00 +Stopped at: Plan 02-01 unified +Next action: Apply dictionary seed on target server, then deploy/test as needed +Resume file: `.paul/phases/02-registration-dictionary-phrases/02-01-SUMMARY.md` + +## Accumulated Context + +### Decisions +| Decision | Phase | Impact | +|----------|-------|--------| +| 2026-04-24: Use stable `registration_*` dictionary keys for registration-specific phrases | Phase 2 | Admin can edit visible registration wording without template changes. | +| 2026-04-24: Preserve form values, persistence, pricing logic, and payment status values during dictionary refactor | Phase 2 | Registration behavior remains aligned with Phase 1. | + +### Blockers/Concerns +- Production must run `_rejestracja/sql/apply-2026-04-24-registration-dictionary-phrases.php?run=20260424` or apply the SQL file before dictionary entries are visible/editable. + +### Deferred Issues +- None. + +### Git State +Last commit: 96a1ac8 +Branch: main +Feature branches merged: none. diff --git a/.paul/changelog/2026-04-24.md b/.paul/changelog/2026-04-24.md new file mode 100644 index 0000000..4fff87d --- /dev/null +++ b/.paul/changelog/2026-04-24.md @@ -0,0 +1,20 @@ +# 2026-04-24 + +## Co zrobiono + +- [Phase 2, Plan 01] Przeniesiono nowe i powiązane frazy rejestracji do słownika. +- Dodano idempotentny SQL i runner PHP do seedowania wpisów `mf_dictionary`. +- Przepięto formularz publiczny, potwierdzenie oraz widoki admina rejestracji na `{translate}` / `|translate`. +- Zachowano dotychczasowe nazwy pól, wartości formularza, logikę ceny i zapis danych uczestnika. + +## Zmienione pliki + +- `_rejestracja/sql/2026-04-24-registration-dictionary-phrases.sql` +- `_rejestracja/sql/apply-2026-04-24-registration-dictionary-phrases.php` +- `_rejestracja/template/partial/Index/Index.tpl` +- `_rejestracja/template/partial/Index/IndexSent.tpl` +- `_rejestracja/Admin/template/partial/Calc/Reg.tpl` +- `_rejestracja/Admin/template/partial/Calc/RegEdit.tpl` +- `.paul/phases/02-registration-dictionary-phrases/02-01-PLAN.md` +- `.paul/phases/02-registration-dictionary-phrases/02-01-APPLY.md` +- `.paul/phases/02-registration-dictionary-phrases/02-01-SUMMARY.md` diff --git a/.paul/phases/02-registration-dictionary-phrases/02-01-APPLY.md b/.paul/phases/02-registration-dictionary-phrases/02-01-APPLY.md new file mode 100644 index 0000000..7c943c3 --- /dev/null +++ b/.paul/phases/02-registration-dictionary-phrases/02-01-APPLY.md @@ -0,0 +1,46 @@ +# APPLY Results: 02-01 + +Date: 2026-04-24 21:25:19 +02:00 + +## Completed Tasks + +### Task 1: Seed dictionary entries for registration phrases +Status: pass + +Notes: +- Added `_rejestracja/sql/2026-04-24-registration-dictionary-phrases.sql` with idempotent Polish `mf_dictionary` inserts. +- Added `_rejestracja/sql/apply-2026-04-24-registration-dictionary-phrases.php` as a guarded browser/CLI seed runner. +- The PHP runner inserts missing phrases for existing dictionary languages; Polish gets the configured replacement, other languages get `lang_keyword` placeholders. +- Duplicate keyword check returned no duplicates. + +### Task 2: Convert public registration form and confirmation output to dictionary phrases +Status: pass + +Notes: +- Updated `_rejestracja/template/partial/Index/Index.tpl` so new invoice, referat/poster, fee, participation, day prompt, surcharge, diet, and price labels render through `{translate}`. +- Updated `_rejestracja/template/partial/Index/IndexSent.tpl` so confirmation labels, yes/no/default text, participation labels, diet labels, price labels, and consent labels use dictionary translations. +- Preserved form field names, radio values, hidden values, selected day values, and JavaScript pricing logic. + +### Task 3: Convert admin registration list/detail display to dictionary phrases +Status: pass + +Notes: +- Updated `_rejestracja/Admin/template/partial/Calc/Reg.tpl` to use dictionary translations for registration-related headers, labels, yes/no/default values, fee labels, consent labels, and edit/delete text. +- Updated `_rejestracja/Admin/template/partial/Calc/RegEdit.tpl` to use dictionary translations for the same registration detail/edit display values and payment status option labels. +- Preserved admin routes, form action, `payment_status` field name, and option values `1`/`2`. + +## Verification + +- `php -l _rejestracja/sql/apply-2026-04-24-registration-dictionary-phrases.php`: pass +- Hard-coded target phrase scan across public/admin registration templates: pass; only a non-visible HTML comment `` remains. +- Duplicate keyword scan in the PHP seed phrase list: pass +- Persistence/model/controller boundary check: pass; participant model and public controller files were not modified. + +## Deviations + +- Admin list/detail legacy fee text had old visible deadline years in templates. The dictionary-enabled display now uses the current `registration_fee_discount_2026` / `registration_fee_normal_2026` phrases while preserving the underlying condition and values. +- Unrelated working tree entries were present and left untouched: `_rejestracja/Static/image/Admin/Thumbs.db` and `.vscode/ftp-kr.sync.cache.json`. + +## Next Step + +Run `$paul-unify .paul/phases/02-registration-dictionary-phrases/02-01-PLAN.md` to reconcile the plan and close the loop. diff --git a/.paul/phases/02-registration-dictionary-phrases/02-01-PLAN.md b/.paul/phases/02-registration-dictionary-phrases/02-01-PLAN.md new file mode 100644 index 0000000..1c63564 --- /dev/null +++ b/.paul/phases/02-registration-dictionary-phrases/02-01-PLAN.md @@ -0,0 +1,170 @@ +--- +phase: 02-registration-dictionary-phrases +plan: 01 +type: execute +wave: 1 +depends_on: ["01-01"] +files_modified: + - _rejestracja/template/partial/Index/Index.tpl + - _rejestracja/template/partial/Index/IndexSent.tpl + - _rejestracja/Admin/template/partial/Calc/Reg.tpl + - _rejestracja/Admin/template/partial/Calc/RegEdit.tpl + - _rejestracja/sql/2026-04-24-registration-dictionary-phrases.sql + - _rejestracja/sql/apply-2026-04-24-registration-dictionary-phrases.php +autonomous: true +delegation: off +--- + + +## Goal +Add the registration phrases introduced or exposed by plan `01-01` to the site dictionary and update the registration/public/admin templates so those phrases render through `Dictionary::Translate`. + +## Purpose +The client can manage conference wording from `/_rejestracja/Admin/Dictionary/Index` instead of requiring template edits for labels, option names, status values, and repeated summary text. + +## Output +- Dictionary seed SQL and an idempotent PHP runner for the new phrase set. +- Public registration form labels/options changed to `{translate word=...}` / `|translate`. +- Confirmation and admin registration views changed to use dictionary translations for repeated labels, option labels, yes/no/default values, and participation/diet display values. + + + +## Project Context +@.paul/PROJECT.md +@.paul/ROADMAP.md +@.paul/STATE.md + +## Prior Work +@.paul/phases/01-registration-form-update/01-01-SUMMARY.md + +## Source Files +@_rejestracja/core/class/Dictionary.class.php +@_rejestracja/core/plugins/Smarty/function.translate.php +@_rejestracja/core/plugins/Smarty/modifier.translate.php +@_rejestracja/Admin/controller/DictionaryController.php +@_rejestracja/template/partial/Index/Index.tpl +@_rejestracja/template/partial/Index/IndexSent.tpl +@_rejestracja/Admin/template/partial/Calc/Reg.tpl +@_rejestracja/Admin/template/partial/Calc/RegEdit.tpl + + + + +## AC-1: Dictionary Contains Registration Phrase Set +```gherkin +Given the new dictionary seed runner has been executed +When an admin opens /_rejestracja/Admin/Dictionary/Index +Then the phrases introduced for the XXXV conference registration flow are listed as editable Polish dictionary entries +``` + +## AC-2: Public Form Uses Dictionary Phrases +```gherkin +Given the registration form is rendered +When the page displays invoice, talk/poster, participation, lodging, day choice, diet, and price labels +Then those visible strings are produced through the existing translation plugin instead of hard-coded template text +``` + +## AC-3: Confirmation And Admin Views Use Dictionary Phrases +```gherkin +Given a registration has been submitted +When the confirmation page/email and admin list/detail views render participant data +Then repeated labels, yes/no values, missing-value text, participation option labels, and diet labels come from the dictionary +``` + +## AC-4: Existing Registration Behavior Is Preserved +```gherkin +Given the phrase refactor is complete +When the modified PHP/Smarty templates are linted and searched +Then no database field mappings, pricing calculations, form field names, POST values, or payment status behavior have changed +``` + + + + + + + Task 1: Seed dictionary entries for registration phrases + _rejestracja/sql/2026-04-24-registration-dictionary-phrases.sql, _rejestracja/sql/apply-2026-04-24-registration-dictionary-phrases.php + + Create an idempotent dictionary seed for `mf_dictionary` covering phrases from the previous plan and additional related repeated phrases found during review: + - invoice/participant/institution/talk sections and field labels + - `Tak`, `Nie`, `brak`, payment status values + - fee labels, payment deadline labels for 03.10.2026, net/gross/VAT labels, total-to-pay labels + - participation labels: full conference, one day with lodging, one day without lodging, selected-day prompts, selected-day output labels + - lodging/accompanying-person labels and diet labels + - consent labels and admin action/status labels only where they are part of the registration views + Use stable keyword names for new implementation-focused phrases where the raw Polish phrase would be awkward or repeated with markup, for example `registration_participation_full`, `registration_yes`, `registration_no`, `registration_missing`, `registration_diet_standard`, `registration_fee_discount_2026`. + Preserve existing dictionary keys already used in templates (`agree1`, `agree2`, `agree_title`, `klauzula_ceny`, `send`, etc.) and do not duplicate them under new names unless a different visible phrase is needed. + The PHP runner must skip existing `(keyword, lang)` rows and create Polish replacements for at least `pl`; if the app exposes other langs through `Router::GetArrayLang()`, create placeholder replacements consistently with `Dictionary::CheckAndAdd`. + Avoid schema changes; this is data seeding only. + + Run `php -l _rejestracja/sql/apply-2026-04-24-registration-dictionary-phrases.php` and inspect the SQL/PHP phrase list for no duplicate keywords. + AC-1 satisfied: seed files can populate all planned registration dictionary phrases without modifying schema. + + + + Task 2: Convert public registration form and confirmation output to dictionary phrases + _rejestracja/template/partial/Index/Index.tpl, _rejestracja/template/partial/Index/IndexSent.tpl + + Replace hard-coded visible text introduced or touched by plan `01-01` with `{translate word='...'}` or `{'...'|translate}`: + - form headings and labels not already translated, especially invoice heading, referat/poster radio labels, fee option labels, participation options, selected-day prompt, lodging/accompanying-person labels, diet labels, `Jaka?`, and conference price label + - confirmation headings/labels and repeated values (`Tak`, `Nie`, `brak`, participation option labels, diet labels) + Keep technical values unchanged (`full`, `one_day_lodging`, `one_day_no_lodging`, `1`, `2`, posted field names, radio values, JavaScript IDs/classes). + For Smarty `replace` chains, translate replacement values with preassigned local variables if inline modifier expressions become hard to read. + Do not change pricing arithmetic, dates, selected-day values, or persisted participant fields in this task. + + Search the two files for the target hard-coded Polish phrases and confirm remaining literals are dates, DB values, CSS/JS text, or legacy content intentionally out of scope. + AC-2 and the public portion of AC-3 satisfied. + + + + Task 3: Convert admin registration list/detail display to dictionary phrases + _rejestracja/Admin/template/partial/Calc/Reg.tpl, _rejestracja/Admin/template/partial/Calc/RegEdit.tpl + + Replace hard-coded registration-related labels and display values in the admin registration list and detail/edit views: + - participant, institution, talk/poster, amount/payment, consent, participation, diet, and payment status labels + - `Tak`, `Nie`, `brak`, participation option labels, `standardowa/specjalna`, edit/delete/cancel/save button text where these are in the registration views + Preserve admin routes, action names, form field names, payment status option values, delete confirmation behavior, and table/layout structure. + Do not refactor unrelated admin modules or compiled template cache. + + Search the two admin templates for the target hard-coded registration phrases and confirm remaining literals are structural/admin legacy text outside this plan or values that must remain technical. + Admin portion of AC-3 and AC-4 satisfied. + + + + + + +## DO NOT CHANGE +- `_rejestracja/controller/IndexController.php` form processing and persistence logic +- `_rejestracja/core/model/MfParticipant.class.php` and `_rejestracja/core/_model/MfParticipant.class.php` +- Existing pricing values, form field names, POST values, participant DB columns, and payment status values +- `_rejestracja/_Admin/temp/compile/*` and `_rejestracja/temp/compile/*` +- Third-party libraries and CKEditor assets + +## SCOPE LIMITS +- This plan only dictionary-enables registration phrases from the recent registration update plus obvious repeated labels in the same registration views. +- Do not translate all legacy admin UI globally. +- Do not alter the admin dictionary UI itself beyond using it as the target for seeded phrases. +- Do not fix unrelated mojibake or old conference-year text unless it is directly in a phrase being moved to dictionary. + + + + +Before declaring plan complete: +- [ ] `php -l _rejestracja/sql/apply-2026-04-24-registration-dictionary-phrases.php` +- [ ] `rg -n "Dane do wystawienia faktury|Zgłaszam|Opłata obniżona|Biorę udział|Proszę zaznaczyć|Preferencje żywieniowe|Cena za konferencję|Typ udziału|Dopłata do pokoju|Osoba towarzysząca|dieta standardowa|dieta specjalna" _rejestracja/template/partial/Index/Index.tpl _rejestracja/template/partial/Index/IndexSent.tpl _rejestracja/Admin/template/partial/Calc/Reg.tpl _rejestracja/Admin/template/partial/Calc/RegEdit.tpl` +- [ ] Review any remaining matches and document why they are intentionally left as literals +- [ ] Confirm no changed file in this plan modifies form names, radio values, price calculations, or participant persistence + + + +- New phrase seed is idempotent and ready for deployment. +- Registration phrases are visible/editable in the dictionary after seed execution or page render. +- Public form, confirmation output, admin list, and admin detail use dictionary translations for the targeted phrases. +- Existing registration behavior from phase 1 remains unchanged. + + + +After completion, create `.paul/phases/02-registration-dictionary-phrases/02-01-SUMMARY.md`. + diff --git a/.paul/phases/02-registration-dictionary-phrases/02-01-SUMMARY.md b/.paul/phases/02-registration-dictionary-phrases/02-01-SUMMARY.md new file mode 100644 index 0000000..5a960fa --- /dev/null +++ b/.paul/phases/02-registration-dictionary-phrases/02-01-SUMMARY.md @@ -0,0 +1,124 @@ +--- +phase: 02-registration-dictionary-phrases +plan: 01 +subsystem: registration +tags: [php, smarty, mysql, dictionary, admin] +requires: + - phase: 01-registration-form-update + provides: updated XXXV Konferencja registration form fields and admin display +provides: + - Dictionary seed for registration phrases + - Public registration templates using dictionary translations + - Confirmation and admin registration views using dictionary translations +affects: [registration, admin-panel, dictionary] +tech-stack: + added: [] + patterns: [legacy Smarty dictionary translation, idempotent PHP seed runner] +key-files: + created: + - _rejestracja/sql/2026-04-24-registration-dictionary-phrases.sql + - _rejestracja/sql/apply-2026-04-24-registration-dictionary-phrases.php + modified: + - _rejestracja/template/partial/Index/Index.tpl + - _rejestracja/template/partial/Index/IndexSent.tpl + - _rejestracja/Admin/template/partial/Calc/Reg.tpl + - _rejestracja/Admin/template/partial/Calc/RegEdit.tpl +key-decisions: + - "Use stable registration_* dictionary keys for implementation phrases instead of raw Polish text keys." + - "Seed Polish replacements and use lang_keyword placeholders for any existing non-Polish dictionary languages." + - "Keep form values, pricing logic, persistence, and payment status values unchanged." +patterns-established: + - "Use Smarty translate helpers with assigned variables for repeated display values like yes/no/missing and participation labels." + - "Use guarded one-off PHP runners for production dictionary/data seeds." +duration: ~9min +started: 2026-04-24T21:16:13+02:00 +completed: 2026-04-24T21:25:19+02:00 +--- + +# Phase 2 Plan 01: Registration Dictionary Phrases Summary + +Registration wording from the XXXV conference update is now dictionary-backed across the public form, confirmation output, and admin registration views. + +## Performance + +| Metric | Value | +|--------|-------| +| Duration | ~9 minutes | +| Started | 2026-04-24T21:16:13+02:00 | +| Completed | 2026-04-24T21:25:19+02:00 | +| Tasks | 3 completed | +| Files modified | 4 modified, 2 created | + +## Acceptance Criteria Results + +| Criterion | Status | Notes | +|-----------|--------|-------| +| AC-1: Dictionary Contains Registration Phrase Set | Pass | Added idempotent SQL and PHP seed runner for the registration phrase set. | +| AC-2: Public Form Uses Dictionary Phrases | Pass | Public form labels/options introduced by the registration update now use `{translate}`. | +| AC-3: Confirmation And Admin Views Use Dictionary Phrases | Pass | Confirmation, admin list, and admin detail views use dictionary-backed labels and display values. | +| AC-4: Existing Registration Behavior Is Preserved | Pass | No controller/model/persistence changes; form names, radio values, pricing logic, and payment status values were preserved. | + +## Accomplishments + +- Added editable dictionary entries for registration labels, options, yes/no values, missing-value text, participation labels, diet labels, fee labels, and admin action/status text. +- Replaced hard-coded visible phrases in the registration form, confirmation view, admin registration list, and admin registration detail view. +- Preserved the legacy PHP/Smarty architecture and the prior registration behavior from phase 1. + +## Files Created/Modified + +| File | Change | Purpose | +|------|--------|---------| +| `_rejestracja/sql/2026-04-24-registration-dictionary-phrases.sql` | Created | Idempotent Polish dictionary inserts for registration phrases. | +| `_rejestracja/sql/apply-2026-04-24-registration-dictionary-phrases.php` | Created | Guarded browser/CLI runner to seed missing dictionary phrases. | +| `_rejestracja/template/partial/Index/Index.tpl` | Modified | Public form labels/options now use dictionary translations. | +| `_rejestracja/template/partial/Index/IndexSent.tpl` | Modified | Confirmation/email labels and display values now use dictionary translations. | +| `_rejestracja/Admin/template/partial/Calc/Reg.tpl` | Modified | Admin registration list labels and display values now use dictionary translations. | +| `_rejestracja/Admin/template/partial/Calc/RegEdit.tpl` | Modified | Admin registration detail/edit labels and payment status labels now use dictionary translations. | + +## Verification Results + +| Check | Status | +|-------|--------| +| `php -l _rejestracja/sql/apply-2026-04-24-registration-dictionary-phrases.php` | Pass | +| Hard-coded target phrase scan across public/admin registration templates | Pass; only non-visible `` comment remains | +| Duplicate keyword scan in PHP seed phrase list | Pass | +| Boundary check for participant controller/model files | Pass; files were not modified | + +## Decisions Made + +| Decision | Rationale | Impact | +|----------|-----------|--------| +| Use `registration_*` keys | Stable keys are easier to reuse than raw Polish strings with punctuation/HTML variants. | Admin dictionary can edit replacements without coupling to template wording. | +| Seed existing non-Polish languages with placeholders | Mirrors the existing `Dictionary::CheckAndAdd` convention. | Avoids missing rows if the site has more dictionary languages. | +| Replace old visible admin fee deadline text with 2026 dictionary keys | Old templates still contained outdated visible dates. | Admin display aligns with the current conference phrase set while preserving conditions and values. | + +## Deviations from Plan + +| Type | Count | Impact | +|------|-------|--------| +| Scope addition | 1 | Added `registration_participation_preferences` after verification found one remaining visible admin label. | +| Existing content correction | 1 | Dictionary-backed admin fee labels now show the current 03.10.2026 deadline phrase instead of legacy 2021/2024 visible text. | + +## Issues Encountered + +| Issue | Resolution | +|-------|------------| +| Legacy templates contain mixed/mojibake text | Touched only the registration phrases in scope and kept unrelated legacy content alone. | +| Unrelated working tree entries existed | Left `_rejestracja/Static/image/Admin/Thumbs.db` and `.vscode/ftp-kr.sync.cache.json` untouched. | + +## Next Phase Readiness + +**Ready:** +- Registration phrase set can be seeded and edited through `/_rejestracja/Admin/Dictionary/Index`. +- Public and admin registration views consume dictionary translations for targeted phrases. + +**Concerns:** +- Production needs the dictionary seed runner or SQL applied before the new keys appear in the admin dictionary. +- Full end-to-end visual verification still depends on live/staging access. + +**Blockers:** +- None for this phase. + +--- +*Phase: 02-registration-dictionary-phrases, Plan: 01* +*Completed: 2026-04-24* diff --git a/_rejestracja/Admin/template/partial/Calc/Reg.tpl b/_rejestracja/Admin/template/partial/Calc/Reg.tpl index c3207d5..6f10486 100644 --- a/_rejestracja/Admin/template/partial/Calc/Reg.tpl +++ b/_rejestracja/Admin/template/partial/Calc/Reg.tpl @@ -1,4 +1,12 @@

Konferencja - Rejestracja

+{assign var=registrationYes value='registration_yes'|translate} +{assign var=registrationNo value='registration_no'|translate} +{assign var=registrationMissing value='registration_missing'|translate} +{assign var=registrationParticipationFull value='registration_participation_full'|translate} +{assign var=registrationParticipationLodging value='registration_participation_one_day_lodging'|translate} +{assign var=registrationParticipationNoLodging value='registration_participation_one_day_no_lodging'|translate} +{assign var=registrationDietStandardShort value='registration_diet_standard_short'|translate} +{assign var=registrationDietSpecialShort value='registration_diet_special_short'|translate} {dropDownContainer title='Zgłoszenia Rejestracji'} {assign var="display" value=""} @@ -16,12 +24,12 @@
Lp.
Imię Nazwisko - Dane uczestnika - Dane instytucji - Dane wystąpienia - Do zapłaty - Zgody - Status opłaty + {'registration_participant_data'|translate} + {'registration_institution_data'|translate} + {'registration_presentation_data'|translate} + {'registration_amount_information'|translate} + {'registration_consents_expressed'|translate} + {'registration_payment_status'|translate}   {assign var=x value=0} @@ -45,53 +53,53 @@ Kod pocztowy: {$obj->getPostCode()}
Miejscowość: {$obj->getCity()}
NIP Instytucji: {$obj->getNip()}
- Referat: {$obj->getReferat()|replace:1:'Tak'|replace:0:'Nie'|replace:2:'Nie'}
- Poster: {$obj->getPoster()|replace:1:'Tak'|replace:0:'Nie'|replace:2:'Nie'} -

Temat: {$obj->getMessage()|default:'brak'}

-

Autor: {$obj->getAutor()|default:'brak'}

-

Typ udziału: {$obj->getParticipationOption()|replace:'full':'cała konferencja'|replace:'one_day_lodging':'jeden dzień konferencji (z noclegiem)'|replace:'one_day_no_lodging':'jeden dzień konferencji (bez noclegu)'|default:'brak'}

-

Dni: {if $obj->getParticipationDays()}{$obj->getParticipationDays()}{elseif $obj->GetFeeOneDay()}{$obj->GetFeeOneDay()}{else}brak{/if}

-

Dieta: {$obj->getDiet()|replace:1:'standardowa'|replace:2:'specjalna'|default:'brak'} {if $obj->getDietSpecial()}- {$obj->getDietSpecial()}{/if}

+ Referat: {$obj->getReferat()|replace:1:$registrationYes|replace:0:$registrationNo|replace:2:$registrationNo}
+ Poster: {$obj->getPoster()|replace:1:$registrationYes|replace:0:$registrationNo|replace:2:$registrationNo} +

{'registration_topic'|translate}: {$obj->getMessage()|default:$registrationMissing}

+

{'registration_author'|translate}: {$obj->getAutor()|default:$registrationMissing}

+

{'registration_participation_type'|translate}: {$obj->getParticipationOption()|replace:'full':$registrationParticipationFull|replace:'one_day_lodging':$registrationParticipationLodging|replace:'one_day_no_lodging':$registrationParticipationNoLodging|default:$registrationMissing}

+

{'registration_days'|translate}: {if $obj->getParticipationDays()}{$obj->getParticipationDays()}{elseif $obj->GetFeeOneDay()}{$obj->GetFeeOneDay()}{else}{$registrationMissing}{/if}

+

{'registration_diet'|translate}: {$obj->getDiet()|replace:1:$registrationDietStandardShort|replace:2:$registrationDietSpecialShort|default:$registrationMissing} {if $obj->getDietSpecial()}- {$obj->getDietSpecial()}{/if}

- Wybrane opcje:
+ {'registration_selected_options'|translate}:
{if $discPrice == 2 || $obj->getDateAdd() > '2024-10-11 00:00:00'} - Opłata zwykła (płatność po 11.10.2024) + {'registration_fee_normal_2026'|translate} {else} - Opłata obniżona (płatność do 11.10.2024) + {'registration_fee_discount_2026'|translate} {/if} - Zgoda przetwarzanie danych: {$obj->GetAgree1()|replace:1:'Tak'|replace:0:'Nie'}
- Zgoda przetwarzanie wizerunku: {$obj->GetAgree2()|replace:1:'Tak'|replace:0:'Nie'} + {'registration_consent_data'|translate}: {$obj->GetAgree1()|replace:1:$registrationYes|replace:0:$registrationNo}
+ {'registration_consent_image'|translate}: {$obj->GetAgree2()|replace:1:$registrationYes|replace:0:$registrationNo} - {$obj->GetStatus()|replace:2:'Tak'|replace:1:'Nie'} + {$obj->GetStatus()|replace:2:$registrationYes|replace:1:$registrationNo} {*edytujusuń*} - edytuj - usuń + {'registration_edit'|translate} + {'registration_delete'|translate} {/foreach} diff --git a/_rejestracja/Admin/template/partial/Calc/RegEdit.tpl b/_rejestracja/Admin/template/partial/Calc/RegEdit.tpl index 1194123..03c8020 100644 --- a/_rejestracja/Admin/template/partial/Calc/RegEdit.tpl +++ b/_rejestracja/Admin/template/partial/Calc/RegEdit.tpl @@ -1,9 +1,17 @@ -

Edytuj zgłoszenie

+

Edytuj zgłoszenie

+{assign var=registrationYes value='registration_yes'|translate} +{assign var=registrationNo value='registration_no'|translate} +{assign var=registrationMissing value='registration_missing'|translate} +{assign var=registrationParticipationFull value='registration_participation_full'|translate} +{assign var=registrationParticipationLodging value='registration_participation_one_day_lodging'|translate} +{assign var=registrationParticipationNoLodging value='registration_participation_one_day_no_lodging'|translate} +{assign var=registrationDietStandardShort value='registration_diet_standard_short'|translate} +{assign var=registrationDietSpecialShort value='registration_diet_special_short'|translate} - {assign var=id value=$obj->GetId()} +{assign var=id value=$obj->GetId()}
{if isset($obj)} @@ -18,114 +26,105 @@ urlStatic = '{$urlStatic}'; - - + - + - - - - - - - - - + - - - - + Referat: {$objParticipant->getReferat()|default:$registrationNo|replace:1:$registrationYes|replace:2:$registrationNo|replace:0:$registrationNo}
+ Poster: {$objParticipant->getPoster()|default:$registrationNo|replace:1:$registrationYes|replace:2:$registrationNo|replace:0:$registrationNo} +

{'registration_topic'|translate}: {$objParticipant->getMessage()|default:$registrationMissing}

+

{'registration_abstract'|translate}: {$objParticipant->getMessageLong()|default:$registrationMissing}

+

{'registration_author'|translate}: {$objParticipant->getAutor()|default:$registrationMissing}

+ - - + + + + + + + + + + + + + +
Dane uczestnika: - Imię: {$objParticipant->getName()}
- Nazwisko: {$objParticipant->getSurname()}
- Tytuł/stop. naukowy:{$objParticipant->getDegree()}
- Stanowisko: {$objParticipant->getPosition()|default:'brak'}
- Telefon: {$objParticipant->getPhone()}
- Fax: {$objParticipant->getFax()|default:'brak'}
- Email: {$objParticipant->getEmail()}
+
{'registration_participant_data'|translate}: + Imię: {$objParticipant->getName()}
+ Nazwisko: {$objParticipant->getSurname()}
+ Tytuł/stop. naukowy:{$objParticipant->getDegree()}
+ Stanowisko: {$objParticipant->getPosition()|default:$registrationMissing}
+ Telefon: {$objParticipant->getPhone()}
+ Fax: {$objParticipant->getFax()|default:$registrationMissing}
+ Email: {$objParticipant->getEmail()}
Dane instytucji::{'registration_institution_data'|translate}: - Instytucja: {$objParticipant->getInstitution()|default:'brak'}
- Ulica i numer: {$objParticipant->getAddress()|default:'brak'}
- Kod pocztowy: {$objParticipant->getPostCode()|default:'brak'}
- Miejscowość: {$objParticipant->getCity()|default:'brak'}
- NIP Instytucji: {$objParticipant->getNip()|default:'brak'}
-
Dane wystąpienia: - Referat: {$objParticipant->getReferat()|default:'Nie'|replace:1:'Tak'|replace:2:'Nie'|replace:0:'Nie'}
- Poster: {$objParticipant->getPoster()|default:'Nie'|replace:1:'Tak'|replace:2:'Nie'|replace:0:'Nie'} -

Temat: {$objParticipant->getMessage()|default:'brak'}

-

Streszczenie: {$objParticipant->getMessageLong()|default:'brak'}

-

Autor: {$objParticipant->getAutor()|default:'brak'}

-
Udział i preferencje: -

Typ udziału: {$objParticipant->getParticipationOption()|replace:'full':'cała konferencja'|replace:'one_day_lodging':'jeden dzień konferencji (z noclegiem)'|replace:'one_day_no_lodging':'jeden dzień konferencji (bez noclegu)'|default:'brak'}

-

Dni: {if $objParticipant->getParticipationDays()}{$objParticipant->getParticipationDays()}{elseif $objParticipant->GetFeeOneDay()}{$objParticipant->GetFeeOneDay()}{else}brak{/if}

-

Dopłata do pokoju 1-osobowego: {$objParticipant->getFeeRoom1()|replace:1:'Tak'|replace:0:'Nie'|default:'Nie'}

-

Osoba towarzysząca/kierowca: {$objParticipant->getFeeRoomAddPerson()|replace:1:'Tak'|replace:0:'Nie'|default:'Nie'}

-

Dieta: {$objParticipant->getDiet()|replace:1:'standardowa'|replace:2:'specjalna'|default:'brak'} {if $objParticipant->getDietSpecial()}- {$objParticipant->getDietSpecial()}{/if}

+ Instytucja: {$objParticipant->getInstitution()|default:$registrationMissing}
+ Ulica i numer: {$objParticipant->getAddress()|default:$registrationMissing}
+ Kod pocztowy: {$objParticipant->getPostCode()|default:$registrationMissing}
+ Miejscowość: {$objParticipant->getCity()|default:$registrationMissing}
+ NIP Instytucji: {$objParticipant->getNip()|default:$registrationMissing}
Informacja o kwocie do zapłaty:{'registration_presentation_data'|translate}: - Wybrane opcje:
- {if $discPrice == 2} - - Opłata zwykła (płatność po 08.10.2021) - {else} - Opłata obniżona (płatność do 08.10.2021) - {/if} -
    - {foreach $arrayObjParameters as $objParam} - {if in_array($objParam->GetId(),$arrayFee)} - {if $discPrice == 2} -
  • {$objParam->GetName()} {if $objParam->GetId() eq 5}({$objParticipant->GetFeeOneDay()}){/if}
    - Cena netto: {$objParam->GetPrice()|number_format:2:",":" "} PLN
    - Cena brutto: {assign var="vat" value=$objParam->GetPrice()*1.23}{$vat|number_format:2:",":" "} PLN
    -
  • - {else} -
  • {$objParam->GetName()} {if $objParam->GetId() eq 5}({$objParticipant->GetFeeOneDay()}){/if}
    - Cena netto (bez VAT): {$objParam->GetPriceProm()|number_format:2:",":" "} PLN
    - Cena brutto (z VAT): {assign var="vat" value=$objParam->GetPriceProm()*1.23}{$vat|number_format:2:",":" "} PLN
    -
  • - {/if} - {/if} - {/foreach} -

    Razem do zapłaty:

    - {assign var="resultPrice" value=$objParticipant->getPrice()} - Cena netto: {$resultPrice|number_format:2:",":" "} PLN
    - Cena brutto: {assign var="resultPriceVat" value=$resultPrice*1.23}{$resultPriceVat|number_format:2:",":" "} PLN
    - - -
-
Wyrażono zgody -

Zgoda na przetwarzanie danych - {$objParticipant->getAgree1()|default:'Nie'|replace:1:'Tak'|replace:'on':'Tak'|replace:0:'Nie'}

- -

Zgoda na przetwarzanie wizerunku - {$objParticipant->getAgree2()|default:'Nie'|replace:1:'Tak'|replace:'on':'Tak'|replace:0:'Nie'}

-
Status opłaty: - -
{'registration_participation_preferences'|translate}: +

{'registration_participation_type'|translate}: {$objParticipant->getParticipationOption()|replace:'full':$registrationParticipationFull|replace:'one_day_lodging':$registrationParticipationLodging|replace:'one_day_no_lodging':$registrationParticipationNoLodging|default:$registrationMissing}

+

{'registration_days'|translate}: {if $objParticipant->getParticipationDays()}{$objParticipant->getParticipationDays()}{elseif $objParticipant->GetFeeOneDay()}{$objParticipant->GetFeeOneDay()}{else}{$registrationMissing}{/if}

+

{'registration_single_room_surcharge'|translate}: {$objParticipant->getFeeRoom1()|replace:1:$registrationYes|replace:0:$registrationNo|default:$registrationNo}

+

{'registration_accompanying_driver'|translate}: {$objParticipant->getFeeRoomAddPerson()|replace:1:$registrationYes|replace:0:$registrationNo|default:$registrationNo}

+

{'registration_diet'|translate}: {$objParticipant->getDiet()|replace:1:$registrationDietStandardShort|replace:2:$registrationDietSpecialShort|default:$registrationMissing} {if $objParticipant->getDietSpecial()}- {$objParticipant->getDietSpecial()}{/if}

+
{'registration_amount_information'|translate}: + {'registration_selected_options'|translate}:
+ {if $discPrice == 2} + {'registration_fee_normal_2026'|translate} + {else} + {'registration_fee_discount_2026'|translate} + {/if} +
    + {foreach $arrayObjParameters as $objParam} + {if in_array($objParam->GetId(),$arrayFee)} + {if $discPrice == 2} +
  • {$objParam->GetName()} {if $objParam->GetId() eq 5}({$objParticipant->GetFeeOneDay()}){/if}
    + {'registration_net_price'|translate}: {$objParam->GetPrice()|number_format:2:",":" "} PLN
    + {'registration_gross_price'|translate}: {assign var="vat" value=$objParam->GetPrice()*1.23}{$vat|number_format:2:",":" "} PLN
    +
  • + {else} +
  • {$objParam->GetName()} {if $objParam->GetId() eq 5}({$objParticipant->GetFeeOneDay()}){/if}
    + {'registration_net_price_no_vat'|translate}: {$objParam->GetPriceProm()|number_format:2:",":" "} PLN
    + {'registration_gross_price_vat'|translate}: {assign var="vat" value=$objParam->GetPriceProm()*1.23}{$vat|number_format:2:",":" "} PLN
    +
  • + {/if} + {/if} + {/foreach} +

    {'registration_total_to_pay'|translate}:

    + {assign var="resultPrice" value=$objParticipant->getPrice()} + {'registration_net_price'|translate}: {$resultPrice|number_format:2:",":" "} PLN
    + {'registration_gross_price'|translate}: {assign var="resultPriceVat" value=$resultPrice*1.23}{$resultPriceVat|number_format:2:",":" "} PLN
    +
+
{'registration_consents_expressed'|translate} +

{'registration_consent_data'|translate} - {$objParticipant->getAgree1()|default:$registrationNo|replace:1:$registrationYes|replace:'on':$registrationYes|replace:0:$registrationNo}

+

{'registration_consent_image'|translate} - {$objParticipant->getAgree2()|default:$registrationNo|replace:1:$registrationYes|replace:'on':$registrationYes|replace:0:$registrationNo}

+
{'registration_payment_status'|translate}: + +
{/dropDownContainer} - - - - +
-
- - - -        - -
+
+ +        + +
- +
diff --git a/_rejestracja/sql/2026-04-24-registration-dictionary-phrases.sql b/_rejestracja/sql/2026-04-24-registration-dictionary-phrases.sql new file mode 100644 index 0000000..036f060 --- /dev/null +++ b/_rejestracja/sql/2026-04-24-registration-dictionary-phrases.sql @@ -0,0 +1,226 @@ +-- Dictionary phrase seed for XXXV Konferencja registration labels. +-- Safe to run more than once: each INSERT checks for an existing Polish key. + +INSERT INTO mf_dictionary (keyword, lang, replacement) +SELECT 'registration_yes', 'pl', 'Tak' +WHERE NOT EXISTS (SELECT 1 FROM mf_dictionary WHERE keyword = 'registration_yes' AND lang = 'pl'); + +INSERT INTO mf_dictionary (keyword, lang, replacement) +SELECT 'registration_no', 'pl', 'Nie' +WHERE NOT EXISTS (SELECT 1 FROM mf_dictionary WHERE keyword = 'registration_no' AND lang = 'pl'); + +INSERT INTO mf_dictionary (keyword, lang, replacement) +SELECT 'registration_missing', 'pl', 'brak' +WHERE NOT EXISTS (SELECT 1 FROM mf_dictionary WHERE keyword = 'registration_missing' AND lang = 'pl'); + +INSERT INTO mf_dictionary (keyword, lang, replacement) +SELECT 'registration_invoice_data', 'pl', 'Dane do wystawienia faktury' +WHERE NOT EXISTS (SELECT 1 FROM mf_dictionary WHERE keyword = 'registration_invoice_data' AND lang = 'pl'); + +INSERT INTO mf_dictionary (keyword, lang, replacement) +SELECT 'registration_participant_data', 'pl', 'Dane uczestnika' +WHERE NOT EXISTS (SELECT 1 FROM mf_dictionary WHERE keyword = 'registration_participant_data' AND lang = 'pl'); + +INSERT INTO mf_dictionary (keyword, lang, replacement) +SELECT 'registration_institution_data', 'pl', 'Dane instytucji' +WHERE NOT EXISTS (SELECT 1 FROM mf_dictionary WHERE keyword = 'registration_institution_data' AND lang = 'pl'); + +INSERT INTO mf_dictionary (keyword, lang, replacement) +SELECT 'registration_presentation_data', 'pl', 'Dane wystąpienia' +WHERE NOT EXISTS (SELECT 1 FROM mf_dictionary WHERE keyword = 'registration_presentation_data' AND lang = 'pl'); + +INSERT INTO mf_dictionary (keyword, lang, replacement) +SELECT 'registration_submit_talk', 'pl', 'Zgłaszam referat' +WHERE NOT EXISTS (SELECT 1 FROM mf_dictionary WHERE keyword = 'registration_submit_talk' AND lang = 'pl'); + +INSERT INTO mf_dictionary (keyword, lang, replacement) +SELECT 'registration_submit_poster', 'pl', 'Zgłaszam poster' +WHERE NOT EXISTS (SELECT 1 FROM mf_dictionary WHERE keyword = 'registration_submit_poster' AND lang = 'pl'); + +INSERT INTO mf_dictionary (keyword, lang, replacement) +SELECT 'registration_topic', 'pl', 'Temat' +WHERE NOT EXISTS (SELECT 1 FROM mf_dictionary WHERE keyword = 'registration_topic' AND lang = 'pl'); + +INSERT INTO mf_dictionary (keyword, lang, replacement) +SELECT 'registration_abstract', 'pl', 'Streszczenie' +WHERE NOT EXISTS (SELECT 1 FROM mf_dictionary WHERE keyword = 'registration_abstract' AND lang = 'pl'); + +INSERT INTO mf_dictionary (keyword, lang, replacement) +SELECT 'registration_author', 'pl', 'Autor' +WHERE NOT EXISTS (SELECT 1 FROM mf_dictionary WHERE keyword = 'registration_author' AND lang = 'pl'); + +INSERT INTO mf_dictionary (keyword, lang, replacement) +SELECT 'registration_amount_information', 'pl', 'Informacja o kwocie do zapłaty' +WHERE NOT EXISTS (SELECT 1 FROM mf_dictionary WHERE keyword = 'registration_amount_information' AND lang = 'pl'); + +INSERT INTO mf_dictionary (keyword, lang, replacement) +SELECT 'registration_selected_options', 'pl', 'Wybrane opcje' +WHERE NOT EXISTS (SELECT 1 FROM mf_dictionary WHERE keyword = 'registration_selected_options' AND lang = 'pl'); + +INSERT INTO mf_dictionary (keyword, lang, replacement) +SELECT 'registration_fee_discount_2026', 'pl', 'Opłata obniżona (płatność do 03.10.2026)' +WHERE NOT EXISTS (SELECT 1 FROM mf_dictionary WHERE keyword = 'registration_fee_discount_2026' AND lang = 'pl'); + +INSERT INTO mf_dictionary (keyword, lang, replacement) +SELECT 'registration_fee_normal_2026', 'pl', 'Opłata zwykła (płatność po 03.10.2026)' +WHERE NOT EXISTS (SELECT 1 FROM mf_dictionary WHERE keyword = 'registration_fee_normal_2026' AND lang = 'pl'); + +INSERT INTO mf_dictionary (keyword, lang, replacement) +SELECT 'registration_net_price', 'pl', 'Cena netto' +WHERE NOT EXISTS (SELECT 1 FROM mf_dictionary WHERE keyword = 'registration_net_price' AND lang = 'pl'); + +INSERT INTO mf_dictionary (keyword, lang, replacement) +SELECT 'registration_net_price_no_vat', 'pl', 'Cena netto (bez VAT)' +WHERE NOT EXISTS (SELECT 1 FROM mf_dictionary WHERE keyword = 'registration_net_price_no_vat' AND lang = 'pl'); + +INSERT INTO mf_dictionary (keyword, lang, replacement) +SELECT 'registration_gross_price', 'pl', 'Cena brutto' +WHERE NOT EXISTS (SELECT 1 FROM mf_dictionary WHERE keyword = 'registration_gross_price' AND lang = 'pl'); + +INSERT INTO mf_dictionary (keyword, lang, replacement) +SELECT 'registration_gross_price_vat', 'pl', 'Cena brutto (z VAT)' +WHERE NOT EXISTS (SELECT 1 FROM mf_dictionary WHERE keyword = 'registration_gross_price_vat' AND lang = 'pl'); + +INSERT INTO mf_dictionary (keyword, lang, replacement) +SELECT 'registration_total_to_pay', 'pl', 'Razem do zapłaty' +WHERE NOT EXISTS (SELECT 1 FROM mf_dictionary WHERE keyword = 'registration_total_to_pay' AND lang = 'pl'); + +INSERT INTO mf_dictionary (keyword, lang, replacement) +SELECT 'registration_full_conference_label', 'pl', 'Cała konferencja' +WHERE NOT EXISTS (SELECT 1 FROM mf_dictionary WHERE keyword = 'registration_full_conference_label' AND lang = 'pl'); + +INSERT INTO mf_dictionary (keyword, lang, replacement) +SELECT 'registration_participation_full_cta', 'pl', 'Biorę udział w całej konferencji' +WHERE NOT EXISTS (SELECT 1 FROM mf_dictionary WHERE keyword = 'registration_participation_full_cta' AND lang = 'pl'); + +INSERT INTO mf_dictionary (keyword, lang, replacement) +SELECT 'registration_participation_one_day_lodging_cta', 'pl', 'Biorę udział w jednym dniu konferencji (z noclegiem)' +WHERE NOT EXISTS (SELECT 1 FROM mf_dictionary WHERE keyword = 'registration_participation_one_day_lodging_cta' AND lang = 'pl'); + +INSERT INTO mf_dictionary (keyword, lang, replacement) +SELECT 'registration_participation_one_day_no_lodging_cta', 'pl', 'Biorę udział w jednym dniu konferencji (bez noclegu)' +WHERE NOT EXISTS (SELECT 1 FROM mf_dictionary WHERE keyword = 'registration_participation_one_day_no_lodging_cta' AND lang = 'pl'); + +INSERT INTO mf_dictionary (keyword, lang, replacement) +SELECT 'registration_participation_full', 'pl', 'cała konferencja' +WHERE NOT EXISTS (SELECT 1 FROM mf_dictionary WHERE keyword = 'registration_participation_full' AND lang = 'pl'); + +INSERT INTO mf_dictionary (keyword, lang, replacement) +SELECT 'registration_participation_one_day_lodging', 'pl', 'jeden dzień konferencji (z noclegiem)' +WHERE NOT EXISTS (SELECT 1 FROM mf_dictionary WHERE keyword = 'registration_participation_one_day_lodging' AND lang = 'pl'); + +INSERT INTO mf_dictionary (keyword, lang, replacement) +SELECT 'registration_participation_one_day_no_lodging', 'pl', 'jeden dzień konferencji (bez noclegu)' +WHERE NOT EXISTS (SELECT 1 FROM mf_dictionary WHERE keyword = 'registration_participation_one_day_no_lodging' AND lang = 'pl'); + +INSERT INTO mf_dictionary (keyword, lang, replacement) +SELECT 'registration_select_day', 'pl', 'Proszę zaznaczyć dzień' +WHERE NOT EXISTS (SELECT 1 FROM mf_dictionary WHERE keyword = 'registration_select_day' AND lang = 'pl'); + +INSERT INTO mf_dictionary (keyword, lang, replacement) +SELECT 'registration_selected_presence_days', 'pl', 'Wskazane dni obecności' +WHERE NOT EXISTS (SELECT 1 FROM mf_dictionary WHERE keyword = 'registration_selected_presence_days' AND lang = 'pl'); + +INSERT INTO mf_dictionary (keyword, lang, replacement) +SELECT 'registration_full_conference_presence', 'pl', 'Obecność podczas całej konferencji.' +WHERE NOT EXISTS (SELECT 1 FROM mf_dictionary WHERE keyword = 'registration_full_conference_presence' AND lang = 'pl'); + +INSERT INTO mf_dictionary (keyword, lang, replacement) +SELECT 'registration_single_room_surcharge', 'pl', 'Dopłata do pokoju 1-osobowego' +WHERE NOT EXISTS (SELECT 1 FROM mf_dictionary WHERE keyword = 'registration_single_room_surcharge' AND lang = 'pl'); + +INSERT INTO mf_dictionary (keyword, lang, replacement) +SELECT 'registration_accompanying_driver_fee', 'pl', 'Opłata za pobyt osoby towarzyszącej lub kierowcy w pokoju dwuosobowym' +WHERE NOT EXISTS (SELECT 1 FROM mf_dictionary WHERE keyword = 'registration_accompanying_driver_fee' AND lang = 'pl'); + +INSERT INTO mf_dictionary (keyword, lang, replacement) +SELECT 'registration_accompanying_driver', 'pl', 'Osoba towarzysząca/kierowca' +WHERE NOT EXISTS (SELECT 1 FROM mf_dictionary WHERE keyword = 'registration_accompanying_driver' AND lang = 'pl'); + +INSERT INTO mf_dictionary (keyword, lang, replacement) +SELECT 'registration_participation_preferences', 'pl', 'Udział i preferencje' +WHERE NOT EXISTS (SELECT 1 FROM mf_dictionary WHERE keyword = 'registration_participation_preferences' AND lang = 'pl'); + +INSERT INTO mf_dictionary (keyword, lang, replacement) +SELECT 'registration_diet_preferences', 'pl', 'Preferencje żywieniowe' +WHERE NOT EXISTS (SELECT 1 FROM mf_dictionary WHERE keyword = 'registration_diet_preferences' AND lang = 'pl'); + +INSERT INTO mf_dictionary (keyword, lang, replacement) +SELECT 'registration_diet_standard', 'pl', 'dieta standardowa' +WHERE NOT EXISTS (SELECT 1 FROM mf_dictionary WHERE keyword = 'registration_diet_standard' AND lang = 'pl'); + +INSERT INTO mf_dictionary (keyword, lang, replacement) +SELECT 'registration_diet_special', 'pl', 'dieta specjalna' +WHERE NOT EXISTS (SELECT 1 FROM mf_dictionary WHERE keyword = 'registration_diet_special' AND lang = 'pl'); + +INSERT INTO mf_dictionary (keyword, lang, replacement) +SELECT 'registration_diet_standard_short', 'pl', 'standardowa' +WHERE NOT EXISTS (SELECT 1 FROM mf_dictionary WHERE keyword = 'registration_diet_standard_short' AND lang = 'pl'); + +INSERT INTO mf_dictionary (keyword, lang, replacement) +SELECT 'registration_diet_special_short', 'pl', 'specjalna' +WHERE NOT EXISTS (SELECT 1 FROM mf_dictionary WHERE keyword = 'registration_diet_special_short' AND lang = 'pl'); + +INSERT INTO mf_dictionary (keyword, lang, replacement) +SELECT 'registration_diet_which', 'pl', 'Jaka?' +WHERE NOT EXISTS (SELECT 1 FROM mf_dictionary WHERE keyword = 'registration_diet_which' AND lang = 'pl'); + +INSERT INTO mf_dictionary (keyword, lang, replacement) +SELECT 'registration_conference_price', 'pl', 'Cena za konferencję' +WHERE NOT EXISTS (SELECT 1 FROM mf_dictionary WHERE keyword = 'registration_conference_price' AND lang = 'pl'); + +INSERT INTO mf_dictionary (keyword, lang, replacement) +SELECT 'registration_consents_expressed', 'pl', 'Wyrażono zgody' +WHERE NOT EXISTS (SELECT 1 FROM mf_dictionary WHERE keyword = 'registration_consents_expressed' AND lang = 'pl'); + +INSERT INTO mf_dictionary (keyword, lang, replacement) +SELECT 'registration_consent_data', 'pl', 'Zgoda na przetwarzanie danych' +WHERE NOT EXISTS (SELECT 1 FROM mf_dictionary WHERE keyword = 'registration_consent_data' AND lang = 'pl'); + +INSERT INTO mf_dictionary (keyword, lang, replacement) +SELECT 'registration_consent_image', 'pl', 'Zgoda na przetwarzanie wizerunku' +WHERE NOT EXISTS (SELECT 1 FROM mf_dictionary WHERE keyword = 'registration_consent_image' AND lang = 'pl'); + +INSERT INTO mf_dictionary (keyword, lang, replacement) +SELECT 'registration_selected_participation_option', 'pl', 'Wybrana opcja udziału' +WHERE NOT EXISTS (SELECT 1 FROM mf_dictionary WHERE keyword = 'registration_selected_participation_option' AND lang = 'pl'); + +INSERT INTO mf_dictionary (keyword, lang, replacement) +SELECT 'registration_participation_type', 'pl', 'Typ udziału' +WHERE NOT EXISTS (SELECT 1 FROM mf_dictionary WHERE keyword = 'registration_participation_type' AND lang = 'pl'); + +INSERT INTO mf_dictionary (keyword, lang, replacement) +SELECT 'registration_days', 'pl', 'Dni' +WHERE NOT EXISTS (SELECT 1 FROM mf_dictionary WHERE keyword = 'registration_days' AND lang = 'pl'); + +INSERT INTO mf_dictionary (keyword, lang, replacement) +SELECT 'registration_diet', 'pl', 'Dieta' +WHERE NOT EXISTS (SELECT 1 FROM mf_dictionary WHERE keyword = 'registration_diet' AND lang = 'pl'); + +INSERT INTO mf_dictionary (keyword, lang, replacement) +SELECT 'registration_payment_status', 'pl', 'Status opłaty' +WHERE NOT EXISTS (SELECT 1 FROM mf_dictionary WHERE keyword = 'registration_payment_status' AND lang = 'pl'); + +INSERT INTO mf_dictionary (keyword, lang, replacement) +SELECT 'registration_paid', 'pl', 'opłacone' +WHERE NOT EXISTS (SELECT 1 FROM mf_dictionary WHERE keyword = 'registration_paid' AND lang = 'pl'); + +INSERT INTO mf_dictionary (keyword, lang, replacement) +SELECT 'registration_unpaid', 'pl', 'nie opłacone' +WHERE NOT EXISTS (SELECT 1 FROM mf_dictionary WHERE keyword = 'registration_unpaid' AND lang = 'pl'); + +INSERT INTO mf_dictionary (keyword, lang, replacement) +SELECT 'registration_edit', 'pl', 'edytuj' +WHERE NOT EXISTS (SELECT 1 FROM mf_dictionary WHERE keyword = 'registration_edit' AND lang = 'pl'); + +INSERT INTO mf_dictionary (keyword, lang, replacement) +SELECT 'registration_delete', 'pl', 'usuń' +WHERE NOT EXISTS (SELECT 1 FROM mf_dictionary WHERE keyword = 'registration_delete' AND lang = 'pl'); + +INSERT INTO mf_dictionary (keyword, lang, replacement) +SELECT 'registration_cancel', 'pl', 'Anuluj' +WHERE NOT EXISTS (SELECT 1 FROM mf_dictionary WHERE keyword = 'registration_cancel' AND lang = 'pl'); + +INSERT INTO mf_dictionary (keyword, lang, replacement) +SELECT 'registration_save', 'pl', 'Zapisz' +WHERE NOT EXISTS (SELECT 1 FROM mf_dictionary WHERE keyword = 'registration_save' AND lang = 'pl'); diff --git a/_rejestracja/sql/apply-2026-04-24-registration-dictionary-phrases.php b/_rejestracja/sql/apply-2026-04-24-registration-dictionary-phrases.php new file mode 100644 index 0000000..da20d8f --- /dev/null +++ b/_rejestracja/sql/apply-2026-04-24-registration-dictionary-phrases.php @@ -0,0 +1,200 @@ + 'Tak', + 'registration_no' => 'Nie', + 'registration_missing' => 'brak', + 'registration_invoice_data' => 'Dane do wystawienia faktury', + 'registration_participant_data' => 'Dane uczestnika', + 'registration_institution_data' => 'Dane instytucji', + 'registration_presentation_data' => 'Dane wystąpienia', + 'registration_submit_talk' => 'Zgłaszam referat', + 'registration_submit_poster' => 'Zgłaszam poster', + 'registration_topic' => 'Temat', + 'registration_abstract' => 'Streszczenie', + 'registration_author' => 'Autor', + 'registration_amount_information' => 'Informacja o kwocie do zapłaty', + 'registration_selected_options' => 'Wybrane opcje', + 'registration_fee_discount_2026' => 'Opłata obniżona (płatność do 03.10.2026)', + 'registration_fee_normal_2026' => 'Opłata zwykła (płatność po 03.10.2026)', + 'registration_net_price' => 'Cena netto', + 'registration_net_price_no_vat' => 'Cena netto (bez VAT)', + 'registration_gross_price' => 'Cena brutto', + 'registration_gross_price_vat' => 'Cena brutto (z VAT)', + 'registration_total_to_pay' => 'Razem do zapłaty', + 'registration_full_conference_label' => 'Cała konferencja', + 'registration_participation_full_cta' => 'Biorę udział w całej konferencji', + 'registration_participation_one_day_lodging_cta' => 'Biorę udział w jednym dniu konferencji (z noclegiem)', + 'registration_participation_one_day_no_lodging_cta' => 'Biorę udział w jednym dniu konferencji (bez noclegu)', + 'registration_participation_full' => 'cała konferencja', + 'registration_participation_one_day_lodging' => 'jeden dzień konferencji (z noclegiem)', + 'registration_participation_one_day_no_lodging' => 'jeden dzień konferencji (bez noclegu)', + 'registration_select_day' => 'Proszę zaznaczyć dzień', + 'registration_selected_presence_days' => 'Wskazane dni obecności', + 'registration_full_conference_presence' => 'Obecność podczas całej konferencji.', + 'registration_single_room_surcharge' => 'Dopłata do pokoju 1-osobowego', + 'registration_accompanying_driver_fee' => 'Opłata za pobyt osoby towarzyszącej lub kierowcy w pokoju dwuosobowym', + 'registration_accompanying_driver' => 'Osoba towarzysząca/kierowca', + 'registration_participation_preferences' => 'Udział i preferencje', + 'registration_diet_preferences' => 'Preferencje żywieniowe', + 'registration_diet_standard' => 'dieta standardowa', + 'registration_diet_special' => 'dieta specjalna', + 'registration_diet_standard_short' => 'standardowa', + 'registration_diet_special_short' => 'specjalna', + 'registration_diet_which' => 'Jaka?', + 'registration_conference_price' => 'Cena za konferencję', + 'registration_consents_expressed' => 'Wyrażono zgody', + 'registration_consent_data' => 'Zgoda na przetwarzanie danych', + 'registration_consent_image' => 'Zgoda na przetwarzanie wizerunku', + 'registration_selected_participation_option' => 'Wybrana opcja udziału', + 'registration_participation_type' => 'Typ udziału', + 'registration_days' => 'Dni', + 'registration_diet' => 'Dieta', + 'registration_payment_status' => 'Status opłaty', + 'registration_paid' => 'opłacone', + 'registration_unpaid' => 'nie opłacone', + 'registration_edit' => 'edytuj', + 'registration_delete' => 'usuń', + 'registration_cancel' => 'Anuluj', + 'registration_save' => 'Zapisz', +); + +$isCli = PHP_SAPI === 'cli'; +$approved = $isCli + ? in_array('--run', $argv, true) + : (isset($_GET['run']) && $_GET['run'] === '20260424'); + +header_safe('Content-Type: text/plain; charset=utf-8'); + +if (!$approved) { + echo "DRY RUN ONLY\n"; + echo "To apply dictionary seed, run with ?run=20260424 in browser or --run in CLI.\n"; + echo "No database changes were made.\n"; + exit; +} + +$configPath = __DIR__ . '/../core/config/Strona/db.config.ini'; +if (!is_file($configPath)) { + fail("Config file not found: " . $configPath); +} + +$config = parse_ini_file($configPath, true); +if (!isset($config['db'])) { + fail("Missing [db] section in config."); +} + +$dbConfig = $config['db']; +foreach (array('prodHost', 'prodUser', 'prodPass', 'prodDb') as $key) { + if (!array_key_exists($key, $dbConfig)) { + fail("Missing db config key: " . $key); + } +} + +$mysqli = new mysqli( + $dbConfig['prodHost'], + $dbConfig['prodUser'], + $dbConfig['prodPass'], + $dbConfig['prodDb'] +); + +if ($mysqli->connect_errno) { + fail("MySQL connection failed: " . $mysqli->connect_error); +} + +$mysqli->set_charset('utf8'); +$langs = get_dictionary_langs($mysqli); + +echo "Applying dictionary phrase seed...\n"; +echo "Languages: " . implode(', ', $langs) . "\n"; + +$inserted = 0; +$skipped = 0; + +foreach ($phrases as $keyword => $replacementPl) { + foreach ($langs as $lang) { + if (dictionary_phrase_exists($mysqli, $keyword, $lang)) { + $skipped++; + continue; + } + + $replacement = $lang === 'pl' ? $replacementPl : $lang . '_' . $keyword; + insert_dictionary_phrase($mysqli, $keyword, $lang, $replacement); + $inserted++; + } +} + +echo "Dictionary seed complete.\n"; +echo "Inserted: " . $inserted . "\n"; +echo "Skipped: " . $skipped . "\n"; +$mysqli->close(); + +function get_dictionary_langs(mysqli $mysqli) { + $langs = array('pl'); + $result = $mysqli->query("SELECT DISTINCT lang FROM mf_dictionary WHERE lang <> ''"); + if (!$result) { + fail("Could not load dictionary languages: " . $mysqli->error); + } + + while ($row = $result->fetch_assoc()) { + if (!in_array($row['lang'], $langs, true)) { + $langs[] = $row['lang']; + } + } + + return $langs; +} + +function dictionary_phrase_exists(mysqli $mysqli, $keyword, $lang) { + $stmt = $mysqli->prepare("SELECT COUNT(*) AS cnt FROM mf_dictionary WHERE keyword = ? AND lang = ?"); + if (!$stmt) { + fail("Prepare failed: " . $mysqli->error); + } + + $stmt->bind_param('ss', $keyword, $lang); + if (!$stmt->execute()) { + fail("Dictionary check failed: " . $stmt->error); + } + + $result = $stmt->get_result(); + $row = $result->fetch_assoc(); + $stmt->close(); + + return isset($row['cnt']) && (int)$row['cnt'] > 0; +} + +function insert_dictionary_phrase(mysqli $mysqli, $keyword, $lang, $replacement) { + $stmt = $mysqli->prepare("INSERT INTO mf_dictionary (keyword, lang, replacement) VALUES (?, ?, ?)"); + if (!$stmt) { + fail("Prepare failed: " . $mysqli->error); + } + + $stmt->bind_param('sss', $keyword, $lang, $replacement); + if (!$stmt->execute()) { + fail("Insert failed for " . $keyword . " / " . $lang . ": " . $stmt->error); + } + + $stmt->close(); +} + +function fail($message) { + echo "ERROR: " . $message . "\n"; + exit(1); +} + +function header_safe($header) { + if (!headers_sent() && PHP_SAPI !== 'cli') { + header($header); + } +} diff --git a/_rejestracja/template/partial/Index/Index.tpl b/_rejestracja/template/partial/Index/Index.tpl index 25c06a0..067ca75 100644 --- a/_rejestracja/template/partial/Index/Index.tpl +++ b/_rejestracja/template/partial/Index/Index.tpl @@ -52,7 +52,7 @@
-
Dane do wystawienia faktury:
+
{translate word='registration_invoice_data'}:
{translate word='Instytucja'}:
@@ -76,14 +76,14 @@
-
Zgłaszam referat
+
{translate word='registration_submit_talk'}
-
-
Zgłaszam poster
+
{translate word='registration_submit_poster'}
-