Title: A1 Tools
Author: a1tools
Published: <strong>3 febrièr 2026</strong>
Last modified: 13 mai 2026

---

Search plugins

![](https://ps.w.org/a1-tools/assets/banner-772x250.png?rev=3453106)

![](https://ps.w.org/a1-tools/assets/icon-256x256.png?rev=3453106)

# A1 Tools

 Per [a1tools](https://profiles.wordpress.org/a1tools/)

[Download](https://downloads.wordpress.org/plugin/a1-tools.2.5.10.zip)

 * [Details](https://oci.wordpress.org/plugins/a1-tools/#description)
 * [Reviews](https://oci.wordpress.org/plugins/a1-tools/#reviews)
 *  [Installation](https://oci.wordpress.org/plugins/a1-tools/#installation)
 * [Development](https://oci.wordpress.org/plugins/a1-tools/#developers)

 [Support](https://wordpress.org/support/plugin/a1-tools/)

## Descripcion

A1 Tools connects your WordPress site to the A1 Tools platform, enabling centralized
management of business information that can be displayed anywhere on your site using
simple shortcodes.

**Perfect for businesses with multiple websites** – update your phone number, address,
or social media links once in the A1 Tools dashboard, and all your connected sites
update automatically.

#### Features

 * **Centralized Management** – Manage all your site variables from one dashboard
 * **Simple Shortcodes** – Display any variable with `[a1tools_var key="phone_primary"]`
 * **Address Formatting** – Multiple address display formats available
 * **Operating Hours** – Display business hours as tables or lists
 * **Social Media Links** – Output all social icons with one shortcode or widget
 * **Social Icons Widget** – Customizable widget with style, shape, size, and hover
   effects
 * **Elementor Support** – Dynamic tags for Elementor page builder
 * **Performance Optimized** – Configurable caching (default 5 minutes)
 * **Developer Friendly** – PHP functions available for theme developers

#### Available Variables

 * Business name, city name, state/location name, tagline
 * Google Maps URL for location
 * Primary and secondary phone numbers
 * Primary and secondary email addresses
 * Full address (line 1, line 2, city, state, ZIP, country)
 * Social media URLs (Facebook, Instagram, YouTube, Twitter, LinkedIn, TikTok, Yelp,
   Google Business)
 * Operating hours for each day of the week

#### Shortcode Examples

    ```
    [a1tools_var key="phone_primary"] - Display primary phone number

    [a1tools_var key="facebook_url" link="true"] - Display Facebook URL as clickable link

    [a1tools_address format="full"] - Display complete formatted address (multi-line)

    [a1tools_full_address] - Display full address in a single line (e.g., "123 Main St, Suite 101, Miami, FL 30001")

    [a1tools_hours format="table"] - Display operating hours as a table

    [a1tools_social_links] - Display all configured social media icons

    [a1tools_social_links style="default" shape="circle" size="50"] - Styled social icons

    [a1tools_city_name] - Display the city name for geo-targeting

    [a1tools_state] - Display the state name for geo-targeting

    [a1tools_google_map type="link"] - Display Google Maps link

    [a1tools_google_map type="embed" width="100%" height="400"] - Embed Google Maps iframe
    ```

#### Requirements

 * Your WordPress site must be registered in the A1 Tools platform
 * An active A1 Tools account with site variables configured
 * Font Awesome 6 for social icons (most themes include this; if not, use a Font
   Awesome plugin)

### External Services

This plugin relies on a third-party service to retrieve site variables (business
information, contact details, social media URLs, etc.) that you configure in the
A1 Tools dashboard.

#### A1 Tools API

**What it is:** A1 Tools is a business management platform operated by A1 Chimney
Service that allows businesses to centrally manage their contact information, addresses,
operating hours, and social media links across multiple websites.

**What data is sent:** When this plugin is activated and the site loads (or when
a shortcode is used), the plugin sends your WordPress site URL to the A1 Tools API
to retrieve the site variables you have configured for that specific site.

**When data is sent:**
 – When a page containing A1 Tools shortcodes is loaded –
When the plugin’s admin settings page is accessed – When the cache expires and fresh
data is needed (configurable, default 5 minutes)

**What data is received:** The plugin receives only the site variables you have 
configured in your A1 Tools dashboard, such as business name, phone numbers, email
addresses, physical address, operating hours, and social media URLs.

**Service Provider:** A1 Chimney Service
 **API Endpoint:** https://tools.a-1chimney.
com/api/website_variables.php **Terms of Service:** https://a-1chimney.com/terms-
of-service/ **Privacy Policy:** https://a-1chimney.com/privacy-policy/

#### Google Maps Embed API

**What it is:** Google Maps is a web mapping service developed by Google. This plugin
can embed Google Maps iframes to display your business location.

**What data is sent:** When using the `[a1tools_google_map type="embed"]` shortcode,
your visitor’s browser loads an iframe from Google Maps containing your business
address or place ID that you configured in the A1 Tools dashboard.

**When data is sent:**
 – Only when a page containing the `[a1tools_google_map type
="embed"]` shortcode is loaded – The embed is loaded client-side by the visitor’s
browser directly from Google

**What data is received:** Google Maps returns the embedded map showing your business
location. Google may collect visitor data according to their privacy policy.

**Service Provider:** Google LLC
 **Embed URL:** https://www.google.com/maps/embed/
v1/place **Terms of Service:** https://www.google.com/intl/en_us/help/terms_maps/**
Privacy Policy:** https://policies.google.com/privacy

## Installacion

 1. Upload the `a1-tools` folder to the `/wp-content/plugins/` directory
 2. Activate the plugin through the ‘Plugins’ menu in WordPress
 3. Ensure your site is registered in your A1 Tools dashboard under Integrations > 
    WordPress Sites
 4. Configure your site variables in A1 Tools under Marketing Tools > Web Management
    > Site Variables
 5. Use the shortcodes in your pages, posts, or widgets

## FAQ

### How do I get an A1 Tools account?

A1 Tools is a business management platform. Contact A1 Chimney Service for access
information.

### Why are my variables not showing?

 1. Verify your site URL in A1 Tools matches your WordPress site URL exactly (including
    https://)
 2. Check that you have saved variables for this site in A1 Tools
 3. Go to A1 Tools in your admin menu and click « Clear Cache Now » to fetch fresh 
    data

### How often do variables update?

Variables are cached based on your settings (default 5 minutes). You can configure
the cache duration or disable caching entirely in the A1 Tools settings page. To
force an immediate update, use the « Clear Cache Now » button on the settings page.

### Can I use this with Elementor?

Yes! The plugin registers dynamic tags that appear under the « A1 Tools » group 
in Elementor. You can also use the Shortcode widget with any of the available shortcodes.

### Is this plugin free?

The plugin is free and open source. However, it requires an A1 Tools account to 
function, as it retrieves data from the A1 Tools platform.

### What data does this plugin send to external services?

See the « External Services » section above for complete details. In summary, the
plugin sends your site URL to the A1 Tools API to retrieve the site variables you
have configured. No personal user data from your visitors is collected or transmitted.

## Reviews

There are no reviews for this plugin.

## Contributors & Developers

“A1 Tools” is open source software. The following people have contributed to this
plugin.

Contributors

 *   [ a1tools ](https://profiles.wordpress.org/a1tools/)

[Translate “A1 Tools” into your language.](https://translate.wordpress.org/projects/wp-plugins/a1-tools)

### Interested in development?

[Browse the code](https://plugins.trac.wordpress.org/browser/a1-tools/), check out
the [SVN repository](https://plugins.svn.wordpress.org/a1-tools/), or subscribe 
to the [development log](https://plugins.trac.wordpress.org/log/a1-tools/) by [RSS](https://plugins.trac.wordpress.org/log/a1-tools/?limit=100&mode=stop_on_copy&format=rss).

## Changelog

#### 2.5.10

 * Improve: Live Chat — pre-chat greeting (the « Hi! Thanks for reaching out — a
   team member will be with you in just a moment. » message configured per-widget)
   now renders as a dispatcher-style chat bubble instead of an italic system notice
   at the top of the thread. Reads as an instant auto-reply so the visitor gets 
   immediate « someone heard me » feedback before a real dispatcher picks up.
 * Improve: Live Chat — visual divider between system metadata lines (like « Chat
   started by Visitor (5551234567) ») and the actual conversation. A faded hairline
   now draws automatically at the boundary between the last system message and the
   first real message, separating session metadata from the conversation flow without
   adding manual UI clutter.
 * Improve: Live Chat — floating button raised 50px on bottom-corner placements (
   br/bl) from `bottom: 20px` to `bottom: 70px` so it doesn’t collide with sticky
   footers, floating CTAs, or mobile safe-area indicators. Top-corner placements
   unchanged.

#### 2.5.9

 * Fix: A1 City List widget on customer sites only listed pages by authors with «
   city » in their display name (e.g., « Single City », « Location City »), silently
   dropping pages authored by « Single Location » users. Mirrors the same broadening
   that landed server-side in 2.5.8 for the CRM Cities tab: `a1tools_get_wp_city_pages()`
   now matches `display_name LIKE '%city%' OR LIKE '%location%'` (still excluding`%
   seo%`). Sites that use the `Single Location` naming convention (e.g., ct.a-1chimney.
   com) will now surface ~all location pages alongside city pages. The page-type
   detection further down keys off « location » in the name, so the `location_city`
   vs `single_city` classification still works correctly regardless of which keyword
   matched.

#### 2.5.8

 * Fix: Live Chat — « Jose Demasi is helping you » banner persisted even after the
   dispatcher resolved/abandoned the session. The 2.5.7 fix correctly hid the banner
   inside `handleSessionClosed()`, but the same poll payload that signals the close
   ALSO carries the `attended_by_dispatcher` field (the server keeps it populated
   on the row for record-keeping), and the subsequent `updateAttended()` call would
   immediately un-hide the banner that was just hidden. Now `updateAttended()` is
   gated on `session_status === 'open'`; when the session is closed the banner is
   forcibly cleared and stays cleared.
 * Fix: Live Chat — visitor-facing strings now show the dispatcher’s **first name
   only** (« Jose is helping you » / « Jose • 12:42 PM ») instead of the full « 
   Jose Demasi ». The CRM dispatcher view (Flutter app) is unchanged — it keeps 
   the full display name. Applied to the attended-by banner AND every dispatcher
   message bubble’s meta line.
 * Fix: Live Chat — « Start chat » (pre-chat submit) and « Start a new chat » (resolved-
   state restart) rendered as thin yellow strips instead of proper buttons. Caused
   by 2.5.7’s chat-window button reset (specificity 0,1,1) winning over those buttons’
   specific style rules (specificity 0,1,0) and zeroing their padding. Fixed by 
   adding the `.a1tools-web-chat-window` parent prefix to both selectors so they
   reach specificity 0,2,0 and keep their padding + shadow + transitions. Restart
   button is now a primary orange button (was an outlined secondary) to match the
   call-to-action role.

#### 2.5.7

 * Fix: Live Chat — pre-chat form, active thread, and « chat closed » banner all
   rendered stacked on top of each other on themes that override `[hidden]` (most
   do — `div { display: block }` etc. at higher specificity than HTML5’s user-agent
   default). Visitor saw the « Start chat » button alongside an active conversation
   and the « Start a new chat » button at the same time. Fixed with a scoped `.a1tools-
   web-chat-window [hidden] { display: none !important }` rule so theme cascade 
   can’t defeat the state machine.
 * Fix: Live Chat — close / attach / send icons rendered as solid yellow blocks (
   again) on sites where the theme also overrides `svg { fill: <brand-color> }` 
   at higher specificity than our scoped `fill: currentColor`. Same-color-on-same-
   color = invisible icon. Strengthened the chat-window SVG rule with `!important`
   on `fill: currentColor`, `visibility`, and `opacity`.
 * Fix: Live Chat — stale « Jose is helping you » banner stayed visible after the
   dispatcher resolved/abandoned the session. `handleSessionClosed()` now clears
   the attended-by banner + typing-dots + `state.attendedBy` alongside flipping 
   the resolved view on. The banner re-renders fresh if the visitor starts a new
   chat that gets attended.

#### 2.5.6

 * Fix: Live Chat / Web Form — widgets rendered with `data-company-id="0"` on every
   site that hadn’t been manually configured, so the chat button did nothing and
   form submissions rejected. The CRM company id is now **auto-resolved from the
   server** when the WP-Admin option is still at the default 0. The plugin hits `
   tools.a-1chimney.com/api/website_variables.php?action=public&url=<site_url>` (
   which already does the `wordpress_sites  wordpress_groups.company_id` JOIN), 
   reads the returned `company_id`, and persists it back into the option so subsequent
   renders don’t re-fetch. Admin overrides win — manual edits in the settings UI
   are never overwritten. The 41 customer sites running 2.5.5 were back-filled directly
   via wp-cli during this release; new installs from here on configure themselves
   on first widget render.

#### 2.5.5

 * Fix: Live Chat — page reload wiped the existing thread. The visitor saw an empty
   chat (or worse, the pre-chat form re-appeared with a « Start a new chat » button)
   even though the session was still open server-side. Caused by the bootstrap restoring`
   since_message_id` from `localStorage` and then polling `id > since_id`, which
   returned no rows because the watermark already covered every prior message. Resolved
   by forcing `since_message_id=0` + an in-memory `isInitialRestore` flag on the
   page-load fetch so the entire thread reloads — including the visitor’s own bubbles(
   which were skipped during live polling as « already optimistically rendered »
   but ARE legitimately needed after a reload because the optimistic DOM is gone).
 * Fix: Live Chat — empty white bar with a non-functional X above the composer. 
   The attachment-preview wrapper used `display: flex` which beat HTML5’s default`[
   hidden] { display: none }` when site themes overrode the hidden default. Added
   explicit `[hidden] !important` rule.
 * Fix: Live Chat — visitor saw the raw dispatcher username (« Aghaji2025 is helping
   you » / « Aghaji2025 • 1:04 PM ») instead of the dispatcher’s real name. Server
   now resolves usernames to `first_name last_name` via a batched lookup against`
   a1tools_users` in poll / resume / list-sessions / session-messages responses (
   single SQL query per request, no N+1). Visitor JS prefers the new `sender_display_name`/`
   attended_by_dispatcher_display_name` fields and falls back to username transparently.

#### 2.5.4

 * Re-tag of 2.5.3 to force the WordPress.org plugin directory to re-index after
   the 2.5.3 hotfix landed. No functional changes between 2.5.3 and 2.5.4 — the 
   chat-window icon visibility fix and cross-origin CORS fix from 2.5.3 are the 
   substantive changes shipping here. Bumping the version forces customer-site auto-
   updaters to re-pull cleanly.

#### 2.5.3

 * Fix: Live Chat — missing icons in the chat window (close / attach / send buttons
   rendered as solid color blocks with the SVG icons invisible). Caused by site 
   themes overriding the chat window’s button styles (e.g. theme rule `button { 
   background: gold; color: gold; }` made every SVG with `fill: currentColor` disappear
   into the same-coloured background). Resolved by introducing a chat-window-scoped
   CSS reset and bumping selector specificity on the close / attach / send buttons
   so theme styles can’t leak in.
 * Fix: Live Chat / Web Form — cross-origin requests blocked by the server’s CORS
   allowlist on every customer site except `a-1chimney.com` (and its `www.` subdomain).
   The widget POSTs to `tools.a-1chimney.com/api/web_chat.php` / `web_forms.php`
   from `dc.a-1chimney.com`, `ct.a-1chimney.com`, and ~40 other A1 Chimney subdomain
   sites, plus the 14 portfolio sites; none were on the static allowlist, so the
   browser refused to read responses  « Network error — please try again » on Start
   Chat / form submit. Resolved by introducing `handlePublicWidgetCors()` in `api/
   config.php` (echoes any origin with `Access-Control-Allow-Credentials: false`)
   and opting the two widget endpoints into permissive CORS via a new `$publicCors`
   parameter on `initApi()`. Safety preserved by the HMAC form-secret (Web Form)
   and visitor_token + Bearer-token authentication (Web Chat) — neither relies on
   cookies, so allowing any origin doesn’t open a CSRF surface.

#### 2.5.2

 * New: Web Form widget — full visual styling controls. Container background + border(
   style/width/color) + border radius + box-shadow + padding. Label typography (
   family/size/weight/color). Input typography + separate placeholder vs user-typed
   colors + input background + input border + focus border. Required-asterisk color(
   default red `#dc2626`) + weight. Submit button alignment (left / center / right/
   full-width).
 * New: Web Form widget — Standard Fields repeater. Toggle, relabel, reorder the
   ten CRM lead-intake fields (First Name, Last Name, Phone, Email, Address, City,
   State, Zip, Commentary, Preferred Contact). Hidden fields are no longer sent 
   to the server; the server in turn accepts missing fields and defaults them to
   empty string (soft-requires at least one of phone / email / commentary so a contentless
   submission still rejects).
 * New: Web Form widget — Custom Fields repeater. Add arbitrary user-defined fields
   beyond the ten standard ones. Types: text, textarea, email, tel, url, number,
   date, dropdown (select), checkbox, radio. Per-field label / placeholder / help
   text / required-flag / options. Stored as a self-describing JSON array on the
   submission row (new `custom_fields` column on `crm_web_form_submissions`) so 
   each submission carries its own field schema and the CRM detail card renders 
   the exact labels the visitor saw at submit time.
 * New: Web Form widget — SMS Consent section. Toggle-gated; WYSIWYG consent text
   with `{{privacy_url}}`, `{{sms_terms_url}}`, `{{help_phone}}` placeholders auto-
   resolved to site-relative defaults when the URL fields are left blank. Optional
   Help phone field. « Require check to submit » toggle. The verbatim consent text
   the visitor saw plus the checked/unchecked flag are stored as first-class columns(`
   consent_text`, `consent_checked`) for downstream Twilio / SMS pipeline TCPA-compliance
   audits.
 * New: Web Form widget — Optional « I’m not a robot » checkbox gate. Simple in-
   form click-through (no external CAPTCHA service); blocks naive automation alongside
   the existing honeypot + minimum-fill-time guards.
 * New: Web Chat widget — Pre-chat Form section. Configurable label + required-flag
   for the Name and Phone-or-Email fields, plus the Start-chat button label.
 * New: Web Chat widget — Window container styling. Background color, border color/
   width, border radius, box-shadow, plus body typography (matches the Web Form 
   widget’s level of control).

#### 2.5.1

 * Fixed: A1 Web Form and A1 Web Chat widgets read the wrong WordPress option for
   the CRM company ID (`a1tools_form_company_id` instead of `a1tools_form_crm_company_id`—
   the latter being the option the existing admin UI + form pipeline have always
   used). On any site that had configured the legacy contact-form CRM integration,
   both new widgets rendered with `data-company-id="0"`. The chat widget’s JS module
   bailed at the `if (!config.companyId)` check, leaving the floating Live Chat 
   button visible but completely unresponsive — clicks did nothing, no errors in
   the WP admin, just silence. Both widgets now read the same option the rest of
   the plugin uses.
 * Improved: « CRM Integration » section heading and description in the admin Settings
   page now explicitly mention BOTH the contact form AND the Live Chat widget. Same
   Company ID drives both; setting it to 0 disables both. Visual styling for the
   chat widget (button color, padding, placement, dispatcher/visitor bubble colors)
   lives in Elementor’s edit panel, not in WP admin — the admin page only carries
   the global Company ID + form secret.

#### 2.5.0

 * New: A1 Web Form Elementor widget — structured lead intake form (First name, 
   Last name, Phone, Email, Address, City, State (searchable US-state dropdown with«
   Outside the US » fallback), Zip, Tell-us-about-your-project commentary, Preferred
   contact method radio). All fields required. Honeypot + minimum-fill-time anti-
   spam. Submissions land in `crm_web_form_submissions` and surface in the CRM’s
   reworked Web Leads tab.
 * New: A1 Web Chat Elementor widget — live chat with both floating-corner and inline
   placements. Multiple placements on the same page share one conversation via a`
   visitor_token` stored in `localStorage`. Pre-chat captures Name + Phone-or-Email
   before the conversation opens so the CRM has a usable identity even if the visitor
   closes the tab mid-conversation. Image attachments (JPEG/PNG/GIF/WEBP, 5 MB cap),
   typing indicator, read receipts, and an « Attended by X » indicator showing which
   dispatcher is currently working the thread. Chats only close when a CRM dispatcher
   resolves or abandons them — page reload, browser close, or device switch all 
   restore the open session.
 * New: Public REST proxy `/wp-json/a1-tools/v1/submit-web-form` that signs the 
   form payload server-side (HMAC-SHA256) and forwards to `tools.a-1chimney.com/
   api/web_forms.php`. Visitor never sees the shared secret.
 * Performance: Web Form + Web Chat assets are versioned with `A1TOOLS_VERSION` 
   so a plugin upgrade busts the browser cache cleanly. Scripts only mount when 
   a corresponding placement exists in the DOM.

#### 2.4.3

 * Fixed: A1 Franchise Location widget rendered the wrong map for franchises that
   had no street address — Google’s iframe embed was being asked to resolve the 
   franchise _name_ alone (e.g. `q=A1+Chimney+-+Trenton`), and Google’s first match
   was often an unrelated business with the same name in another state (Hallandale
   FL was a frequent culprit). Even franchises that had correct latitude/longitude
   in the database were affected, because the embed builder never actually used 
   the stored coordinates. The widget now prefers `name + full address` when an 
   address exists (rich Google business card), falls back to the stored `latitude,
   longitude` when only coordinates are available (deterministic pin), and renders
   no map at all when neither is available — better than misleading visitors with
   the wrong location.
 * Fixed: Franchise grid alignment — when one card’s title wrapped to two lines (
   e.g. « A1 Chimney – Mount Laurel Township ») and the others were single-line,
   the map iframes shifted to different y-coordinates across the row. Cards are 
   now flex columns with a 2-line `min-height` reserved for the title and the « 
   Get Directions » button pinned to the bottom (`margin-top: auto`), so maps line
   up horizontally regardless of title length.

#### 2.4.2

 * Fixed: City List widget (and every other A1 Tools data widget) could be stuck
   rendering an outdated payload — most visibly, all city pages collapsing into 
   a single « Ungrouped » section when their group assignments had changed in the
   A1 Tools dashboard. Root cause: `a1tools_cache_expiry` is stored in seconds by
   the settings page, but `a1tools_fetch_api_data()` was multiplying it by `MINUTE_IN_SECONDS`
   again, making every cached payload live 60× longer than the admin had configured.
   Worse, picking « No caching (always fresh) » stored `0`, which WordPress’s `set_transient()`
   interprets as « no expiration » — so the transient persisted forever, forever
   serving stale data.
 * Fixed: « No caching (always fresh) » now actually means no caching — the plugin
   no longer writes a transient when caching is disabled, and proactively deletes
   any pre-existing transient on the first request after the upgrade so legacy forever-
   caches are evicted.
 * Migration: On upgrade, all `a1tools_*` transients are flushed automatically via`
   a1tools_clear_cache()` so any payload poisoned by the pre-2.4.2 TTL bug is replaced
   with a fresh fetch on the next page load. No admin action is required.
 * Security: Blog-sync REST routes (`/blog-posts`, `/blog-sync/create`, `/blog-sync/
   update`) now authenticate against a dedicated `a1tools_blog_sync_secret` option,
   falling back to the legacy `a1tools_form_secret` only for backwards compatibility(
   with an error_log notice when the legacy secret is used). Operators should provision
   a fresh per-purpose secret in wp-admin  Settings  A1 Tools and then rotate the
   form secret; one leaked secret no longer grants read+write access to every post
   on every connected site.

#### 2.4.1

 * Fixed: X (Twitter) icon rendering as a blank tile in the Social Icons widget 
   and the Elementor social-icons widget. The icon ships as inline SVG (since X’s
   logo isn’t in Font Awesome 5), but the render path was passing the markup through
   wp_kses_post() which strips / tags. Now uses a dedicated allowed-tags array that
   permits both Font Awesome and inline SVG.

#### 2.4.0

 * Security: Form submissions now sign each request with HMAC-SHA256 (X-Form-Signature
   header) and a timestamp (X-Form-Timestamp) for replay protection
 * Security: Removed redundant form_secret from JSON body — secret is now only sent
   in the X-Form-Secret header to avoid exposure in logs
 * Removed: Unused « Target Board ID » and « Target Group ID » admin fields (these
   were never actually sent to the server; routing is owned by the A1 Tools app’s
   Sunday forms mapping table)
 * Added: « Test Connection » button on the Form Submission Integration settings
   page — verifies the secret, CRM company ID, and CRM franchise ID resolve correctly
   against the A1 Tools server
 * Added: « Last Submission » status panel showing the most recent submission outcome(
   success/failure + reason + timestamp) so admins can spot integration issues without
   enabling WP_DEBUG
 * Improved: Form submission API call now uses fastcgi_finish_request() when available
   so the visitor’s browser receives the thank-you response before the API call 
   fires, while still capturing the actual response for diagnostics

#### 2.3.1

 * Performance: Fixed N+1 query in /blog-posts endpoint by priming post meta and
   term caches once per batch (up to ~200x fewer DB calls on a 50-post page)

#### 2.3.0

 * Added: licence field to site variables
 * Added: [a1tools_licence] shortcode for displaying licence number

#### 2.2.0

 * New: Blog Sync REST endpoints for cross-site post management
 * New: /blog-posts endpoint for listing posts with metadata and Yoast SEO
 * New: /blog-posts/{id} endpoint for full post content with SEO data
 * New: /blog-sync/create endpoint for creating synced posts with categories, tags,
   featured images, and Yoast SEO
 * New: /blog-sync/update/{id} endpoint for updating synced posts
 * New: Image sideloading helper for featured image sync across sites

#### 2.1.6

 * Fixed: SEO location shortcode names in app reference had incorrect _seo_ prefix
 * New: SEO Location Shortcodes section on A1 Tools settings page with sample values
   and copy buttons
 * New: Expandable « View all locations » table on settings page for multi-location
   sites

#### 2.1.3

 * Fixed: All Plugin Check errors and warnings resolved
 * Fixed: Output escaping on social icon HTML
 * Fixed: Added translators comment for Elementor widget
 * Fixed: Replaced rename() with WP_Filesystem::move()
 * Fixed: Added wp_unslash() to all $_POST/$_SERVER inputs
 * Fixed: Prefixed global variables in uninstall.php

#### 2.1.2

 * Fixed: Plugin zip packaging for WordPress compatibility

#### 2.1.1

 * Fixed: Syntax error in media management module

#### 2.1.0

 * Security: Full security and standards audit per WordPress Plugin Directory review
 * Removed: Update URI header (per WordPress.org guidelines)
 * Fixed: Output escaping in city address inline format
 * Fixed: REST API permission callback now uses WP_REST_Request instead of getallheaders()
 * Fixed: All database queries now use $wpdb->prepare()
 * Fixed: Replaced @unlink() with wp_delete_file()
 * Fixed: error_log() calls now wrapped in WP_DEBUG checks
 * Improved: Uninstall handler now cleans up all plugin options and transients
 * Updated: Tested up to WordPress 6.9

#### 2.0.10

 * New: City, Full Address, and State fields for SEO location pages
 * New: [a1tools_location_city], [a1tools_location_address], [a1tools_location_state]
   shortcodes
 * Improved: [a1tools_location_web] link text now uses full address, [a1tools_city_web]
   uses city name, [a1tools_state_web] uses state name

#### 2.0.9

 * New: SEO Locations system — manage phone, URLs, map address, and Street View 
   embed per SEO City page
 * New: 7 shortcodes — [a1tools_location_phone], [a1tools_location_web], [a1tools_city_web],[
   a1tools_state_web], [a1tools_map_address], [a1tools_viewpoint], [a1tools_location_list]
 * New: Data fetchers for SEO City author pages (separate from regular City Pages)

#### 2.0.8

 * Refactor: Split monolithic plugin file into logical modules for maintainability
 * New: Cache invalidation REST endpoint for programmatic cache busting
 * Improved: Plugin architecture — shortcodes, data fetching, admin, forms, REST
   API, Elementor, and Yoast integration now in separate include files

#### 2.0.7

 * New: [a1tools_post_title] shortcode — outputs the current post/page title with
   optional tag, class, before/after text

#### 2.0.6

 * Improved: CRM leads now capture service requested, appointment date/time, and
   state from form submissions
 * Improved: Leads stored with separate service_need, preferred_date, preferred_time
   fields

#### 2.0.5

 * Maintenance: Version bump to sync latest plugin updates

#### 2.0.2

 * New: CRM Lead Integration — form submissions now optionally create CRM leads
 * New: CRM Company ID and CRM Franchise ID settings for targeting leads to specific
   CRM locations

#### 2.0.1

 * New: Replace File button — swap a media file with a new upload while keeping 
   the same attachment ID, URL, and post references
 * Replaces physical file, regenerates all thumbnails, updates MIME type and metadata
   automatically

#### 2.0.0

 * Improved: Unified Save button — renames file (if changed) and saves all meta 
   in one click
 * New: Delete button to permanently remove media files
 * Improved: Full-width input fields for better usability
 * Improved: Update refs checkbox moved to actions row with Save and Delete

#### 1.9.9

 * New: Media Management — Title, Caption, and Description fields matching WordPress
   Media editor
 * Improved: Aligned field labels (File Name, Alt Text, Title, Caption, Description)
   for clean layout
 * Improved: Single « Save Details » button saves all meta fields at once

#### 1.9.8

 * New: SEO score badges (0-4) per media item — filename quality, alt text, file
   size, usage
 * New: Inline alt text editor — edit image alt text directly from the media list
 * New: Smart SEO filters — Needs Rename, Missing Alt Text, Large Files, Unused 
   Media, SEO Optimized
 * New: Random filename detection — automatically flags camera/screenshot/gibberish
   filenames
 * New: Usage tracking — shows how many posts reference each media file
 * New: File size warnings — badges for oversized files (>500KB)
 * New: Bulk rename with pattern — select multiple files, rename with auto-incrementing
   pattern
 * New: Bulk alt text — set alt text for multiple images at once (supports {filename}
   variable)
 * New: Undo rename — revert a rename with one click
 * New: Duplicate file detection — finds identical files uploaded multiple times
 * New: Sort options — sort by date or filename, ascending or descending

#### 1.9.7

 * Improved: Media Management — wider rename input field and MIME type filter dropdown
 * New: Media Management — click any image thumbnail to preview full-size in a lightbox

#### 1.9.4

 * New: Media Management tool — browse and rename media files with SEO-friendly 
   names
 * New: Renames physical files, thumbnails, updates metadata, and optionally updates
   post references
 * New: Photo shape option for Team widget — circle or square (fill card)
 * Fix: Team widget card background is now transparent by default (customizable 
   in Style tab)
 * Fix: Elementor editor now live-updates when changing Team widget content settings
 * Improvement: Columns max increased from 4 to 6

#### 1.9.3

 * Fix: City link and state link shortcodes now correctly receive URL data from 
   API
 * Fix: API public endpoint now returns city_url and state_url fields

#### 1.9.2

 * New: [a1tools_city_link] shortcode — outputs city name as a clickable link
 * New: [a1tools_state_link] shortcode — outputs state name as a clickable link
 * New: City Link URL and State Link URL fields in site Information tab
 * Both shortcodes support text, target, and class attributes
 * Falls back to plain text when no URL is configured

#### 1.9.1

 * New: Team member categories — assign members to categories (e.g., Management,
   Technicians, Office)
 * New: Team members grouped by category with section headings on the website
 * New: Category display order control via Elementor widget or shortcode attribute
 * New: Category Heading style controls in Elementor (typography, color, border 
   color, spacing)
 * New: [a1tools_team category= »Management »] — filter to a single category
 * New: [a1tools_team category_order= »Management, Technicians »] — set category
   display order
 * Fix: Services tab now correctly discovers WordPress service pages

#### 1.9.0

 * New: A1 Services Elementor widget and [a1tools_services] shortcode — display 
   site-specific service cards loaded from WordPress pages
 * New: A1 Reviews Elementor widget and [a1tools_reviews] shortcode — display customer
   reviews with star ratings in grid, carousel, or list layout
 * New: A1 Before/After Elementor widget and [a1tools_before_after] shortcode — 
   comparison slider or grid of before/after project photos
 * New: A1 Team Elementor widget and [a1tools_team] shortcode — display team member
   cards with photo, role, bio, and certifications
 * New: A1 FAQ Elementor widget and [a1tools_faq] shortcode — accordion FAQ with
   Schema.org FAQPage JSON-LD structured data
 * New: Services tab in site view — loads WordPress pages by « Large Service » author
   for per-site service management
 * New: Reviews, Before/After, Team, and FAQ tabs in group settings view for cross-
   site content management
 * Five new API endpoints for full CRUD operations on all new content types
 * All new shortcodes support layout options (grid/list/carousel/slider), column
   controls, featured-only filtering, and custom CSS classes
 * Elementor widgets include full content and style controls with responsive settings

#### 1.8.4

 * New: Accordion/collapsible groups — collapse city lists under clickable group
   headings
 * New: Accordion settings — default state (collapsed/expanded), open behavior (
   multiple/single), arrow indicator
 * New: Search bar — live-filter search box that filters cities as you type, auto-
   expands matching accordion groups
 * New: City count badge — display number of cities per group in the heading
 * New: Elementor style controls for accordion (arrow color, size, animation speed),
   search bar (typography, colors, border, padding), and count badge color
 * Keyboard accessible accordion (Enter/Space to toggle)

#### 1.8.6

 * Fix: Mobile/tablet responsive columns now work correctly in Elementor widget
 * Fix: Inline column styles no longer override Elementor responsive breakpoint 
   settings

#### 1.8.5

 * Fix: Ungrouped cities now show « Ungrouped » heading instead of no heading
 * Fix: Ungrouped section supports accordion expand/collapse and city count badge

#### 1.8.3

 * Fix: City List widget now shows ALL city pages, not just ones with saved data
 * Fix: Exclude « SEO City » author pages from city lists (both widget and app)
 * Fix: Rewrote city page discovery using $wpdb + WP_Query for reliability across
   all WP versions
 * Fix: Connection Status now shows all city pages from WP database (not just API-
   saved ones)
 * New: WordPress-side city page discovery — queries local WP database for complete
   page list

#### 1.8.1

 * New: A1 City List Elementor widget — displays linked city page lists with optional
   group headings
 * New: [a1tools_city_list] shortcode — renders grouped or flat city lists with 
   permalinks
 * New: City page grouping — assign cities to groups (e.g., counties) from the A1
   Tools app
 * Widget supports: single/multi-column layout, group filtering, type filtering,
   state suffix
 * Full Elementor styling: container, group heading, list items (Normal/Hover), 
   column gap
 * Group headings support typography, colors, background, padding, border, and spacing
   controls

#### 1.8.0

 * New: City Pages management — assign unique phone numbers and addresses to individual
   city pages
 * New: [a1tools_city_phone] shortcode — auto-detects current page and outputs city-
   specific phone number
 * New: [a1tools_city_phone link= »yes »] — outputs phone as a clickable tel: link
 * New: [a1tools_city_address] shortcode — outputs city-specific address (supports
   format= »inline » and format= »full »)
 * New: City Pages section in Connection Status showing all configured cities with
   their data
 * City shortcodes fall back to site primary phone and address when no city-specific
   data is assigned

#### 1.7.8

 * Fix: Icons in A1 Contact Info and A1 Business Hours widgets now align to the 
   top of their content
 * Hours widget icon aligns to flex-start instead of center to prevent visual gaps
 * Added more specific CSS selector to prevent theme overrides on icon vertical 
   alignment

#### 1.7.7

 * New: Parent Page selector on Import — assign all imported pages as children of
   a specific page
 * Import now respects the selected parent page for both new inserts and existing
   page updates

#### 1.7.6

 * New: Interactive store locator powered by Google Maps JavaScript API with custom
   markers
 * New: Professional split-panel layout with scrollable store cards (with images)
   and interactive map
 * New: Custom marker icon support (set via Plugin Settings or Elementor widget)
 * New: Google Maps API Key setting in Plugin Settings page
 * New: Store editor now includes Full Address auto-fill, Google Maps URL field,
   and auto lat/lng extraction
 * New: google_maps_url field added to group_stores database table
 * Store cards now show images, phone, email, directions link, and website link
 * Map pans and zooms when clicking store cards; info windows show on marker click
 * Search filters both card list and map markers simultaneously
 * Falls back to iframe embeds gracefully when no Google Maps API key is configured

#### 1.7.5

 * Fix: Google Maps embeds now show place info instead of « Place info couldn’t 
   load »
 * Maps now use business name + address for embed queries instead of raw coordinates
 * Franchise and Store Locator maps both fixed for proper place resolution
 * Maps can now display even without lat/lng as long as address data is available

#### 1.7.4

 * New: Show/Hide Title toggle for franchise widget and shortcode (`show_title` 
   attribute)
 * New: Alignment controls for Address, Phone, and Directions Button sections
 * All text elements in the franchise widget can now be independently aligned (left/
   center/right)

#### 1.7.3

 * Enhanced: A1 Franchise Location widget — full styling controls: border, border
   hover, box shadow, hover shadow, typography groups, button normal/hover tabs,
   spacing, alignment
 * Enhanced: A1 Store Locator widget — full styling controls: border, border hover,
   box shadow, hover shadow, typography groups, link hover colors, card spacing,
   search/filter styling
 * Both widgets now match the styling depth of the Info Box and CTA widgets

#### 1.7.2

 * Fix: Franchise locations not loading on frontend (fixed site_id column resolution
   in API)
 * New: Franchise Locations table in admin Connection Status page
 * New: Store Locator table in admin Connection Status page
 * Franchise and Store shortcode references with copy buttons on settings page

#### 1.7.1

 * Updated: [a1tools_franchise] shortcode now supports multiple franchise locations
   per site
 * New: `columns` attribute (1-3) for grid layout of franchise cards
 * New: `id` attribute to display a specific franchise by ID
 * New: `show_address` attribute to toggle address display
 * New: Dedicated site_franchises API for per-site franchise CRUD
 * Updated: A1 Franchise Location Elementor widget with Columns and Franchise ID
   controls
 * Updated: Franchise data now cached separately with its own transient
 * Franchise locations include full address (line1, line2, city, state, zip, country)

#### 1.7.0

 * New: Store Locator Elementor widget (A1 Store Locator) — displays searchable 
   store locations with map embeds
 * New: Franchise Location Elementor widget (A1 Franchise Location) — displays site-
   specific location card with name, phone, and map
 * New: [a1tools_store_locator] shortcode with search, state filter, and Google 
   Maps embeds
 * New: [a1tools_franchise] shortcode with phone …

## Mèta

 *  Version **2.5.10**
 *  Last updated **3 oras ago**
 *  Active installations **100+**
 *  WordPress version ** 5.0 or higher **
 *  Tested up to **6.9.4**
 *  PHP version ** 7.4 or higher **
 *  Language
 * [English (US)](https://wordpress.org/plugins/a1-tools/)
 * Tags
 * [Business Information](https://oci.wordpress.org/plugins/tags/business-information/)
   [contact info](https://oci.wordpress.org/plugins/tags/contact-info/)[multi-site](https://oci.wordpress.org/plugins/tags/multi-site/)
   [shortcodes](https://oci.wordpress.org/plugins/tags/shortcodes/)
 *  [Advanced View](https://oci.wordpress.org/plugins/a1-tools/advanced/)

## Ratings

No reviews have been submitted yet.

[Your review](https://wordpress.org/support/plugin/a1-tools/reviews/#new-post)

[See all reviews](https://wordpress.org/support/plugin/a1-tools/reviews/)

## Contributors

 *   [ a1tools ](https://profiles.wordpress.org/a1tools/)

## Support

Got something to say? Need help?

 [View support forum](https://wordpress.org/support/plugin/a1-tools/)