diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 00ed899..283bc06 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -60,7 +60,7 @@ body: id: versions attributes: label: Versions - placeholder: 'Procore Connect 2.0.3, WordPress 7.0, PHP 8.3' + placeholder: 'Connect for Procore 2.0.3, WordPress 7.0, PHP 8.3' validations: required: true diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml index 95f1bd1..7d883f3 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.yml +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -13,7 +13,7 @@ body: - type: textarea id: proposal attributes: - label: What would you like Procore Connect to do? + label: What would you like Connect for Procore to do? validations: required: true diff --git a/.github/workflows/plugin-check.yml b/.github/workflows/plugin-check.yml index 8b8044f..a174f74 100644 --- a/.github/workflows/plugin-check.yml +++ b/.github/workflows/plugin-check.yml @@ -28,17 +28,17 @@ jobs: # check runs against what users actually install — not the dev tree. - name: Stage the distributable run: | - mkdir -p build/procore-connect + mkdir -p build/connect-for-procore rsync -a --exclude-from=.distignore \ --exclude='.git' --exclude='build' --exclude='vendor' \ - ./ build/procore-connect/ + ./ build/connect-for-procore/ echo "Staged files:" - find build/procore-connect -type f | sort + find build/connect-for-procore -type f | sort - name: Run Plugin Check uses: wordpress/plugin-check-action@v1 with: - build-dir: ./build/procore-connect + build-dir: ./build/connect-for-procore # Target zero findings. Remove nothing from this list without a # documented reason in the pull request. categories: | diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 93280cc..659247a 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -39,7 +39,7 @@ jobs: run: | TAG="${{ github.event.inputs.tag || github.ref_name }}" TAG_VERSION="${TAG#v}" - HEADER_VERSION=$(grep -oP '^\s*\*\s*Version:\s*\K[0-9.]+' procore-connect.php) + HEADER_VERSION=$(grep -oP '^\s*\*\s*Version:\s*\K[0-9.]+' connect-for-procore.php) README_VERSION=$(grep -oP '^Stable tag:\s*\K[0-9.]+' readme.txt) echo "tag=$TAG_VERSION header=$HEADER_VERSION readme=$README_VERSION" @@ -56,24 +56,24 @@ jobs: - name: Stage the distributable run: | - mkdir -p build/procore-connect + mkdir -p build/connect-for-procore rsync -a --exclude-from=.distignore \ --exclude='.git' --exclude='build' --exclude='vendor' \ - ./ build/procore-connect/ + ./ build/connect-for-procore/ - name: Create the ZIP run: | cd build - zip -r "../procore-connect-${{ github.event.inputs.tag || github.ref_name }}.zip" procore-connect + zip -r "../connect-for-procore-${{ github.event.inputs.tag || github.ref_name }}.zip" connect-for-procore cd .. - unzip -l "procore-connect-${{ github.event.inputs.tag || github.ref_name }}.zip" + unzip -l "connect-for-procore-${{ github.event.inputs.tag || github.ref_name }}.zip" - name: Publish the release uses: softprops/action-gh-release@v2 with: tag_name: ${{ github.event.inputs.tag || github.ref_name }} - name: Procore Connect ${{ github.event.inputs.tag || github.ref_name }} + name: Connect for Procore ${{ github.event.inputs.tag || github.ref_name }} body_path: CHANGELOG.md - files: procore-connect-*.zip + files: connect-for-procore-*.zip draft: false generate_release_notes: true diff --git a/.wordpress-org/banner-1544x500.png b/.wordpress-org/banner-1544x500.png index 533e08a..8433afc 100644 Binary files a/.wordpress-org/banner-1544x500.png and b/.wordpress-org/banner-1544x500.png differ diff --git a/.wordpress-org/banner-772x250.png b/.wordpress-org/banner-772x250.png index 69144f1..d91f726 100644 Binary files a/.wordpress-org/banner-772x250.png and b/.wordpress-org/banner-772x250.png differ diff --git a/CHANGELOG.md b/CHANGELOG.md index 0ac10db..4dea2f8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,10 +1,45 @@ # Changelog -All notable changes to Procore Connect are documented here. +All notable changes to Connect for Procore are documented here. The format follows [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). +## [3.0.0] — 2026-08-15 + +### Changed + +- **Renamed to Connect for Procore.** WordPress.org guideline 17 forbids a plugin slug + or display name that *begins* with someone else's trademark, and "Procore" is a + registered trademark of Procore Technologies, Inc. "Procore Connect" would have been + rejected on review. The new name follows the format the guideline itself prescribes + for integrations built by non-employees. + + Worth stating plainly: Plugin Check passes this either way. Its trademark test + compares against a hardcoded list of well-known brands, and "procore" is not on it, + so the automated result was a false negative. The rule is enforced by a human + reviewer. + + What changed: the plugin slug, directory, main file, display name, text domain and + the WordPress.org banner and icon. **You must reactivate the plugin once**, because + WordPress identifies a plugin by its directory and now sees a different one. + + What deliberately did *not* change, so that existing sites keep working: every option + name, the `procore_connect_` hook prefix, the `/wp-json/procore-connect/v1/` REST + namespace, the `yourtheme/procore-connect/` template override directory, the + `procore-connect` CSS classes, the block name and the `wp procore-connect` CLI + command. Your settings, template overrides and custom CSS all survive the rename + untouched. + +### Fixed + +- **The REST proxy sent a malformed HTTP header.** The cache-status header was named + `X-Procore Connect-Cached` — a field name containing a space, which RFC 7230 does not + permit. It is now `X-Connect-For-Procore-Cached`. Introduced by an earlier blanket + rename and found while auditing this one. +- **The User-Agent contained a space inside its product token.** `Procore Connect/2.0.6` + is not a valid product token; it is now `ConnectForProcore/3.0.0`. + ## [2.0.6] — 2026-08-09 ### Fixed @@ -160,12 +195,12 @@ every install was non-functional regardless of configuration. ### ⚠️ Action required when upgrading -- **The plugin is now called Procore Connect**, with the slug `procore-connect`. The +- **The plugin is now called Connect for Procore**, with the slug `procore-connect`. The previous name contained "wp", which wordpress.org disallows in both a plugin name and a slug, making the directory listing impossible. The GitHub repository stays at `ibuilder/ProcoreWP`. - The main plugin file was renamed from `index.php` to `procore-connect.php`. WordPress - treats this as a different plugin, so **Procore Connect must be activated once** after + treats this as a different plugin, so **Connect for Procore must be activated once** after updating. Settings are imported automatically by the upgrade routine. - Because 1.x never obtained a token, any stored token is discarded. **Re-run Procore → Connection → Test connection** after upgrading. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c608c4f..21617c6 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,4 +1,4 @@ -# Contributing to Procore Connect +# Contributing to Connect for Procore Thanks for helping. This document covers how to get set up and what the review will look for. @@ -7,7 +7,7 @@ for. ```bash git clone https://github.com/ibuilder/ProcoreWP.git -cd Procore Connect +cd Connect for Procore composer install ``` diff --git a/README.md b/README.md index cf22f52..f56cf7f 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Procore Connect +# Connect for Procore [![Plugin Check](https://github.com/ibuilder/ProcoreWP/actions/workflows/plugin-check.yml/badge.svg)](https://github.com/ibuilder/ProcoreWP/actions/workflows/plugin-check.yml) [![Coding Standards](https://github.com/ibuilder/ProcoreWP/actions/workflows/phpcs.yml/badge.svg)](https://github.com/ibuilder/ProcoreWP/actions/workflows/phpcs.yml) @@ -15,7 +15,7 @@ Publish live [Procore](https://www.procore.com/) construction project data on a Renders Procore data on the front end of a WordPress site: project directories, project detail panels, team lists, drawings, specifications, RFIs, submittals, punch lists, observations, daily logs, change orders, schedule milestones, company vendors and offices. -Everything is **read-only**. Procore Connect never writes to Procore. +Everything is **read-only**. Connect for Procore never writes to Procore. ``` [procore_project_list company_id="4242" limit="10"] @@ -131,7 +131,7 @@ wp procore-connect reset-token Copy any file from `templates/` into `yourtheme/procore-connect/` and edit it there. Overrides survive plugin updates — unlike 1.x, which told you to edit CSS inside the plugin directory and lost your work on every release. ``` -wp-content/plugins/procore-connect/templates/collection.php +wp-content/plugins/connect-for-procore/templates/collection.php → wp-content/themes/your-theme/procore-connect/collection.php ``` @@ -167,13 +167,13 @@ Contributions are welcome — see [CONTRIBUTING.md](CONTRIBUTING.md). Security r Settings are imported automatically, all shortcode names are unchanged, and the legacy `id` attribute still works. -Two things need your attention. The main plugin file was renamed from `index.php` to `procore-connect.php`, which WordPress sees as a different plugin, so **activate Procore Connect once after updating**. And because 1.x never successfully authenticated, **re-run the connection test** before assuming a blank shortcode is a bug. +Two things need your attention. The main plugin file was renamed from `index.php` to `connect-for-procore.php`, which WordPress sees as a different plugin, so **activate Connect for Procore once after updating**. And because 1.x never successfully authenticated, **re-run the connection test** before assuming a blank shortcode is a bug. Full detail: [the upgrade guide](https://ibuilder.github.io/ProcoreWP/upgrading/). ## Third-party service -Procore Connect contacts Procore to retrieve the data you ask it to display: `login.procore.com` for authentication and `api.procore.com` for data, or the sandbox or regional hosts you configure. It sends your Client ID and Client Secret during authentication, plus the company and project identifiers you configure. No visitor data is sent to Procore. +Connect for Procore contacts Procore to retrieve the data you ask it to display: `login.procore.com` for authentication and `api.procore.com` for data, or the sandbox or regional hosts you configure. It sends your Client ID and Client Secret during authentication, plus the company and project identifiers you configure. No visitor data is sent to Procore. [Procore terms](https://www.procore.com/legal/termsofservice) · [Procore privacy policy](https://www.procore.com/legal/privacy) · [Procore API docs](https://developers.procore.com/documentation/introduction) @@ -181,4 +181,4 @@ Procore Connect contacts Procore to retrieve the data you ask it to display: `lo GPL-2.0-or-later. See [LICENSE](LICENSE). -Procore Connect is not affiliated with, endorsed by, or sponsored by Procore Technologies, Inc. "Procore" is a trademark of Procore Technologies, Inc. +Connect for Procore is not affiliated with, endorsed by, or sponsored by Procore Technologies, Inc. "Procore" is a trademark of Procore Technologies, Inc. diff --git a/assets/css/admin.css b/assets/css/admin.css index 77cb49e..82e6518 100644 --- a/assets/css/admin.css +++ b/assets/css/admin.css @@ -1,5 +1,5 @@ /*! - * Procore Connect admin styles. + * Connect for Procore admin styles. */ .procore-connect-admin .nav-tab-wrapper { diff --git a/assets/css/procore-connect.css b/assets/css/procore-connect.css index 6f2b5df..4725b20 100644 --- a/assets/css/procore-connect.css +++ b/assets/css/procore-connect.css @@ -1,5 +1,5 @@ /*! - * Procore Connect front-end styles. + * Connect for Procore front-end styles. * * Do not edit this file: it is replaced on every plugin update. To restyle the * output, either add rules under Procore -> Display -> Custom CSS, or copy a diff --git a/assets/js/admin.js b/assets/js/admin.js index 8a7edaf..4cf73ac 100644 --- a/assets/js/admin.js +++ b/assets/js/admin.js @@ -1,5 +1,5 @@ /** - * Procore Connect admin behaviour. + * Connect for Procore admin behaviour. * * Plain ES5 with no build step, so the shipped file is the source file. * diff --git a/blocks/procore/block.json b/blocks/procore/block.json index 7b4b205..65e66d7 100644 --- a/blocks/procore/block.json +++ b/blocks/procore/block.json @@ -7,7 +7,7 @@ "icon": "building", "description": "Display data from Procore. Pick what to show, then set the project or company it applies to.", "keywords": [ "procore", "construction", "project", "rfi", "submittal" ], - "textdomain": "procore-connect", + "textdomain": "connect-for-procore", "supports": { "html": false, "align": [ "wide", "full" ], diff --git a/blocks/procore/index.js b/blocks/procore/index.js index 9716885..747e668 100644 --- a/blocks/procore/index.js +++ b/blocks/procore/index.js @@ -1,5 +1,5 @@ /** - * Procore Connect block editor integration. + * Connect for Procore block editor integration. * * Hand-written ES5 against the global `wp.*` runtime, with no build step, so * the file that ships is the file that was authored. @@ -34,24 +34,24 @@ * Everything else remains reachable through the equivalent shortcode. */ var CONTROLS = [ - { key: 'project_id', label: __( 'Project ID', 'procore-connect' ), type: 'number' }, - { key: 'company_id', label: __( 'Company ID', 'procore-connect' ), type: 'number' }, - { key: 'endpoint', label: __( 'Endpoint', 'procore-connect' ), type: 'text' }, - { key: 'field', label: __( 'Field', 'procore-connect' ), type: 'text' }, - { key: 'label', label: __( 'Label', 'procore-connect' ), type: 'text' }, - { key: 'title', label: __( 'Heading', 'procore-connect' ), type: 'text' }, - { key: 'limit', label: __( 'Maximum rows', 'procore-connect' ), type: 'number' }, - { key: 'status', label: __( 'Filter by status', 'procore-connect' ), type: 'text' }, - { key: 'orderby', label: __( 'Sort by field', 'procore-connect' ), type: 'text' }, - { key: 'order', label: __( 'Sort direction', 'procore-connect' ), type: 'select', options: [ - { label: __( 'Ascending', 'procore-connect' ), value: 'asc' }, - { label: __( 'Descending', 'procore-connect' ), value: 'desc' }, + { key: 'project_id', label: __( 'Project ID', 'connect-for-procore' ), type: 'number' }, + { key: 'company_id', label: __( 'Company ID', 'connect-for-procore' ), type: 'number' }, + { key: 'endpoint', label: __( 'Endpoint', 'connect-for-procore' ), type: 'text' }, + { key: 'field', label: __( 'Field', 'connect-for-procore' ), type: 'text' }, + { key: 'label', label: __( 'Label', 'connect-for-procore' ), type: 'text' }, + { key: 'title', label: __( 'Heading', 'connect-for-procore' ), type: 'text' }, + { key: 'limit', label: __( 'Maximum rows', 'connect-for-procore' ), type: 'number' }, + { key: 'status', label: __( 'Filter by status', 'connect-for-procore' ), type: 'text' }, + { key: 'orderby', label: __( 'Sort by field', 'connect-for-procore' ), type: 'text' }, + { key: 'order', label: __( 'Sort direction', 'connect-for-procore' ), type: 'select', options: [ + { label: __( 'Ascending', 'connect-for-procore' ), value: 'asc' }, + { label: __( 'Descending', 'connect-for-procore' ), value: 'desc' }, ] }, - { key: 'columns', label: __( 'Columns', 'procore-connect' ), type: 'text' }, - { key: 'width', label: __( 'Image width', 'procore-connect' ), type: 'number' }, - { key: 'show_email', label: __( 'Show email addresses', 'procore-connect' ), type: 'toggle' }, - { key: 'all', label: __( 'Fetch every page', 'procore-connect' ), type: 'toggle' }, - { key: 'class', label: __( 'Extra CSS classes', 'procore-connect' ), type: 'text' }, + { key: 'columns', label: __( 'Columns', 'connect-for-procore' ), type: 'text' }, + { key: 'width', label: __( 'Image width', 'connect-for-procore' ), type: 'number' }, + { key: 'show_email', label: __( 'Show email addresses', 'connect-for-procore' ), type: 'toggle' }, + { key: 'all', label: __( 'Fetch every page', 'connect-for-procore' ), type: 'toggle' }, + { key: 'class', label: __( 'Extra CSS classes', 'connect-for-procore' ), type: 'text' }, ]; /** @@ -122,7 +122,7 @@ key: control.key, label: control.label, value: value, - options: [ { label: __( 'Default', 'procore-connect' ), value: '' } ].concat( control.options ), + options: [ { label: __( 'Default', 'connect-for-procore' ), value: '' } ].concat( control.options ), onChange: function ( next ) { update( control.key, next ); }, @@ -155,9 +155,9 @@ {}, el( PanelBody, - { title: __( 'Procore data', 'procore-connect' ), initialOpen: true }, + { title: __( 'Procore data', 'connect-for-procore' ), initialOpen: true }, el( SelectControl, { - label: __( 'Show', 'procore-connect' ), + label: __( 'Show', 'connect-for-procore' ), value: attributes.shortcode, options: variations.map( function ( item ) { return { label: item.title, value: item.shortcode }; @@ -171,7 +171,7 @@ ), el( PanelBody, - { title: __( 'Options', 'procore-connect' ), initialOpen: true }, + { title: __( 'Options', 'connect-for-procore' ), initialOpen: true }, buildControls( attributes, setAttributes ) ) ); @@ -183,14 +183,14 @@ EmptyResponsePlaceholder: function () { return el( Placeholder, - { icon: 'building', label: __( 'Procore', 'procore-connect' ) }, - __( 'Nothing to display yet. Check the project and company IDs in the block settings.', 'procore-connect' ) + { icon: 'building', label: __( 'Procore', 'connect-for-procore' ) }, + __( 'Nothing to display yet. Check the project and company IDs in the block settings.', 'connect-for-procore' ) ); }, } ) : el( Placeholder, - { icon: 'building', label: __( 'Procore', 'procore-connect' ) }, + { icon: 'building', label: __( 'Procore', 'connect-for-procore' ) }, variation ? variation.title : attributes.shortcode ); diff --git a/composer.json b/composer.json index 8eb3d7a..70f175e 100644 --- a/composer.json +++ b/composer.json @@ -1,5 +1,5 @@ { - "name": "ibuilder/procore-connect", + "name": "ibuilder/connect-for-procore", "description": "Connect WordPress to the Procore construction management platform and display project data with shortcodes, blocks and a REST proxy.", "type": "wordpress-plugin", "license": "GPL-2.0-or-later", diff --git a/procore-connect.php b/connect-for-procore.php similarity index 89% rename from procore-connect.php rename to connect-for-procore.php index 50773ee..5cc9586 100644 --- a/procore-connect.php +++ b/connect-for-procore.php @@ -1,16 +1,16 @@ - - Procore Connect is licensed GPL-2.0-or-later. It is not affiliated with, endorsed by, or + Connect for Procore is licensed GPL-2.0-or-later. It is not affiliated with, endorsed by, or sponsored by Procore Technologies, Inc. back_to_top: true diff --git a/docs/authentication.md b/docs/authentication.md index c992bd2..60ac66c 100644 --- a/docs/authentication.md +++ b/docs/authentication.md @@ -6,7 +6,7 @@ nav_order: 3 # Authentication -Procore Connect supports both of Procore's OAuth 2.0 grants. Which one you want depends on +Connect for Procore supports both of Procore's OAuth 2.0 grants. Which one you want depends on whether the connection should belong to your organisation or to a person. ## Which mode? @@ -78,7 +78,7 @@ that creates inconsistencies with the manifest. Paste the DMSA Client ID and Client Secret into **Procore → Connection**, pick a default company, and click **Test connection**. -Tokens are valid for 90 minutes. No refresh token is issued for this grant — Procore Connect +Tokens are valid for 90 minutes. No refresh token is issued for this grant — Connect for Procore simply requests a new one when the old one nears expiry, with a two-minute safety margin. --- @@ -105,7 +105,7 @@ It must match character for character, including the scheme and any `www`. ### How the round trip is protected -Procore Connect generates a single-use `state` value, stores it in a short-lived transient, and +Connect for Procore generates a single-use `state` value, stores it in a short-lived transient, and refuses any callback whose `state` does not match. The outbound leg additionally requires a WordPress nonce and the `manage_options` capability. This is what stops someone grafting their own Procore account onto your site by feeding you a crafted callback URL. @@ -116,7 +116,7 @@ Procore invalidates a refresh token the moment it is exchanged and issues a new Two concurrent requests both refreshing would leave one holding a dead token and lock the site out of the API entirely. -Procore Connect guards every refresh with a lock. A request that loses the race waits briefly +Connect for Procore guards every refresh with a lock. A request that loses the race waits briefly and re-reads the token the winner stored, rather than refreshing again. If a refresh token is ever rejected outright, the connection is cleared and the admin is told to reconnect — there is no recovery from a rotated-away refresh token. @@ -135,7 +135,7 @@ there is no recovery from a rotated-away refresh token. A blank Client Secret field on save means "leave the stored value alone". To remove a stored secret, tick **Delete the stored secret**. -If OpenSSL is unavailable, Procore Connect says so in an admin notice and falls back to +If OpenSSL is unavailable, Connect for Procore says so in an admin notice and falls back to unencrypted storage — use the `wp-config.php` constants on such a host. --- diff --git a/docs/blocks.md b/docs/blocks.md index a1a926d..4a07f6a 100644 --- a/docs/blocks.md +++ b/docs/blocks.md @@ -6,7 +6,7 @@ nav_order: 5 # Blocks -Procore Connect registers a single **Procore** block with one inserter variation per shortcode. +Connect for Procore registers a single **Procore** block with one inserter variation per shortcode. Search the inserter for "Procore" and you will see entries for RFIs, submittals, the project list and the rest. @@ -62,6 +62,6 @@ a one-line fix. The file in `blocks/procore/index.js` is the file that runs. ## Turning blocks off -**Procore → Tools → Register Procore Connect blocks.** Existing block content stops rendering +**Procore → Tools → Register Connect for Procore blocks.** Existing block content stops rendering while this is off; converting those blocks to their shortcode equivalents first avoids surprises. diff --git a/docs/caching.md b/docs/caching.md index 4cec413..046bcc0 100644 --- a/docs/caching.md +++ b/docs/caching.md @@ -18,7 +18,7 @@ response: | `X-Rate-Limit-Remaining` | Requests left in it | | `X-Rate-Limit-Reset` | Unix timestamp when it resets | -A page with six uncached Procore Connect shortcodes makes six or more API calls **per visitor**. +A page with six uncached Connect for Procore shortcodes makes six or more API calls **per visitor**. On any site with real traffic that exhausts the spike limit within minutes and the page starts erroring for everyone. @@ -91,7 +91,7 @@ At most three attempts per request, and never longer than a ten-second pause. Procore accepts `page` and `per_page` (keep it at or below 2000) and returns `Total`, `Per-Page` and `Link` headers. -With `all="true"`, Procore Connect walks the `Link: rel="next"` chain rather than incrementing +With `all="true"`, Connect for Procore walks the `Link: rel="next"` chain rather than incrementing page numbers — following the links avoids the off-by-one at the end of the result set, because the `next` link simply disappears on the final page. @@ -126,7 +126,7 @@ ProcoreConnect\Api\Cache::flush( 'projects' ); // React to a purge. add_action( 'procore_connect_cache_flushed', function ( string $group, int $removed ): void { - error_log( "Procore Connect purged {$removed} entries from {$group}" ); + error_log( "Connect for Procore purged {$removed} entries from {$group}" ); }, 10, 2 ); ``` diff --git a/docs/index.md b/docs/index.md index a3bc448..603a73b 100644 --- a/docs/index.md +++ b/docs/index.md @@ -4,12 +4,12 @@ layout: default nav_order: 1 --- -# Procore Connect +# Connect for Procore Publish live [Procore](https://www.procore.com/) construction project data on a WordPress site — with shortcodes, blocks, and a cached REST proxy. -Everything Procore Connect does is **read-only**. It never writes to Procore. +Everything Connect for Procore does is **read-only**. It never writes to Procore. ``` [procore_project_list company_id="4242" limit="10"] @@ -26,8 +26,8 @@ Everything Procore Connect does is **read-only**. It never writes to Procore. | [Installation](installation/) | Get the plugin running | | [Authentication](authentication/) | Create a Procore app and connect | | [Shortcodes](shortcodes/) | Full reference for all eighteen | -| [Blocks](blocks/) | Using Procore Connect in the block editor | -| [Caching & rate limits](caching/) | How Procore Connect stays inside Procore's quotas | +| [Blocks](blocks/) | Using Connect for Procore in the block editor | +| [Caching & rate limits](caching/) | How Connect for Procore stays inside Procore's quotas | | [Templating & styling](templating/) | Change the markup and the CSS | | [REST API](rest-api/) | The optional read-only proxy | | [WP-CLI](wp-cli/) | Command line operations | @@ -81,7 +81,7 @@ WP-CLI. The complete list is in the ## Third-party service -Procore Connect contacts Procore to retrieve the data you ask it to display: `login.procore.com` +Connect for Procore contacts Procore to retrieve the data you ask it to display: `login.procore.com` for authentication and `api.procore.com` for data, or the sandbox or regional hosts you configure. diff --git a/docs/rest-api.md b/docs/rest-api.md index a4486ad..bd0db06 100644 --- a/docs/rest-api.md +++ b/docs/rest-api.md @@ -71,7 +71,7 @@ GET /wp-json/procore-connect/v1/data/rfis?project_id=123&per_page=25 `cached` tells you the response came from the plugin's cache rather than a live API call; `stale` tells you Procore was unreachable and this is the last good copy. Responses also -carry an `X-Procore Connect-Cached` header. +carry an `X-Connect for Procore-Cached` header. ## Example diff --git a/docs/shortcodes.md b/docs/shortcodes.md index 356608c..906dc8e 100644 --- a/docs/shortcodes.md +++ b/docs/shortcodes.md @@ -263,7 +263,7 @@ Nothing outside this registry is callable. That boundary is what makes both ## Privacy Procore project directories contain personal data. Publishing them exposes staff and -subcontractors to address harvesting, so Procore Connect will not output an email address +subcontractors to address harvesting, so Connect for Procore will not output an email address unless **both** of the following are true: 1. **Procore → Display → Never output email addresses** is unticked, and diff --git a/docs/templating.md b/docs/templating.md index 83ebd6e..e721268 100644 --- a/docs/templating.md +++ b/docs/templating.md @@ -30,14 +30,14 @@ rules win without needing `!important`. Markup is stripped on save. ``` To drop the plugin stylesheet entirely and style everything from your theme, untick -**Load the Procore Connect stylesheet**. +**Load the Connect for Procore stylesheet**. ## Template overrides Copy a template out of the plugin and into your theme: ``` -wp-content/plugins/procore-connect/templates/collection.php +wp-content/plugins/connect-for-procore/templates/collection.php → wp-content/themes/your-theme/procore-connect/collection.php ``` diff --git a/docs/troubleshooting.md b/docs/troubleshooting.md index fa17466..2472e89 100644 --- a/docs/troubleshooting.md +++ b/docs/troubleshooting.md @@ -146,9 +146,9 @@ site's own date format. ### Styling is missing -The stylesheet loads only on pages containing Procore Connect output. If output comes from a +The stylesheet loads only on pages containing Connect for Procore output. If output comes from a widget or a direct `do_shortcode()` call in a template, it loads in the footer instead of -the head. Check that **Load the Procore Connect stylesheet** is on under **Display**. +the head. Check that **Load the Connect for Procore stylesheet** is on under **Display**. ### A template override is ignored @@ -162,8 +162,8 @@ the head. Check that **Load the Procore Connect stylesheet** is on under **Displ ### The plugin looks deactivated -Expected. The main file was renamed from `index.php` to `procore-connect.php`, so WordPress sees -a different plugin. Activate Procore Connect once — your settings are imported automatically. +Expected. The main file was renamed from `index.php` to `connect-for-procore.php`, so WordPress sees +a different plugin. Activate Connect for Procore once — your settings are imported automatically. ### It still does not connect diff --git a/docs/upgrading.md b/docs/upgrading.md index 115866b..851dfce 100644 --- a/docs/upgrading.md +++ b/docs/upgrading.md @@ -12,17 +12,17 @@ nav_order: 11 Two renames happened, and both were unavoidable. -**The plugin is now called Procore Connect**, with the slug `procore-connect`. The old +**The plugin is now called Connect for Procore**, with the slug `procore-connect`. The old name contained "wp", which wordpress.org disallows outright in both a plugin name and a slug — keeping it would have ruled out the plugin directory permanently. The GitHub repository is unchanged and still lives at [ibuilder/ProcoreWP](https://github.com/ibuilder/ProcoreWP). -**The main file moved** from `index.php` to `procore-connect.php`, because a main file +**The main file moved** from `index.php` to `connect-for-procore.php`, because a main file called `index.php` fails Plugin Check. WordPress identifies a plugin by its file path, so it treats 2.0.0 as a different plugin and shows it as inactive. -Go to **Plugins**, find **Procore Connect**, and activate it. Your settings are imported +Go to **Plugins**, find **Connect for Procore**, and activate it. Your settings are imported automatically by the upgrade routine — you do not need to re-enter anything. ### 2. Re-run the connection test diff --git a/languages/procore-connect.pot b/languages/connect-for-procore.pot similarity index 95% rename from languages/procore-connect.pot rename to languages/connect-for-procore.pot index 5e76191..f2f339d 100644 --- a/languages/procore-connect.pot +++ b/languages/connect-for-procore.pot @@ -2,7 +2,7 @@ # This file is distributed under the GPL-2.0-or-later license. msgid "" msgstr "" -"Project-Id-Version: Procore Connect 2.0.0\n" +"Project-Id-Version: Connect for Procore 3.0.0\n" "Report-Msgid-Bugs-To: https://github.com/ibuilder/ProcoreWP/issues\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -11,8 +11,8 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "POT-Creation-Date: 2026-08-07T00:00:00+00:00\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Procore Connect build script\n" -"X-Domain: procore-connect\n" +"X-Generator: Connect for Procore build script\n" +"X-Domain: connect-for-procore\n" #. translators: 1: number of companies, 2: comma-separated company names. #: src/Admin/ConnectionTester.php:193 @@ -83,7 +83,7 @@ msgstr "" msgid "Access token" msgstr "" -#: src/Support/Format.php:162 +#: src/Support/Format.php:190 msgid "Active" msgstr "" @@ -244,6 +244,35 @@ msgstr "" msgid "Configuration" msgstr "" +#: src/Admin/SettingsPage.php:59 +#: src/Admin/SettingsPage.php:156 +msgid "Connect for Procore" +msgstr "" + +#. translators: %s: error message from the Procore API. +#: src/Frontend/Shortcodes/AbstractShortcode.php:362 +msgid "Connect for Procore (visible to administrators only): %s" +msgstr "" + +#. translators: %s: settings screen URL. +#: src/Admin/Notices.php:139 +msgid "Connect for Procore could not recover your stored Client Secret. Versions 2.0.0 and 2.0.1 re-encrypted it on every settings save until it became unreadable, so it has been cleared. Please enter it again; this cannot happen on 2.0.2 or later." +msgstr "" + +#. translators: %s: settings screen URL. +#: src/Admin/Notices.php:103 +msgid "Connect for Procore imported your settings from version 1.x. Version 1.x authenticated against the wrong Procore host, so you need to re-run the connection test before shortcodes will return data." +msgstr "" + +#. translators: 1: environment label, 2: API host. +#: src/Admin/Notices.php:176 +msgid "Connect for Procore is pointed at %1$s (%2$s). Front-end shortcodes are showing sandbox data." +msgstr "" + +#: src/Admin/Notices.php:129 +msgid "Connect for Procore repaired your stored Client Secret. Versions 2.0.0 and 2.0.1 re-encrypted it on every settings save, which eventually made it unreadable. Nothing further is needed, though it is worth running Procore → Connection → Test connection to confirm." +msgstr "" + #: src/Admin/SettingsPage.php:248 msgid "Connect to Procore" msgstr "" @@ -471,7 +500,7 @@ msgstr "" msgid "ID" msgstr "" -#: src/Support/Format.php:162 +#: src/Support/Format.php:190 msgid "Inactive" msgstr "" @@ -500,7 +529,7 @@ msgid "Level" msgstr "" #: src/Admin/SettingsPage.php:444 -msgid "Load the Procore Connect stylesheet" +msgid "Load the Connect for Procore stylesheet" msgstr "" #: src/Admin/SettingsPage.php:115 @@ -713,35 +742,6 @@ msgstr "" msgid "Procore" msgstr "" -#: src/Admin/SettingsPage.php:59 -#: src/Admin/SettingsPage.php:156 -msgid "Procore Connect" -msgstr "" - -#. translators: %s: error message from the Procore API. -#: src/Frontend/Shortcodes/AbstractShortcode.php:362 -msgid "Procore Connect (visible to administrators only): %s" -msgstr "" - -#. translators: %s: settings screen URL. -#: src/Admin/Notices.php:139 -msgid "Procore Connect could not recover your stored Client Secret. Versions 2.0.0 and 2.0.1 re-encrypted it on every settings save until it became unreadable, so it has been cleared. Please enter it again; this cannot happen on 2.0.2 or later." -msgstr "" - -#. translators: %s: settings screen URL. -#: src/Admin/Notices.php:103 -msgid "Procore Connect imported your settings from version 1.x. Version 1.x authenticated against the wrong Procore host, so you need to re-run the connection test before shortcodes will return data." -msgstr "" - -#. translators: 1: environment label, 2: API host. -#: src/Admin/Notices.php:176 -msgid "Procore Connect is pointed at %1$s (%2$s). Front-end shortcodes are showing sandbox data." -msgstr "" - -#: src/Admin/Notices.php:129 -msgid "Procore Connect repaired your stored Client Secret. Versions 2.0.0 and 2.0.1 re-encrypted it on every settings save, which eventually made it unreadable. Nothing further is needed, though it is worth running Procore → Connection → Test connection to confirm." -msgstr "" - #: src/Api/Auth/AbstractAuth.php:101 msgid "Procore did not return an access token." msgstr "" @@ -928,7 +928,7 @@ msgid "Redirect URI" msgstr "" #: src/Admin/SettingsPage.php:586 -msgid "Register Procore Connect blocks" +msgid "Register Connect for Procore blocks" msgstr "" #: src/Admin/SettingsPage.php:229 @@ -1105,7 +1105,7 @@ msgid "Test connection" msgstr "" #: src/Rest/Controller.php:177 -msgid "The Procore Connect REST proxy is disabled." +msgid "The Connect for Procore REST proxy is disabled." msgstr "" #: src/Admin/Notices.php:77 @@ -1160,7 +1160,7 @@ msgid "The stored secret is never shown. Leave this blank to keep the current va msgstr "" #: src/Admin/SettingsPage.php:445 -msgid "The stylesheet loads only on pages that actually contain Procore Connect output. Turn it off entirely if your theme styles the markup itself." +msgid "The stylesheet loads only on pages that actually contain Connect for Procore output. Turn it off entirely if your theme styles the markup itself." msgstr "" #: src/Frontend/Shortcodes/AbstractShortcode.php:216 diff --git a/phpcs.xml.dist b/phpcs.xml.dist index d2dfab8..8e3f762 100644 --- a/phpcs.xml.dist +++ b/phpcs.xml.dist @@ -26,7 +26,7 @@ - + diff --git a/readme.txt b/readme.txt index 9d8960f..46a68d2 100644 --- a/readme.txt +++ b/readme.txt @@ -1,10 +1,10 @@ -=== Procore Connect === +=== Connect for Procore === Contributors: ibuilder Tags: procore, construction, project management, shortcode, api Requires at least: 6.5 Tested up to: 7.0 Requires PHP: 7.4 -Stable tag: 2.0.6 +Stable tag: 3.0.0 License: GPLv2 or later License URI: https://www.gnu.org/licenses/gpl-2.0.html @@ -12,9 +12,9 @@ Publish live Procore project data on your WordPress site with shortcodes and blo == Description == -Procore Connect connects your WordPress site to the Procore construction management platform and publishes project data on the front end: project directories, team members, drawings, specifications, RFIs, submittals, punch lists, daily logs, change orders and more. +Connect for Procore connects your WordPress site to the Procore construction management platform and publishes project data on the front end: project directories, team members, drawings, specifications, RFIs, submittals, punch lists, daily logs, change orders and more. -Data is read-only. Procore Connect never writes to Procore. +Data is read-only. Connect for Procore never writes to Procore. = Built for the way Procore actually works = @@ -26,7 +26,7 @@ Data is read-only. Procore Connect never writes to Procore. = Privacy first = -Procore project directories contain personal data. Procore Connect will not publish email addresses unless you turn off the global suppression setting **and** opt in on the individual shortcode. Error messages from Procore, which routinely name accounts and permissions, are shown to administrators only. +Procore project directories contain personal data. Connect for Procore will not publish email addresses unless you turn off the global suppression setting **and** opt in on the individual shortcode. Error messages from Procore, which routinely name accounts and permissions, are shown to administrators only. = Shortcodes = @@ -78,7 +78,7 @@ Data sent: your Procore Client ID and Client Secret during authentication, and t == Installation == -1. Upload the plugin to `/wp-content/plugins/procore-connect/` or install it through the Plugins screen. +1. Upload the plugin to `/wp-content/plugins/connect-for-procore/` or install it through the Plugins screen. 2. Activate it. 3. Go to **Procore → Connection** and enter your Client ID and Client Secret. 4. Choose a default company, then click **Test connection**. @@ -127,6 +127,14 @@ Yes. Caching goes through the transient API, so a persistent object cache such a == Changelog == += 3.0.0 = + +* Renamed from "Procore Connect" to "Connect for Procore". WordPress.org does not permit a plugin name or slug to begin with someone else's trademark, and Procore is a registered trademark of Procore Technologies, Inc. The new name follows the format WordPress.org prescribes for integrations built by non-employees. +* **You need to activate the plugin once after updating.** WordPress identifies a plugin by its directory, and the directory changed, so it sees a new plugin. +* Your settings, template overrides and custom CSS are all preserved. Option names, the REST namespace `/wp-json/procore-connect/v1/`, the `yourtheme/procore-connect/` override directory, the CSS classes, the block and the `wp procore-connect` CLI command are all deliberately unchanged. +* Fixed: the REST proxy sent a cache-status header named `X-Procore Connect-Cached`, which contains a space and is not a valid HTTP header name. It is now `X-Connect-For-Procore-Cached`. +* Fixed: the User-Agent contained a space inside its product token; it is now `ConnectForProcore/3.0.0`. + = 2.0.6 = * Fixed: a column you named in `columns=` could be dropped. 2.0.5 applied its empty-column filter to hand-written column lists too, so `[procore_team columns="name,email_address"]` rendered only Name. An explicit list is now rendered exactly as written; only the default column set is trimmed. @@ -193,6 +201,9 @@ A complete rewrite. See the upgrade notice below before updating. == Upgrade Notice == += 3.0.0 = +The plugin is now called Connect for Procore, to comply with WordPress.org's trademark naming rule. Activate it once after updating — WordPress sees the renamed directory as a new plugin. Your settings, template overrides and custom CSS are preserved. + = 2.0.6 = Corrects the 2.0.5 column-hiding fix, which dropped columns you had asked for by name and did not drop the empty ones it claimed to. Recommended for anyone on 2.0.5 who sets `columns=` on a shortcode. diff --git a/src/Admin/Ajax.php b/src/Admin/Ajax.php index 87ddb74..17c3cf5 100644 --- a/src/Admin/Ajax.php +++ b/src/Admin/Ajax.php @@ -74,7 +74,7 @@ public function clear_cache(): void { 'removed' => $removed, 'message' => sprintf( /* translators: %d: number of cache entries removed. */ - _n( 'Removed %d cached response.', 'Removed %d cached responses.', $removed, 'procore-connect' ), + _n( 'Removed %d cached response.', 'Removed %d cached responses.', $removed, 'connect-for-procore' ), $removed ), 'stats' => Cache::stats(), @@ -157,7 +157,7 @@ public function disconnect(): void { Client::reset_circuit(); Logger::info( 'Procore connection reset from the admin screen.' ); - wp_send_json_success( array( 'message' => __( 'Disconnected from Procore.', 'procore-connect' ) ) ); + wp_send_json_success( array( 'message' => __( 'Disconnected from Procore.', 'connect-for-procore' ) ) ); } /** @@ -167,7 +167,7 @@ public function disconnect(): void { */ private function authorise(): void { if ( ! current_user_can( 'manage_options' ) ) { - wp_send_json_error( array( 'message' => __( 'You do not have permission to do that.', 'procore-connect' ) ), 403 ); + wp_send_json_error( array( 'message' => __( 'You do not have permission to do that.', 'connect-for-procore' ) ), 403 ); } check_ajax_referer( self::NONCE, 'nonce' ); diff --git a/src/Admin/ConnectionTester.php b/src/Admin/ConnectionTester.php index 875dabf..0c1380d 100644 --- a/src/Admin/ConnectionTester.php +++ b/src/Admin/ConnectionTester.php @@ -71,24 +71,24 @@ private function check_prerequisites(): array { $issues = array(); if ( '' === Settings::client_id() ) { - $issues[] = __( 'No Client ID is set.', 'procore-connect' ); + $issues[] = __( 'No Client ID is set.', 'connect-for-procore' ); } if ( '' === Settings::client_secret() ) { - $issues[] = __( 'No Client Secret is set.', 'procore-connect' ); + $issues[] = __( 'No Client Secret is set.', 'connect-for-procore' ); } if ( ! Encryption::is_strong() ) { - $issues[] = __( 'OpenSSL is unavailable, so credentials cannot be encrypted at rest. Define PROCORE_CONNECT_CLIENT_SECRET in wp-config.php instead.', 'procore-connect' ); + $issues[] = __( 'OpenSSL is unavailable, so credentials cannot be encrypted at rest. Define PROCORE_CONNECT_CLIENT_SECRET in wp-config.php instead.', 'connect-for-procore' ); } return $this->step( - __( 'Configuration', 'procore-connect' ), + __( 'Configuration', 'connect-for-procore' ), empty( $issues ), empty( $issues ) ? sprintf( /* translators: 1: environment label, 2: API host. */ - __( 'Ready. Environment: %1$s (%2$s).', 'procore-connect' ), + __( 'Ready. Environment: %1$s (%2$s).', 'connect-for-procore' ), Environment::choices()[ Environment::current() ], Environment::api_host() ) @@ -106,24 +106,24 @@ private function check_token(): array { $auth = $client->auth(); if ( ! $auth->is_configured() ) { - return $this->step( __( 'Access token', 'procore-connect' ), false, __( 'Credentials are incomplete.', 'procore-connect' ) ); + return $this->step( __( 'Access token', 'connect-for-procore' ), false, __( 'Credentials are incomplete.', 'connect-for-procore' ) ); } $token = $auth->access_token(); if ( is_wp_error( $token ) ) { - return $this->step( __( 'Access token', 'procore-connect' ), false, $token->get_error_message() ); + return $this->step( __( 'Access token', 'connect-for-procore' ), false, $token->get_error_message() ); } $stored = TokenStore::all(); $expires = (int) $stored['expires_at']; return $this->step( - __( 'Access token', 'procore-connect' ), + __( 'Access token', 'connect-for-procore' ), true, sprintf( /* translators: 1: grant type label, 2: human readable time difference. */ - __( 'Obtained via %1$s. Valid for another %2$s.', 'procore-connect' ), + __( 'Obtained via %1$s. Valid for another %2$s.', 'connect-for-procore' ), $auth->label(), human_time_diff( time(), max( $expires, time() ) ) ) @@ -139,23 +139,23 @@ private function check_identity(): array { $me = Client::instance()->fetch( 'me', array(), array( 'bypass_cache' => true ) ); if ( is_wp_error( $me ) ) { - return $this->step( __( 'Authenticated account', 'procore-connect' ), false, $me->get_error_message() ); + return $this->step( __( 'Authenticated account', 'connect-for-procore' ), false, $me->get_error_message() ); } $name = Arr::str( $me, 'name' ); $login = Arr::str( $me, 'login' ); return $this->step( - __( 'Authenticated account', 'procore-connect' ), + __( 'Authenticated account', 'connect-for-procore' ), true, '' !== $name || '' !== $login ? sprintf( /* translators: 1: account display name, 2: account login. */ - __( 'Connected as %1$s (%2$s).', 'procore-connect' ), - '' !== $name ? $name : __( 'service account', 'procore-connect' ), - '' !== $login ? $login : __( 'no login', 'procore-connect' ) + __( 'Connected as %1$s (%2$s).', 'connect-for-procore' ), + '' !== $name ? $name : __( 'service account', 'connect-for-procore' ), + '' !== $login ? $login : __( 'no login', 'connect-for-procore' ) ) - : __( 'Connected.', 'procore-connect' ) + : __( 'Connected.', 'connect-for-procore' ) ); } @@ -168,14 +168,14 @@ private function check_companies(): array { $companies = $this->companies(); if ( is_wp_error( $companies ) ) { - return $this->step( __( 'Company access', 'procore-connect' ), false, $companies->get_error_message() ); + return $this->step( __( 'Company access', 'connect-for-procore' ), false, $companies->get_error_message() ); } if ( empty( $companies ) ) { return $this->step( - __( 'Company access', 'procore-connect' ), + __( 'Company access', 'connect-for-procore' ), false, - __( 'Procore returned no companies. Ask a company administrator to install the app and grant it access.', 'procore-connect' ) + __( 'Procore returned no companies. Ask a company administrator to install the app and grant it access.', 'connect-for-procore' ) ); } @@ -186,11 +186,11 @@ private function check_companies(): array { } return $this->step( - __( 'Company access', 'procore-connect' ), + __( 'Company access', 'connect-for-procore' ), true, sprintf( /* translators: 1: number of companies, 2: comma-separated company names. */ - _n( '%1$d company available: %2$s', '%1$d companies available: %2$s', count( $companies ), 'procore-connect' ), + _n( '%1$d company available: %2$s', '%1$d companies available: %2$s', count( $companies ), 'connect-for-procore' ), count( $companies ), implode( ', ', $names ) ) @@ -207,9 +207,9 @@ private function check_company_access(): array { if ( $company <= 0 ) { return $this->step( - __( 'Default company', 'procore-connect' ), + __( 'Default company', 'connect-for-procore' ), false, - __( 'No default company is set. Choose one below, or pass company_id in every shortcode.', 'procore-connect' ) + __( 'No default company is set. Choose one below, or pass company_id in every shortcode.', 'connect-for-procore' ) ); } @@ -224,23 +224,23 @@ private function check_company_access(): array { ); if ( is_wp_error( $projects ) ) { - return $this->step( __( 'Default company', 'procore-connect' ), false, $projects->get_error_message() ); + return $this->step( __( 'Default company', 'connect-for-procore' ), false, $projects->get_error_message() ); } $total = Client::instance()->meta()['total']; return $this->step( - __( 'Default company', 'procore-connect' ), + __( 'Default company', 'connect-for-procore' ), true, null === $total ? sprintf( /* translators: %d: company ID. */ - __( 'Projects are readable for company %d.', 'procore-connect' ), + __( 'Projects are readable for company %d.', 'connect-for-procore' ), $company ) : sprintf( /* translators: 1: number of projects, 2: company ID. */ - _n( '%1$d project visible in company %2$d.', '%1$d projects visible in company %2$d.', (int) $total, 'procore-connect' ), + _n( '%1$d project visible in company %2$d.', '%1$d projects visible in company %2$d.', (int) $total, 'connect-for-procore' ), (int) $total, $company ) @@ -256,17 +256,17 @@ private function check_rate_limit(): array { $limit = Client::rate_limit(); if ( 0 === $limit['limit'] ) { - return $this->step( __( 'Rate limit', 'procore-connect' ), true, __( 'Procore has not reported a rate limit yet.', 'procore-connect' ) ); + return $this->step( __( 'Rate limit', 'connect-for-procore' ), true, __( 'Procore has not reported a rate limit yet.', 'connect-for-procore' ) ); } $healthy = $limit['limit'] < 1 || ( $limit['remaining'] / max( 1, $limit['limit'] ) ) > 0.1; return $this->step( - __( 'Rate limit', 'procore-connect' ), + __( 'Rate limit', 'connect-for-procore' ), $healthy, sprintf( /* translators: 1: remaining requests, 2: total allowed requests, 3: human readable time until reset. */ - __( '%1$d of %2$d requests remaining; resets in %3$s.', 'procore-connect' ), + __( '%1$d of %2$d requests remaining; resets in %3$s.', 'connect-for-procore' ), $limit['remaining'], $limit['limit'], human_time_diff( time(), max( $limit['reset'], time() ) ) @@ -295,7 +295,7 @@ private function probe_endpoints(): array { 'label' => (string) $definition['label'], 'permission' => (string) $definition['permission'], 'status' => 'skipped', - 'message' => __( 'No project was available to test against.', 'procore-connect' ), + 'message' => __( 'No project was available to test against.', 'connect-for-procore' ), ); continue; } @@ -327,7 +327,7 @@ private function probe_endpoints(): array { 'label' => (string) $definition['label'], 'permission' => (string) $definition['permission'], 'status' => 'ok', - 'message' => __( 'Readable.', 'procore-connect' ), + 'message' => __( 'Readable.', 'connect-for-procore' ), ); }//end foreach @@ -415,10 +415,10 @@ private function report( array $steps, array $probes ): array { 'probes' => $probes, 'ok' => 0 === $failed, 'summary' => 0 === $failed - ? __( 'Everything checked out.', 'procore-connect' ) + ? __( 'Everything checked out.', 'connect-for-procore' ) : sprintf( /* translators: %d: number of failed checks. */ - _n( '%d check needs attention.', '%d checks need attention.', $failed, 'procore-connect' ), + _n( '%d check needs attention.', '%d checks need attention.', $failed, 'connect-for-procore' ), $failed ), ); diff --git a/src/Admin/Notices.php b/src/Admin/Notices.php index b55ee93..88ce8dd 100644 --- a/src/Admin/Notices.php +++ b/src/Admin/Notices.php @@ -66,7 +66,7 @@ private function oauth_result(): void { } if ( 'connected' === $status ) { - $this->notice( 'success', __( 'Connected to Procore.', 'procore-connect' ) ); + $this->notice( 'success', __( 'Connected to Procore.', 'connect-for-procore' ) ); return; } @@ -74,9 +74,9 @@ private function oauth_result(): void { $stored_error = (string) get_transient( 'procore_connect_oauth_error' ); $messages = array( - 'denied' => __( 'The Procore authorization request was declined.', 'procore-connect' ), - 'missing_credentials' => __( 'Enter a Client ID and Client Secret before connecting.', 'procore-connect' ), - 'failed' => '' !== $stored_error ? $stored_error : __( 'The Procore connection could not be completed.', 'procore-connect' ), + 'denied' => __( 'The Procore authorization request was declined.', 'connect-for-procore' ), + 'missing_credentials' => __( 'Enter a Client ID and Client Secret before connecting.', 'connect-for-procore' ), + 'failed' => '' !== $stored_error ? $stored_error : __( 'The Procore connection could not be completed.', 'connect-for-procore' ), ); delete_transient( 'procore_connect_oauth_error' ); @@ -100,7 +100,7 @@ private function migration_notice(): void { 'warning', sprintf( /* translators: %s: settings screen URL. */ - __( 'Procore Connect imported your settings from version 1.x. Version 1.x authenticated against the wrong Procore host, so you need to re-run the connection test before shortcodes will return data.', 'procore-connect' ), + __( 'Connect for Procore imported your settings from version 1.x. Version 1.x authenticated against the wrong Procore host, so you need to re-run the connection test before shortcodes will return data.', 'connect-for-procore' ), esc_url( admin_url( 'admin.php?page=procore-connect' ) ) ), true @@ -126,7 +126,7 @@ private function secret_repair_notice(): void { if ( 'repaired' === $state ) { $this->notice( 'success', - __( 'Procore Connect repaired your stored Client Secret. Versions 2.0.0 and 2.0.1 re-encrypted it on every settings save, which eventually made it unreadable. Nothing further is needed, though it is worth running Procore → Connection → Test connection to confirm.', 'procore-connect' ) + __( 'Connect for Procore repaired your stored Client Secret. Versions 2.0.0 and 2.0.1 re-encrypted it on every settings save, which eventually made it unreadable. Nothing further is needed, though it is worth running Procore → Connection → Test connection to confirm.', 'connect-for-procore' ) ); return; @@ -136,7 +136,7 @@ private function secret_repair_notice(): void { 'error', sprintf( /* translators: %s: settings screen URL. */ - __( 'Procore Connect could not recover your stored Client Secret. Versions 2.0.0 and 2.0.1 re-encrypted it on every settings save until it became unreadable, so it has been cleared. Please enter it again; this cannot happen on 2.0.2 or later.', 'procore-connect' ), + __( 'Connect for Procore could not recover your stored Client Secret. Versions 2.0.0 and 2.0.1 re-encrypted it on every settings save until it became unreadable, so it has been cleared. Please enter it again; this cannot happen on 2.0.2 or later.', 'connect-for-procore' ), esc_url( admin_url( 'admin.php?page=procore-connect' ) ) ), true @@ -155,7 +155,7 @@ private function encryption_notice(): void { $this->notice( 'warning', - __( 'OpenSSL is not available on this server, so your Procore Client Secret cannot be encrypted in the database. Define PROCORE_CONNECT_CLIENT_SECRET in wp-config.php instead.', 'procore-connect' ) + __( 'OpenSSL is not available on this server, so your Procore Client Secret cannot be encrypted in the database. Define PROCORE_CONNECT_CLIENT_SECRET in wp-config.php instead.', 'connect-for-procore' ) ); } @@ -173,7 +173,7 @@ private function environment_notice(): void { 'info', sprintf( /* translators: 1: environment label, 2: API host. */ - __( 'Procore Connect is pointed at %1$s (%2$s). Front-end shortcodes are showing sandbox data.', 'procore-connect' ), + __( 'Connect for Procore is pointed at %1$s (%2$s). Front-end shortcodes are showing sandbox data.', 'connect-for-procore' ), Environment::choices()[ Environment::current() ], Environment::api_host() ) @@ -196,7 +196,7 @@ private function circuit_notice(): void { 'error', sprintf( /* translators: %s: human readable time difference. */ - __( 'Procore requests are paused after repeated failures and will resume in %s. Cached data is being served in the meantime.', 'procore-connect' ), + __( 'Procore requests are paused after repeated failures and will resume in %s. Cached data is being served in the meantime.', 'connect-for-procore' ), human_time_diff( time(), $state['open_until'] ) ) ); @@ -205,12 +205,12 @@ private function circuit_notice(): void { /** * Whether the current screen belongs to this plugin. * - * @return bool True on a Procore Connect screen. + * @return bool True on a Connect for Procore screen. */ private function on_plugin_screen(): bool { $screen = function_exists( 'get_current_screen' ) ? get_current_screen() : null; - return $screen instanceof \WP_Screen && false !== strpos( (string) $screen->id, 'procore-connect' ); + return $screen instanceof \WP_Screen && false !== strpos( (string) $screen->id, 'connect-for-procore' ); } /** diff --git a/src/Admin/OAuthController.php b/src/Admin/OAuthController.php index 702bf0f..7e0e4f7 100644 --- a/src/Admin/OAuthController.php +++ b/src/Admin/OAuthController.php @@ -45,7 +45,7 @@ public function register(): void { */ public function connect(): void { if ( ! current_user_can( 'manage_options' ) ) { - wp_die( esc_html__( 'You do not have permission to connect this site to Procore.', 'procore-connect' ), '', array( 'response' => 403 ) ); + wp_die( esc_html__( 'You do not have permission to connect this site to Procore.', 'connect-for-procore' ), '', array( 'response' => 403 ) ); } check_admin_referer( self::NONCE ); @@ -74,7 +74,7 @@ public function connect(): void { */ public function callback(): void { if ( ! current_user_can( 'manage_options' ) ) { - wp_die( esc_html__( 'You do not have permission to complete this connection.', 'procore-connect' ), '', array( 'response' => 403 ) ); + wp_die( esc_html__( 'You do not have permission to complete this connection.', 'connect-for-procore' ), '', array( 'response' => 403 ) ); } // phpcs:disable WordPress.Security.NonceVerification.Recommended -- Verified via the one-time OAuth state parameter below. diff --git a/src/Admin/SettingsPage.php b/src/Admin/SettingsPage.php index 2504915..07753ea 100644 --- a/src/Admin/SettingsPage.php +++ b/src/Admin/SettingsPage.php @@ -56,8 +56,8 @@ public function register(): void { */ public function add_menu(): void { add_menu_page( - __( 'Procore Connect', 'procore-connect' ), - __( 'Procore', 'procore-connect' ), + __( 'Connect for Procore', 'connect-for-procore' ), + __( 'Procore', 'connect-for-procore' ), self::CAPABILITY, self::SLUG, array( $this, 'render' ), @@ -110,13 +110,13 @@ public function enqueue( string $hook ): void { 'ajaxUrl' => admin_url( 'admin-ajax.php' ), 'nonce' => wp_create_nonce( Ajax::NONCE ), 'strings' => array( - 'testing' => __( 'Running checks…', 'procore-connect' ), - 'clearing' => __( 'Clearing…', 'procore-connect' ), - 'loading' => __( 'Loading…', 'procore-connect' ), - 'failed' => __( 'The request failed. Check your connection and try again.', 'procore-connect' ), - 'copied' => __( 'Copied', 'procore-connect' ), - 'confirmed' => __( 'Disconnect this site from Procore?', 'procore-connect' ), - 'skipped' => __( 'Skipped', 'procore-connect' ), + 'testing' => __( 'Running checks…', 'connect-for-procore' ), + 'clearing' => __( 'Clearing…', 'connect-for-procore' ), + 'loading' => __( 'Loading…', 'connect-for-procore' ), + 'failed' => __( 'The request failed. Check your connection and try again.', 'connect-for-procore' ), + 'copied' => __( 'Copied', 'connect-for-procore' ), + 'confirmed' => __( 'Disconnect this site from Procore?', 'connect-for-procore' ), + 'skipped' => __( 'Skipped', 'connect-for-procore' ), ), ) ); @@ -136,16 +136,16 @@ public function enqueue( string $hook ): void { */ public function render(): void { if ( ! current_user_can( self::CAPABILITY ) ) { - wp_die( esc_html__( 'You do not have permission to view this page.', 'procore-connect' ), '', array( 'response' => 403 ) ); + wp_die( esc_html__( 'You do not have permission to view this page.', 'connect-for-procore' ), '', array( 'response' => 403 ) ); } $tabs = array( - 'connection' => __( 'Connection', 'procore-connect' ), - 'display' => __( 'Display', 'procore-connect' ), - 'cache' => __( 'Cache', 'procore-connect' ), - 'shortcodes' => __( 'Shortcodes', 'procore-connect' ), - 'status' => __( 'Status', 'procore-connect' ), - 'tools' => __( 'Tools', 'procore-connect' ), + 'connection' => __( 'Connection', 'connect-for-procore' ), + 'display' => __( 'Display', 'connect-for-procore' ), + 'cache' => __( 'Cache', 'connect-for-procore' ), + 'shortcodes' => __( 'Shortcodes', 'connect-for-procore' ), + 'status' => __( 'Status', 'connect-for-procore' ), + 'tools' => __( 'Tools', 'connect-for-procore' ), ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only tab selector. @@ -153,7 +153,7 @@ public function render(): void { $active = array_key_exists( $active, $tabs ) ? $active : 'connection'; echo '
'; - echo '

' . esc_html__( 'Procore Connect', 'procore-connect' ) . '

'; + echo '

' . esc_html__( 'Connect for Procore', 'connect-for-procore' ) . '

'; echo '