Pickup Points Database

The plugin stores all Slovenská Pošta pickup point data in a dedicated local database. This design means:

  • No live API calls during checkout — all pickup point lookups (search, nearby, details) are performed against your local WordPress database. Checkout performance is not affected by Slovenská Pošta’s server availability.
  • Fast search — indexed database queries return results in milliseconds, even with thousands of pickup points.
  • Offline resilience — if Slovenská Pošta’s servers are down, your checkout continues to work with the last imported dataset.

Data Source

Pickup point data is imported from an XML feed provided by Slovenská Pošta:

Default URL:

https://www.posta.sk/public/forms/zoznam_post.xml

This URL can be overridden in wp-config.php using the WCSP_PICKUP_POINTS_XML_URL constant.

The XML contains:

  • Post office and BalikoBOX location identifiers
  • Names and full addresses
  • GPS coordinates (latitude and longitude)
  • Maximum accepted weight per pickup point
  • Opening hours (as structured XML)
  • Notes and special instructions

Services

The plugin recognizes two service codes:

Code Service
BNP Balík na Poštu — post office branches
BBOX BalikoBOX — self-service parcel lockers

A single physical location can offer both services (e.g., a post office that also hosts a BalikoBOX locker). The many-to-many relationship between pickup points and services is stored in a junction table.


Data Freshness

Slovenská Pošta periodically updates its pickup point network — opening new offices, closing others, and changing opening hours. To keep your local data current, the plugin supports both manual updates and automatic scheduled updates.

The last update timestamp is displayed in the Pickup Points DB settings tab.


Related Pages

Updating Pickup Points

Manual Update

To immediately refresh the pickup point data:

  1. Navigate to WP-Admin > Slovenská Pošta > Pickup Points DB.
  2. Click Update Now.
  3. An AJAX request is sent to the server, which fetches and processes the XML feed.
  4. The page displays a success message with the updated counts, or an error message if the update fails.

The manual update process is also available programmatically. The admin AJAX action wcsp_update_pickup_points_db can be triggered with a valid admin nonce.


Automatic Updates

Enable automatic updates to keep pickup point data current without manual work:

  1. Navigate to WP-Admin > Slovenská Pošta > Pickup Points DB.
  2. Check Enable Automatic Updates.
  3. Select an Update Frequency from the dropdown.
  4. Save settings.

The plugin registers a WP-Cron event that fires on the selected schedule.

Available frequencies:

Option Schedule
daily Once per day
twicedaily Twice per day
weekly Once per week
twicemonthly Twice per month
monthly Once per month

Recommendation: Weekly is sufficient for most stores.


The Update Process

When an update runs (manually or automatically), the following steps occur:

  1. Fetch — The plugin downloads the XML file from the configured URL (timeout: 120 seconds).
  2. Validate — The downloaded XML is parsed and <POSTA> entries are counted. If fewer than 100 valid entries are found, the update is aborted to prevent replacing the database with a partial or corrupted feed.
  3. Save locally — The validated XML is written to feed/zoznam_post.xml inside the plugin directory, replacing the previously bundled file.
  4. Import — The existing pickup point data is truncated and replaced with the new dataset. The import is done in batches of 250 records for memory efficiency.
  5. Timestamp — The wcsp_last_sync option is updated with the current time.

Update Safety Guard

The 100-entry threshold is a safeguard against:

  • Incomplete XML feeds (network interruptions mid-download)
  • Empty or malformed feed responses
  • Slovenská Pošta temporarily returning an error page instead of XML

If the safety check fails, the existing database is preserved unchanged and an error is logged (visible in the admin update response).


WP-Cron Dependency

Automatic updates rely on WordPress’s built-in WP-Cron system. WP-Cron is triggered by site traffic — it runs when a page is loaded, not at a fixed clock time.

Implications:

  • On high-traffic sites, cron events fire close to their scheduled time.
  • On low-traffic sites, events may be delayed until the next page load after the scheduled time.

