2026-05-21 11:44:21 -05:00
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog ](https://keepachangelog.com/en/1.1.0/ ),
and this project adheres to [Semantic Versioning ](https://semver.org/spec/v2.0.0.html ).
2026-06-27 14:37:15 -05:00
## [1.2.0] - Unreleased
### Added
- Multi-category support with parent/child hierarchy (#1 )
- Categories admin CRUD — list, edit, color picker, custom marker icon
- Location-category junction table (many-to-many)
- Categories tab on location edit form (multi-select)
- Category filtering on site frontend (`catid` parameter)
- Custom map markers per category — SVG/PNG icon support (#2 )
- Map module JOINs category data for marker icons and colors
- `access.xml` with full Joomla ACL permissions (#30 )
- SQL update schema with `sql/updates/mysql/` versioned files (#31 )
- REST API via Web Services plugin (`plg_webservices_mokosuitestorelocator` ) (#29 )
- API controller + JSON:API view for locations CRUD at `/api/v1/mokosuitestorelocator/locations`
- `LocationBridgeHelper` — static helper for cross-extension integration (#48 )
- `LocationSavedEvent` — fires `onStoreLocatorLocationSaved` for cache invalidation
- Plugin added to package manifest
2026-06-28 11:22:10 -05:00
- Leaflet map on location detail page with marker and popup (#57 )
- Leaflet.markercluster for automatic marker grouping at low zoom levels (#61 )
- Clustering toggle parameter in map module settings (enabled by default)
- Junction table orphan cleanup on location/category delete (#60 )
2026-06-28 13:48:31 -05:00
- License key warning on install/update when no download key is configured
- Download key (dlid) preserved across package upgrades
2026-06-28 15:06:57 -05:00
- Pretty display names for all extensions in Joomla admin (e.g. "MokoSuite Store Locator" instead of raw element names)
- Plugin `.sys.ini` language file for system-level name translation
2026-06-27 14:37:15 -05:00
### Changed
- Map module dispatcher uses aliased table queries with category JOIN
- ORDER BY clauses in admin and site models now validated against filter_fields allowlist
2026-06-28 11:22:10 -05:00
- Category filter uses EXISTS subquery instead of JOIN to avoid ONLY_FULL_GROUP_BY errors (#59 )
- Inline `<script>` blocks replaced with `$wa->addInlineScript()` for CSP nonce support (#34 )
### Removed
- Dead `catid` column from locations table — junction table is the source of truth (#58 )
- `idx_catid` index dropped from locations table
2026-06-27 14:37:15 -05:00
### Security
- CSV import: MIME type validation, 2 MB file size limit, delimiter allowlist (#34 )
- CSV import: formula injection prevention (strips leading `=+\-@\t\r` characters)
- ORDER BY injection prevention — replaced `$db->escape()` with allowlist validation
- Map module: `$mapHeight` CSS value validated with regex pattern
2026-06-28 11:22:10 -05:00
- CSP compatibility: all inline scripts use WebAssetManager for automatic nonce injection (#34 )
2026-06-28 13:48:31 -05:00
- XSS fix: detail map popup uses DOM textContent instead of raw string in bindPopup()
### Fixed
- SQL migration compatibility: removed `DROP COLUMN IF EXISTS` (MySQL 8.0.13+ only) in favor of plain `DROP COLUMN`
2026-07-06 11:14:07 -05:00
- Honest installer success: package postflight now verifies every bundled child extension (component, modules, plugin) actually landed in `#__extensions` before showing the license/next-steps message; if any is missing it shows an error and suppresses the success message instead of reporting a false success. Fails open so a transient DB/IO glitch never fakes a failure.
2026-06-27 14:37:15 -05:00
## [1.1.0] - 2026-06-23
2026-06-23 11:50:02 -05:00
### Added
- Haversine proximity search — filter locations by distance from user's coordinates
- Hidden `radius_unit` field in search module to pass miles/km preference to component
- Distance-sorted results when proximity search is active
- "Get Directions" link on location detail page (Google Maps, no API key needed)
- "Get Directions" link in Leaflet map popup markers
- Auto-geocoding on admin save — coordinates populated from address via Nominatim/OSM API
- CSV import: upload CSV file to bulk-create locations
- CSV import: auto-detect column headers (title/name/store, address/street, city, etc.)
- CSV import: per-row validation via LocationTable::bind()->check()->store()
- CSV import view accessible from admin toolbar and submenu
2026-06-27 14:37:15 -05:00
- FocalPoint (Shack Locations) migration import
2026-06-23 11:50:02 -05:00
- Language strings for directions, geocoding feedback, and import UI
2026-06-23 12:42:06 -05:00
## [01.00.00] - 2026-06-23
2026-05-21 11:44:21 -05:00
2026-06-23 08:40:02 -05:00
### Added
- Admin `LocationController` (FormController) for single-record save/cancel/apply
- Admin `LocationsController` (AdminController) for bulk publish/unpublish/delete
- Admin location edit view and tabbed template (Details, Address, Contact)
- Admin locations list renders data rows with edit links and published toggle
- `LocationTable::check()` validation: required title, auto-alias, lat/lng range, timestamps
- `LocationsModel::populateState()` for filter persistence
- Search filter across title, city, state, address
- Published state filter and sort ordering support
- Filter form XML (`filter_locations.xml` ) with search tools bar
- Language strings for filters, sort options, and save messages
2026-06-23 08:49:07 -05:00
- Site frontend `DisplayController` routing to list and detail views
- Site `LocationsModel` — published locations with search, city, and state filters
- Site `LocationModel` — single location by ID (published only)
- Site locations list view with Schema.org `LocalBusiness` markup and pagination
- Site location detail view with address, contact, hours, and map placeholder
- SEF URL router (`Service\Router` ) with menu/standard/nomenu rules
- Menu item types: "All Locations" list and "Location Detail" with location picker
- Site language strings for frontend views and menu items
- Router registered in service provider and component extension class
2026-06-23 10:45:50 -05:00
- Map module dispatcher loads published locations with coordinates from DB
- Leaflet.js/OpenStreetMap integration with markers, popups, and auto-fit bounds
- Leaflet CSS/JS loaded via Joomla Web Asset Manager (`registerAndUseStyle` /`registerAndUseScript` )
- Search module dispatcher loads distinct cities/states and builds radius options
- City dropdown filter on search form (populated from DB, toggled by module param)
- Radius dropdown filter with configurable distance values and unit (miles/km)
- Geolocation "Use My Location" button with browser geolocation API
- Hidden lat/lng fields passed to component for proximity search
- Language strings for search module (city, radius, geolocation states)
2026-06-23 08:40:02 -05:00
2026-05-24 04:09:53 +00:00
### Removed
2026-06-23 08:40:02 -05:00
- Makefile (no longer used)
- deploy-manual.yml workflow
2026-05-24 04:09:53 +00:00
2026-06-23 08:40:02 -05:00
### Previous (scaffold)
2026-05-21 11:44:21 -05:00
- Initial package scaffold with component, map module, and search module
- Database schema for locations table with coordinates
2026-06-23 08:40:02 -05:00
- Admin MVC skeleton for location CRUD
- Map module with Leaflet/Google Maps provider support (stub)
- Search module with city and radius filter options (stub)