From b14a5f51d7861a88a929ea43b94c19b83650c002 Mon Sep 17 00:00:00 2001 From: "Matthew M. Emma" Date: Sat, 15 Aug 2026 19:52:30 -0700 Subject: [PATCH] Rename to Connect for Procore for WordPress.org guideline 17 "Procore" is a registered trademark of Procore Technologies, Inc. Guideline 17 forbids a plugin slug or display name that *begins* with someone else's trademark, so "Procore Connect" would have been rejected on human review. The new name uses the format the guideline itself prescribes for integrations written by non-employees. Plugin Check does not catch this. Its trademark test compares against a hardcoded list of well-known brands in Trademarks_Check.php and "procore" is not on it, so the plugin passed clean at severity 1 with experimental checks on while still being unshippable. That is worth recording: a green Plugin Check is necessary, not sufficient. Renamed: slug, directory, main file, display name, text domain (378 gettext calls plus wp_set_script_translations and block.json), the POT, and the wordpress.org banner and icon, which the guideline also covers. Deliberately not renamed, because none of it affects guideline 17 and all of it would break working sites: 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. Settings, template overrides and custom CSS therefore survive the rename; only a one-time reactivation is needed, because WordPress identifies a plugin by its directory. Two real defects surfaced while auditing the old name, both artifacts of the earlier ProcoreWP to Procore Connect rename: - The REST proxy sent a cache-status header named `X-Procore Connect-Cached`. A header field name may not contain a space (RFC 7230); it is now `X-Connect-For-Procore-Cached`. - The User-Agent product token was `Procore Connect/2.0.6`, which is likewise not a valid token. It is now `ConnectForProcore/3.0.0`. Major version because the directory change forces a reactivation. Verified: 106 tests pass; PHPCS clean across 52 files with the text_domain property switched to connect-for-procore, so it would have failed on any missed gettext call; Plugin Check clean on the staged distributable across every category with experimental checks at severity 1; and the plugin activates in a real WordPress 7.0 install with no textdomain-too-early notice, with shortcodes, the opt-in REST routes and the WP-CLI subcommands all confirmed working. Co-Authored-By: Claude Opus 5 --- .github/ISSUE_TEMPLATE/bug_report.yml | 2 +- .github/ISSUE_TEMPLATE/feature_request.yml | 2 +- .github/workflows/plugin-check.yml | 8 +- .github/workflows/release.yml | 14 +- .wordpress-org/banner-1544x500.png | Bin 34174 -> 35096 bytes .wordpress-org/banner-772x250.png | Bin 16228 -> 17018 bytes CHANGELOG.md | 41 ++- CONTRIBUTING.md | 4 +- README.md | 12 +- assets/css/admin.css | 2 +- assets/css/procore-connect.css | 2 +- assets/js/admin.js | 2 +- blocks/procore/block.json | 2 +- blocks/procore/index.js | 50 ++-- composer.json | 2 +- ...ore-connect.php => connect-for-procore.php | 10 +- docs/_config.yml | 4 +- docs/authentication.md | 10 +- docs/blocks.md | 4 +- docs/caching.md | 6 +- docs/index.md | 10 +- docs/rest-api.md | 2 +- docs/shortcodes.md | 2 +- docs/templating.md | 4 +- docs/troubleshooting.md | 8 +- docs/upgrading.md | 6 +- ...re-connect.pot => connect-for-procore.pot} | 76 +++--- phpcs.xml.dist | 2 +- readme.txt | 23 +- src/Admin/Ajax.php | 6 +- src/Admin/ConnectionTester.php | 66 ++--- src/Admin/Notices.php | 24 +- src/Admin/OAuthController.php | 4 +- src/Admin/SettingsPage.php | 244 +++++++++--------- src/Api/Auth/AbstractAuth.php | 10 +- src/Api/Auth/AuthorizationCode.php | 14 +- src/Api/Auth/ClientCredentials.php | 4 +- src/Api/Client.php | 18 +- src/Api/Endpoints.php | 80 +++--- src/Api/Environment.php | 8 +- src/Api/TokenStore.php | 2 +- src/Blocks/Registrar.php | 6 +- src/Cli/Commands.php | 2 +- src/Frontend/Assets.php | 2 +- src/Frontend/Renderer.php | 2 +- src/Frontend/Shortcodes/AbstractShortcode.php | 10 +- src/Frontend/Shortcodes/DataShortcode.php | 4 +- src/Frontend/Shortcodes/FieldShortcode.php | 6 +- src/Frontend/Shortcodes/ImageShortcode.php | 6 +- src/Frontend/Shortcodes/MapShortcode.php | 2 +- src/Frontend/Shortcodes/Registrar.php | 178 ++++++------- src/Plugin.php | 2 +- src/Rest/Controller.php | 6 +- src/Support/Arr.php | 2 +- src/Support/Format.php | 2 +- src/Support/Logger.php | 2 +- templates/map.php | 2 +- tests/bootstrap.php | 6 +- tests/unit/ClientTest.php | 3 +- uninstall.php | 2 +- 60 files changed, 541 insertions(+), 494 deletions(-) rename procore-connect.php => connect-for-procore.php (89%) rename languages/{procore-connect.pot => connect-for-procore.pot} (95%) 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 533e08a80d7cf29cf399402ac3f3dda3695df920..8433afc5e71fb62118dfa4b0eedd5787e2f15658 100644 GIT binary patch literal 35096 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 literal 34174 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 JB0imO{|6k_2Il|( 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 '