<?xml version="1.0" encoding="utf-8"?>
	<rss version="2.0">
		<channel> 
			<title>Version history CMS Donate Engine</title> 
			<link>https://cde.by/en/news/</link> 
			<description>Here you can see the history of changes in CMS Donate Engine.</description>
			<item>
				<title>v19.2.16</title>
				<description><![CDATA[fix(store): register 'store' service alias for home=store config
RequestHandler::runLegacy resolves home page via $container->has($page).
Legacy store.php handled this; after extraction, needs a service with
id 'store' pointing to StoreCatalogController. Admin can still switch
home to any other page via config.]]></description>
				<files><![CDATA[Total: 2 files (+1, ~1, -0)

www/src/app/
  M constants.php
www/src/app/Features/Store/
  A services.php]]></files>
				<pubDate>Fri, 09 Oct 2026 17:45:49 +0300</pubDate>
			</item>
			<item>
				<title>v19.2.15</title>
				<description><![CDATA[refactor(store): extract store.php into Symfony controllers
- Add StoreCatalogController (page + PJAX), StoreModalController (HTML
  modals), StoreApiController (JSON) with #[Route] attributes
- Remove legacy store.php (2750 lines)
- Enforce ACL via #[Acl] attributes on admin routes; manual checks in
  insert/add (dynamic perm)
- Fix: itemID reads username from POST; editGroupSave validates name
  and guards empty cloneGroup; cloneProducts early-returns; page_update
  uses data->id for cat; url_delete points to /store/del-N;
  Discount::apply lazy-inits items; sql_escape (string) casts
- Add StoreRoutesTest (24 assertions: 21 routes + PJAX + JSON)
- Update Store.php.md contract
- Bump version]]></description>
				<files><![CDATA[Total: 7 files (+1, ~5, -1)

docs/
  M Store.php.md
www/src/app/
  M constants.php
www/src/app/controllers/
  D store.php
www/src/app/Features/Store/Catalog/
  M StoreGroupCommand.php
www/src/app/Features/Store/Http/
  M StoreApiController.php
  M StoreModalController.php
www/tests/Functional/Store/
  A StoreRoutesTest.php]]></files>
				<pubDate>Fri, 09 Oct 2026 17:34:35 +0300</pubDate>
			</item>
			<item>
				<title>v19.2.14</title>
				<description><![CDATA[refactor(store): extract api to StoreApiController]]></description>
				<files><![CDATA[Total: 8 files (+1, ~7, -0)

www/public/style/gente/mods/store/
  M admin_modal_delete.tpl
  M admin_modal_group_edit.tpl
  M modal_footer_price.tpl
www/src/app/
  M constants.php
www/src/app/config/
  M services.php
www/src/app/Features/Store/Admin/View/
  M StoreAdminDeleteService.php
www/src/app/Features/Store/Http/
  A StoreApiController.php
www/src/app/Features/Store/View/
  M StoreResponse.php]]></files>
				<pubDate>Fri, 09 Oct 2026 14:04:08 +0300</pubDate>
			</item>
			<item>
				<title>v19.2.13</title>
				<description><![CDATA[fix(http): fallback to legacy on transient container errors
When the DI container fails to load a newly deployed class before
autoload catches up, dispatch to the legacy router instead of
returning 500. Prevents first-request errors after deploy.]]></description>
				<files><![CDATA[Total: 2 files (+0, ~2, -0)

www/src/app/
  M constants.php
www/src/app/Http/
  M RequestHandler.php]]></files>
				<pubDate>Fri, 09 Oct 2026 13:46:12 +0300</pubDate>
			</item>
			<item>
				<title>v19.2.12</title>
				<description><![CDATA[fix(store): lazy-init Discount so apply() works without explicit data()]]></description>
				<files><![CDATA[Total: 2 files (+0, ~2, -0)

www/src/app/
  M constants.php
www/src/app/lib/
  M Discount.php]]></files>
				<pubDate>Fri, 09 Oct 2026 13:34:12 +0300</pubDate>
			</item>
			<item>
				<title>v19.2.11</title>
				<description><![CDATA[refactor(store): extract modals to StoreModalController]]></description>
				<files><![CDATA[Total: 4 files (+1, ~3, -0)

www/public/style/gente/mods/store/
  M admin_modal_source.tpl
www/src/app/
  M constants.php
www/src/app/Features/Store/Http/
  M StoreCatalogController.php
  A StoreModalController.php]]></files>
				<pubDate>Fri, 09 Oct 2026 13:23:29 +0300</pubDate>
			</item>
			<item>
				<title>v19.2.10</title>
				<description><![CDATA[refactor(store): extract catalog to StoreCatalogController]]></description>
				<files><![CDATA[Total: 3 files (+1, ~2, -0)

www/src/app/
  M constants.php
www/src/app/config/
  M services.php
www/src/app/Features/Store/Http/
  A StoreCatalogController.php]]></files>
				<pubDate>Fri, 09 Oct 2026 13:05:11 +0300</pubDate>
			</item>
			<item>
				<title>v19.2.9</title>
				<description><![CDATA[refactor(template): add renderModal/renderRestContent without exit]]></description>
				<files><![CDATA[Total: 2 files (+0, ~2, -0)

www/src/app/
  M constants.php
www/src/app/lib/
  M Template.php]]></files>
				<pubDate>Fri, 09 Oct 2026 12:37:26 +0300</pubDate>
			</item>
			<item>
				<title>v19.2.8</title>
				<description><![CDATA[refactor(store): simplify]]></description>
				<files><![CDATA[Total: 2 files (+0, ~2, -0)

www/src/app/
  M constants.php
www/src/app/controllers/
  M store.php]]></files>
				<pubDate>Fri, 09 Oct 2026 12:00:12 +0300</pubDate>
			</item>
			<item>
				<title>v19.2.7</title>
				<description><![CDATA[refactor(store): drop Template from services, add StoreResponse
Services now return data (notify-structure) instead of rendered HTML.
StoreResponse::restContent() is the single exit point that renders
notify_message.tpl and delegates to Template::restContent.
- StorePurchaseService: no Template, uses session->get() for cid/id
- StoreAdminDeleteService: no Template, returns notify
- StoreResponse: shared view helper for Store JSON responses
- store.php: 851 lines, HTTP-only]]></description>
				<files><![CDATA[Total: 5 files (+1, ~4, -0)

www/src/app/
  M constants.php
www/src/app/controllers/
  M store.php
www/src/app/Features/Store/Admin/View/
  M StoreAdminDeleteService.php
www/src/app/Features/Store/Purchase/
  M StorePurchaseService.php
www/src/app/Features/Store/View/
  A StoreResponse.php]]></files>
				<pubDate>Fri, 09 Oct 2026 11:26:15 +0300</pubDate>
			</item>
		</channel>
	</rss>