# 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). ## [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 ### 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 ### 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 ## [1.1.0] - 2026-06-23 ### 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 - FocalPoint (Shack Locations) migration import - Language strings for directions, geocoding feedback, and import UI ## [01.00.00] - 2026-06-23 ### 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 - 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 - 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) ### Removed - Makefile (no longer used) - deploy-manual.yml workflow ### Previous (scaffold) - Initial package scaffold with component, map module, and search module - Database schema for locations table with coordinates - Admin MVC skeleton for location CRUD - Map module with Leaflet/Google Maps provider support (stub) - Search module with city and radius filter options (stub)