For guaranteed scheduling on low-traffic sites, disable WP-Cron’s standard behavior and use a real server cron job:

  1. Add to wp-config.php:
    define( 'DISABLE_WP_CRON', true );
    
  2. Add a server cron job (e.g., every 5 minutes):
    */5 * * * * curl -s https://yoursite.com/wp-cron.php > /dev/null 2>&1
    

Changing the Feed URL

By default, data is fetched from https://www.posta.sk/public/forms/zoznam_post.xml. To use a different URL, define this constant in wp-config.php:

define( 'WCSP_PICKUP_POINTS_XML_URL', 'https://your-url.com/custom-feed.xml' );

Database Tables

The plugin creates three custom database tables on activation. Table names use the WordPress table prefix (e.g., wp_ by default).


Table: {prefix}wcsp_pickup_points

The main table storing all pickup point records.

Column Type Description
id BIGINT(20) UNSIGNED Auto-increment primary key
ref_id INT(11) UNSIGNED Slovenská Pošta reference ID (unique)
name VARCHAR(255) Display name of the pickup point
note TEXT Optional operational note
address_street VARCHAR(255) Street name
address_number VARCHAR(50) Street / house number
address_city VARCHAR(255) City
address_zip VARCHAR(10) Postal code
address_country CHAR(2) ISO country code, default SK
address_note TEXT Optional address note
lat DECIMAL(10,7) Latitude (GPS)
lng DECIMAL(10,7) Longitude (GPS)
max_weight_submit DECIMAL(5,2) Maximum weight for submission (kg)
max_weight_delivery DECIMAL(5,2) Maximum weight for delivery (kg)
opening_hours_xml TEXT Opening hours stored as raw XML
last_synced_at DATETIME Timestamp of last import

Indexes:

  • ref_id — unique index for fast lookups by Slovenská Pošta ID
  • address_zip — index for postal code searches
  • address_city — index for city searches
  • lat, lng — individual indexes supporting coordinate-based queries

Table: {prefix}wcsp_services

A lookup table for service codes. Typically contains two rows after import.

Column Type Description
id BIGINT(20) UNSIGNED Auto-increment primary key
code VARCHAR(10) Service code (e.g., BNP, BBOX) — unique
name VARCHAR(100) Human-readable service name

Standard rows:

code name
BNP Balík na Poštu
BBOX BalikoBOX

Table: {prefix}wcsp_pickup_point_services

A junction table linking pickup points to the services they offer. A single pickup point can offer both BNP and BBOX.

Column Type Description
id BIGINT(20) UNSIGNED Auto-increment primary key
pickup_point_id BIGINT(20) UNSIGNED Foreign key → wcsp_pickup_points.id
service_id BIGINT(20) UNSIGNED Foreign key → wcsp_services.id

Constraint: The combination of pickup_point_id + service_id is unique — a pickup point cannot be linked to the same service twice.


Table Creation and Updates

Tables are created using WordPress’s dbDelta() function on plugin activation. This function safely applies schema changes without data loss, making it suitable for plugin updates that alter the table structure.

If a table already exists with the correct schema, dbDelta() makes no changes. If columns are missing or types differ, it applies the necessary alterations.


Querying the Tables

The plugin provides a WCSP_Pickup_Points class with methods for all common queries. Direct SQL queries are generally not necessary. Available methods include:

  • get_all_map_markers( $service_code, $exclude_bbox ) — Returns all lat/lng coordinates for map marker initialization.
  • search( $term, $service_code, $exclude_bbox ) — Text search by name, city, or postal code.
  • get_closeby( $lat, $lng, $limit, $service_code, $exclude_bbox ) — Haversine-based proximity search.
  • get_details( $id ) — Full details for a single pickup point including formatted opening hours.
  • can_accept_weight( $id, $weight_kg ) — Boolean weight limit check.

See AJAX Endpoints for how these are exposed to the frontend.