129 Commits
Author SHA1 Message Date
frommeandClaude Opus 5.5 cdf04823b0 fix: no warnings when a hotel has no 4-person price in the event price table
The hotels of an event price table are sorted by their 4-person room price
(rooms are keyed by pax). Hotels without one raised 'Undefined array key 4' /
'array offset on null' on every request; they now compare as '' like PHP 7.4
read the missing offset, so the order is unchanged.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-21 21:20:09 +02:00
frommeandClaude Opus 5.5 bb1901fed6 fix: build theme assets before composer install
Composer publishes an extension's Resources/Public as public/_assets/<hash>
only if the directory exists when it runs. The theme's is created by the
asset build, so it has to run first; otherwise the release has no
_assets link for ep_theme and the theme CSS/JS answer 404. The build now
checks the link.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-21 19:18:47 +02:00
frommeandClaude Opus 5.5 4a9777c56a fix: deploy from the host, build inside DDEV
dep runs on the host with its SSH keys; the build (composer install,
npm ci, npm run build) runs through ddev exec, so Composer and Node are
the project's versions. Inside DDEV the commands run directly.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-21 19:10:03 +02:00
frommeandClaude Opus 5.5 64aa43c5af fix: define the TYPO3 deploy tasks in deploy.php
The recipe's task names differ between Deployer versions; with a
globally installed dep the deploy failed with 'Task
typo3:extension:setup not found'.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-21 18:55:30 +02:00
frommeandClaude Opus 5.5 178a5e6c14 feat: first deploy sets up the shared paths and the secrets template
typo3:secrets:init uploads secrets.example.php into shared/ when no
secrets.php exists (never overwrites one); typo3:secrets:check stops
the deploy before extension:setup while the database connection is
still missing. So the first "dep deploy prod" creates the structure and
stops before anything goes live.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-21 18:52:41 +02:00
frommeandClaude Opus 5.5 f6307d7552 fix: hybrid deploy without OPcache tool, tolerant of missing secrets
- No cachetool: its web adapter needs PHP below www.ep-reisen.de/typo3temp,
  which is the static docroot in the hybrid setup (blocked, and not the
  release's typo3temp). Not needed: the exporter's front controller stubs
  resolve the "current" symlink with readlink() on every request.
- additional.php only merges secrets.php when it returns an array:
  Deployer creates an empty shared file on the first deploy.
- public/.htaccess sets TYPO3_CONTEXT=Production/Staging for
  staging.ep-reisen.de, the smoke-test vhost.
- dep host:check: read-only checks of the host before the first deploy.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-21 18:08:17 +02:00
frommeandClaude Opus 5.5 67c32802dc feat: travel info on TYPO3 13
/reiseinformationen/{path segment} and /reiseinformationen/{travel code}
(travel info records combined with live travel data and pickup planning
from MyE&P). All of them answer 404 in production since the static
switch: the export never found these URLs.

Compared with TYPO3 10 (482 travel info pages, 40 travel codes, 20
fallbacks through the base code, unknown code): identical apart from
the content of the 404 page. The page without parameter fails on both,
as intended.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-21 17:34:37 +02:00
frommeandClaude Opus 5.5 fc98dc7d37 fix: optional table options default to what PHP 7.4 read
DateService reads options that callers only sometimes pass (paCode,
filterSettings, date, nonBookableDateUids, showBookingButton). Missing
keys were null on PHP 7.4; in_array() on null returned a falsy value,
so nonBookableDateUids defaults to an empty list. Fixes the event
price table (500).

All 216 distinct AJAX fragment URLs referenced from the TYPO3 10 pages
(date and price tables, event price tables, concept popups, filter
panel) were compared with TYPO3 10 on the same data: identical, apart
from daytripRooms, which fails on both.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-21 17:28:11 +02:00
frommeandClaude Opus 5.5 00034c99ae feat: watchlist on TYPO3 13
Watchlist page (/merkliste/) and its list action, which renders the
hotel/product pairs a visitor stored in sessionStorage. The "remember"
buttons on teasers and detail pages had nowhere to show their list
since the static switch.

Compared with TYPO3 10 (page, empty and invalid input, unknown and
1 to 25 real pairs): identical.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-21 17:28:10 +02:00
frommeandClaude Opus 5.5 214b4b6b86 chore: Deployer configuration for the production host
Built locally from the committed state (git archive, composer install
--no-dev, theme build) and synced with rsync, so the host needs neither
Composer nor Node. Shared: secrets.php, logs, locks, typo3temp/assets
and the MyE&P import baseline. fileadmin links to the production
fileadmin of the TYPO3 10 release, which the CDN origin serves.
extension:setup before the switch, OPcache and TYPO3 caches after it.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-21 16:23:41 +02:00
frommeandClaude Opus 5.5 96a9c7217d chore: production-safe settings, development values only in DDEV
settings.php now holds production values (no debug, no devIPmask,
displayErrors off, warnings logged instead of thrown, deprecation log
off, sendmail, trustedHostsPattern for the production domains,
FE.compressionLevel 0 as the CDN compresses). The development values
moved into the DDEV block of additional.php. secrets.example.php gets
the production database connection.

Composer platform: PHP 8.5.12 (the version Hetzner rolls out).
Deployer 8 as dev dependency for the deployment.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-21 16:22:17 +02:00
frommeandClaude Opus 5.5 18d84d65b0 fix: import no longer writes fileadmin/products_import.info
The marker was display-only for the TYPO3 10 backend module, which is
not ported. Locally fileadmin is hardlinked from the TYPO3 10 project,
so writing it also changed that project's copy.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-21 15:47:51 +02:00
frommeandClaude Opus 5.5 72465053cd feat: product search on TYPO3 13
Search page (searchresult plugin), AJAX results and filter panel, the
mobile filter overlay, search links ("Alle anzeigen", menu icon) and
the /reiseauswahl/{name} landing redirects are back. The search bar in
the page header stays out (SearchbarController not ported); on detail
pages the menu icon links to the search page instead of toggling it.

- Extbase requests are immutable: withArgument() instead of
  setArgument()
- StaticSearchParamsMiddleware runs after site resolution and before
  page resolution (the old position is a cycle in v13); FilterService
  copes with the missing TypoScript there, as TYPO3 10 did
- Search and filter forms are sent URL-encoded instead of multipart, so
  production can keep rejecting multipart requests
- ski-wochenenden: websiteTitle from the old sys_template sitetitle

Compared with TYPO3 10 on the same data (249 cases: search pages with
all 41 preset filters, landing redirects, AJAX results and filter
panel, GET and POST): 186 identical, 63 with the same results in a
different order (PHP 8 sorts stably, ties came out in arbitrary order
on PHP 7.4). Processed image names differ by their configuration hash.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-21 15:47:15 +02:00
frommeandClaude Opus 5.5 18757781bb fix: content feed matches TYPO3 10 for news and sites
- News records: EXT:news is not installed, so the default restrictions
  lack its TCA; deleted, hidden, starttime and endtime are applied by
  hand (TYPO3 13 listed 37 deleted or hidden news in the manifest)
- Site config ski-wochenenden is back: the content feed lists it
  (contentFeedSites); DDEV host skiwe-ep13.ddev.site

Compared with the TYPO3 10 project on the same database (912 cases):
240 identical, 665 differ only because TYPO3 13 leaves out hidden
file references in image lists, 7 only in the order of MM relations
with equal sorting values.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-21 15:29:32 +02:00
frommeandClaude Opus 5.5 a912e0c614 fix: local MyE&P runs as myep.ddev.site
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-21 15:22:03 +02:00
frommeandClaude Opus 5.5 bc2a914b67 feat: ep:import-dates command on TYPO3 13
- Registered with #[AsCommand]; Configuration/Commands.php is no
  longer read
- Storage page of the imported records from the extension
  configuration (importStoragePid, 11 as in all site templates):
  frontend TypoScript is not available on the CLI in TYPO3 13
- The reseller and travel info page cache flush is gone with those
  plugins; the import still clears the page cache

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-21 15:19:13 +02:00
frommeandClaude Opus 5.5 5227da2381 fix: content feed manifest language codes on TYPO3 13
SiteLanguage::getTwoLetterIsoCode() is gone; the locale provides the
language code.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-21 15:17:57 +02:00
frommeandClaude Opus 5.5 c1b4979583 feat: price calendar and price table for group houses
Ports AjaxCalendarController::priceCalendarAction and priceTableAction
(MyE&P price config and price table), used on the /gruppe/gruppenhaus-*
pages and example trips. Page cache tags and "do not cache" on API
errors go through the frontend.cache.collector and
frontend.cache.instruction request attributes instead of TSFE.

Left out: priceConfig (no caller) and range (daytrip calendar via
bpn-connect, out of scope), so bpn-connect needs no credentials.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-21 15:11:12 +02:00
frommeandClaude Opus 5.5 294d270bc1 chore: load secrets from config/system/secrets.php
additional.php is maintained in Git now (taken over from DDEV's
generated file): DDEV settings apply inside DDEV only, and
secrets.php (gitignored, template secrets.example.php) is merged in
everywhere, ignoring empty values. The web container reaches the local
MyE&P project as myep-next.ddev.site, as in EP/website.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-21 15:09:50 +02:00
frommeandClaude Opus 5.5 e70c5f48d5 fix: date tables and group booking links on TYPO3 13
- Uri\ProductViewHelper builds links with the Extbase UriBuilder (no
  controller context in v13), also from content elements
- Null-safe reads of missing row fields and plugin settings, with the
  values PHP 7.4 produced
- /gruppe/ without a product redirects to the search page again
  instead of failing on findByIdentifier(null)

Checked against the TYPO3 10 project: 355 of 359 /gruppe/{product}
pages identical (the rest differ by newer content), all product pages
render, 377 of 396 date tables load (the 19 others fail on TYPO3 10
too: products without a hotel).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-21 15:03:10 +02:00
frommeandClaude Opus 5.5 34f2d55f2c fix: render product detail pages on TYPO3 13
- ObjectManager replaced by GeneralUtility::makeInstance(), the
  services fetched that way are public
- QueryBuilder::add('orderBy') and the remaining execute() calls,
  detailAction returns a response
- PHP 8 warnings for missing array keys (same values as on PHP 7.4)
- Webcam images are external URLs: plain img tag, f:image only takes
  FAL files
- typo3_encore 7 needs the PKG:ssch/typo3-encore: prefix and
  external = 1 so TYPO3's path check does not drop the entry
- CDN image rewriting as a middleware instead of EXT:replacer, which
  is not PHP 8.5 clean; same pattern, only for page responses
- vhs 8 for the ViewHelpers the templates use
- OpenGraph meta tag manager skips the backend
- myEpUrl with trailing slash as in production

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-21 14:34:10 +02:00
frommeandClaude Opus 5.5 4eb1de2e29 fix: restore commented example in DDEV config
The additional_hostnames edit also replaced a commented example and left
uncommented list items behind, which made the YAML unreadable.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-21 14:31:36 +02:00
frommeandClaude Opus 5.5 a598339f67 feat: boot TYPO3 13 with site configs and the theme build
- Site configs for the seven live sites from EP/website, Development
  base variants on *-ep13.ddev.site (DDEV additional_hostnames)
- Webpack Encore build moved to the root, output in
  packages/ep_theme/Resources/Public, public path /_assets/<hash>
- Search UI removed from the kept layouts and partials, as the static
  export already does
- Daytrip room selection and the contingent chain removed (contingent
  import is not ported; no daytrip product has current contingents)
- f:uri.action is final in v13: Uri\AjaxViewHelper invokes it
- Remaining QueryBuilder::execute() and array logicalAnd() calls,
  addRootLineFields, TSFE getData, legacy typo3conf/ext template path
- Rector skips the plugin-to-CType rules; plugins stay list_type

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-21 14:25:01 +02:00
frommeandClaude Opus 5.5 41b9302d9b refactor: apply TYPO3 13 Rector and Fractor migrations
Automated migrations from rector.php and fractor.php (TCA, Extbase
controllers and annotations, ViewHelpers, QueryBuilder, FlexForms,
TypoScript conditions).

Plugins stay list_type plugins: Rector switched them to content
element types, which needs a tt_content migration. That is deferred to
the TYPO3 14 step, where list_type is removed.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-21 14:14:38 +02:00
frommeandClaude Opus 5.5 1b958a6084 chore: set composer platform to production PHP 8.5.11
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-21 14:13:45 +02:00
frommeandClaude Opus 5.5 b890a55115 refactor: remove code outside the first-goal scope
Keeps what the product detail pages, the AJAX date/price tables, the
API endpoints (/api/hotel, /api/product, /api/content/*), the chatbot
content-only page type and the MyE&P import need, determined by a class
and template reference closure from those entry points.

Removed: search, watchlist, calendar/contingent AJAX, snow report and
contingent imports, groups swiss, iCal, reseller export, team/EpTeam,
newsletter, CSV feeds, BpnConnect client, backend modules and page
module previews, Tcemain hooks, scheduler tasks, staging and static
search middlewares, forms and their finishers, gridelements and news
templates, and the plugins and content elements not used on product
pages.

The SFTP and local XML import sources are gone; the import reads
MyE&P only (ApiImportSource as ProductImportSource) and runs as
ep:import-dates.

ext_tables.sql stays complete so no table or column is dropped while
the TYPO3 10 project shares the data.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-21 14:08:06 +02:00
frommeandClaude Opus 5.5 a46918de9d chore: copy ep_products and ep_theme from EP/website@9593cc8
Copied unchanged from public/typo3conf/ext/ of EP/website at
9593cc8631354f8a363d6609de8b7433f669a9a0 (Git-tracked files only).
History stays in the old repository. Only composer.json files are
added so the extensions install as path packages.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-21 14:01:20 +02:00
frommeandClaude Opus 5.5 59afaecea1 chore: add container, encore, redirects and upgrade tooling
Adds b13/container and ssch/typo3-encore as the base for the theme,
typo3/cms-redirects for the existing sys_redirect records and
typo3/cms-lowlevel. Rector and Fractor are configured for the
TYPO3 10 to 13 migration of the packages.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-21 14:01:13 +02:00
Björn Fromme ae1ae3cb38 chore: initial commit of fresh project 2026-10-21 13:24:40 +02:00